diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-01-31 22:43:11 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-01-31 22:43:11 +0100 |
| commit | 6fcef9973be4253e5b377251dd9d1921f9738fc1 (patch) | |
| tree | b849a6a8707d207c5cec5a1dcbeb60e4bf52b73c /src | |
| parent | e3139ed3ee8c96b89f7f10f4ed72b4893d724689 (diff) | |
Refresh tests 🔄
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/mod.rs | 50 | ||||
| -rw-r--r-- | src/eval/ops.rs | 6 | ||||
| -rw-r--r-- | src/parse/parser.rs | 2 |
3 files changed, 43 insertions, 15 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index a43219e7..1a211670 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -317,17 +317,11 @@ impl Spanned<&ExprBinary> { return Value::Error; } - let lhty = lhs.type_name(); - let rhty = rhs.type_name(); + let (l, r) = (lhs.type_name(), rhs.type_name()); + let out = op(lhs, rhs); if out == Value::Error { - ctx.diag(error!( - self.span, - "cannot apply '{}' to {} and {}", - self.v.op.v.as_str(), - lhty, - rhty, - )); + self.error(ctx, l, r); } out @@ -358,13 +352,41 @@ impl Spanned<&ExprBinary> { } }; - if let Ok(mut slot) = slot.try_borrow_mut() { - *slot = op(std::mem::take(&mut slot), rhs); - return Value::None; + let (constant, err, value) = if let Ok(mut inner) = slot.try_borrow_mut() { + let lhs = std::mem::take(&mut *inner); + let types = (lhs.type_name(), rhs.type_name()); + + *inner = op(lhs, rhs); + if *inner == Value::Error { + (false, Some(types), Value::Error) + } else { + (false, None, Value::None) + } + } else { + (true, None, Value::Error) + }; + + if constant { + ctx.diag(error!(span, "cannot assign to a constant")); } - ctx.diag(error!(span, "cannot assign to a constant")); - Value::Error + if let Some((l, r)) = err { + self.error(ctx, l, r); + } + + value + } + + fn error(&self, ctx: &mut EvalContext, l: &str, r: &str) { + let op = self.v.op.v.as_str(); + let message = match self.v.op.v { + BinOp::Add => format!("cannot add {} and {}", l, r), + BinOp::Sub => format!("cannot subtract {1} from {0}", l, r), + BinOp::Mul => format!("cannot multiply {} with {}", l, r), + BinOp::Div => format!("cannot divide {} by {}", l, r), + _ => format!("cannot apply '{}' to {} and {}", op, l, r), + }; + ctx.diag(error!(self.span, "{}", message)); } } diff --git a/src/eval/ops.rs b/src/eval/ops.rs index 56d6687b..c52a62ca 100644 --- a/src/eval/ops.rs +++ b/src/eval/ops.rs @@ -44,10 +44,16 @@ pub fn add(lhs: Value, rhs: Value) -> Value { (Linear(a), Length(b)) => Linear(a + b), (Linear(a), Relative(b)) => Linear(a + b), (Linear(a), Linear(b)) => Linear(a + b), + (Str(a), Str(b)) => Str(a + &b), (Array(a), Array(b)) => Array(concat(a, b)), (Dict(a), Dict(b)) => Dict(concat(a, b)), + + // TODO: Add string and template. (Template(a), Template(b)) => Template(concat(a, b)), + (Template(a), None) => Template(a), + (None, Template(b)) => Template(b), + _ => Error, } } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 2ca8eb10..b7767772 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -205,7 +205,7 @@ impl<'s> Parser<'s> { pub fn expect(&mut self, t: Token) -> bool { let eaten = self.eat_if(t); if !eaten { - self.expected(t.name()); + self.expected_at(t.name(), self.last_end); } eaten } |
