Cycle
Cycle is a stack-based programming language designed by User:EZ132. It was designed to be extremely simple, having only two types of commands, yet easy to program in.
Overview
Cycle programs consist of a list of statements and code blocks. When a program is executed, its statements and code blocks are put onto a main cycle. It then starts from the beginning and goes around and around the cycle and executing statements when it encounters them. It stops either when there are no statements in the cycle or when an error occurs.
Cycle is based on three fundamental elements.
* Statements and code blocks * Stacks and stack-like objects * Numbers
Statements and code blocks are executable elements, that is, they can be run. These are the building blocks of Cycle. A statement simply consists of a direction to execute followed by a semicolon. A code block is an array of statements enclosed by curly brackets. An example of a statement is NUMIO->MEM;
, while an example of a code block is
{ NUMIO->ADD; NUMIO->ADD; ADD->NUMIO; }
Statements can also be marked onetime by prefixing with a single quote, which will cause it to be deleted after running for the first time. However, statements inside code blocks cannot be marked onetime.
When Cycle encounters a statement, it executes it, but when it encounters a code block, it will not. However, code blocks are executable in different ways, and they can be pretty useful.
Stacks and stack-like objects should be familiar from other esolangs. Basically, they can be pushed and popped from. Cycle only provides one "true" stack, MEM, but there are a lot of other useful "pseudo-stacks" as well. Here is a table of all stacks and their behaviors:
Stack name | Behavior on push | Behavior on pop |
---|---|---|
MAIN | Writes pushed code block/statement before the current statement. Errors on numbers | Deletes and returns next statement |
BLOCKS | Pushed onto it normally and code blocks are pushed onto it when encountered in the program. Errors on numbers | Popped normally and returned |
MEM | Pushed normally | Popped normally and returned. Errors if empty |
ADD | Added to the stored value. Errors on statements and code blocks | Stored value is returned and reset to 0 |
SUB | If the stored value is RESET, then set the stored value to the pushed value. Otherwise, subtract the pushed value from the stored value. Errors on statements and code blocks | Stored value is returned and set to RESET. If stored value is RESET, it errors |
MUL | Multiplied to the stored value. Errors on statements and code blocks | Stored value is returned and reset to 1 |
DIV | If the stored value is RESET, then set the stored value to the pushed value. Otherwise, divide the stored value by the pushed value. Errors on statements and code blocks | Stored value is returned and set to RESET. If stored value is RESET, it errors |
MOD | If the stored value is RESET, then set the stored value to the pushed value. Otherwise, take the remainder of the stored value by the pushed value. Note that mod always returns a positive number. Errors on statements and code blocks | Stored value is returned and set to RESET. If stored value is RESET, it errors |
NEG | Sets stored value to the negative of the pushed value. Errors on statements and code blocks | Stored value is returned |
ABS | Sets stored value to the absolute value of the pushed value. Errors on statements and code blocks | Stored value is returned |
NUMIO | Prints out pushed value as a number. Errors on statements and code blocks | Gets numeric input from user, terminated by the first non-numeric inputted character.. Errors if input is not a number |
TEXTIO | Prints out pushed value an an ASCII character. Errors on statements and code blocks | Inputs a character from user |
EXEC | Executes pushed statement/code block. Errors on numbers, and if the statement/code block errors. | Errors |
IF | If the pushed value is a number, it will execute the next code blocks until the next number if it is nonzero | Returns the last pushed number, and errors if there isn't one |
IFZ | If the pushed value is a number, it will execute the next code blocks until the next number if it is zero | Returns the last pushed number, and errors if there isn't one |
LOOP | If the pushed value is a number, it will execute the next code blocks until the next number that many times | Returns the last pushed number, and errors if there isn't one |
WHILE | If the pushed value is a statement/code block, it will repeatedly execute it until the statement/code block pushes a number onto `WHILE` | Errors |
Some of the stacks reference stored values. MEM starts off as an empty stack. ADD and MUL start as 0 and 1, respectively. SUB, DIV, and MOD start as RESET. NEG starts with the value 0.
Numbers are simple, and can be written by number literals like 0, 10, -21.
As mentioned before, Cycle programs consist of statements and code blocks, and code blocks are made out of statements. Statements themselves have the form STACK1->STACK2
, where STACK1 and STACK2 are valid stack names. This will pop the last value off of STACK1, or do whatever happens when STACK1 is popped from, and push that onto STACK2, or do whatever happens on push. When the stack pop returns multiple values, they will be pushed onto the new stack in reverse order. In addition, numbers can be directly treated as stacks. The syntax is (number)->STACK
. This will take number and push its value onto STACK. For example, the statement (123)->NUMIO;
will push the number 123 onto the stack NUMIO, which will cause it to print 123. Another example is NUMIO->MEM;
, which will get an input number and push it onto the memory stack.
A # sign will make Cycle ignore the rest of the line, so it can be used to make comments.
Sample programs
Prints out about 20 Fibonacci numbers before stopping.
# Fibonacci number caluculator # Initialize the values '(1)->MEM; '(1)->MEM; '(1)->NUMIO; '(32)->TEXTIO; '(1)->NUMIO; '(20)->MEM; (32)->TEXTIO; # Print out seperating space MEM->SUB; # Move counter and prepare to decrement # Just caluculate the next term and remove the oldest term MEM->NEG; NEG->NEG; MEM->ADD; NEG->ADD; NEG->MEM; ADD->NEG; NEG->NEG; NEG->MEM; NEG->NUMIO; # Print out next term (1)->SUB; # Decrement counter SUB->NEG; NEG->NEG; { WHILE->MEM; # Intentionally error } # If counter reaches zero, exit, else, push the updated counter onto MEM NEG->IFZ; BLOCKS->IFZ; NEG->MEM;
99 bottles
# Prints out the 99 bottles of beer on the wall song # Very long since the text has to be printed character by character '(99)->MEM; MEM->NEG; NEG->NEG; NEG->NUMIO; (32)->TEXTIO; (98)->TEXTIO; (111)->TEXTIO; (116)->TEXTIO; (116)->TEXTIO; (108)->TEXTIO; (101)->TEXTIO; (115)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (102)->TEXTIO; (32)->TEXTIO; (98)->TEXTIO; (101)->TEXTIO; (101)->TEXTIO; (114)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (110)->TEXTIO; (32)->TEXTIO; (116)->TEXTIO; (104)->TEXTIO; (101)->TEXTIO; (32)->TEXTIO; (119)->TEXTIO; (97)->TEXTIO; (108)->TEXTIO; (108)->TEXTIO; (44)->TEXTIO; (10)->TEXTIO; NEG->NUMIO; (32)->TEXTIO; (98)->TEXTIO; (111)->TEXTIO; (116)->TEXTIO; (116)->TEXTIO; (108)->TEXTIO; (101)->TEXTIO; (115)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (102)->TEXTIO; (32)->TEXTIO; (98)->TEXTIO; (101)->TEXTIO; (101)->TEXTIO; (114)->TEXTIO; (46)->TEXTIO; (10)->TEXTIO; (84)->TEXTIO; (97)->TEXTIO; (107)->TEXTIO; (101)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (110)->TEXTIO; (101)->TEXTIO; (32)->TEXTIO; (100)->TEXTIO; (111)->TEXTIO; (119)->TEXTIO; (110)->TEXTIO; (44)->TEXTIO; (32)->TEXTIO; (112)->TEXTIO; (97)->TEXTIO; (115)->TEXTIO; (115)->TEXTIO; (32)->TEXTIO; (105)->TEXTIO; (116)->TEXTIO; (32)->TEXTIO; (97)->TEXTIO; (114)->TEXTIO; (111)->TEXTIO; (117)->TEXTIO; (110)->TEXTIO; (100)->TEXTIO; (44)->TEXTIO; (10)->TEXTIO; NEG->SUB; (1)->SUB; SUB->NEG; NEG->NEG; NEG->MEM; NEG->NUMIO; (32)->TEXTIO; (98)->TEXTIO; (111)->TEXTIO; (116)->TEXTIO; (116)->TEXTIO; (108)->TEXTIO; (101)->TEXTIO; (115)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (102)->TEXTIO; (32)->TEXTIO; (98)->TEXTIO; (101)->TEXTIO; (101)->TEXTIO; (114)->TEXTIO; (32)->TEXTIO; (111)->TEXTIO; (110)->TEXTIO; (32)->TEXTIO; (116)->TEXTIO; (104)->TEXTIO; (101)->TEXTIO; (32)->TEXTIO; (119)->TEXTIO; (97)->TEXTIO; (108)->TEXTIO; (108)->TEXTIO; (46)->TEXTIO; (10)->TEXTIO; (10)->TEXTIO; { WHILE->MEM; # Intentional error } NEG->IFZ; BLOCKS->IFZ;