diff --git a/resources/dsa/bf.dsa b/resources/dsa/bf.dsa new file mode 100644 index 0000000..a58c24a --- /dev/null +++ b/resources/dsa/bf.dsa @@ -0,0 +1,148 @@ + +// 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: diff --git a/resources/dsa/test.dsa b/resources/dsa/test.dsa index 667229e..a64d8e5 100644 --- a/resources/dsa/test.dsa +++ b/resources/dsa/test.dsa @@ -14,5 +14,5 @@ start: push rg1 call print::print pop rg1 - - hlt \ No newline at end of file + + hlt