feat(tvix/eval): carry optional SyntaxNode in error type
This starts paving the way for nicer, source-code based error reporting. Right now the code paths in the VM do not emit annotated errors, as we do not yet preserve that structure from the compiler. However, error emitting code paths in the compiler have been amended to include known nodes. Change-Id: I1b74410ffd891c40cd913361bd73c4336ec8aa5b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6235 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
This commit is contained in:
parent
51be6542c9
commit
2662376941
6 changed files with 62 additions and 40 deletions
|
|
@ -5,7 +5,7 @@ use std::rc::Rc;
|
|||
|
||||
use crate::{
|
||||
chunk::Chunk,
|
||||
errors::{Error, EvalResult},
|
||||
errors::{ErrorKind, EvalResult},
|
||||
opcode::OpCode,
|
||||
value::{NixAttrs, NixList, Value},
|
||||
};
|
||||
|
|
@ -38,14 +38,14 @@ macro_rules! arithmetic_op {
|
|||
(Value::Integer(i1), Value::Float(f2)) => Value::Float(i1 as f64 $op f2),
|
||||
(Value::Float(f1), Value::Integer(i2)) => Value::Float(f1 $op i2 as f64),
|
||||
|
||||
(v1, v2) => return Err(Error::TypeError {
|
||||
(v1, v2) => return Err(ErrorKind::TypeError {
|
||||
expected: "number (either int or float)",
|
||||
actual: if v1.is_number() {
|
||||
v2.type_of()
|
||||
} else {
|
||||
v1.type_of()
|
||||
},
|
||||
}),
|
||||
}.into()),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -65,10 +65,10 @@ macro_rules! cmp_op {
|
|||
(Value::Float(f1), Value::Integer(i2)) => f1 $op (i2 as f64),
|
||||
(Value::String(s1), Value::String(s2)) => s1 $op s2,
|
||||
|
||||
(lhs, rhs) => return Err(Error::Incomparable {
|
||||
(lhs, rhs) => return Err(ErrorKind::Incomparable {
|
||||
lhs: lhs.type_of(),
|
||||
rhs: rhs.type_of(),
|
||||
}),
|
||||
}.into()),
|
||||
};
|
||||
|
||||
$self.push(Value::Bool(result));
|
||||
|
|
@ -136,10 +136,11 @@ impl VM {
|
|||
Value::Integer(i) => self.push(Value::Integer(-i)),
|
||||
Value::Float(f) => self.push(Value::Float(-f)),
|
||||
v => {
|
||||
return Err(Error::TypeError {
|
||||
return Err(ErrorKind::TypeError {
|
||||
expected: "number (either int or float)",
|
||||
actual: v.type_of(),
|
||||
})
|
||||
}
|
||||
.into())
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -177,9 +178,10 @@ impl VM {
|
|||
Some(value) => self.push(value.clone()),
|
||||
|
||||
None => {
|
||||
return Err(Error::AttributeNotFound {
|
||||
return Err(ErrorKind::AttributeNotFound {
|
||||
name: key.as_str().to_string(),
|
||||
})
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -255,10 +257,11 @@ impl VM {
|
|||
OpCode::OpAssertBool => {
|
||||
let val = self.peek(0);
|
||||
if !val.is_bool() {
|
||||
return Err(Error::TypeError {
|
||||
return Err(ErrorKind::TypeError {
|
||||
expected: "bool",
|
||||
actual: val.type_of(),
|
||||
});
|
||||
}
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,12 +305,12 @@ impl VM {
|
|||
}
|
||||
}
|
||||
|
||||
return Err(Error::UnknownDynamicVariable(ident.to_string()));
|
||||
return Err(ErrorKind::UnknownDynamicVariable(ident.to_string()).into());
|
||||
}
|
||||
|
||||
OpCode::OpAssert => {
|
||||
if !self.pop().as_bool()? {
|
||||
return Err(Error::AssertionFailed);
|
||||
return Err(ErrorKind::AssertionFailed.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue