by Sandro Maffiodo
smaffer@gmail.com
www.assezeta.com/sandromaffiodo
This is a simple SUBLEQ emulator. It also embeds a SUBLEQ interpreter writen in SUBLEQ.
SUBLEQ is a simple OISC machine: A one instruction set computer (OISC), sometimes called an ultimate reduced instruction set computer (URISC), is an abstract machine that uses only one instruction [...] an OISC is capable of being a universal computer in the same manner as traditional computers that have multiple instructions.
SUBLEQ instruction is defined like this:
The subleq instruction ("SUbtract and Branch if Less than or EQual to zero") subtracts the contents at address A from the contents at address B, stores the result at address B, and then, if the result is not positive, transfers control to address C (if the result is positive, execution proceeds to the next instruction in sequence)
A SUBLEQ instruciton looks like this:
A B C
This emulator execute its input until the program jump to the address -1 (C==-1).
This emulator can also read values from stdin, write to stdout and allocate some memory. To do that i've overloaded the original meaning of the SUBLEQ instruction by adding two special memory addresses: -1 and -2. These addresses must be used like that:
A -1 C
write the number stored in A to stdout and jump to C.
A -2 C
Write the character code stored in A to the stdout and jump to C
-1 B C
Read a number from stdin, save it to B and jump to C
-2 B C
Allocate 1000 bytes of memory, save the address of the allocated memory to B and jump to C
To terminate the sourcecode of your program you must use the magic number:
-65535
Your programs cannot be greater than 64 kilobytes of RAM.
$(CC) prog.c -o prog
If you run this program without arguments, it will print a SUBLEQ interpreter writen in SUBLEQ.
If you run this program with some arguments, it will act as a SUBLEQ emulator.
To test the emulator you can pipe the HELLOWORLD demo like this:
cat hello | ./prog demo
To run the emulator in an interactive mode you can simply type
./prog 7 20 1981
Or
./prog SM1981
Or type some random garbage for the program's arguments... who cares.
Then you can cut and paste some of these SUBLEQ programs to your stdin (WARNING: if you use "cat" to pipe the programs to the emulator, their input must be appended after the program code):
HELLO WORLD!
36 -2 3 37 -2 6 38 -2 9 38 -2 12 39 -2 15 40 -2 18 41 -2 21 39 -2 24 42 -2 27 38 -2 30 43 -2 33 44 -2 -1 72 69 76 79 32 87 82 68 33 -65535
Add 2 numbers
49 -2 3 52 -2 6 -1 53 9 53 54 12 50 -2 15 52 -2 18 53 53 21 -1 53 24 53 55 27 54 48 30 55 48 33 56 56 36 48 56 39 51 -2 42 52 -2 45 56 -1 -1 0 65 66 67 61 0 0 0 0 -65535
Multiply 2 numbers
52 52 3 53 53 6 54 54 9 60 60 12 56 -2 15 58 -2 18 -1 52 21 52 53 24 51 54 27 52 52 30 55 -2 33 58 -2 36 -1 52 39 59 59 42 52 59 45 54 53 61 60 60 42 -1 0 0 0 65 66 67 61 0 0 57 -2 64 58 -2 67 59 -1 -1 -65535
You can write your programs in SUBLEQ. It's fun, comfortable and very very easy. Trust me. Look at my SUBLEQ emulator writen in SUBLEQ, its really simple understand what it does :D
You can execute "prog" without arguments and get the wonderful SUBLEQ emulator writen in SUBLEQ. Try this:
./prog > subleq
You now can read the clear and simple code of the emulator. Comments are not needed to understand what it does:
-2 329 3 322 322 6 329 322 9 322 36 12 322 37
15 322 40 18 -1 318 21 323 323 24 318 323 27
324 324 30 335 324 33 324 323 54 0 0 39 318 0
42 325 40 45 325 36 48 325 37 51 322 322 18
322 322 57 329 322 60 322 90 63 322 93 66 322
96 69 325 93 72 325 96 75 325 96 78 331 331
81 319 319 84 320 320 87 321 321 90 0 319 93
0 320 96 0 321 99 322 322 102 326 322 105 319
322 147 322 322 111 325 322 114 319 322 147
322 322 120 323 323 123 329 322 126 322 323
129 319 323 132 225 225 135 322 322 138 323
322 141 322 225 144 322 322 156 328 331 150
225 225 153 319 225 156 322 322 159 326 322
162 320 322 210 322 322 168 325 322 171 320
322 210 322 322 177 323 323 180 329 322 183
322 323 186 320 323 189 226 226 192 234 234
195 322 322 198 323 322 201 322 226 204 322
234 207 322 322 225 226 226 213 234 234 216
320 226 219 320 234 222 328 331 225 0 0 228
325 331 255 322 322 234 0 322 237 323 323 240
322 323 255 327 90 246 327 93 249 327 96 252
322 322 78 322 322 258 321 322 315 322 322
264 323 323 267 329 322 270 322 323 273 321
323 276 330 330 279 322 322 282 323 330 285
90 90 288 93 93 291 96 96 294 330 90 297 330
93 300 330 96 303 325 93 306 325 96 309 325
96 312 322 322 78 322 322 -1 0 0 0 0 0 0 0 -1
-2 -3 1 0 0 0 33 35 10 65535 -65535
Then you can pipe the new emulator plus the hello program to the "native" emulator:
cat subleq hello | ./prog complete
Next you can try more levels of emulations, because the SUBLEQ interpreter writen in SUBLEQ can obviously interpret itself:
cat subleq subleq hello | ./prog turing
That's it. Due to the limitations of the addressable instructions of the "native" emulator, you can't emulate the emulator more than three times.
cat subleq subleq subleq hello | ./prog machine
The build process will generate some warnings about: