From 1ef0da5dd140500d3012322e5927b6919ca35d0a Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Fri, 23 May 2025 13:42:29 -0400 Subject: [PATCH] compiler: decouple stack & bindings resetting --- src/compiler.rs | 74 ++++++++++++++++++++++++++----------------------- src/main.rs | 9 +++--- src/vm.rs | 2 +- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index c4d2881..3c9c32d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -355,6 +355,7 @@ impl Compiler { } Block(lines) => { self.scope_depth += 1; + let stack_depth = self.stack_depth; for expr in lines.iter().take(lines.len() - 1) { if is_binding(expr) { self.visit(expr); @@ -365,6 +366,7 @@ impl Compiler { } } let last_expr = lines.last().unwrap(); + // TODO: make sure this actually returns the RHS of the expression if is_binding(last_expr) { self.visit(last_expr); self.emit_op(Op::Duplicate); @@ -375,17 +377,19 @@ impl Compiler { } self.emit_op(Op::Store); self.scope_depth -= 1; + // reset bindings while let Some(binding) = self.bindings.last() { if binding.depth > self.scope_depth { - self.pop(); - // self.emit_op(Op::Pop); - self.bindings.pop(); + let binding = self.bindings.pop().unwrap(); + println!("popping: {:?}", binding); } else { break; } } - self.pop(); - // self.emit_op(Op::Pop); + // reset stack + while self.stack_depth > stack_depth + 1 { + self.pop(); + } self.emit_op(Op::Load); } If(cond, then, r#else) => { @@ -635,43 +639,45 @@ impl Compiler { // conditional compilation of guards // hard to DRY out match guard.as_ref() { - Some(expr) => { - self.visit(expr); - self.emit_op(Op::JumpIfFalse); - let jif_idx = self.len(); - self.emit_byte(0xff); - self.visit(body); - self.emit_op(Op::Store); - self.scope_depth -= 1; - while let Some(binding) = self.bindings.last() { - if binding.depth > self.scope_depth { - self.pop(); - // self.emit_op(Op::Pop); - self.bindings.pop(); - } else { - break; - } - } - self.emit_op(Op::Jump); - jump_idxes.push(self.len()); - self.emit_byte(0xff); - self.chunk.bytecode[jnm_jump_idx] = - self.len() as u8 - jnm_jump_idx as u8 - 1; - self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1; - } + Some(_) => todo!(), + // Some(expr) => { + // self.visit(expr); + // self.emit_op(Op::JumpIfFalse); + // let jif_idx = self.len(); + // self.emit_byte(0xff); + // self.visit(body); + // self.emit_op(Op::Store); + // self.scope_depth -= 1; + // while let Some(binding) = self.bindings.last() { + // if binding.depth > self.scope_depth { + // self.pop(); + // // self.emit_op(Op::Pop); + // self.bindings.pop(); + // } else { + // break; + // } + // } + // self.emit_op(Op::Jump); + // jump_idxes.push(self.len()); + // self.emit_byte(0xff); + // self.chunk.bytecode[jnm_jump_idx] = + // self.len() as u8 - jnm_jump_idx as u8 - 1; + // self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1; + // } None => { self.visit(body); self.emit_op(Op::Store); self.scope_depth -= 1; while let Some(binding) = self.bindings.last() { if binding.depth > self.scope_depth { - self.pop(); - // self.emit_op(Op::Pop); self.bindings.pop(); } else { break; } } + while self.stack_depth > stack_depth { + self.pop(); + } self.emit_op(Op::Jump); jump_idxes.push(self.len()); self.emit_byte(0xff); @@ -679,14 +685,14 @@ impl Compiler { self.len() as u8 - jnm_jump_idx as u8 - 1; } } - self.stack_depth = stack_depth; } self.emit_op(Op::PanicNoMatch); for idx in jump_idxes { self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1; } - self.pop(); - // self.emit_op(Op::Pop); + while self.stack_depth > stack_depth { + self.pop(); + } self.emit_op(Op::Load); self.stack_depth += 1; } diff --git a/src/main.rs b/src/main.rs index 4bdb25e..49fd6a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,18 +67,17 @@ pub fn run(src: &'static str) { Ok(val) => val.show(&compiler.chunk), Err(panic) => format!("{:?}", panic), }; + vm.print_stack(); println!("{output}"); } pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -match (-1, (2)) with { - (0) -> :nope - (1) -> :yup - (x, (1)) -> :thing +{let x = match (-1, (2)) with { (x, (y)) -> y } - "; +x +} "; run(src); } diff --git a/src/vm.rs b/src/vm.rs index 7da5af0..71cf25f 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -65,7 +65,7 @@ impl<'a> Vm<'a> { self.stack.last().unwrap() } - fn print_stack(&self) { + pub fn print_stack(&self) { let inner = self .stack .iter()