// 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: