149 lines
2.7 KiB
Plaintext
149 lines
2.7 KiB
Plaintext
|
|
// a simple brainf##k interpreter, because I already wrote a compiler lol.
|
|
|
|
include print "./lib/print.dsa"
|
|
|
|
// "print hello world"
|
|
db program: "++++++[>++++++++++++<-]>.>++++++++++[>++++++++++<-]>+.+++++++..+++.>++++[>+++++++++++<-]>.<+++[>----<-]>.<<<<<+++[>+++++<-]>.>>.+++.------.--------.>>+."
|
|
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
|
|
|
|
// rg0 is our instruction pointer
|
|
// rg1 is our data pointer
|
|
// acc is the value at the data pointer
|
|
// rg3 stores the current instruction
|
|
// rg4 is the expression nesting level.
|
|
|
|
lui rg8, 43 // + = 43 increment
|
|
lui rg9, 45 // - = 45 decrement
|
|
lui rga, 62 // > = 62 increment pointer
|
|
lui rgb, 60 // < = 60 decrement pointer
|
|
lui rgc, 46 // . = 46 output
|
|
lui rgd, 44 // , = 44 input
|
|
lui rge, 91 // [ = 91 loop start
|
|
lui rgf, 93 // ] = 93 loop end
|
|
|
|
loop:
|
|
// load the current instruction into rg3
|
|
ldb rg0, rg3
|
|
inc rg0
|
|
|
|
// switch on the instruction
|
|
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
|
|
|
|
// if we get here, we don't know what the instruction is
|
|
lwi error, rg0
|
|
push rg0
|
|
call print::print
|
|
pop zero
|
|
hlt
|
|
|
|
// increment the current cell
|
|
increment:
|
|
inc acc
|
|
jmp loop
|
|
|
|
// decrement the current cell
|
|
decrement:
|
|
dec acc
|
|
jmp loop
|
|
|
|
// increment the pointer
|
|
inc_ptr:
|
|
stw acc, rg1
|
|
addi rg1, 4
|
|
ldw rg1, acc
|
|
jmp loop
|
|
|
|
// decrement the pointer
|
|
dec_ptr:
|
|
stw rg1, acc
|
|
subi rg1, 4
|
|
ldw rg1, acc
|
|
jmp loop
|
|
|
|
// print the byte in the current cell
|
|
output:
|
|
push acc
|
|
call print::print_byte
|
|
pop zero
|
|
jmp loop
|
|
|
|
// read a byte into the current cell
|
|
input:
|
|
ldw input, acc
|
|
jmp loop
|
|
|
|
expr_start:
|
|
cmp acc, zero
|
|
jeq _traverse_right
|
|
inc rg4
|
|
jmp loop
|
|
|
|
expr_end:
|
|
cmp acc, zero
|
|
jne _traverse_left
|
|
dec rg4
|
|
jmp loop
|
|
|
|
traverse_right_start:
|
|
// we need to traverse to the right until we find the closing bracket.
|
|
// for each open bracket, we push to the stack
|
|
// for each close bracket, we pop from the stack
|
|
_traverse_right_loop:
|
|
inc rg0
|
|
ldb rg0, rg3
|
|
|
|
cmp rg3, rge
|
|
jeq _open
|
|
|
|
cmp rg3, rgf
|
|
jeq _close
|
|
|
|
jmp _traverse_right
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_open:
|
|
push rg4
|
|
inc rg4
|
|
jmp _traverse_right
|
|
|
|
_close:
|
|
pop rg5
|
|
cmp rg4,
|
|
jmp _traverse_right
|
|
|
|
|
|
|
|
_traverse_left:
|