You have to write an interpreter for a cool language called Chicken!
You should read a Chicken program from a file, standard input, program or function arguments, or whatever is most convenient for your language, as well as input to the program.
You should print or return the result of interpreting the program according to the Chicken language specification.
Chicken Program Overview
Chicken operates on a single stack, which composes its entire memory model. As instructions are executed, the program will push and pop values from the stack, but there are also instructions that allow the program to modify other parts of the stack at will.
There are three segments in the stack:
- The registers, at indices 0 and 1. Index 0 is a reference to the stack itself, and index 1 is a reference to the user input. Mostly used for instruction 6 (see below).
- The loaded code: for each line of code there is cell in this segment that contains the number of "chicken"s in the line. This is padded with a 0 (opcode for terminate program) at the end.
- The actual program stack, where values are pushed/popped as the program runs. Note that the segments are not isolated, which means that it is possible to create self-modifying code or execute code from this segment of the stack space.
The Chicken ISA
Chicken's instruction set is based around the number of times the word "chicken" appears on each line of the program. An empty line terminates the program and prints the topmost value in the stack.
The Chicken instruction set, by number of "chicken"s per line:
- Push the literal string "chicken" to the stack
- Add top two stack values as natural numbers and push the result.
- Subtract top two values as natural numbers and push the result.
- Multiply top two values as natural numbers and push the result.
- Compare two top values for equality, push 1 if they are equal and 0 otherwise.
- Look at the next instruction to determine which source to load from: 0 loads from stack, 1 loads from user input. Top of stack points to address/index to load from the given source; load that value and push it onto stack. Since this is a double wide instruction, the instruction pointer skips the instruction used to determine the source.
- Top of stack points to address/index to store to. The value below that will be popped and stored in the stack at the given index.
- Top of stack is a relative offset to jump to. If the value below that is truthy, then the program jumps by the offset.
- Interprets the top of the stack as ascii and pushes the corresponding character.
- (10 + N) Pushes the literal number n-10 onto the stack.
Assume the program is:
chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken (an empty line)
(A cat program. Note that the empty line is required because of the preceding line having 6 "chicken".)
Input provided to Chicken program
The interpreter should leave an error and terminate when any word not "chicken" is present in the source.