I can see no difference between growing crops and writing esoteric programs. -- Keymaker (I have not really said that, I just needed a quote)
Wheat is an esoteric programming language, designed by Keymaker in 2009. The language is fully deterministic and Turing-complete.
The main principle by which Wheat works is outputting and inputting. The program can only input its own output. A program never terminates unless it is especially terminated with the terminating instruction. On every cycle, which is the execution of every program line (there are no infinite loop constructs in the language), a program may access the output of its previous cycle, and everything it outputs it will be able to input on its next cycle. However, the buffers only last one cycle, and then they are cleaned. In the beginning of executing a Wheat program, both buffers are empty. If there is no output during a cycle, the input buffer on the next cycle will be empty. Reading an empty buffer returns nothing, but it is not an error. Once a cycle is completed, the execution is begun again on the very first line.
As for memory, the language has 36 one-character registers. They are accessed with the one-character names a-z and 0-9. In the beginning of every cycle the content of each register is set to nothing, that is, empty string (or empty character, it does not matter how you think about it). Their content may be modified only by inputting into them.
Each line has one instruction. The number of lines per program is not limited. Lines may have indenting, depending on their preceding instructions. (See 'Indenting'.) There may not be empty lines. Comment lines, lines beginning with a '-' character, are allowed. A program must have at least one instruction (comments not count).
The language has the following five instructions.
One may output any string of finite size, with the exception it may not have "-characters or new-lines. Those are handled with special characters Q and N. These lines:
output "here be output" output 5 output N
would output 'here be output', the content (either a one-character string or the empty string) of register 5, and a new-line.
Input reads data from the output buffer of the previous cycle. If the cycle was 'abc', the first character to read would be 'a'. Input must always be done to a register. This line:
would input and store the input in the h register.
This conditional checks if the value of the given register is or is not the given character. Note that the given character can not be the empty string. It, as well, always needs to be a character, you can not compare two registers. If the condition is true, the indented lines below the instruction are executed, otherwise the execution continues where the indented lines end. This:
if a "f": output a
would output the content of the a register if the value of a was 'f'. This:
input c if not c "v": if c Q: output "c was " output Q output N
would output 'c was "' (along with a new-line) if the character input to c was the quote-character.
This finite loop -- the loops are finite because there is no infinite input and the output is finite because there are no infinite loops -- reads the remaining input into the given register and executes the indented lines for every read character. If the size of the input buffer is zero when this is called, it will not be executed, and the register will not change (no empty string is set unlike in normal input reading). This, just like the conditional, may be nested. This piece:
for-input j: if j "a": for-input j: if j N: output "abc"
would first begin a for-input loop and store in register j. For every input character, it would first be checked if the content of j was 'a'. If that happens, another for-input loop is executed. It has no indented lines (look carefully!), so the only thing it would do would be reading all the remaining input (if any) in register j. Then, the value of j would be compared to a new-line character, and if matching, an output would appear on the screen.
This instruction is required to terminate a program. Simply, it ends the execution if encountered. This:
if d "s": -Here comes the end... output "bye" terminate
would, if the value of d was 's', output 'bye' and then quit. The above code also represents the usage of the comment line. The commented line has to have '-' as its very first character no matter how much there is indenting on the lines around it.
As you may have noticed by now, indenting, where it is required, is done with spaces. One space per one level of indenting. This:
output a output b output c
would not be a valid program, as indenting may only happen after 'if' or 'for-input'. This:
for-input a: output a if a "A": output "c"
would be valid. The indention is correct -- condition or loop neither need to have indented lines, even if a condition with nothing is essentially useless.
Here's a few I've written.
a.whe - A simple test program. Never terminates.
1.whe - This prints out a simple, limitlessly increasing sequence. 1, 11, 111, 1111, 11111...
thumor.whe - Thue-Morse sequence.
trum.whe - A truth-machine.
1stquine.whe - A quine. Or is it? The opinion may vary -- I think it is a quine, since the program is not reading any external input (such a thing is impossible in this language), only its own, which it generates all on its own. This is the first quine I wrote in this language.
kquine.whe - A much shorter and simpler quine, written after I began to think that there probably is a simpler way than the above.
ct.whe - A cyclic tag system to prove the Turing-completeness of this language.
An interpreter can be found here. I have replaced the original horribly buggy Perl interpreter with one written in Python. This one should work perfectly.
-- Keymaker, 1.9.2009