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); self.emit_op(Op::JumpIfNoMatch);
let jnm_jump_idx = self.len(); let jnm_jump_idx = self.len();
self.emit_byte(0xff); self.emit_byte(0xff);
if let Some(expr) = guard.as_ref() { // conditional compilation of guards
self.visit(expr); // hard to DRY out
self.emit_op(Op::JumpIfFalse); match guard.as_ref() {
let jif_idx = self.len(); Some(expr) => {
self.emit_byte(0xff); self.visit(expr);
self.visit(body); self.emit_op(Op::JumpIfFalse);
self.emit_op(Op::Store); let jif_idx = self.len();
self.scope_depth -= 1; self.emit_byte(0xff);
while let Some(binding) = self.bindings.last() { self.visit(body);
if binding.depth > self.scope_depth { self.emit_op(Op::Store);
self.emit_op(Op::Pop); self.scope_depth -= 1;
self.bindings.pop(); while let Some(binding) = self.bindings.last() {
} else { if binding.depth > self.scope_depth {
break; 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); None => {
jump_idxes.push(self.len()); self.visit(body);
self.emit_byte(0xff); self.emit_op(Op::Store);
self.chunk.bytecode[jnm_jump_idx] = self.scope_depth -= 1;
self.len() as u8 - jnm_jump_idx as u8 - 1; while let Some(binding) = self.bindings.last() {
self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1; if binding.depth > self.scope_depth {
} else { self.emit_op(Op::Pop);
self.visit(body); self.bindings.pop();
self.emit_op(Op::Store); } else {
self.scope_depth -= 1; break;
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); self.emit_op(Op::PanicNoMatch);

View File

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