feat(tvix/eval): track source spans for if expressions

These are again a bit tricky in terms of emitted errors. The main
error is that the condition is not a boolean, which means that the
jump inspecting the condition must derive from the condition itself to
return an error at the correct position.

For other parts of the expression, it is simply the node itself.

Change-Id: I72411630e5d57dfc199f4c3c48afe443fe966322
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6392
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-09-01 17:36:13 +03:00 committed by tazjin
parent baa012d5a3
commit 7f687f0e99

View file

@ -625,15 +625,18 @@ impl Compiler<'_> {
fn compile_if_else(&mut self, slot: Option<LocalIdx>, node: ast::IfElse) { fn compile_if_else(&mut self, slot: Option<LocalIdx>, node: ast::IfElse) {
self.compile(slot, node.condition().unwrap()); self.compile(slot, node.condition().unwrap());
let then_idx = self.push_op_old(OpCode::OpJumpIfFalse(JumpOffset(0))); let then_idx = self.push_op(
OpCode::OpJumpIfFalse(JumpOffset(0)),
&node.condition().unwrap(),
);
self.push_op_old(OpCode::OpPop); // discard condition value self.push_op(OpCode::OpPop, &node); // discard condition value
self.compile(slot, node.body().unwrap()); self.compile(slot, node.body().unwrap());
let else_idx = self.push_op_old(OpCode::OpJump(JumpOffset(0))); let else_idx = self.push_op(OpCode::OpJump(JumpOffset(0)), &node);
self.patch_jump(then_idx); // patch jump *to* else_body self.patch_jump(then_idx); // patch jump *to* else_body
self.push_op_old(OpCode::OpPop); // discard condition value self.push_op(OpCode::OpPop, &node); // discard condition value
self.compile(slot, node.else_body().unwrap()); self.compile(slot, node.else_body().unwrap());
self.patch_jump(else_idx); // patch jump *over* else body self.patch_jump(else_idx); // patch jump *over* else body