found a cause of a memory bug in emulator - fix is TODO (#6) - continued working on brainf interpreter. we really need better debugging tools tbh.
This commit is contained in:
@@ -183,7 +183,7 @@ fn expand_stx(current: Node, nodes: &mut Vec<Node>) -> Result<(), AssembleError>
|
||||
let base = expect_type!(current.arg(0).unwrap(), Register)?;
|
||||
let dest = expect_type!(current.arg(1).unwrap(), Symbol)?;
|
||||
let offset = expect_type!(current.arg(2).unwrap(), Immediate)?;
|
||||
let temp = Token::Register(Register::Rgf);
|
||||
let temp = Token::Register(Register::Acc);
|
||||
|
||||
nodes.extend(vec![
|
||||
node!(current.label(), Opcode::Lli, dest, temp),
|
||||
|
||||
@@ -326,8 +326,8 @@ impl FromStr for Opcode {
|
||||
"include" => Ok(Self::Include),
|
||||
"call" => Ok(Self::Call),
|
||||
"return" => Ok(Self::Return),
|
||||
"pusha" => Ok(Self::Push),
|
||||
"popa" => Ok(Self::Pop),
|
||||
"pusha" => Ok(Self::Pusha),
|
||||
"popa" => Ok(Self::Popa),
|
||||
_ => Err(OpcodeFromStrError::InvalidRegister("unknown opcode")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,9 @@ impl MemoryUnit for MainStore {
|
||||
|
||||
fn read_word(&mut self, addr: u32) -> u32 {
|
||||
let (block_addr, offset) = Self::segment_addr(addr);
|
||||
|
||||
println!("reading word from {block_addr:x?} + {offset}");
|
||||
|
||||
let block = self.mut_block(block_addr);
|
||||
let mut bytes = [0; 4];
|
||||
bytes[0] = block.data[offset as usize];
|
||||
|
||||
@@ -21,6 +21,10 @@ pub struct Processor {
|
||||
pub dustbin: u32,
|
||||
}
|
||||
|
||||
fn log(message: &str) {
|
||||
println!("\x1b[32mINFO:\x1b[0m {message}");
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_ref_mut)]
|
||||
impl Processor {
|
||||
#[must_use]
|
||||
@@ -62,12 +66,10 @@ impl Processor {
|
||||
// Decode and execute the instruction.
|
||||
let instruction = Instruction::decode(val)?;
|
||||
|
||||
println!("Executing instruction: {instruction}");
|
||||
log(&instruction.to_string());
|
||||
|
||||
instruction.execute(self);
|
||||
|
||||
println!("ok!");
|
||||
|
||||
Ok((addr, instruction))
|
||||
}
|
||||
|
||||
|
||||
+114
-56
@@ -1,10 +1,12 @@
|
||||
|
||||
// a simple brainf##k interpreter, because I already wrote a compiler lol.
|
||||
// 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
|
||||
@@ -21,25 +23,32 @@ start:
|
||||
|
||||
// rg0 is our instruction pointer
|
||||
// rg1 is our data pointer
|
||||
// acc is the value at the data pointer
|
||||
// rg2 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
|
||||
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:
|
||||
loop_start:
|
||||
// load the current instruction into rg3
|
||||
ldb rg0, rg3
|
||||
inc rg0
|
||||
|
||||
|
||||
// pusha 2
|
||||
// push rg3
|
||||
// call print::print_byte
|
||||
// pop zero
|
||||
// popa 2
|
||||
|
||||
// switch on the instruction
|
||||
// all cases will return to either loop_start or loop_end
|
||||
cmp rg3, rg8
|
||||
jeq increment
|
||||
cmp rg3, rg9
|
||||
@@ -56,93 +65,142 @@ loop:
|
||||
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, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
|
||||
end:
|
||||
lwi error, rg2
|
||||
pusha 2
|
||||
push rg2
|
||||
call print::print
|
||||
pop zero
|
||||
popa 2
|
||||
hlt
|
||||
|
||||
loop_end:
|
||||
inc rg0
|
||||
jmp loop_start
|
||||
|
||||
// ------------------------------------------
|
||||
// increment the current cell
|
||||
increment:
|
||||
inc acc
|
||||
jmp loop
|
||||
inc rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// decrement the current cell
|
||||
decrement:
|
||||
dec acc
|
||||
jmp loop
|
||||
dec rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// increment the pointer
|
||||
inc_ptr:
|
||||
stw acc, rg1
|
||||
stw rg2, rg1
|
||||
addi rg1, 4
|
||||
ldw rg1, acc
|
||||
jmp loop
|
||||
ldw rg1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// decrement the pointer
|
||||
dec_ptr:
|
||||
stw rg1, acc
|
||||
stw rg1, rg2
|
||||
subi rg1, 4
|
||||
ldw rg1, acc
|
||||
jmp loop
|
||||
ldw rg1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// print the byte in the current cell
|
||||
output:
|
||||
push acc
|
||||
pusha 2
|
||||
push rg2
|
||||
call print::print_byte
|
||||
pop zero
|
||||
jmp loop
|
||||
popa 2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// read a byte into the current cell
|
||||
input:
|
||||
ldw input, acc
|
||||
jmp loop
|
||||
ldw input, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// handle an open bracket instruction
|
||||
expr_start:
|
||||
cmp acc, zero
|
||||
jeq _traverse_right
|
||||
inc rg4
|
||||
jmp loop
|
||||
cmp rg2, zero
|
||||
jne loop_end
|
||||
|
||||
expr_end:
|
||||
cmp acc, zero
|
||||
jne _traverse_left
|
||||
dec rg4
|
||||
jmp loop
|
||||
_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_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:
|
||||
_traverse_right:
|
||||
inc rg0
|
||||
ldb rg0, rg3
|
||||
|
||||
cmp rg3, rge
|
||||
jeq _open
|
||||
|
||||
jeq open_right
|
||||
cmp rg3, rgf
|
||||
jeq _close
|
||||
|
||||
jeq close_right
|
||||
cmp rg3, zero
|
||||
jeq end
|
||||
jmp _traverse_right
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_open:
|
||||
push rg4
|
||||
inc rg4
|
||||
open_right:
|
||||
// push zero to the stack
|
||||
push zero
|
||||
jmp _traverse_right
|
||||
|
||||
_close:
|
||||
pop rg5
|
||||
cmp rg4,
|
||||
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
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user