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