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![];
|
||||
|
||||
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<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.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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user