improved brainf__k doc
This commit is contained in:
@@ -40,4 +40,207 @@ we currently have two implementations of the brainf##k esoteric programming lang
|
|||||||
<assembler binary name> -brainf
|
<assembler binary name> -brainf
|
||||||
```
|
```
|
||||||
|
|
||||||
test
|
### Using the Interpreter
|
||||||
|
|
||||||
|
- We currently have a simple interpreter for brainf##k, which can be used to run brainf##k programs on the DSA architecture.
|
||||||
|
- To use the interpreter, Start the emulator binary and open the editor, then open brainf__k.dsa from the included resources/dsa/bin directory.
|
||||||
|
- The brainf##k program to run is defined as a string at the start of the file. paste the program you wish to run here, then build and load the program to use!
|
||||||
|
- Full source code for the interpreter is attached below for reference:
|
||||||
|
|
||||||
|
```dsa
|
||||||
|
// a simple brainf##k interpreter,
|
||||||
|
// because I already wrote a compiler lol.
|
||||||
|
|
||||||
|
include print "./lib/io/print.dsa"
|
||||||
|
|
||||||
|
// "print hello world"
|
||||||
|
db program: "<Your Program Goes Here!>"
|
||||||
|
|
||||||
|
db error: "Invalid Instruction!"
|
||||||
|
dw stack: 0x10000
|
||||||
|
dw input: 0x30000
|
||||||
|
resb data: 1024
|
||||||
|
|
||||||
|
// set up a stack so we can call functions
|
||||||
|
_init_stack:
|
||||||
|
ldw stack, bpr
|
||||||
|
mov bpr, spr
|
||||||
|
|
||||||
|
start:
|
||||||
|
// load the start of the program into rg0
|
||||||
|
lwi program, rg0
|
||||||
|
lwi data, rg1
|
||||||
|
|
||||||
|
// rg0 is our instruction pointer
|
||||||
|
// rg1 is our data pointer
|
||||||
|
// rg2 is the value at the data pointer
|
||||||
|
// rg3 stores the current instruction
|
||||||
|
// rg4 is the expression nesting level.
|
||||||
|
|
||||||
|
lli 43, rg8 // + = 43 increment
|
||||||
|
lli 45, rg9 // - = 45 decrement
|
||||||
|
lli 62, rga // > = 62 increment pointer
|
||||||
|
lli 60, rgb // < = 60 decrement pointer
|
||||||
|
lli 46, rgc // . = 46 output
|
||||||
|
lli 44, rgd // , = 44 input
|
||||||
|
lli 91, rge // [ = 91 loop start
|
||||||
|
lli 93, rgf // ] = 93 loop end
|
||||||
|
|
||||||
|
loop_start:
|
||||||
|
// load the current instruction into rg3
|
||||||
|
ldb rg0, rg3
|
||||||
|
|
||||||
|
// switch on the instruction
|
||||||
|
// all cases will return to either loop_start or loop_end
|
||||||
|
cmp rg3, rg8
|
||||||
|
jeq increment
|
||||||
|
cmp rg3, rg9
|
||||||
|
jeq decrement
|
||||||
|
cmp rg3, rga
|
||||||
|
jeq inc_ptr
|
||||||
|
cmp rg3, rgb
|
||||||
|
jeq dec_ptr
|
||||||
|
cmp rg3, rgc
|
||||||
|
jeq output
|
||||||
|
cmp rg3, rgd
|
||||||
|
jeq input
|
||||||
|
cmp rg3, rge
|
||||||
|
jeq expr_start
|
||||||
|
cmp rg3, rgf
|
||||||
|
jeq expr_end
|
||||||
|
cmp rg3, zero
|
||||||
|
jeq end
|
||||||
|
|
||||||
|
// if we get here, we don't know what the instruction is
|
||||||
|
lwi error, rg2
|
||||||
|
pusha 2
|
||||||
|
push rg2
|
||||||
|
call print::print
|
||||||
|
pop zero
|
||||||
|
popa 2
|
||||||
|
|
||||||
|
end:
|
||||||
|
hlt
|
||||||
|
|
||||||
|
loop_end:
|
||||||
|
inc rg0
|
||||||
|
jmp loop_start
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// increment the current cell
|
||||||
|
increment:
|
||||||
|
inc rg2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// decrement the current cell
|
||||||
|
decrement:
|
||||||
|
dec rg2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// increment the pointer
|
||||||
|
inc_ptr:
|
||||||
|
stw rg2, rg1
|
||||||
|
addi rg1, 4
|
||||||
|
ldw rg1, rg2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// decrement the pointer
|
||||||
|
dec_ptr:
|
||||||
|
stw rg2, rg1
|
||||||
|
subi rg1, 4
|
||||||
|
ldw rg1, rg2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// print the byte in the current cell
|
||||||
|
output:
|
||||||
|
pusha 2
|
||||||
|
push rg2
|
||||||
|
call print::print_byte
|
||||||
|
pop zero
|
||||||
|
popa 2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// read a byte into the current cell
|
||||||
|
input:
|
||||||
|
ldw input, rg2
|
||||||
|
jmp loop_end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// handle an open bracket instruction
|
||||||
|
expr_start:
|
||||||
|
cmp rg2, zero
|
||||||
|
jne loop_end
|
||||||
|
|
||||||
|
_traverse_right_start:
|
||||||
|
// push a register that definitely has a nonzero value
|
||||||
|
// when we pop this value from the stack
|
||||||
|
// we know we've finished traversing.
|
||||||
|
push rg8
|
||||||
|
|
||||||
|
_traverse_right:
|
||||||
|
inc rg0
|
||||||
|
ldb rg0, rg3
|
||||||
|
|
||||||
|
cmp rg3, rge
|
||||||
|
jeq open_right
|
||||||
|
cmp rg3, rgf
|
||||||
|
jeq close_right
|
||||||
|
cmp rg3, zero
|
||||||
|
jeq end
|
||||||
|
jmp _traverse_right
|
||||||
|
|
||||||
|
open_right:
|
||||||
|
// push zero to the stack
|
||||||
|
push zero
|
||||||
|
jmp _traverse_right
|
||||||
|
|
||||||
|
close_right:
|
||||||
|
// check if we've reached the bottom of the stack
|
||||||
|
pop rg4
|
||||||
|
cmp rg4, zero
|
||||||
|
jeq _traverse_right
|
||||||
|
|
||||||
|
// go to next instruction after closing bracket
|
||||||
|
inc rg0
|
||||||
|
jmp loop_start
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// handle the close bracket instruction
|
||||||
|
expr_end:
|
||||||
|
cmp rg2, zero
|
||||||
|
jeq loop_end
|
||||||
|
|
||||||
|
_traverse_left_start:
|
||||||
|
push rg8
|
||||||
|
_traverse_left:
|
||||||
|
dec rg0
|
||||||
|
ldb rg0, rg3
|
||||||
|
|
||||||
|
cmp rg3, rge
|
||||||
|
jeq open_left
|
||||||
|
cmp rg3, rgf
|
||||||
|
jeq close_left
|
||||||
|
cmp rg3, zero
|
||||||
|
jeq end
|
||||||
|
jmp _traverse_left
|
||||||
|
|
||||||
|
open_left:
|
||||||
|
// check if we've reached the bottom of the stack
|
||||||
|
pop rg4
|
||||||
|
cmp rg4, zero
|
||||||
|
jeq _traverse_left
|
||||||
|
|
||||||
|
// go to next instruction after open bracket
|
||||||
|
inc rg0
|
||||||
|
jmp loop_start
|
||||||
|
|
||||||
|
close_left:
|
||||||
|
// push zero to the stack
|
||||||
|
push zero
|
||||||
|
jmp _traverse_left
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user