diff --git a/src/compiler.rs b/src/compiler.rs index 1737b95..52bad71 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -972,7 +972,7 @@ impl<'a> Compiler<'a> { let mut upvalues = vec![]; for clause in fn_body { - let MatchClause(pattern, _, clause_body) = &clause.0 else { + let MatchClause(pattern, guard, clause_body) = &clause.0 else { unreachable!() }; let TuplePattern(pattern) = &pattern.0 else { @@ -1021,9 +1021,20 @@ impl<'a> Compiler<'a> { compiler.emit_op(Op::Pop); } compiler.chunk.bytecode[jump_idx] = compiler.len() as u8 - jump_idx as u8 - 1; + let mut no_match_jumps = vec![]; compiler.emit_op(Op::JumpIfNoMatch); - let jnm_idx = compiler.len(); + // let jnm_idx = compiler.len(); + no_match_jumps.push(compiler.len()); compiler.emit_byte(0xff); + if guard.is_some() { + let guard_expr: &'static Spanned = + Box::leak(Box::new(guard.clone().unwrap())); + compiler.visit(guard_expr); + compiler.emit_op(Op::JumpIfFalse); + no_match_jumps.push(self.len()); + compiler.emit_byte(0xff); + compiler.stack_depth -= 1; + } compiler.visit(clause_body); compiler.emit_op(Op::Store); compiler.scope_depth -= 1; @@ -1039,7 +1050,10 @@ impl<'a> Compiler<'a> { } compiler.stack_depth = 0; compiler.emit_op(Op::Return); - compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8 - 1; + for idx in no_match_jumps { + compiler.chunk.bytecode[idx] = compiler.len() as u8 - idx as u8 - 1; + } + // compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8 - 1; compiler.scope_depth -= 1; std::mem::swap(&mut compiler.upvalues, &mut upvalues); diff --git a/src/main.rs b/src/main.rs index 23fe9b3..1723d52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,10 +76,12 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -match :foo with { - :foo if eq? (1, 2) -> :no - x if eq? (x, :foo) -> :yes +fn foo { + () if false -> :no + () if true -> :yes } + +foo () "; run(src); }