diff --git a/src/evaluate/operator.rs b/src/evaluate/operator.rs index 5f2984f..a21d88a 100644 --- a/src/evaluate/operator.rs +++ b/src/evaluate/operator.rs @@ -8,17 +8,7 @@ use crate::context::Context; pub fn eval_operator(op: &Operator, args: &VecDeque, context: &mut Context) -> Result, EvalError> { match op { - - // Handled seperately in evaluate.rs - Operator::Function(_) | - - // These are never evaluated, - // but are converted to one of the following instead. - Operator::ImplicitMultiply | - Operator::Sqrt | - Operator::Divide | - Operator::DivideLong | - Operator::Subtract => { panic!() } + Operator::Function(_) => unreachable!("Functions are handled seperately."), Operator::Define => { if args.len() != 2 { panic!() }; @@ -39,18 +29,6 @@ pub fn eval_operator(op: &Operator, args: &VecDeque, context: &mut C } else { return Ok(None); } }, - Operator::Flip => { - if args.len() != 1 { panic!() }; - let args = &args[0]; - - if let Expression::Quantity(v) = args { - if v.is_zero() { return Err(EvalError::ZeroDivision); } - return Ok(Some(Expression::Quantity( - Quantity::new_rational(1f64).unwrap()/v.clone() - ))); - } else { return Ok(None); } - }, - Operator::Add => { let mut sum: Quantity; if let Expression::Quantity(s) = &args[0] { @@ -73,6 +51,38 @@ pub fn eval_operator(op: &Operator, args: &VecDeque, context: &mut C return Ok(Some(Expression::Quantity(sum))); }, + Operator::Subtract => { + if args.len() != 2 { panic!() }; + let a = &args[0]; + let b = &args[1]; + + if let Expression::Quantity(a) = a { + if let Expression::Quantity(b) = b { + return Ok(Some(Expression::Quantity(a.clone() - b.clone()))); + } + } + + return Ok(None); + }, + + + Operator::Divide | + Operator::DivideLong => { + if args.len() != 2 { panic!() }; + let a = &args[0]; + let b = &args[1]; + + if let Expression::Quantity(a) = a { + if let Expression::Quantity(b) = b { + if b.is_zero() { return Err(EvalError::ZeroDivision); } + return Ok(Some(Expression::Quantity(a.clone() / b.clone()))); + } + } + + return Ok(None); + }, + + Operator::ImplicitMultiply | Operator::Multiply => { let mut prod = Quantity::new_rational(1f64).unwrap(); for i in args.iter() { @@ -106,8 +116,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque, context: &mut C } else { return Ok(None); } }, - Operator::UnitConvert - => { + Operator::UnitConvert => { if args.len() != 2 { panic!() }; let a = &args[0]; let b = &args[1]; @@ -123,6 +132,19 @@ pub fn eval_operator(op: &Operator, args: &VecDeque, context: &mut C } else { return Ok(None); } }, + + Operator::Sqrt => { + if args.len() != 1 { panic!() } + let a = &args[0]; + + if let Expression::Quantity(va) = a { + if va.is_negative() { return Err(EvalError::BadMath); } + let p = va.pow(Quantity::new_rational_from_string("0.5").unwrap()); + if p.is_nan() {return Err(EvalError::BadMath);} + return Ok(Some(Expression::Quantity(p))); + } else { return Ok(None); } + }, + Operator::Power => { if args.len() != 2 {panic!()}; let a = &args[0]; diff --git a/src/parser/expression/operator.rs b/src/parser/expression/operator.rs index 07cee78..a03bb4f 100644 --- a/src/parser/expression/operator.rs +++ b/src/parser/expression/operator.rs @@ -1,6 +1,5 @@ use std::cmp::Ordering; use std::collections::VecDeque; -use crate::quantity::Quantity; use super::Expression; use super::Function; @@ -29,9 +28,6 @@ pub enum Operator { Factorial, Function(Function), - - // Not accessible from prompt - Flip, } impl PartialEq for Operator { @@ -111,69 +107,6 @@ impl Operator { } } - #[inline(always)] - pub fn into_expression(self, mut args: VecDeque) -> Expression { - match self { - Operator::Subtract => { - if args.len() != 2 { panic!() } - let a = args.pop_front().unwrap(); - let b = args.pop_front().unwrap(); - - let b_new; - if let Expression::Quantity(q) = b { - b_new = Expression::Quantity(-q); - } else { - b_new = Expression::Operator(Operator::Negative, VecDeque::from(vec!(b))); - } - - Expression::Operator( - Operator::Add, - VecDeque::from(vec!(a,b_new)) - ) - }, - - Operator::DivideLong | - Operator::Divide => { - if args.len() != 2 { panic!() } - let a = args.pop_front().unwrap(); - let b = args.pop_front().unwrap(); - let b = Expression::Operator(Operator::Flip, VecDeque::from(vec!(b))); - - Expression::Operator( - Operator::Multiply, - VecDeque::from(vec!(a,b)) - ) - }, - - Operator::Sqrt => { - if args.len() != 1 { panic!() } - let a = args.pop_front().unwrap(); - - Expression::Operator( - Operator::Power, - VecDeque::from(vec!(a, Expression::Quantity(Quantity::new_rational_from_string("0.5").unwrap()))) - ) - }, - - Operator::ImplicitMultiply - => { Expression::Operator(Operator::Multiply, args) }, - - Operator::Function(_) - | Operator::Factorial - | Operator::Negative - | Operator::Flip - | Operator::Add - | Operator::Multiply - | Operator::Modulo - | Operator::Power - | Operator::ModuloLong - | Operator::UnitConvert - | Operator::Define - => { Expression::Operator(self, args) }, - } - } - - #[inline(always)] fn add_parens_to_arg(&self, arg: &Expression) -> String { let mut astr: String = arg.to_string(); @@ -199,11 +132,6 @@ impl Operator { pub fn print(&self, args: &VecDeque) -> String { match self { - Operator::ImplicitMultiply | - Operator::Sqrt | - Operator::Divide | - Operator::Subtract => { panic!() } - Operator::Define => { return format!( "{} = {}", @@ -212,14 +140,17 @@ impl Operator { ); }, - Operator::Flip => { - return format!("{}⁻¹", Operator::Divide.add_parens_to_arg(&args[0])); - }, - Operator::Negative => { return format!("-{}", self.add_parens_to_arg(&args[0])); }, + Operator::Sqrt => { + return format!( + "√{}", + self.add_parens_to_arg(&args[0]), + ); + }, + Operator::ModuloLong => { return format!( "{} mod {}", @@ -252,6 +183,14 @@ impl Operator { ); }, + Operator::Subtract => { + return format!( + "{} - {}", + self.add_parens_to_arg(&args[0]), + self.add_parens_to_arg(&args[1]) + ); + }, + Operator::Power => { return format!( "{}^{}", @@ -265,50 +204,17 @@ impl Operator { }, Operator::Add => { - let a = &args[0]; - - let b; let sub; - if let Expression::Operator(o, ar) = &args[1] { - if let Operator::Negative = o { - sub = true; - b = &ar[0]; - } else { sub = false; b = &args[1]; } - } else { sub = false; b = &args[1]; } - - if sub { - return format!( - "{} - {}", - self.add_parens_to_arg(a), - self.add_parens_to_arg(b) - ); - } else { - return format!( - "{} + {}", - self.add_parens_to_arg(a), - self.add_parens_to_arg(b) - ); - } + return format!( + "{} + {}", + self.add_parens_to_arg(&args[0]), + self.add_parens_to_arg(&args[1]) + ); }, + Operator::ImplicitMultiply | Operator::Multiply => { let a = &args[0]; - - let b; let div; - if let Expression::Operator(o, ar) = &args[1] { - if let Operator::Flip = o { - div = true; - b = &ar[0]; - } else { div = false; b = &args[1]; } - } else { div = false; b = &args[1]; } - - // Division symbol case - if div { - return format!("{} ÷ {}", - self.add_parens_to_arg_strict(a), - self.add_parens_to_arg_strict(b) - ); - } - + let b = &args[1]; // Omit times sign when we have a number // multiplied by a unit (like 10 m) @@ -342,6 +248,24 @@ impl Operator { } }, + Operator::Divide => { + let a = &args[0]; + let b = &args[1]; + + if let Expression::Quantity(q) = a { + if q.is_one() { + return format!("{}⁻¹", + self.add_parens_to_arg_strict(b) + ); + } + } + + return format!("{} ÷ {}", + self.add_parens_to_arg_strict(a), + self.add_parens_to_arg_strict(b) + ); + }, + Operator::Function(s) => { return format!("{}({})", s.to_string(), args[0].to_string()); } diff --git a/src/parser/stage/find_subs.rs b/src/parser/stage/find_subs.rs index 28f9e40..aceb668 100644 --- a/src/parser/stage/find_subs.rs +++ b/src/parser/stage/find_subs.rs @@ -26,7 +26,7 @@ pub fn find_subs( let mut t = g.pop_back().unwrap(); let target: Option<&str> = match &mut t { - Token::PreOperator(_, s) => { + Token::Operator(_, s) => { let target = match &s[..] { "*" => {Some("×")}, "/" => {Some("÷")}, @@ -41,7 +41,7 @@ pub fn find_subs( target }, - Token::PreWord(_, s) => { + Token::Word(_, s) => { let target = match &s[..] { // Greek letters "alpha" => {Some("α")}, diff --git a/src/parser/stage/groupify.rs b/src/parser/stage/groupify.rs index b7be870..4c8cc5d 100644 --- a/src/parser/stage/groupify.rs +++ b/src/parser/stage/groupify.rs @@ -19,10 +19,10 @@ fn lookback_signs( if i == 0 { let a: Token = g.remove(i).unwrap(); match &a { - Token::PreOperator(l,o) + Token::Operator(l,o) => { if o == "-" { - g.insert(i, Token::PreOperator(*l, String::from("neg"))); + g.insert(i, Token::Operator(*l, String::from("neg"))); } else if o == "+" { continue; // We should not increment i if we remove a token } else {g.insert(i, a);} @@ -35,7 +35,7 @@ fn lookback_signs( let b: Token = g.remove(i-1).unwrap(); match (&a, &b) { - (Token::PreOperator(_, sa), Token::PreOperator(l,sb)) + (Token::Operator(_, sa), Token::Operator(l,sb)) => { if { let o = Operator::from_string(sa); @@ -47,7 +47,7 @@ fn lookback_signs( ) } { if sb == "-" { - g.insert(i-1, Token::PreOperator(*l, String::from("neg"))); + g.insert(i-1, Token::Operator(*l, String::from("neg"))); g.insert(i-1, a); } else if sb == "+" { g.insert(i-1, a); @@ -71,7 +71,7 @@ fn lookback_signs( let b: Token = g.remove(i-1).unwrap(); match (&a, &b) { - (Token::PreOperator(_,sa), Token::PreOperator(_,sb)) + (Token::Operator(_,sa), Token::Operator(_,sb)) => { if !((sa == "neg") && (sb == "neg")) { g.insert(i-1, b); @@ -108,19 +108,19 @@ fn lookback( match (&a, &b) { // Insert ImplicitMultiply - (Token::PreGroup(_,_), Token::PreGroup(l ,_)) - | (Token::PreGroup(_,_), Token::PreQuantity(l,_)) - | (Token::PreQuantity(_,_), Token::PreGroup(l,_)) - | (Token::PreGroup(_,_), Token::PreWord(l,_)) - | (Token::PreWord(_,_), Token::PreGroup(l,_)) - | (Token::PreQuantity(_,_), Token::PreWord(l,_)) - | (Token::PreWord(_,_), Token::PreQuantity(l,_)) - | (Token::PreWord(_,_), Token::PreWord(l,_)) + (Token::Group(_,_), Token::Group(l ,_)) + | (Token::Group(_,_), Token::Quantity(l,_)) + | (Token::Quantity(_,_), Token::Group(l,_)) + | (Token::Group(_,_), Token::Word(l,_)) + | (Token::Word(_,_), Token::Group(l,_)) + | (Token::Quantity(_,_), Token::Word(l,_)) + | (Token::Word(_,_), Token::Quantity(l,_)) + | (Token::Word(_,_), Token::Word(l,_)) => { let loc = LineLocation{pos: l.pos-1, len: 0}; g.insert(i-1, b); - g.insert(i-1, Token::PreOperator( + g.insert(i-1, Token::Operator( loc, String::from("i*") )); @@ -128,9 +128,9 @@ fn lookback( }, // Insert implicit multiplications for right-unary operators - (Token::PreQuantity(_,_), Token::PreOperator(l,s)) - | (Token::PreGroup(_,_), Token::PreOperator(l,s)) - | (Token::PreWord(_,_), Token::PreOperator(l,s)) + (Token::Quantity(_,_), Token::Operator(l,s)) + | (Token::Group(_,_), Token::Operator(l,s)) + | (Token::Word(_,_), Token::Operator(l,s)) => { let o = Operator::from_string(s); let loc = LineLocation{pos: l.pos-1, len: 0}; @@ -139,7 +139,7 @@ fn lookback( if o.is_some() { let o = o.unwrap(); if (!o.is_binary()) && (!o.is_left_associative()) { - g.insert(i-1, Token::PreOperator( + g.insert(i-1, Token::Operator( loc, String::from("i*") )); @@ -149,9 +149,9 @@ fn lookback( }, // Insert implicit multiplications for left-unary operators. - (Token::PreOperator(_,s), Token::PreQuantity(l,_)) - | (Token::PreOperator(_,s), Token::PreGroup(l,_)) - | (Token::PreOperator(_,s), Token::PreWord(l,_)) + (Token::Operator(_,s), Token::Quantity(l,_)) + | (Token::Operator(_,s), Token::Group(l,_)) + | (Token::Operator(_,s), Token::Word(l,_)) => { let o = Operator::from_string(s); let loc = LineLocation{pos: l.pos-1, len: 0}; @@ -160,7 +160,7 @@ fn lookback( if o.is_some() { let o = o.unwrap(); if (!o.is_binary()) && o.is_left_associative() { - g.insert(i-1, Token::PreOperator( + g.insert(i-1, Token::Operator( loc, String::from("i*") )); @@ -170,7 +170,7 @@ fn lookback( }, // The following are syntax errors - (Token::PreQuantity(la,_), Token::PreQuantity(lb,_)) + (Token::Quantity(la,_), Token::Quantity(lb,_)) => { return Err(( LineLocation{pos: la.pos, len: lb.pos - la.pos + lb.len}, @@ -206,12 +206,12 @@ pub fn groupify( let (l_now, v_now) = levels.last_mut().unwrap(); match t { - Token::PreGroupStart(l) => { + Token::GroupStart(l) => { levels.push((l, VecDeque::with_capacity(8))); i_level += 1; }, - Token::PreGroupEnd(l) => { + Token::GroupEnd(l) => { let l = LineLocation { pos: l_now.pos, len: l.len + l.pos - l_now.pos @@ -226,7 +226,7 @@ pub fn groupify( let (_, v_now) = levels.last_mut().unwrap(); lookback(&mut v)?; - v_now.push_back(Token::PreGroup(l, v)); + v_now.push_back(Token::Group(l, v)); }, _ => { @@ -252,12 +252,12 @@ pub fn groupify( if v.len() == 0 { return Err((l, ParserError::EmptyGroup)) } lookback(&mut v)?; - v_now.push_back(Token::PreGroup(l, v)); + v_now.push_back(Token::Group(l, v)); } let (_, mut v) = levels.pop().unwrap(); lookback(&mut v)?; - return Ok(Token::PreGroup(LineLocation{pos:0, len:0}, v)); + return Ok(Token::Group(LineLocation{pos:0, len:0}, v)); } \ No newline at end of file diff --git a/src/parser/stage/tokenize.rs b/src/parser/stage/tokenize.rs index a8b9121..00e5ce0 100644 --- a/src/parser/stage/tokenize.rs +++ b/src/parser/stage/tokenize.rs @@ -14,11 +14,11 @@ fn push_token(g: &mut VecDeque, t: Option, stop_i: usize) { let mut t = t.unwrap(); match t { - Token::PreGroupStart(ref mut l) - | Token::PreGroupEnd(ref mut l) - | Token::PreOperator(ref mut l, _) - | Token::PreQuantity(ref mut l, _) - | Token::PreWord(ref mut l, _) + Token::GroupStart(ref mut l) + | Token::GroupEnd(ref mut l) + | Token::Operator(ref mut l, _) + | Token::Quantity(ref mut l, _) + | Token::Word(ref mut l, _) => { *l = LineLocation{ pos: l.pos, @@ -26,7 +26,7 @@ fn push_token(g: &mut VecDeque, t: Option, stop_i: usize) { }; }, - Token::PreGroup(_,_) + Token::Group(_,_) | Token::Container(_) => panic!() }; @@ -34,14 +34,14 @@ fn push_token(g: &mut VecDeque, t: Option, stop_i: usize) { // `2e` isn't exponential notation, it's 2*e. // If a number ends in `e`, disconnect the `e` and make it a word. - if let Token::PreQuantity(l, s) = &t { + if let Token::Quantity(l, s) = &t { let last = &s[s.len()-1..]; if last == "e" { - g.push_back(Token::PreQuantity( + g.push_back(Token::Quantity( LineLocation { pos: l.pos, len: l.len-1 }, String::from(&s[0..s.len()-1]) )); - g.push_back(Token::PreWord( + g.push_back(Token::Word( LineLocation { pos: l.pos + l.len - 1, len: 1 }, String::from("e") )); @@ -51,9 +51,9 @@ fn push_token(g: &mut VecDeque, t: Option, stop_i: usize) { } // Some operators are written as words. - if let Token::PreWord(l, s) = &t { + if let Token::Word(l, s) = &t { if Operator::from_string(s).is_some() { - t = Token::PreOperator(*l, s.clone()); + t = Token::Operator(*l, s.clone()); } } @@ -74,7 +74,7 @@ pub fn tokenize(input: &String) -> VecDeque { match &mut t { // If we're already building a number, // append. - Some(Token::PreQuantity(_, val)) => { + Some(Token::Quantity(_, val)) => { val.push(if c == ',' {'.'} else {c}); }, @@ -82,7 +82,7 @@ pub fn tokenize(input: &String) -> VecDeque { // previous token and start one. _ => { push_token(&mut g, t, i); - t = Some(Token::PreQuantity(LineLocation{pos: i, len: 0}, String::from(c))); + t = Some(Token::Quantity(LineLocation{pos: i, len: 0}, String::from(c))); } }; }, @@ -91,12 +91,12 @@ pub fn tokenize(input: &String) -> VecDeque { // Can be both a word or a number. 'e' => { match &mut t { - Some(Token::PreWord(_, val)) => { val.push(c); }, - Some(Token::PreQuantity(_, val)) => { val.push(c); }, + Some(Token::Word(_, val)) => { val.push(c); }, + Some(Token::Quantity(_, val)) => { val.push(c); }, _ => { push_token(&mut g, t, i); - t = Some(Token::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); + t = Some(Token::Word(LineLocation{pos: i, len: 0}, String::from(c))); } }; } @@ -106,7 +106,7 @@ pub fn tokenize(input: &String) -> VecDeque { // or it can specify a negative exponent. '-' | '+' => { match &mut t { - Some(Token::PreQuantity(_, val)) => { + Some(Token::Quantity(_, val)) => { if &val[val.len()-1..] == "e" { // If the current number ends in an `e`, // this negative specifies a negative exponent @@ -116,7 +116,7 @@ pub fn tokenize(input: &String) -> VecDeque { // Otherwise, end the number. // We probably have a subtraction. push_token(&mut g, t, i); - t = Some(Token::PreOperator( + t = Some(Token::Operator( LineLocation{pos: i, len: 1}, String::from(c) )); @@ -126,7 +126,7 @@ pub fn tokenize(input: &String) -> VecDeque { // This may be a negative or a subtraction _ => { push_token(&mut g, t, i); - t = Some(Token::PreOperator( + t = Some(Token::Operator( LineLocation{pos: i, len: 1}, String::from(c) )); @@ -139,10 +139,10 @@ pub fn tokenize(input: &String) -> VecDeque { '^'|'!'|'%'|'=' => { match &mut t { - Some(Token::PreOperator(_, val)) => { val.push(c); }, + Some(Token::Operator(_, val)) => { val.push(c); }, _ => { push_token(&mut g, t, i); - t = Some(Token::PreOperator(LineLocation{pos: i, len: 0}, String::from(c))); + t = Some(Token::Operator(LineLocation{pos: i, len: 0}, String::from(c))); } }; }, @@ -150,11 +150,11 @@ pub fn tokenize(input: &String) -> VecDeque { // Group '(' => { push_token(&mut g, t, i); - t = Some(Token::PreGroupStart(LineLocation{pos: i, len: 0})); + t = Some(Token::GroupStart(LineLocation{pos: i, len: 0})); }, ')' => { push_token(&mut g, t, i); - t = Some(Token::PreGroupEnd(LineLocation{pos: i, len: 0})); + t = Some(Token::GroupEnd(LineLocation{pos: i, len: 0})); }, // Space. Basic seperator. @@ -166,11 +166,11 @@ pub fn tokenize(input: &String) -> VecDeque { // Word _ => { match &mut t { - Some(Token::PreWord(_, val)) => { val.push(c); }, + Some(Token::Word(_, val)) => { val.push(c); }, _ => { push_token(&mut g, t, i); - t = Some(Token::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); + t = Some(Token::Word(LineLocation{pos: i, len: 0}, String::from(c))); } }; } diff --git a/src/parser/stage/treeify.rs b/src/parser/stage/treeify.rs index d1e0d48..ce7d63d 100644 --- a/src/parser/stage/treeify.rs +++ b/src/parser/stage/treeify.rs @@ -20,7 +20,7 @@ fn treeify_binary( if i == 0 { // This binary operator is at the end of an expression. let l = match this { - Token::PreOperator(l, _) => l, + Token::Operator(l, _) => l, _ => panic!() }; return Err((*l, ParserError::Syntax)); @@ -32,7 +32,7 @@ fn treeify_binary( &g_inner[i-1] } else { let l = match this { - Token::PreOperator(l, _) => l, + Token::Operator(l, _) => l, _ => panic!() }; return Err((*l, ParserError::Syntax)); @@ -44,7 +44,7 @@ fn treeify_binary( &g_inner[i+1] } else { let l = match this { - Token::PreOperator(l, _) => l, + Token::Operator(l, _) => l, _ => panic!() }; return Err((*l, ParserError::Syntax)); @@ -55,7 +55,7 @@ fn treeify_binary( - if let Token::PreOperator(l, s) = left { + if let Token::Operator(l, s) = left { let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } let o = o.unwrap(); @@ -74,7 +74,7 @@ fn treeify_binary( } } - if let Token::PreOperator(l, s) = right { + if let Token::Operator(l, s) = right { let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } let o = o.unwrap(); @@ -96,7 +96,7 @@ fn treeify_binary( // This operator let this_op = { - let Token::PreOperator(l, s) = this else {panic!()}; + let Token::Operator(l, s) = this else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } o.unwrap() @@ -104,14 +104,14 @@ fn treeify_binary( // The operators contesting our arguments let left_op = if i > 1 { - let Token::PreOperator(l, s) = &g_inner[i-2] else {panic!()}; + let Token::Operator(l, s) = &g_inner[i-2] else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } Some(o.unwrap()) } else { None }; let right_op = if i < g_inner.len()-2 { - let Token::PreOperator(l, s) = &g_inner[i+2] else {panic!()}; + let Token::Operator(l, s) = &g_inner[i+2] else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } Some(o.unwrap()) @@ -127,11 +127,11 @@ fn treeify_binary( let this_pre = g_inner.remove(i-1).unwrap(); let right_pre = g_inner.remove(i-1).unwrap(); let left: Expression; let right: Expression; - if let Token::PreGroup(_, _) = right_pre { right = treeify(right_pre, context)?; } else {right = right_pre.to_expression(context)?;} - if let Token::PreGroup(_, _) = left_pre { left = treeify(left_pre, context)?; } else {left = left_pre.to_expression(context)?;} + if let Token::Group(_, _) = right_pre { right = treeify(right_pre, context)?; } else {right = right_pre.to_expression(context)?;} + if let Token::Group(_, _) = left_pre { left = treeify(left_pre, context)?; } else {left = left_pre.to_expression(context)?;} let o = { - let Token::PreOperator(_, s) = this_pre else {panic!()}; + let Token::Operator(_, s) = this_pre else {panic!()}; let o = Operator::from_string(&s); if o.is_none() { panic!() } o.unwrap() @@ -141,7 +141,7 @@ fn treeify_binary( new_token_args.push_back(left); new_token_args.push_back(right); - g_inner.insert(i-1, Token::Container(o.into_expression(new_token_args))); + g_inner.insert(i-1, Token::Container(Expression::Operator(o, new_token_args))); return Ok(true); } else { @@ -164,7 +164,7 @@ fn treeify_unary( &g_inner[i-1] } else { let l = match this { - Token::PreOperator(l, _) => l, + Token::Operator(l, _) => l, _ => panic!() }; return Err((*l, ParserError::Syntax)); @@ -176,7 +176,7 @@ fn treeify_unary( &g_inner[i+1] } else { let l = match this { - Token::PreOperator(l, _) => l, + Token::Operator(l, _) => l, _ => panic!() }; return Err((*l, ParserError::Syntax)); @@ -194,7 +194,7 @@ fn treeify_unary( } if prev.is_some() { - if let Token::PreOperator(_,_) = prev.unwrap() { + if let Token::Operator(_,_) = prev.unwrap() { } else { return Err(( *this.get_line_location(), @@ -203,7 +203,7 @@ fn treeify_unary( } } - if let Token::PreOperator(l, _) = next { + if let Token::Operator(l, _) = next { let tl = *this.get_line_location(); return Err(( LineLocation{pos: tl.pos, len: l.pos - tl.pos + l.len}, @@ -214,7 +214,7 @@ fn treeify_unary( // This operator let this_op = { - let Token::PreOperator(l, s) = this else {panic!()}; + let Token::Operator(l, s) = this else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } o.unwrap() @@ -223,14 +223,14 @@ fn treeify_unary( // The operator contesting our argument let next_op = if left_associative { if i > 1 { - let Token::PreOperator(l, s) = &g_inner[i-2] else {panic!()}; + let Token::Operator(l, s) = &g_inner[i-2] else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } Some(o.unwrap()) } else { None } } else { if i < g_inner.len()-2 { - let Token::PreOperator(l, s) = &g_inner[i+2] else {panic!()}; + let Token::Operator(l, s) = &g_inner[i+2] else {panic!()}; let o = Operator::from_string(s); if o.is_none() { return Err((*l, ParserError::Syntax)); } Some(o.unwrap()) @@ -245,10 +245,10 @@ fn treeify_unary( } else { next_pre = g_inner.remove(i).unwrap(); } - if let Token::PreGroup(_, _) = next_pre { next = treeify(next_pre, context)?; } else { next = next_pre.to_expression(context)? } + if let Token::Group(_, _) = next_pre { next = treeify(next_pre, context)?; } else { next = next_pre.to_expression(context)? } let o = { - let Token::PreOperator(_, s) = this_pre else {panic!()}; + let Token::Operator(_, s) = this_pre else {panic!()}; let o = Operator::from_string(&s); if o.is_none() { panic!() } o.unwrap() @@ -258,9 +258,9 @@ fn treeify_unary( new_token_args.push_back(next); if left_associative { - g_inner.insert(i-1, Token::Container(o.into_expression(new_token_args))); + g_inner.insert(i-1, Token::Container(Expression::Operator(o, new_token_args))); } else { - g_inner.insert(i, Token::Container(o.into_expression(new_token_args))); + g_inner.insert(i, Token::Container(Expression::Operator(o, new_token_args))); } return Ok(true); @@ -279,7 +279,7 @@ pub fn treeify( ) -> Result { let g_inner: &mut VecDeque = match g { - Token::PreGroup(_, ref mut x) => x, + Token::Group(_, ref mut x) => x, _ => panic!() }; @@ -297,10 +297,10 @@ pub fn treeify( let i = j as usize; - // Convert preoperators + // Convert operators // If not an operator, move on. let this_op = match &g_inner[i] { - Token::PreOperator(l, s) => { + Token::Operator(l, s) => { let o = Operator::from_string(&s); if o.is_none() { return Err((*l, ParserError::Syntax)); } o.unwrap() @@ -342,10 +342,10 @@ pub fn treeify( let g = g_inner.pop_front().unwrap(); return match g { // Catch edge cases - Token::PreOperator(l, _) => { + Token::Operator(l, _) => { Err((l, ParserError::Syntax)) }, - Token::PreGroup(_,_) => { + Token::Group(_,_) => { treeify(g, context) }, diff --git a/src/parser/token.rs b/src/parser/token.rs index 25fe121..eb54a69 100644 --- a/src/parser/token.rs +++ b/src/parser/token.rs @@ -13,14 +13,15 @@ use super::{ #[derive(Debug)] pub enum Token { - PreQuantity(LineLocation, String), - PreWord(LineLocation, String), - PreOperator(LineLocation, String), + Quantity(LineLocation, String), + Word(LineLocation, String), + Operator(LineLocation, String), - PreGroupStart(LineLocation), - PreGroupEnd(LineLocation), - PreGroup(LineLocation, VecDeque), + GroupStart(LineLocation), + GroupEnd(LineLocation), + Group(LineLocation, VecDeque), + // Never parsed from input, used to build a tree. Container(Expression) } @@ -28,37 +29,37 @@ impl Token { #[inline(always)] pub fn get_line_location(&self) -> &LineLocation { match self { - Token::PreQuantity(l, _) - | Token::PreWord(l, _) - | Token::PreOperator(l, _) - | Token::PreGroupStart(l) - | Token::PreGroupEnd(l) - | Token::PreGroup(l, _) + Token::Quantity(l, _) + | Token::Word(l, _) + | Token::Operator(l, _) + | Token::GroupStart(l) + | Token::GroupEnd(l) + | Token::Group(l, _) => l, - _ => panic!() + Token::Container(_) => panic!("Containers do not have a linelocation.") } } #[inline(always)] pub fn get_mut_line_location(&mut self) -> &mut LineLocation { match self { - Token::PreQuantity(l, _) - | Token::PreWord(l, _) - | Token::PreOperator(l, _) - | Token::PreGroupStart(l) - | Token::PreGroupEnd(l) - | Token::PreGroup(l, _) + Token::Quantity(l, _) + | Token::Word(l, _) + | Token::Operator(l, _) + | Token::GroupStart(l) + | Token::GroupEnd(l) + | Token::Group(l, _) => l, - _ => panic!() + Token::Container(_) => panic!("Containers do not have a linelocation.") } } #[inline(always)] pub fn to_expression(self, context: &Context) -> Result{ match self { - Token::PreQuantity(l, mut s) => { + Token::Quantity(l, mut s) => { // The length check here ensures that // `.` is not parsed as `0.` @@ -76,7 +77,7 @@ impl Token { return Ok(Expression::Quantity(r.unwrap())); }, - Token::PreWord(_l, s) => { + Token::Word(_l, s) => { let c = Constant::from_string(&s); if c.is_some() { return Ok(Expression::Constant(c.unwrap())); } @@ -91,10 +92,10 @@ impl Token { Token::Container(v) => { return Ok(v); } - Token::PreOperator(_,_) - | Token::PreGroupStart(_) - | Token::PreGroupEnd(_) - | Token::PreGroup(_, _) + Token::Operator(_,_) + | Token::GroupStart(_) + | Token::GroupEnd(_) + | Token::Group(_, _) => panic!() }; }