Tarflex

From Esolang
Jump to: navigation, search

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

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

External resources