refactor if/else to match in guard compilation
This commit is contained in:
parent
f5965fdb44
commit
6f582bff06
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user