From Esolang
Jump to navigation Jump to search

Subleq (SUBtract and branch if Less-than or EQual to zero) is an assembly extension to the OISC instruction subleq.


Subleq is a simple one instruction language. Each implied subleq instruction has 3 memory address operands


The execution of one instruction subtracts the value in memory address A from the value in memory address B, assigning the result into memory address B. If the subtraction result assigned into memory address B is less than or equal to zero, the execution jumps to the memory address C; otherwise it continues to the next instruction. Each value has its own address so each instruction is three addresses long.

For example, in

3 4 6
7 7 7
3 4 0

the first instruction, at address zero, subtracts 7 (address 3) from 7 (address 4). The result in address 4 is 0, so jump to 6. Starting at address 6 is the instruction 3 4 0 which again subtracts 7 from now 0 and jumps back to 0. Here is a sequence of execution (A and B are shown after subtraction)

0: 3 4 6 A=7 B=0
6: 3 4 0 A=7 B=-7
0: 3 4 6 A=7 B=-14
6: 3 4 0 A=7 B=-21
0: 3 4 6 A=7 B=-28

Hello, world!

For simplicity, let us replace the real cell addresses with names(labels).

X Y 6
X:7 Y:7 7
X Y 0

On the first line X refer to a memory cell defined somewhere else. On the second line X is actually defined by X:7, which means that this memory cell has name X and its initial value 7.

Now let our language to make something useful - produce output. To achieve that we need a special memory address (because all the instruction can do is subtract). Lets call it -1, then the processor must know that an operation with the address -1 is input or output.

H (-1) 3
i (-1) 6
0 0 (-1)
H:72 i:105

This program prints "Hi". The program's code is

9 -1 3
10 -1 6
0 0 -1
72 105

72 and 105 are ASCII codes for 'H' and 'i'. The third line instruct to subtract value of zero's cell from itself and to go to the address -1 (since the result will always be 0). Go to negative address means halt. This last instruction could well be

5 5 -8

any A and B registers but A=B and any negative C.

Since we are using already symbolic names for cell addresses we need a simple converter to produce a digit code for SUBLEQ executor. This simple converter can do slightly more:

# Hello world! (Hi)
Hi (-1)
Hi+1 (-1)
0 0 (-1) 
. Hi: "Hi"

Note the differences: comment line, goto address may be left out (meaning next instruction address), arithmetic expression (Hi+1), literal "Hi" equivalent to 'H' 'i', and dot meaning that the following is not an instruction.

Dot does not make difference in the execution in this case, but it make difference in the code:

72 105

without dot this line would be

72 105 12

12 is the address of the next (not present) instruction.

Hello, world! (more)

Placing more than 1 instruction on one line will require semicolon:

Hi (-1);  Hi+1 (-1); 0 0 (-1) 

Instructions which clear one memory cell are always in the form: Z Z. This can be shortened to just Z. And yet another convention is ?(question mark): it refers to the next to current address. For example,

3 4 6
7 7 7
3 4 0

can be rewritten as

3 4 ?+3
7 7 ?+1
3 4 0

Given these improvements we can write a proper "hello world" program which iterates over a string of characters .

# Hello world!

# output *p; 
a; p Z; Z a; Z
a:0 (-1)

# p++
m1 p;

#check if p<E
a; E Z; Z a; Z;
p a (-1)

Z Z 0

. p:H Z:0 m1:-1

. H: "Hello, World!\n" E:E

How to run subleq programs

Subleq assembler

Download windows executable (or C++ source) assembler. It takes stdin and produce stdout. The command

sqasm.exe < hw.sq > hw

will read hw.sq file and produce hw text file. If hw.sq is the first "hello world" example, the command also prints "UNRESOLVED: [OUT:4]" which tells that label OUT was not resolved - it is OK because OUT is the default name for the output register for the emulator.

Subleq emulator

Download windows executable emulator (or C++ source). Running with no arguments it prints a brief help.

sqrun.exe hw

See also

External resources