guards work in match forms

This commit is contained in:
Scott Richmond 2025-06-04 18:55:40 -04:00
parent 01ce043379
commit 0f8645d2eb
2 changed files with 22 additions and 6 deletions

View File

@ -972,7 +972,7 @@ impl<'a> Compiler<'a> {
let mut upvalues = vec![]; let mut upvalues = vec![];
for clause in fn_body { for clause in fn_body {
let MatchClause(pattern, _, clause_body) = &clause.0 else { let MatchClause(pattern, guard, clause_body) = &clause.0 else {
unreachable!() unreachable!()
}; };
let TuplePattern(pattern) = &pattern.0 else { let TuplePattern(pattern) = &pattern.0 else {
@ -1021,9 +1021,20 @@ impl<'a> Compiler<'a> {
compiler.emit_op(Op::Pop); compiler.emit_op(Op::Pop);
} }
compiler.chunk.bytecode[jump_idx] = compiler.len() as u8 - jump_idx as u8 - 1; 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); 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); compiler.emit_byte(0xff);
if guard.is_some() {
let guard_expr: &'static Spanned<Ast> =
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.visit(clause_body);
compiler.emit_op(Op::Store); compiler.emit_op(Op::Store);
compiler.scope_depth -= 1; compiler.scope_depth -= 1;
@ -1039,7 +1050,10 @@ impl<'a> Compiler<'a> {
} }
compiler.stack_depth = 0; compiler.stack_depth = 0;
compiler.emit_op(Op::Return); 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; compiler.scope_depth -= 1;
std::mem::swap(&mut compiler.upvalues, &mut upvalues); std::mem::swap(&mut compiler.upvalues, &mut upvalues);

View File

@ -76,10 +76,12 @@ pub fn run(src: &'static str) {
pub fn main() { pub fn main() {
env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_BACKTRACE", "1");
let src = " let src = "
match :foo with { fn foo {
:foo if eq? (1, 2) -> :no () if false -> :no
x if eq? (x, :foo) -> :yes () if true -> :yes
} }
foo ()
"; ";
run(src); run(src);
} }