Tarflex
Tarflex is a reflective turing tarpit invented by Adrian Toncean in 2012. It is an imperative language, designed to be as minimalistic as possible while also allowing reflection.
Language overview
There are basic instructions for incrementing, decrementing, copying, jumping, storing into an indexed memory and retrieving data from it, reading from input and writing to the output. Variables need not be declared - every variable is automatically initialized with 0. There are no numeric literals.
The language is reflective - the program may alter its program code at runtime using specific instructions. Because of its minimalistic nature, the program code can be viewed as a list of labels and every label can be viewed as a list of instructions. There are specific instructions for adding or removing instructions or labels.
To output the program code at any moment use the !selfprint instruction.
Comments start with a "/" and must be on their own line. Empty lines are ignored.
Instructions
Basic
Instruction | Action |
---|---|
inc var | increments variable var by 1 |
dec var | decrements variable var by 1 |
mov dest_var source_var | copies source_var to dest_var |
if var1 < var2 goto dest_label | performs a jump to dest_label if the condition is met - other supported relations are: <=, ==, >=, >, != |
Memory instructions
Instruction | Action |
---|---|
store address_var source_var | stores source_var in memory at address address_var |
load dest_var address_var | retrieves the value stored in memory at address address_var and copies it in dest_var |
IO instructions
Instruction | Action |
---|---|
read dest_var | reads a value from the input buffer and stores in dest_var |
outv var | outputs variable var |
outs any_string... | outputs anything that follows |
outnl | outputs a new line |
Program alteration instructions
Instruction | Action |
---|---|
if isempty label goto dest_label | jumps to dest_label if label contains no instructions |
push dest_label | adds the next instruction at the end of the list defined by dest_label |
push dest_label head/last source_label | adds the first/last instruction from the list defined by source_label at the end of the list defined by dest_label |
pop label | removes the last instruction from the list defined by label |
unshift dest_label | adds the next instruction at the beginning of the list defined by dest_label |
unshift dest_label head/last source_label | adds the first/last instruction from the list defined by source_label at the beginning of the list defined by dest_label |
shift label | removes the first instruction from the list defined by label |
pushlab dest_label new_label | adds new_label after dest_label |
unshiftlab dest_label new_label | adds new_label before dest_label |
dellab label | removes label; the instructions of label are left unchanged and thus merged with the list of instructions defined by the previous label |
delwholelab label | erases label and its contents |
!selfprint | outputs the program code |
Examples
Adding 2 numbers
read a read b :l1 dec a inc r if a > z goto l1 :l2 dec b inc r if b > z goto l2 outv r
Printing Hello World with reflection
inc a inc a inc a inc a inc a :l2 push l1 outs Hello push l1 outs World push l1 outnl dec a if a > z goto l2 :l1 !selfprint
Cheating Quine
!selfprint
Reversing instructions with reflection
:orig outs message 1 outs message 2 outs message 3 :int if isempty orig goto prev unshift rev head orig shift orig if z == z goto int :prev outnl :rev !selfprint