feat(tvix/compiler): implement ->
(implication) operator
Similar to `||`, but inverting the left-hand side. In other words, `a -> b` is essentially rewritten as `!a || b`. Change-Id: I8a62da65ff070b389e46048d047a54279060a97b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6152 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
c7c7ab9bd4
commit
63a0cc83d1
1 changed files with 21 additions and 1 deletions
|
@ -149,7 +149,7 @@ impl Compiler {
|
|||
match op.operator().unwrap() {
|
||||
BinOpKind::And => return self.compile_and(op),
|
||||
BinOpKind::Or => return self.compile_or(op),
|
||||
BinOpKind::Implication => todo!(),
|
||||
BinOpKind::Implication => return self.compile_implication(op),
|
||||
|
||||
_ => {}
|
||||
};
|
||||
|
@ -374,6 +374,26 @@ impl Compiler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_implication(&mut self, node: rnix::types::BinOp) -> EvalResult<()> {
|
||||
debug_assert!(
|
||||
matches!(node.operator(), Some(BinOpKind::Implication)),
|
||||
"compile_implication called with wrong operator kind: {:?}",
|
||||
node.operator(),
|
||||
);
|
||||
|
||||
// Leave left-hand side value on the stack and invert it.
|
||||
self.compile(node.lhs().unwrap())?;
|
||||
self.chunk.add_op(OpCode::OpInvert);
|
||||
|
||||
// Exactly as `||` (because `a -> b` = `!a || b`).
|
||||
let end_idx = self.chunk.add_op(OpCode::OpJumpIfTrue(0));
|
||||
self.chunk.add_op(OpCode::OpPop);
|
||||
self.compile(node.rhs().unwrap())?;
|
||||
self.patch_jump(end_idx);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn patch_jump(&mut self, idx: CodeIdx) {
|
||||
let offset = self.chunk.code.len() - 1 - idx.0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue