Implement addition

This commit is contained in:
Tiffany Bennett 2016-08-03 21:20:49 -04:00
parent fb39d5fb9f
commit 25d0da1f22
2 changed files with 34 additions and 4 deletions

View file

@ -32,6 +32,13 @@ impl Value {
.collect::<Unit>())
}
pub fn add(&self, other: &Value) -> Option<Value> {
if self.1 != other.1 {
return None
}
Some(Value(self.0 + other.0, self.1.clone()))
}
pub fn mul(&self, other: &Value) -> Value {
let mut val = Unit::new();
let mut a = self.1.iter().peekable();
@ -232,6 +239,16 @@ impl Context {
(Err(e), _) => Err(e),
(_, Err(e)) => Err(e),
},
Expr::Add(ref top, ref bottom) => match (self.eval(&**top), self.eval(&**bottom)) {
(Ok(top), Ok(bottom)) => {
top.add(&bottom).ok_or_else(|| {
format!("Add of values with differing units is not meaningful: {} + {}",
self.show(&top), self.show(&bottom))
})
},
(Err(e), _) => Err(e),
(_, Err(e)) => Err(e),
},
Expr::Convert(ref top, ref bottom) => match (self.eval(&**top), self.eval(&**bottom)) {
(Ok(top), Ok(bottom)) => {
if top.1 != bottom.1 {

View file

@ -195,6 +195,7 @@ pub enum Expr {
Frac(Box<Expr>, Box<Expr>),
Mul(Vec<Expr>),
Pow(Box<Expr>, Box<Expr>),
Add(Box<Expr>, Box<Expr>),
Neg(Box<Expr>),
Plus(Box<Expr>),
Convert(Box<Expr>, Box<Expr>),
@ -250,8 +251,8 @@ fn parse_pow(mut iter: &mut Iter) -> Expr {
fn parse_mul(mut iter: &mut Iter) -> Expr {
let mut terms = vec![parse_pow(iter)];
loop { match *iter.peek().unwrap() {
Token::DashArrow | Token::TriplePipe | Token::RPar | Token::Newline | Token::Comment(_) |
Token::Eof => break,
Token::Plus | Token::DashArrow | Token::TriplePipe | Token::RPar | Token::Newline |
Token::Comment(_) | Token::Eof => break,
Token::Slash => {
iter.next();
let right = parse_pow(iter);
@ -274,12 +275,24 @@ fn parse_mul(mut iter: &mut Iter) -> Expr {
}
}
pub fn parse_expr(mut iter: &mut Iter) -> Expr {
fn parse_add(mut iter: &mut Iter) -> Expr {
let left = parse_mul(iter);
match *iter.peek().unwrap() {
Token::Plus => {
iter.next();
let right = parse_add(iter);
Expr::Add(Box::new(left), Box::new(right))
},
_ => left
}
}
pub fn parse_expr(mut iter: &mut Iter) -> Expr {
let left = parse_add(iter);
match iter.peek().cloned().unwrap() {
Token::DashArrow => {
iter.next();
let right = parse_mul(iter);
let right = parse_add(iter);
Expr::Convert(Box::new(left), Box::new(right))
},
_ => left