Separate assign_expression method

This commit is contained in:
greg 2018-10-18 01:46:30 -07:00
parent cae6f2f768
commit 40ccea8c05

View File

@ -191,23 +191,7 @@ impl<'a> State<'a> {
Ok(Node::PrimTuple { items: nodes }) Ok(Node::PrimTuple { items: nodes })
}, },
Conditional { box cond, then_clause, else_clause } => self.conditional(cond, then_clause, else_clause), Conditional { box cond, then_clause, else_clause } => self.conditional(cond, then_clause, else_clause),
Assign { box val, box expr } => { Assign { box val, box expr } => self.assign_expression(val, expr),
let name = match val {
Expr::Val(name) => name,
_ => return Err(format!("Trying to assign to a non-value")),
};
let constant = match self.values.lookup(&name) {
None => return Err(format!("{} is undefined", name)),
Some(ValueEntry::Binding { constant, .. }) => constant.clone(),
};
if constant {
return Err(format!("trying to update {}, a non-mutable binding", name));
}
let val = self.expression(Node::Expr(expr))?;
self.values.insert(name.clone(), ValueEntry::Binding { constant: false, val });
Ok(Node::Expr(Expr::Unit))
},
Unit => Ok(Node::Expr(Unit)), Unit => Ok(Node::Expr(Unit)),
CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? { CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? {
Node::PrimObject { name, tag, items } => { Node::PrimObject { name, tag, items } => {
@ -391,6 +375,24 @@ impl<'a> State<'a> {
}) })
} }
fn assign_expression(&mut self, val: Expr, expr: Expr) -> EvalResult<Node> {
let name = match val {
Expr::Val(name) => name,
_ => return Err(format!("Trying to assign to a non-value")),
};
let constant = match self.values.lookup(&name) {
None => return Err(format!("Constant {} is undefined", name)),
Some(ValueEntry::Binding { constant, .. }) => constant.clone(),
};
if constant {
return Err(format!("trying to update {}, a non-mutable binding", name));
}
let val = self.expression(Node::Expr(expr))?;
self.values.insert(name.clone(), ValueEntry::Binding { constant: false, val });
Ok(Node::Expr(Expr::Unit))
}
fn value(&mut self, name: Rc<String>) -> EvalResult<Node> { fn value(&mut self, name: Rc<String>) -> EvalResult<Node> {
use self::ValueEntry::*; use self::ValueEntry::*;
use self::Func::*; use self::Func::*;