refactor if/else to match in guard compilation

This commit is contained in:
Scott Richmond 2024-12-26 23:48:38 -05:00
parent f5965fdb44
commit 6f582bff06
2 changed files with 42 additions and 36 deletions

View File

@ -479,45 +479,50 @@ impl Compiler {
self.emit_op(Op::JumpIfNoMatch);
let jnm_jump_idx = self.len();
self.emit_byte(0xff);
if let Some(expr) = guard.as_ref() {
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.emit_op(Op::Pop);
self.bindings.pop();
} else {
break;
// 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.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;
}
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;
} else {
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.emit_op(Op::Pop);
self.bindings.pop();
} else {
break;
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.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.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.emit_op(Op::PanicNoMatch);

View File

@ -69,8 +69,9 @@ pub fn run(src: &'static str) {
pub fn main() {
let src = "
match :foo with {
:foo if true -> :oops
:foo if nil -> :oops
:foo if true -> :yay!
:bar -> :thing
}
";
run(src);