diff --git a/src/parser.rs b/src/parser.rs index b135e11..d4d61ec 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -40,7 +40,6 @@ pub enum Token { Number(LineLocation, f64), Constant(LineLocation, f64, String), - Root(VecDeque), Multiply(VecDeque), Divide(VecDeque), Add(VecDeque), @@ -52,6 +51,42 @@ pub enum Token { impl Token { + #[inline(always)] + pub fn get_args(&mut self) -> Option<&mut VecDeque> { + match self { + Token::Multiply(ref mut v) + | Token::Divide(ref mut v) + | Token::Add(ref mut v) + | Token::Factorial(ref mut v) + | Token::Negative(ref mut v) + | Token::Power(ref mut v) + | Token::Modulo(ref mut v) + => Some(v), + _ => None + } + } + + #[inline(always)] + pub fn get_line_location(&self) -> &LineLocation { + match self { + Token::PreNumber(l, _) | + Token::PreWord(l, _) | + Token::PreOperator(l, _) | + Token::PreGroupStart(l) | + Token::PreGroupEnd(l) | + Token::PreGroup(l, _) + => l, + + // These have a line location, but we shouldn't ever need to get it. + Token::Number(_l, _) | + Token::Constant(_l, _, _) + => panic!(), + + + _ => panic!() + } + } + #[inline(always)] fn as_number(&self) -> Token { match self { diff --git a/src/parser/evaluate.rs b/src/parser/evaluate.rs index ec93e90..9ef2674 100644 --- a/src/parser/evaluate.rs +++ b/src/parser/evaluate.rs @@ -9,17 +9,7 @@ fn get_at_coords<'a>(g: &'a mut Token, coords: &Vec) -> &'a mut Token { let mut h = &mut *g; for t in coords.iter() { - let inner = match h { - Token::Multiply(ref mut v) => v, - Token::Divide(ref mut v) => v, - Token::Add(ref mut v) => v, - Token::Factorial(ref mut v) => v, - Token::Negative(ref mut v) => v, - Token::Power(ref mut v) => v, - Token::Modulo(ref mut v) => v, - _ => panic!() - }; - + let inner = h.get_args().unwrap(); h = &mut inner[*t]; } @@ -37,17 +27,7 @@ pub fn p_evaluate( let mut h = &mut g; for t in coords.iter() { - let inner: Option<&mut VecDeque> = match h { - Token::Multiply(ref mut v) - | Token::Divide(ref mut v) - | Token::Add(ref mut v) - | Token::Factorial(ref mut v) - | Token::Negative(ref mut v) - | Token::Power(ref mut v) - | Token::Modulo(ref mut v) - => Some(v), - _ => None - }; + let inner = h.get_args(); if inner.is_none() || *t >= inner.as_ref().unwrap().len() { coords.pop(); diff --git a/src/parser/treeify.rs b/src/parser/treeify.rs index 3982250..565c230 100644 --- a/src/parser/treeify.rs +++ b/src/parser/treeify.rs @@ -5,18 +5,6 @@ use crate::parser::LineLocation; use crate::parser::ParserError; use crate::parser::Operator; -#[inline(always)] -fn get_line_location(t: &Token) -> &LineLocation { - match t { - Token::PreNumber(l, _) | - Token::PreWord(l, _) | - Token::PreOperator(l, _) | - Token::PreGroup(l, _) - => l, - _ => panic!() - } -} - #[inline(always)] fn select_op(k: Operator, mut new_token_args: VecDeque) -> Token { match k { @@ -87,7 +75,7 @@ fn treeify_binary( => { // Binary and right-unary operators cannot // follow a binary operator. - let LineLocation { pos: posa, .. } = *get_line_location(&this); + let LineLocation { pos: posa, .. } = *this.get_line_location(); let LineLocation { pos: posb, len: lenb } = *l; return Err(( LineLocation{pos: posa, len: posb - posa + lenb}, @@ -184,7 +172,7 @@ fn treeify_unaryleft( => { // Binary and right-unary operators cannot // follow a binary operator. - let LineLocation { pos: posa, .. } = *get_line_location(&this); + let LineLocation { pos: posa, .. } = *this.get_line_location(); let LineLocation { pos: posb, len: lenb } = *l; return Err(( LineLocation{pos: posa, len: posb - posa + lenb}, @@ -273,7 +261,7 @@ fn treeify_unaryright( match o { // Left unary operators Operator::Negative => { - let LineLocation { pos: posa, .. } = *get_line_location(&this); + let LineLocation { pos: posa, .. } = *this.get_line_location(); let LineLocation { pos: posb, len: lenb } = *l; return Err(( LineLocation{pos: posa, len: posb - posa + lenb}, @@ -284,14 +272,14 @@ fn treeify_unaryright( }; } else { return Err(( - *get_line_location(&this), + *this.get_line_location(), ParserError::Syntax )); } } if let Token::PreOperator(l, _) = left { - let LineLocation { pos: posa, .. } = *get_line_location(&this); + let LineLocation { pos: posa, .. } = *this.get_line_location(); let LineLocation { pos: posb, len: lenb } = *l; return Err(( LineLocation{pos: posa, len: posb - posa + lenb},