compose_eval/expression/
assignment.rs1use crate::access::Access;
2use crate::{Eval, Evaluated, Machine};
3use compose_library::diag::{bail, At, SourceResult};
4use compose_library::{ops, Value};
5use compose_syntax::ast;
6use compose_syntax::ast::{AssignOp, AstNode};
7
8impl Eval for ast::Assignment<'_> {
9 fn eval(self, vm: &mut Machine) -> SourceResult<Evaluated> {
10 let op = match self.op() {
11 AssignOp::Assign => |_init: &Value, rhs: &Value| Ok(rhs.clone()),
12 AssignOp::AddAssign => ops::add,
13 AssignOp::SubAssign => ops::sub,
14 AssignOp::MulAssign => ops::mul,
15 AssignOp::DivAssign => ops::div,
16 other => bail!(self.span(), "unsupported assignment operator: {:?}", other),
17 };
18
19 let rhs = self.rhs().eval(vm)?;
21
22 let lhs = self.lhs().access(vm)?;
23 let value = op(&lhs, &rhs.value).at(self.span())?;
24 *lhs = value;
25
26 Ok(Evaluated::unit())
27 }
28}