diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-11T11·54+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-25T16·01+0000 |
commit | 63a0cc83d13ebce3ae17c45778c4f25e831f1b7b (patch) | |
tree | 20de3ece65e514dc4f6a5d770a34e37f0e293d1a /tvix/eval/src/compiler.rs | |
parent | c7c7ab9bd4e105251ad56eb6c97157ee17354a9a (diff) |
feat(tvix/compiler): implement `->` (implication) operator r/4487
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>
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index b8ade621743c..90a6155b6b62 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -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; |