This commit is contained in:
nora 2022-01-01 14:23:07 +01:00
parent a93412c3cd
commit 09deb07e85
4 changed files with 36 additions and 21 deletions

View file

@ -14,6 +14,8 @@ pub struct FnBlock<'bc> {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Instr { pub enum Instr {
Nop,
/// Store the current value on the stack to the stack location with the local offset `usize` /// Store the current value on the stack to the stack location with the local offset `usize`
Store(usize), Store(usize),
/// Load the variable value from the local offset `usize` onto the stack /// Load the variable value from the local offset `usize` onto the stack
@ -39,8 +41,8 @@ pub enum Instr {
/// Println the value on top of the stack /// Println the value on top of the stack
Print, Print,
/// If the current stack value is true, skip `usize` instructions. /// If the current stack value is true, skip `usize` instructions. When jumping backwards
JumpFalse(usize), JumpFalse(isize),
/// Same as `JumpCond`, but unconditional /// Same as `JumpCond`, but unconditional
Jmp(usize), Jmp(isize),
} }

View file

@ -87,6 +87,10 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
}; };
self.blocks.push(global_block); self.blocks.push(global_block);
self.current_block = self.blocks.len() - 1; self.current_block = self.blocks.len() - 1;
// padding for backwards jumps
self.push_instr(Instr::Nop, StackChange::None, Span::dummy());
self.compile_stmts(&ast.0)?; self.compile_stmts(&ast.0)?;
Ok(()) Ok(())
} }
@ -169,7 +173,7 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
let block = &mut self.blocks[self.current_block]; let block = &mut self.blocks[self.current_block];
let next_index = block.code.len(); let next_index = block.code.len();
let jmp_pos = (next_index - 1) - jmp_idx; let jmp_pos = (next_index - 1) - jmp_idx;
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos); block.code[jmp_idx] = Instr::JumpFalse(jmp_pos as isize);
match else_part { match else_part {
ElsePart::Else(block, _) => { ElsePart::Else(block, _) => {
@ -183,19 +187,35 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
let block = &mut self.blocks[self.current_block]; let block = &mut self.blocks[self.current_block];
let next_index = block.code.len(); let next_index = block.code.len();
let jmp_pos = (next_index - else_skip_jmp_idx) - 1; let jmp_pos = (next_index - else_skip_jmp_idx) - 1;
block.code[else_skip_jmp_idx] = Instr::Jmp(jmp_pos); block.code[else_skip_jmp_idx] = Instr::Jmp(jmp_pos as isize);
} else { } else {
let block = &mut self.blocks[self.current_block]; let block = &mut self.blocks[self.current_block];
let next_index = block.code.len(); let next_index = block.code.len();
let jmp_pos = (next_index - 1) - jmp_idx; let jmp_pos = (next_index - 1) - jmp_idx;
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos); block.code[jmp_idx] = Instr::JumpFalse(jmp_pos as isize);
} }
Ok(()) Ok(())
} }
fn compile_loop(&mut self, _: &Block, _: Span) -> CResult<()> { fn compile_loop(&mut self, ast_block: &'ast Block, span: Span) -> CResult<()> {
todo!() /*
>0 // do things
1 JMP (-2),
*/
let block = &self.blocks[self.current_block];
let first_stmt_idx = block.code.len() as isize;
self.compile_block(ast_block)?;
let block = &self.blocks[self.current_block];
let jmp_index = block.code.len() as isize;
let jmp_offset = -(jmp_index - first_stmt_idx + 1);
self.push_instr(Instr::Jmp(jmp_offset), StackChange::None, span);
Ok(())
} }
fn compile_while(&mut self, _: &WhileStmt) -> CResult<()> { fn compile_while(&mut self, _: &WhileStmt) -> CResult<()> {

View file

@ -68,6 +68,7 @@ impl<'bc> Vm<'bc, '_> {
fn dispatch_instr(&mut self, instr: Instr) -> VmResult { fn dispatch_instr(&mut self, instr: Instr) -> VmResult {
match instr { match instr {
Instr::Nop => {}
Instr::Store(index) => { Instr::Store(index) => {
let val = self.stack.pop().unwrap(); let val = self.stack.pop().unwrap();
self.stack.insert(index, val); self.stack.insert(index, val);
@ -153,12 +154,12 @@ impl<'bc> Vm<'bc, '_> {
Instr::JumpFalse(pos) => { Instr::JumpFalse(pos) => {
let val = self.stack.pop().unwrap(); let val = self.stack.pop().unwrap();
match val { match val {
Value::Bool(false) => self.pc += pos, Value::Bool(false) => self.pc = (self.pc as isize + pos) as usize,
Value::Bool(true) => {} Value::Bool(true) => {}
_ => return Err("bad type"), _ => return Err("bad type"),
} }
} }
Instr::Jmp(pos) => self.pc += pos, Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
} }
Ok(()) Ok(())

View file

@ -1,11 +1,3 @@
let x = 5; if 54 > 53 {
print "hallo conny";
let y = 0;
if x < 0 {
y = x;
} else {
y = "hello it is smaller";
} }
print y;