guards work in match forms
This commit is contained in:
parent
01ce043379
commit
0f8645d2eb
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user