mirror of
				https://github.com/rm-dr/daisy
				synced 2025-10-30 22:14:55 -07:00 
			
		
		
		
	Renamed token and pretoken
This commit is contained in:
		| @ -93,7 +93,7 @@ pub fn write(target: &Path) { | ||||
|  | ||||
| 	writeln!(file, | ||||
| 		concat!( | ||||
| 			"\tpub fn value(&self) -> Token {{\n", | ||||
| 			"\tpub fn value(&self) -> Expression {{\n", | ||||
| 			"\t\tmatch self {{" | ||||
| 		) | ||||
| 	).unwrap(); | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| use crate::parser::Token; | ||||
| use crate::parser::Expression; | ||||
| use std::collections::HashMap; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| pub struct Context { | ||||
| 	history: Vec<Token>, | ||||
| 	variables: HashMap<String, Token> | ||||
| 	history: Vec<Expression>, | ||||
| 	variables: HashMap<String, Expression> | ||||
| } | ||||
|  | ||||
| impl Context { | ||||
| @ -12,13 +12,13 @@ impl Context { | ||||
| 		Context{ history: Vec::new(), variables: HashMap::new() } | ||||
| 	} | ||||
|  | ||||
| 	pub fn push_hist(&mut self, t: Token) { self.history.push(t); } | ||||
| 	pub fn push_var(&mut self, s: String, t: Token) { self.variables.insert(s, t); } | ||||
| 	pub fn push_hist(&mut self, t: Expression) { self.history.push(t); } | ||||
| 	pub fn push_var(&mut self, s: String, t: Expression) { self.variables.insert(s, t); } | ||||
| 	pub fn del_var(&mut self, s: &String) { self.variables.remove(s); } | ||||
|  | ||||
| 	pub fn get_variable(&self, s: &String) -> Option<Token> { | ||||
| 	pub fn get_variable(&self, s: &String) -> Option<Expression> { | ||||
|  | ||||
| 		let v: Option<&Token>; | ||||
| 		let v: Option<&Expression>; | ||||
|  | ||||
| 		if s == "ans" { | ||||
| 			v = self.history.last(); | ||||
|  | ||||
| @ -25,7 +25,7 @@ fn do_expression( | ||||
| 	stdout: &mut RawTerminal<std::io::Stdout>, | ||||
| 	s: &String, | ||||
| 	context: &mut Context | ||||
| ) -> Result<parser::Token, ()> { | ||||
| ) -> Result<parser::Expression, ()> { | ||||
| 	#[cfg(debug_assertions)] | ||||
| 	RawTerminal::suspend_raw_mode(&stdout).unwrap(); | ||||
| 	let g = parser::parse(&s, context); | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| use crate::parser::Token; | ||||
| use crate::parser::Expression; | ||||
| use crate::parser::Operator; | ||||
| use crate::context::Context; | ||||
|  | ||||
| @ -7,9 +7,9 @@ use super::operator::eval_operator; | ||||
| use super::function::eval_function; | ||||
| use super::EvalError; | ||||
|  | ||||
| pub fn evaluate(t: &Token, context: &mut Context) -> Result<Token, EvalError> { | ||||
| pub fn evaluate(t: &Expression, context: &mut Context) -> Result<Expression, EvalError> { | ||||
|  | ||||
| 	// Keeps track of our position in the token tree. | ||||
| 	// Keeps track of our position in the expression tree. | ||||
| 	// For example, the coordinates [0, 2, 1] are interpreted as follows: | ||||
| 	// Start at the root node, | ||||
| 	//    then move to that node's 0th child, | ||||
| @ -40,12 +40,12 @@ pub fn evaluate(t: &Token, context: &mut Context) -> Result<Token, EvalError> { | ||||
|  | ||||
|  | ||||
| 			let new = match g { | ||||
| 				Token::Quantity(_) => None, | ||||
| 				Expression::Quantity(_) => None, | ||||
|  | ||||
| 				Token::Constant(c) => { Some(evaluate(&c.value(), context).unwrap()) }, | ||||
| 				Token::Variable(s) => { context.get_variable(&s) }, | ||||
| 				Token::Operator(Operator::Function(f), v) => { Some(eval_function(&f, &v)?) }, | ||||
| 				Token::Operator(o, v) => { eval_operator(&o, &v, context)? }, | ||||
| 				Expression::Constant(c) => { Some(evaluate(&c.value(), context).unwrap()) }, | ||||
| 				Expression::Variable(s) => { context.get_variable(&s) }, | ||||
| 				Expression::Operator(Operator::Function(f), v) => { Some(eval_function(&f, &v)?) }, | ||||
| 				Expression::Operator(o, v) => { eval_operator(&o, &v, context)? }, | ||||
| 			}; | ||||
|  | ||||
| 			if new.is_some() { *g = new.unwrap()} | ||||
| @ -63,7 +63,7 @@ pub fn evaluate(t: &Token, context: &mut Context) -> Result<Token, EvalError> { | ||||
|  | ||||
| 			let n = root.get_at_coords(&coords[..]); | ||||
| 			if let Some(n) = n { | ||||
| 				if let Token::Operator(Operator::Define, _) = n { | ||||
| 				if let Expression::Operator(Operator::Define, _) = n { | ||||
| 					*coords.last_mut().unwrap() += 1; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @ -1,19 +1,19 @@ | ||||
| use std::collections::VecDeque; | ||||
|  | ||||
| use crate::parser::Token; | ||||
| use crate::parser::Expression; | ||||
| use crate::parser::Function; | ||||
| use super::EvalError; | ||||
|  | ||||
|  | ||||
| pub fn eval_function(f: &Function, args: &VecDeque<Token>) -> Result<Token, EvalError> { | ||||
| pub fn eval_function(f: &Function, args: &VecDeque<Expression>) -> Result<Expression, EvalError> { | ||||
| 	if args.len() != 1 {panic!()}; | ||||
| 	let a = &args[0]; | ||||
| 	let Token::Quantity(q) = a else {panic!()}; | ||||
| 	let Expression::Quantity(q) = a else {panic!()}; | ||||
|  | ||||
|  | ||||
| 	match f { | ||||
| 		Function::NoUnit => { return Ok(Token::Quantity(q.without_unit())); } | ||||
| 		Function::ToBase => { return Ok(Token::Quantity(q.convert_to_base())); } | ||||
| 		Function::NoUnit => { return Ok(Expression::Quantity(q.without_unit())); } | ||||
| 		Function::ToBase => { return Ok(Expression::Quantity(q.convert_to_base())); } | ||||
| 		_ => {} | ||||
| 	} | ||||
|  | ||||
| @ -22,35 +22,35 @@ pub fn eval_function(f: &Function, args: &VecDeque<Token>) -> Result<Token, Eval | ||||
| 	} | ||||
|  | ||||
| 	match f { | ||||
| 		Function::Abs => { return Ok(Token::Quantity(q.abs())); }, | ||||
| 		Function::Floor => { return Ok(Token::Quantity(q.floor())); }, | ||||
| 		Function::Ceil => { return Ok(Token::Quantity(q.ceil())); }, | ||||
| 		Function::Round => { return Ok(Token::Quantity(q.round())); }, | ||||
| 		Function::Abs => { return Ok(Expression::Quantity(q.abs())); }, | ||||
| 		Function::Floor => { return Ok(Expression::Quantity(q.floor())); }, | ||||
| 		Function::Ceil => { return Ok(Expression::Quantity(q.ceil())); }, | ||||
| 		Function::Round => { return Ok(Expression::Quantity(q.round())); }, | ||||
|  | ||||
| 		Function::NaturalLog => { return Ok(Token::Quantity(q.ln())); }, | ||||
| 		Function::TenLog => { return Ok(Token::Quantity(q.log10())); }, | ||||
| 		Function::NaturalLog => { return Ok(Expression::Quantity(q.ln())); }, | ||||
| 		Function::TenLog => { return Ok(Expression::Quantity(q.log10())); }, | ||||
|  | ||||
| 		Function::Sin => { return Ok(Token::Quantity(q.sin())); }, | ||||
| 		Function::Cos => { return Ok(Token::Quantity(q.cos())); }, | ||||
| 		Function::Tan => { return Ok(Token::Quantity(q.tan())); }, | ||||
| 		Function::Asin => { return Ok(Token::Quantity(q.asin())); }, | ||||
| 		Function::Acos => { return Ok(Token::Quantity(q.acos())); }, | ||||
| 		Function::Atan => { return Ok(Token::Quantity(q.atan())); }, | ||||
| 		Function::Sin => { return Ok(Expression::Quantity(q.sin())); }, | ||||
| 		Function::Cos => { return Ok(Expression::Quantity(q.cos())); }, | ||||
| 		Function::Tan => { return Ok(Expression::Quantity(q.tan())); }, | ||||
| 		Function::Asin => { return Ok(Expression::Quantity(q.asin())); }, | ||||
| 		Function::Acos => { return Ok(Expression::Quantity(q.acos())); }, | ||||
| 		Function::Atan => { return Ok(Expression::Quantity(q.atan())); }, | ||||
|  | ||||
| 		Function::Csc => { return Ok(Token::Quantity(q.csc())); }, | ||||
| 		Function::Sec => { return Ok(Token::Quantity(q.sec())); }, | ||||
| 		Function::Cot => { return Ok(Token::Quantity(q.cot())); }, | ||||
| 		Function::Csc => { return Ok(Expression::Quantity(q.csc())); }, | ||||
| 		Function::Sec => { return Ok(Expression::Quantity(q.sec())); }, | ||||
| 		Function::Cot => { return Ok(Expression::Quantity(q.cot())); }, | ||||
|  | ||||
| 		Function::Sinh => { return Ok(Token::Quantity(q.sinh())); }, | ||||
| 		Function::Cosh => { return Ok(Token::Quantity(q.cosh())); }, | ||||
| 		Function::Tanh => { return Ok(Token::Quantity(q.tanh())); }, | ||||
| 		Function::Asinh => { return Ok(Token::Quantity(q.asinh())); }, | ||||
| 		Function::Acosh => { return Ok(Token::Quantity(q.acosh())); }, | ||||
| 		Function::Atanh => { return Ok(Token::Quantity(q.atanh())); }, | ||||
| 		Function::Sinh => { return Ok(Expression::Quantity(q.sinh())); }, | ||||
| 		Function::Cosh => { return Ok(Expression::Quantity(q.cosh())); }, | ||||
| 		Function::Tanh => { return Ok(Expression::Quantity(q.tanh())); }, | ||||
| 		Function::Asinh => { return Ok(Expression::Quantity(q.asinh())); }, | ||||
| 		Function::Acosh => { return Ok(Expression::Quantity(q.acosh())); }, | ||||
| 		Function::Atanh => { return Ok(Expression::Quantity(q.atanh())); }, | ||||
|  | ||||
| 		Function::Csch => { return Ok(Token::Quantity(q.csch())); }, | ||||
| 		Function::Sech => { return Ok(Token::Quantity(q.sech())); }, | ||||
| 		Function::Coth => { return Ok(Token::Quantity(q.coth())); }, | ||||
| 		Function::Csch => { return Ok(Expression::Quantity(q.csch())); }, | ||||
| 		Function::Sech => { return Ok(Expression::Quantity(q.sech())); }, | ||||
| 		Function::Coth => { return Ok(Expression::Quantity(q.coth())); }, | ||||
|  | ||||
| 		Function::ToBase | ||||
| 		| Function::NoUnit | ||||
|  | ||||
| @ -2,11 +2,11 @@ use std::collections::VecDeque; | ||||
|  | ||||
| use crate::quantity::Quantity; | ||||
| use crate::parser::Operator; | ||||
| use crate::parser::Token; | ||||
| use crate::parser::Expression; | ||||
| use super::EvalError; | ||||
| use crate::context::Context; | ||||
|  | ||||
| pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Context) -> Result<Option<Token>, EvalError> { | ||||
| pub fn eval_operator(op: &Operator, args: &VecDeque<Expression>, context: &mut Context) -> Result<Option<Expression>, EvalError> { | ||||
| 	match op { | ||||
|  | ||||
| 		// Handled seperately in evaluate.rs | ||||
| @ -24,7 +24,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			if args.len() != 2 { panic!() }; | ||||
| 			let b = &args[1]; | ||||
|  | ||||
| 			if let Token::Variable(s) = &args[0] { | ||||
| 			if let Expression::Variable(s) = &args[0] { | ||||
| 				context.push_var(s.clone(), b.clone()); | ||||
| 				return Ok(Some(b.clone())); | ||||
| 			} else { return Err(EvalError::BadDefineName); } | ||||
| @ -34,8 +34,8 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			if args.len() != 1 { panic!() }; | ||||
| 			let args = &args[0]; | ||||
|  | ||||
| 			if let Token::Quantity(v) = args { | ||||
| 				return Ok(Some(Token::Quantity(-v.clone()))); | ||||
| 			if let Expression::Quantity(v) = args { | ||||
| 				return Ok(Some(Expression::Quantity(-v.clone()))); | ||||
| 			} else { return Ok(None); } | ||||
| 		}, | ||||
|  | ||||
| @ -43,9 +43,9 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			if args.len() != 1 { panic!() }; | ||||
| 			let args = &args[0]; | ||||
|  | ||||
| 			if let Token::Quantity(v) = args { | ||||
| 			if let Expression::Quantity(v) = args { | ||||
| 				if v.is_zero() { return Err(EvalError::ZeroDivision); } | ||||
| 				return Ok(Some(Token::Quantity( | ||||
| 				return Ok(Some(Expression::Quantity( | ||||
| 					Quantity::new_rational(1f64).unwrap()/v.clone() | ||||
| 				))); | ||||
| 			} else { return Ok(None); } | ||||
| @ -53,14 +53,14 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
|  | ||||
| 		Operator::Add => { | ||||
| 			let mut sum: Quantity; | ||||
| 			if let Token::Quantity(s) = &args[0] { | ||||
| 			if let Expression::Quantity(s) = &args[0] { | ||||
| 				sum = s.clone(); | ||||
| 			} else { return Ok(None); }; | ||||
|  | ||||
| 			let mut i: usize = 1; | ||||
| 			while i < args.len() { | ||||
| 				let j = &args[i]; | ||||
| 				if let Token::Quantity(v) = j { | ||||
| 				if let Expression::Quantity(v) = j { | ||||
|  | ||||
| 					if !sum.unit.compatible_with(&v.unit) { | ||||
| 						return Err(EvalError::IncompatibleUnit); | ||||
| @ -70,18 +70,18 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 				} else { return Ok(None); } | ||||
| 				i += 1; | ||||
| 			} | ||||
| 			return Ok(Some(Token::Quantity(sum))); | ||||
| 			return Ok(Some(Expression::Quantity(sum))); | ||||
| 		}, | ||||
|  | ||||
| 		Operator::Multiply => { | ||||
| 			let mut prod = Quantity::new_rational(1f64).unwrap(); | ||||
| 			for i in args.iter() { | ||||
| 				let j = i; | ||||
| 				if let Token::Quantity(v) = j { | ||||
| 				if let Expression::Quantity(v) = j { | ||||
| 					prod *= v.clone(); | ||||
| 				} else { return Ok(None); } | ||||
| 			} | ||||
| 			return Ok(Some(Token::Quantity(prod))); | ||||
| 			return Ok(Some(Expression::Quantity(prod))); | ||||
| 		}, | ||||
|  | ||||
| 		Operator::ModuloLong | ||||
| @ -90,8 +90,8 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			let a = &args[0]; | ||||
| 			let b = &args[1]; | ||||
|  | ||||
| 			if let Token::Quantity(va) = a { | ||||
| 				if let Token::Quantity(vb) = b { | ||||
| 			if let Expression::Quantity(va) = a { | ||||
| 				if let Expression::Quantity(vb) = b { | ||||
|  | ||||
| 					if !(va.unitless() && vb.unitless()) { | ||||
| 						return Err(EvalError::IncompatibleUnit); | ||||
| @ -101,7 +101,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 					if va.fract() != Quantity::new_rational(0f64).unwrap() { return Err(EvalError::BadMath); } | ||||
| 					if vb.fract() != Quantity::new_rational(0f64).unwrap() { return Err(EvalError::BadMath); } | ||||
|  | ||||
| 					return Ok(Some(Token::Quantity(va.clone() % vb.clone()))); | ||||
| 					return Ok(Some(Expression::Quantity(va.clone() % vb.clone()))); | ||||
| 				} else { return Ok(None); } | ||||
| 			} else { return Ok(None); } | ||||
| 		}, | ||||
| @ -112,13 +112,13 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			let a = &args[0]; | ||||
| 			let b = &args[1]; | ||||
|  | ||||
| 			if let Token::Quantity(va) = a { | ||||
| 				if let Token::Quantity(vb) = b { | ||||
| 			if let Expression::Quantity(va) = a { | ||||
| 				if let Expression::Quantity(vb) = b { | ||||
| 					let n = va.clone().convert_to(vb.clone()); | ||||
| 					if n.is_none() { | ||||
| 						return Err(EvalError::IncompatibleUnit); | ||||
| 					} | ||||
| 					return Ok(Some(Token::Quantity(n.unwrap()))); | ||||
| 					return Ok(Some(Expression::Quantity(n.unwrap()))); | ||||
| 				} else { return Ok(None); } | ||||
| 			} else { return Ok(None); } | ||||
| 		}, | ||||
| @ -128,8 +128,8 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			let a = &args[0]; | ||||
| 			let b = &args[1]; | ||||
|  | ||||
| 			if let Token::Quantity(va) = a { | ||||
| 				if let Token::Quantity(vb) = b { | ||||
| 			if let Expression::Quantity(va) = a { | ||||
| 				if let Expression::Quantity(vb) = b { | ||||
|  | ||||
| 					if !vb.unitless() { | ||||
| 						return Err(EvalError::IncompatibleUnit); | ||||
| @ -141,7 +141,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
|  | ||||
| 					let p = va.pow(vb.clone()); | ||||
| 					if p.is_nan() {return Err(EvalError::BadMath);} | ||||
| 					return Ok(Some(Token::Quantity(p))); | ||||
| 					return Ok(Some(Expression::Quantity(p))); | ||||
| 				} else { return Ok(None); } | ||||
| 			} else { return Ok(None); } | ||||
| 		}, | ||||
| @ -150,7 +150,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 			if args.len() != 1 {panic!()}; | ||||
| 			let args = &args[0]; | ||||
|  | ||||
| 			if let Token::Quantity(v) = args { | ||||
| 			if let Expression::Quantity(v) = args { | ||||
|  | ||||
| 				if !v.unitless() { | ||||
| 					return Err(EvalError::IncompatibleUnit); | ||||
| @ -166,7 +166,7 @@ pub fn eval_operator(op: &Operator, args: &VecDeque<Token>, context: &mut Contex | ||||
| 					u = u - Quantity::new_rational(1f64).unwrap(); | ||||
| 				} | ||||
|  | ||||
| 				return Ok(Some(Token::Quantity(prod))); | ||||
| 				return Ok(Some(Expression::Quantity(prod))); | ||||
| 			} else { return Ok(None); } | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| @ -4,64 +4,64 @@ use crate::quantity::Quantity; | ||||
| use super::Operator; | ||||
| use super::Constant; | ||||
| 
 | ||||
| /// Tokens represent logical objects in an expession.
 | ||||
| /// Expressions represent logical objects in an expession.
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Clone)] | ||||
| pub enum Token { | ||||
| pub enum Expression { | ||||
| 	Variable(String), | ||||
| 	Quantity(Quantity), | ||||
| 	Constant(Constant), | ||||
| 	Operator(Operator, VecDeque<Token>), | ||||
| 	Operator(Operator, VecDeque<Expression>), | ||||
| } | ||||
| 
 | ||||
| impl ToString for Token { | ||||
| impl ToString for Expression { | ||||
| 	fn to_string(&self) -> String { | ||||
| 		match self { | ||||
| 			Token::Quantity(v) => v.to_string(), | ||||
| 			Token::Constant(c) => c.to_string(), | ||||
| 			Token::Variable(s) => s.clone(), | ||||
| 			Token::Operator(o,a) => o.print(a) | ||||
| 			Expression::Quantity(v) => v.to_string(), | ||||
| 			Expression::Constant(c) => c.to_string(), | ||||
| 			Expression::Variable(s) => s.clone(), | ||||
| 			Expression::Operator(o,a) => o.print(a) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Token { | ||||
| 	// This is called only when this is the outermost token.
 | ||||
| impl Expression { | ||||
| 	// This is called only when this is the outermost Expression.
 | ||||
| 	// This sometimes leads to different--usually more verbose--behavior.
 | ||||
| 	pub fn to_string_outer(&self) -> String { | ||||
| 		match self { | ||||
| 			Token::Quantity(v) => v.to_string_outer(), | ||||
| 			Token::Constant(c) => c.to_string(), | ||||
| 			Token::Variable(s) => s.clone(), | ||||
| 			Token::Operator(o,a) => o.print(a) | ||||
| 			Expression::Quantity(v) => v.to_string_outer(), | ||||
| 			Expression::Constant(c) => c.to_string(), | ||||
| 			Expression::Variable(s) => s.clone(), | ||||
| 			Expression::Operator(o,a) => o.print(a) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn is_quantity(&self) -> bool { | ||||
| 		match self { | ||||
| 			Token::Quantity(_) => true, | ||||
| 			Expression::Quantity(_) => true, | ||||
| 			_ => false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_args_mut(&mut self) -> Option<&mut VecDeque<Token>> { | ||||
| 	pub fn get_args_mut(&mut self) -> Option<&mut VecDeque<Expression>> { | ||||
| 		match self { | ||||
| 			Token::Operator(_, ref mut a) => Some(a), | ||||
| 			Expression::Operator(_, ref mut a) => Some(a), | ||||
| 			_ => None | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_args(&self) -> Option<&VecDeque<Token>> { | ||||
| 	pub fn get_args(&self) -> Option<&VecDeque<Expression>> { | ||||
| 		match self { | ||||
| 			Token::Operator(_, ref a) => Some(a), | ||||
| 			Expression::Operator(_, ref a) => Some(a), | ||||
| 			_ => None | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_at_coords<'a, 'b, I>(&'a self, coords: I) -> Option<&'a Token> | ||||
| 	pub fn get_at_coords<'a, 'b, I>(&'a self, coords: I) -> Option<&'a Expression> | ||||
| 	where I: IntoIterator<Item = &'b usize> + Sized { | ||||
| 		let mut g = self; | ||||
| 		for t in coords.into_iter() { | ||||
| @ -73,7 +73,7 @@ impl Token { | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_at_coords_mut<'a, 'b, I>(&'a mut self, coords: I) -> Option<&'a mut Token> | ||||
| 	pub fn get_at_coords_mut<'a, 'b, I>(&'a mut self, coords: I) -> Option<&'a mut Expression> | ||||
| 	where I: IntoIterator<Item = &'b usize> + Sized { | ||||
| 		let mut g = self; | ||||
| 		for t in coords.into_iter() { | ||||
| @ -1,10 +1,10 @@ | ||||
| mod operator; | ||||
| mod function; | ||||
| mod token; | ||||
| mod expression; | ||||
| 
 | ||||
| pub use self::operator::Operator; | ||||
| pub use self::function::Function; | ||||
| pub use self::token::Token; | ||||
| pub use self::expression::Expression; | ||||
| 
 | ||||
| 
 | ||||
| use super::parse_no_context; | ||||
| @ -2,7 +2,7 @@ use std::cmp::Ordering; | ||||
| use std::collections::VecDeque; | ||||
| use crate::quantity::Quantity; | ||||
| 
 | ||||
| use super::Token; | ||||
| use super::Expression; | ||||
| use super::Function; | ||||
| 
 | ||||
| 
 | ||||
| @ -112,7 +112,7 @@ impl Operator { | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn into_token(self, mut args: VecDeque<Token>) -> Token { | ||||
| 	pub fn into_expression(self, mut args: VecDeque<Expression>) -> Expression { | ||||
| 		match self { | ||||
| 			Operator::Subtract => { | ||||
| 				if args.len() != 2 { panic!() } | ||||
| @ -120,13 +120,13 @@ impl Operator { | ||||
| 				let b = args.pop_front().unwrap(); | ||||
| 
 | ||||
| 				let b_new; | ||||
| 				if let Token::Quantity(q) = b { | ||||
| 					b_new = Token::Quantity(-q); | ||||
| 				if let Expression::Quantity(q) = b { | ||||
| 					b_new = Expression::Quantity(-q); | ||||
| 				} else { | ||||
| 					b_new = Token::Operator(Operator::Negative, VecDeque::from(vec!(b))); | ||||
| 					b_new = Expression::Operator(Operator::Negative, VecDeque::from(vec!(b))); | ||||
| 				} | ||||
| 
 | ||||
| 				Token::Operator( | ||||
| 				Expression::Operator( | ||||
| 					Operator::Add, | ||||
| 					VecDeque::from(vec!(a,b_new)) | ||||
| 				) | ||||
| @ -137,9 +137,9 @@ impl Operator { | ||||
| 				if args.len() != 2 { panic!() } | ||||
| 				let a = args.pop_front().unwrap(); | ||||
| 				let b = args.pop_front().unwrap(); | ||||
| 				let b = Token::Operator(Operator::Flip, VecDeque::from(vec!(b))); | ||||
| 				let b = Expression::Operator(Operator::Flip, VecDeque::from(vec!(b))); | ||||
| 
 | ||||
| 				Token::Operator( | ||||
| 				Expression::Operator( | ||||
| 					Operator::Multiply, | ||||
| 					VecDeque::from(vec!(a,b)) | ||||
| 				) | ||||
| @ -149,14 +149,14 @@ impl Operator { | ||||
| 				if args.len() != 1 { panic!() } | ||||
| 				let a = args.pop_front().unwrap(); | ||||
| 
 | ||||
| 				Token::Operator( | ||||
| 				Expression::Operator( | ||||
| 					Operator::Power, | ||||
| 					VecDeque::from(vec!(a, Token::Quantity(Quantity::new_rational_from_string("0.5").unwrap()))) | ||||
| 					VecDeque::from(vec!(a, Expression::Quantity(Quantity::new_rational_from_string("0.5").unwrap()))) | ||||
| 				) | ||||
| 			}, | ||||
| 
 | ||||
| 			Operator::ImplicitMultiply | ||||
| 			=> { Token::Operator(Operator::Multiply, args) }, | ||||
| 			=> { Expression::Operator(Operator::Multiply, args) }, | ||||
| 
 | ||||
| 			Operator::Function(_) | ||||
| 			| Operator::Factorial | ||||
| @ -169,15 +169,15 @@ impl Operator { | ||||
| 			| Operator::ModuloLong | ||||
| 			| Operator::UnitConvert | ||||
| 			| Operator::Define | ||||
| 			=> { Token::Operator(self, args) }, | ||||
| 			=> { Expression::Operator(self, args) }, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	fn add_parens_to_arg(&self, arg: &Token) -> String { | ||||
| 	fn add_parens_to_arg(&self, arg: &Expression) -> String { | ||||
| 		let mut astr: String = arg.to_string(); | ||||
| 		if let Token::Operator(o,_) = arg { | ||||
| 		if let Expression::Operator(o,_) = arg { | ||||
| 			if o < self { | ||||
| 				astr = format!("({})", astr); | ||||
| 			} | ||||
| @ -186,9 +186,9 @@ impl Operator { | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	fn add_parens_to_arg_strict(&self, arg: &Token) -> String { | ||||
| 	fn add_parens_to_arg_strict(&self, arg: &Expression) -> String { | ||||
| 		let mut astr: String = arg.to_string(); | ||||
| 		if let Token::Operator(o,_) = arg { | ||||
| 		if let Expression::Operator(o,_) = arg { | ||||
| 			if o <= self { | ||||
| 				astr = format!("({})", astr); | ||||
| 			} | ||||
| @ -197,7 +197,7 @@ impl Operator { | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	pub fn print(&self, args: &VecDeque<Token>) -> String { | ||||
| 	pub fn print(&self, args: &VecDeque<Expression>) -> String { | ||||
| 		match self { | ||||
| 			Operator::ImplicitMultiply | | ||||
| 			Operator::Sqrt | | ||||
| @ -268,7 +268,7 @@ impl Operator { | ||||
| 				let a = &args[0]; | ||||
| 
 | ||||
| 				let b; let sub; | ||||
| 				if let Token::Operator(o, ar) = &args[1] { | ||||
| 				if let Expression::Operator(o, ar) = &args[1] { | ||||
| 					if let Operator::Negative = o { | ||||
| 						sub = true; | ||||
| 						b = &ar[0]; | ||||
| @ -294,7 +294,7 @@ impl Operator { | ||||
| 				let a = &args[0]; | ||||
| 
 | ||||
| 				let b; let div; | ||||
| 				if let Token::Operator(o, ar) = &args[1] { | ||||
| 				if let Expression::Operator(o, ar) = &args[1] { | ||||
| 					if let Operator::Flip = o { | ||||
| 						div = true; | ||||
| 						b = &ar[0]; | ||||
| @ -314,15 +314,15 @@ impl Operator { | ||||
| 				// multiplied by a unit (like 10 m)
 | ||||
| 				// Times sign should stay in all other cases.
 | ||||
| 				let no_times = { | ||||
| 					if let Token::Quantity(p) = a { | ||||
| 						if let Token::Quantity(q) = b { | ||||
| 					if let Expression::Quantity(p) = a { | ||||
| 						if let Expression::Quantity(q) = b { | ||||
| 							p.unitless() && !q.unitless() | ||||
| 						} else {false} | ||||
| 					} else {false} | ||||
| 				}; | ||||
| 
 | ||||
| 				if no_times { | ||||
| 					let Token::Quantity(u) = b else {panic!()}; | ||||
| 					let Expression::Quantity(u) = b else {panic!()}; | ||||
| 					if u.unit.no_space() { | ||||
| 						return format!("{}{}", | ||||
| 							self.add_parens_to_arg_strict(a), | ||||
| @ -1,20 +1,20 @@ | ||||
| mod stage; | ||||
|  | ||||
| mod pretoken; | ||||
| mod parsererror; | ||||
| mod token; | ||||
| mod parsererror; | ||||
| mod expression; | ||||
|  | ||||
| use self::{ | ||||
| 	pretoken::PreToken, | ||||
| 	token::Token, | ||||
| 	parsererror::ParserError, | ||||
| 	parsererror::LineLocation | ||||
| }; | ||||
|  | ||||
| pub use self::{ | ||||
| 	token::Token, | ||||
| 	token::Constant, | ||||
| 	token::Operator, | ||||
| 	token::Function, | ||||
| 	expression::Expression, | ||||
| 	expression::Constant, | ||||
| 	expression::Operator, | ||||
| 	expression::Function, | ||||
| }; | ||||
|  | ||||
| use crate::context::Context; | ||||
| @ -22,18 +22,18 @@ use crate::context::Context; | ||||
|  | ||||
| pub fn parse( | ||||
| 	s: &String, context: &Context | ||||
| ) -> Result<Token, (LineLocation, ParserError)> { | ||||
| ) -> Result<Expression, (LineLocation, ParserError)> { | ||||
|  | ||||
| 	let tokens = stage::tokenize(s); | ||||
| 	let (_, tokens) = stage::find_subs(tokens); | ||||
| 	let g = stage::groupify(tokens)?; | ||||
| 	let expressions = stage::tokenize(s); | ||||
| 	let (_, expressions) = stage::find_subs(expressions); | ||||
| 	let g = stage::groupify(expressions)?; | ||||
|  | ||||
| 	let g = stage::treeify(g, context)?; | ||||
|  | ||||
| 	return Ok(g); | ||||
| } | ||||
|  | ||||
| pub fn parse_no_context(s: &String) -> Result<Token, (LineLocation, ParserError)> { | ||||
| pub fn parse_no_context(s: &String) -> Result<Expression, (LineLocation, ParserError)> { | ||||
| 	parse(s, &Context::new()) | ||||
| } | ||||
|  | ||||
| @ -49,8 +49,8 @@ pub fn substitute( | ||||
| 	let mut new_s = s.clone(); | ||||
|  | ||||
| 	let l = s.chars().count(); | ||||
| 	let tokens = stage::tokenize(s); | ||||
| 	let (subs, _) = stage::find_subs(tokens); | ||||
| 	let expressions = stage::tokenize(s); | ||||
| 	let (subs, _) = stage::find_subs(expressions); | ||||
| 	let mut new_c = l - c; | ||||
|  | ||||
| 	for r in subs.iter() { | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| /// Specifies the location of a token in an input string. | ||||
| /// Used to locate ParserErrors. | ||||
| #[derive(Debug)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub struct LineLocation { | ||||
|  | ||||
| @ -1,23 +1,23 @@ | ||||
| use std::collections::VecDeque; | ||||
|  | ||||
| use super::super::{ | ||||
| 	PreToken, | ||||
| 	Token, | ||||
| 	LineLocation | ||||
| }; | ||||
|  | ||||
|  | ||||
| pub fn find_subs( | ||||
| 	mut g: VecDeque<PreToken>, | ||||
| 	mut g: VecDeque<Token>, | ||||
| ) -> ( | ||||
| 	Vec<(LineLocation, String)>, | ||||
| 	VecDeque<PreToken> | ||||
| 	VecDeque<Token> | ||||
| ) { | ||||
|  | ||||
| 	// Array of replacements | ||||
| 	let mut r: Vec<(LineLocation, String)> = Vec::with_capacity(8); | ||||
|  | ||||
| 	// New token array, with updated locations | ||||
| 	let mut n: VecDeque<PreToken> = VecDeque::with_capacity(g.len()); | ||||
| 	let mut n: VecDeque<Token> = VecDeque::with_capacity(g.len()); | ||||
|  | ||||
| 	let mut offset: usize = 0; | ||||
|  | ||||
| @ -26,7 +26,7 @@ pub fn find_subs( | ||||
| 		let mut t = g.pop_back().unwrap(); | ||||
|  | ||||
| 		let target: Option<&str> = match &mut t { | ||||
| 			PreToken::PreOperator(_, s) => { | ||||
| 			Token::PreOperator(_, s) => { | ||||
| 				let target = match &s[..] { | ||||
| 					"*" => {Some("×")}, | ||||
| 					"/" => {Some("÷")}, | ||||
| @ -41,7 +41,7 @@ pub fn find_subs( | ||||
| 				target | ||||
| 			}, | ||||
|  | ||||
| 			PreToken::PreWord(_, s) => { | ||||
| 			Token::PreWord(_, s) => { | ||||
| 				let target = match &s[..] { | ||||
| 					// Greek letters | ||||
| 					"alpha"   => {Some("α")}, | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use std::collections::VecDeque; | ||||
|  | ||||
| use super::super::{ | ||||
| 	PreToken, | ||||
| 	Token, | ||||
| 	LineLocation, | ||||
| 	ParserError, | ||||
| 	Operator | ||||
| @ -9,7 +9,7 @@ use super::super::{ | ||||
|  | ||||
|  | ||||
| fn lookback_signs( | ||||
| 	g: &mut VecDeque<PreToken> | ||||
| 	g: &mut VecDeque<Token> | ||||
| ) -> Result<(), (LineLocation, ParserError)> { | ||||
|  | ||||
| 	// Convert `-` operators to `neg` operators | ||||
| @ -17,12 +17,12 @@ fn lookback_signs( | ||||
| 	let mut i: usize = 0; | ||||
| 	while i < g.len() { | ||||
| 		if i == 0 { | ||||
| 			let a: PreToken = g.remove(i).unwrap(); | ||||
| 			let a: Token = g.remove(i).unwrap(); | ||||
| 			match &a { | ||||
| 				PreToken::PreOperator(l,o) | ||||
| 				Token::PreOperator(l,o) | ||||
| 				=> { | ||||
| 					if o == "-" { | ||||
| 						g.insert(i, PreToken::PreOperator(*l, String::from("neg"))); | ||||
| 						g.insert(i, Token::PreOperator(*l, String::from("neg"))); | ||||
| 					} else if o == "+" { | ||||
| 						continue; // We should not increment i if we remove a token | ||||
| 					} else {g.insert(i, a);} | ||||
| @ -31,11 +31,11 @@ fn lookback_signs( | ||||
| 			}; | ||||
|  | ||||
| 		} else { | ||||
| 			let a: PreToken = g.remove(i-1).unwrap(); | ||||
| 			let b: PreToken = g.remove(i-1).unwrap(); | ||||
| 			let a: Token = g.remove(i-1).unwrap(); | ||||
| 			let b: Token = g.remove(i-1).unwrap(); | ||||
|  | ||||
| 			match (&a, &b) { | ||||
| 				(PreToken::PreOperator(_, sa), PreToken::PreOperator(l,sb)) | ||||
| 				(Token::PreOperator(_, sa), Token::PreOperator(l,sb)) | ||||
| 				=> { | ||||
| 					if { | ||||
| 						let o = Operator::from_string(sa); | ||||
| @ -47,7 +47,7 @@ fn lookback_signs( | ||||
| 						) | ||||
| 					} { | ||||
| 						if sb == "-" { | ||||
| 							g.insert(i-1, PreToken::PreOperator(*l, String::from("neg"))); | ||||
| 							g.insert(i-1, Token::PreOperator(*l, String::from("neg"))); | ||||
| 							g.insert(i-1, a); | ||||
| 						} else if sb == "+" { | ||||
| 							g.insert(i-1, a); | ||||
| @ -67,11 +67,11 @@ fn lookback_signs( | ||||
| 	// Delete consecutive `neg`s | ||||
| 	let mut i: usize = 1; | ||||
| 	while i < g.len() { | ||||
| 		let a: PreToken = g.remove(i-1).unwrap(); | ||||
| 		let b: PreToken = g.remove(i-1).unwrap(); | ||||
| 		let a: Token = g.remove(i-1).unwrap(); | ||||
| 		let b: Token = g.remove(i-1).unwrap(); | ||||
|  | ||||
| 		match (&a, &b) { | ||||
| 			(PreToken::PreOperator(_,sa), PreToken::PreOperator(_,sb)) | ||||
| 			(Token::PreOperator(_,sa), Token::PreOperator(_,sb)) | ||||
| 			=> { | ||||
| 				if !((sa == "neg") && (sb == "neg")) { | ||||
| 					g.insert(i-1, b); | ||||
| @ -95,7 +95,7 @@ fn lookback_signs( | ||||
|  | ||||
| // Inserts implicit operators | ||||
| fn lookback( | ||||
| 	g: &mut VecDeque<PreToken> | ||||
| 	g: &mut VecDeque<Token> | ||||
| ) -> Result<(), (LineLocation, ParserError)> { | ||||
|  | ||||
| 	lookback_signs(g)?; | ||||
| @ -103,24 +103,24 @@ fn lookback( | ||||
| 	let mut i: usize = 0; | ||||
| 	while i < g.len() { | ||||
| 		if i >= 1 { | ||||
| 			let a: PreToken = g.remove(i-1).unwrap(); | ||||
| 			let b: PreToken = g.remove(i-1).unwrap(); | ||||
| 			let a: Token = g.remove(i-1).unwrap(); | ||||
| 			let b: Token = g.remove(i-1).unwrap(); | ||||
|  | ||||
| 			match (&a, &b) { | ||||
| 				// Insert ImplicitMultiply | ||||
| 				(PreToken::PreGroup(_,_), PreToken::PreGroup(l ,_)) | ||||
| 				| (PreToken::PreGroup(_,_), PreToken::PreQuantity(l,_)) | ||||
| 				| (PreToken::PreQuantity(_,_), PreToken::PreGroup(l,_)) | ||||
| 				| (PreToken::PreGroup(_,_), PreToken::PreWord(l,_)) | ||||
| 				| (PreToken::PreWord(_,_), PreToken::PreGroup(l,_)) | ||||
| 				| (PreToken::PreQuantity(_,_), PreToken::PreWord(l,_)) | ||||
| 				| (PreToken::PreWord(_,_), PreToken::PreQuantity(l,_)) | ||||
| 				| (PreToken::PreWord(_,_), PreToken::PreWord(l,_)) | ||||
| 				(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,_)) | ||||
| 				=> { | ||||
| 					let loc = LineLocation{pos: l.pos-1, len: 0}; | ||||
|  | ||||
| 					g.insert(i-1, b); | ||||
| 					g.insert(i-1, PreToken::PreOperator( | ||||
| 					g.insert(i-1, Token::PreOperator( | ||||
| 						loc, | ||||
| 						String::from("i*") | ||||
| 					)); | ||||
| @ -128,9 +128,9 @@ fn lookback( | ||||
| 				}, | ||||
|  | ||||
| 				// Insert implicit multiplications for right-unary operators | ||||
| 				(PreToken::PreQuantity(_,_), PreToken::PreOperator(l,s)) | ||||
| 				| (PreToken::PreGroup(_,_), PreToken::PreOperator(l,s)) | ||||
| 				| (PreToken::PreWord(_,_), PreToken::PreOperator(l,s)) | ||||
| 				(Token::PreQuantity(_,_), Token::PreOperator(l,s)) | ||||
| 				| (Token::PreGroup(_,_), Token::PreOperator(l,s)) | ||||
| 				| (Token::PreWord(_,_), Token::PreOperator(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, PreToken::PreOperator( | ||||
| 							g.insert(i-1, Token::PreOperator( | ||||
| 								loc, | ||||
| 								String::from("i*") | ||||
| 							)); | ||||
| @ -149,9 +149,9 @@ fn lookback( | ||||
| 				}, | ||||
|  | ||||
| 				// Insert implicit multiplications for left-unary operators. | ||||
| 				(PreToken::PreOperator(_,s), PreToken::PreQuantity(l,_)) | ||||
| 				| (PreToken::PreOperator(_,s), PreToken::PreGroup(l,_)) | ||||
| 				| (PreToken::PreOperator(_,s), PreToken::PreWord(l,_)) | ||||
| 				(Token::PreOperator(_,s), Token::PreQuantity(l,_)) | ||||
| 				| (Token::PreOperator(_,s), Token::PreGroup(l,_)) | ||||
| 				| (Token::PreOperator(_,s), Token::PreWord(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, PreToken::PreOperator( | ||||
| 							g.insert(i-1, Token::PreOperator( | ||||
| 								loc, | ||||
| 								String::from("i*") | ||||
| 							)); | ||||
| @ -170,7 +170,7 @@ fn lookback( | ||||
| 				}, | ||||
|  | ||||
| 				// The following are syntax errors | ||||
| 				(PreToken::PreQuantity(la,_), PreToken::PreQuantity(lb,_)) | ||||
| 				(Token::PreQuantity(la,_), Token::PreQuantity(lb,_)) | ||||
| 				=> { | ||||
| 					return Err(( | ||||
| 						LineLocation{pos: la.pos, len: lb.pos - la.pos + lb.len}, | ||||
| @ -189,13 +189,13 @@ fn lookback( | ||||
|  | ||||
|  | ||||
| pub fn groupify( | ||||
| 	mut g: VecDeque<PreToken> | ||||
| 	mut g: VecDeque<Token> | ||||
| ) -> Result< | ||||
| 	PreToken, | ||||
| 	Token, | ||||
| 	(LineLocation, ParserError) | ||||
| > { | ||||
| 	// Vector of grouping levels | ||||
| 	let mut levels: Vec<(LineLocation, VecDeque<PreToken>)> = Vec::with_capacity(8); | ||||
| 	let mut levels: Vec<(LineLocation, VecDeque<Token>)> = Vec::with_capacity(8); | ||||
| 	levels.push((LineLocation{pos: 0, len: 0}, VecDeque::with_capacity(8))); | ||||
|  | ||||
| 	// Makes sure parenthesis are matched | ||||
| @ -206,12 +206,12 @@ pub fn groupify( | ||||
| 		let (l_now, v_now) = levels.last_mut().unwrap(); | ||||
|  | ||||
| 		match t { | ||||
| 			PreToken::PreGroupStart(l) => { | ||||
| 			Token::PreGroupStart(l) => { | ||||
| 				levels.push((l, VecDeque::with_capacity(8))); | ||||
| 				i_level += 1; | ||||
| 			}, | ||||
|  | ||||
| 			PreToken::PreGroupEnd(l) => { | ||||
| 			Token::PreGroupEnd(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(PreToken::PreGroup(l, v)); | ||||
| 				v_now.push_back(Token::PreGroup(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(PreToken::PreGroup(l, v)); | ||||
| 		v_now.push_back(Token::PreGroup(l, v)); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	let (_, mut v) = levels.pop().unwrap(); | ||||
| 	lookback(&mut v)?; | ||||
|  | ||||
| 	return Ok(PreToken::PreGroup(LineLocation{pos:0, len:0}, v)); | ||||
| 	return Ok(Token::PreGroup(LineLocation{pos:0, len:0}, v)); | ||||
| } | ||||
| @ -1,24 +1,24 @@ | ||||
| use std::collections::VecDeque; | ||||
|  | ||||
| use super::super::{ | ||||
| 	PreToken, | ||||
| 	Token, | ||||
| 	LineLocation, | ||||
| 	Operator | ||||
| }; | ||||
|  | ||||
| // Called whenever a token is finished. | ||||
| #[inline(always)] | ||||
| fn push_token(g: &mut VecDeque<PreToken>, t: Option<PreToken>, stop_i: usize) { | ||||
| fn push_token(g: &mut VecDeque<Token>, t: Option<Token>, stop_i: usize) { | ||||
|  | ||||
| 	if t.is_none() { return } | ||||
| 	let mut t = t.unwrap(); | ||||
|  | ||||
| 	match t { | ||||
| 		PreToken::PreGroupStart(ref mut l) | ||||
| 		| PreToken::PreGroupEnd(ref mut l) | ||||
| 		| PreToken::PreOperator(ref mut l, _) | ||||
| 		| PreToken::PreQuantity(ref mut l, _) | ||||
| 		| PreToken::PreWord(ref mut l, _) | ||||
| 		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, _) | ||||
| 		=> { | ||||
| 			*l = LineLocation{ | ||||
| 				pos: l.pos, | ||||
| @ -26,22 +26,22 @@ fn push_token(g: &mut VecDeque<PreToken>, t: Option<PreToken>, stop_i: usize) { | ||||
| 			}; | ||||
| 		}, | ||||
|  | ||||
| 		PreToken::PreGroup(_,_) | ||||
| 		| PreToken::Container(_) | ||||
| 		Token::PreGroup(_,_) | ||||
| 		| Token::Container(_) | ||||
| 		=> panic!() | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	// `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 PreToken::PreQuantity(l, s) = &t { | ||||
| 	if let Token::PreQuantity(l, s) = &t { | ||||
| 		let last = &s[s.len()-1..]; | ||||
| 		if last == "e" { | ||||
| 			g.push_back(PreToken::PreQuantity( | ||||
| 			g.push_back(Token::PreQuantity( | ||||
| 				LineLocation { pos: l.pos, len: l.len-1 }, | ||||
| 				String::from(&s[0..s.len()-1]) | ||||
| 			)); | ||||
| 			g.push_back(PreToken::PreWord( | ||||
| 			g.push_back(Token::PreWord( | ||||
| 				LineLocation { pos: l.pos + l.len - 1, len: 1 }, | ||||
| 				String::from("e") | ||||
| 			)); | ||||
| @ -51,9 +51,9 @@ fn push_token(g: &mut VecDeque<PreToken>, t: Option<PreToken>, stop_i: usize) { | ||||
| 	} | ||||
|  | ||||
| 	// Some operators are written as words. | ||||
| 	if let PreToken::PreWord(l, s) = &t { | ||||
| 	if let Token::PreWord(l, s) = &t { | ||||
| 		if Operator::from_string(s).is_some() { | ||||
| 			t = PreToken::PreOperator(*l, s.clone()); | ||||
| 			t = Token::PreOperator(*l, s.clone()); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -61,9 +61,9 @@ fn push_token(g: &mut VecDeque<PreToken>, t: Option<PreToken>, stop_i: usize) { | ||||
| } | ||||
|  | ||||
| /// Turns a string into Tokens. First stage of parsing. | ||||
| pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 	let mut t: Option<PreToken> = None; // The current token we're reading | ||||
| 	let mut g: VecDeque<PreToken> = VecDeque::with_capacity(32); | ||||
| pub fn tokenize(input: &String) -> VecDeque<Token> { | ||||
| 	let mut t: Option<Token> = None; // The current token we're reading | ||||
| 	let mut g: VecDeque<Token> = VecDeque::with_capacity(32); | ||||
|  | ||||
|  | ||||
| 	for (i, c) in input.chars().enumerate() { | ||||
| @ -74,7 +74,7 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 				match &mut t { | ||||
| 					// If we're already building a number, | ||||
| 					// append. | ||||
| 					Some(PreToken::PreQuantity(_, val)) => { | ||||
| 					Some(Token::PreQuantity(_, val)) => { | ||||
| 						val.push(if c == ',' {'.'} else {c}); | ||||
| 					}, | ||||
|  | ||||
| @ -82,7 +82,7 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 					// previous token and start one. | ||||
| 					_ => { | ||||
| 						push_token(&mut g, t, i); | ||||
| 						t = Some(PreToken::PreQuantity(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 						t = Some(Token::PreQuantity(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 					} | ||||
| 				}; | ||||
| 			}, | ||||
| @ -91,12 +91,12 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 			// Can be both a word or a number. | ||||
| 			'e' => { | ||||
| 				match &mut t { | ||||
| 					Some(PreToken::PreWord(_, val)) => { val.push(c); }, | ||||
| 					Some(PreToken::PreQuantity(_, val)) => { val.push(c); }, | ||||
| 					Some(Token::PreWord(_, val)) => { val.push(c); }, | ||||
| 					Some(Token::PreQuantity(_, val)) => { val.push(c); }, | ||||
|  | ||||
| 					_ => { | ||||
| 						push_token(&mut g, t, i); | ||||
| 						t = Some(PreToken::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 						t = Some(Token::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 					} | ||||
| 				}; | ||||
| 			} | ||||
| @ -106,7 +106,7 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 			// or it can specify a negative exponent. | ||||
| 			'-' | '+' => { | ||||
| 				match &mut t { | ||||
| 					Some(PreToken::PreQuantity(_, val)) => { | ||||
| 					Some(Token::PreQuantity(_, 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<PreToken> { | ||||
| 							// Otherwise, end the number. | ||||
| 							// We probably have a subtraction. | ||||
| 							push_token(&mut g, t, i); | ||||
| 							t = Some(PreToken::PreOperator( | ||||
| 							t = Some(Token::PreOperator( | ||||
| 								LineLocation{pos: i, len: 1}, | ||||
| 								String::from(c) | ||||
| 							)); | ||||
| @ -126,7 +126,7 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 					// This may be a negative or a subtraction | ||||
| 					_ => { | ||||
| 						push_token(&mut g, t, i); | ||||
| 						t = Some(PreToken::PreOperator( | ||||
| 						t = Some(Token::PreOperator( | ||||
| 							LineLocation{pos: i, len: 1}, | ||||
| 							String::from(c) | ||||
| 						)); | ||||
| @ -139,10 +139,10 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 			'^'|'!'|'%'|'=' | ||||
| 			=> { | ||||
| 				match &mut t { | ||||
| 					Some(PreToken::PreOperator(_, val)) => { val.push(c); }, | ||||
| 					Some(Token::PreOperator(_, val)) => { val.push(c); }, | ||||
| 					_ => { | ||||
| 						push_token(&mut g, t, i); | ||||
| 						t = Some(PreToken::PreOperator(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 						t = Some(Token::PreOperator(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 					} | ||||
| 				}; | ||||
| 			}, | ||||
| @ -150,11 +150,11 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 			// Group | ||||
| 			'(' => { | ||||
| 				push_token(&mut g, t, i); | ||||
| 				t = Some(PreToken::PreGroupStart(LineLocation{pos: i, len: 0})); | ||||
| 				t = Some(Token::PreGroupStart(LineLocation{pos: i, len: 0})); | ||||
| 			}, | ||||
| 			')' => { | ||||
| 				push_token(&mut g, t, i); | ||||
| 				t = Some(PreToken::PreGroupEnd(LineLocation{pos: i, len: 0})); | ||||
| 				t = Some(Token::PreGroupEnd(LineLocation{pos: i, len: 0})); | ||||
| 			}, | ||||
|  | ||||
| 			// Space. Basic seperator. | ||||
| @ -166,11 +166,11 @@ pub fn tokenize(input: &String) -> VecDeque<PreToken> { | ||||
| 			// Word | ||||
| 			_ => { | ||||
| 				match &mut t { | ||||
| 					Some(PreToken::PreWord(_, val)) => { val.push(c); }, | ||||
| 					Some(Token::PreWord(_, val)) => { val.push(c); }, | ||||
|  | ||||
| 					_ => { | ||||
| 						push_token(&mut g, t, i); | ||||
| 						t = Some(PreToken::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 						t = Some(Token::PreWord(LineLocation{pos: i, len: 0}, String::from(c))); | ||||
| 					} | ||||
| 				}; | ||||
| 			} | ||||
|  | ||||
| @ -2,25 +2,25 @@ use std::collections::VecDeque; | ||||
| use crate::context::Context; | ||||
|  | ||||
| use super::super::{ | ||||
| 	PreToken, | ||||
| 	Token, | ||||
| 	ParserError, | ||||
| 	LineLocation, | ||||
| 	Token, | ||||
| 	Expression, | ||||
| 	Operator | ||||
| }; | ||||
|  | ||||
| fn treeify_binary( | ||||
| 	i: usize, | ||||
| 	g_inner: &mut VecDeque<PreToken>, | ||||
| 	g_inner: &mut VecDeque<Token>, | ||||
| 	context: &Context | ||||
| ) -> Result<bool, (LineLocation, ParserError)> { | ||||
|  | ||||
| 	let this: &PreToken = &g_inner[i]; | ||||
| 	let this: &Token = &g_inner[i]; | ||||
|  | ||||
| 	if i == 0 { | ||||
| 		// This binary operator is at the end of an expression. | ||||
| 		let l = match this { | ||||
| 			PreToken::PreOperator(l, _) => l, | ||||
| 			Token::PreOperator(l, _) => l, | ||||
| 			_ => panic!() | ||||
| 		}; | ||||
| 		return Err((*l, ParserError::Syntax)); | ||||
| @ -32,7 +32,7 @@ fn treeify_binary( | ||||
| 			&g_inner[i-1] | ||||
| 		} else { | ||||
| 			let l = match this { | ||||
| 				PreToken::PreOperator(l, _) => l, | ||||
| 				Token::PreOperator(l, _) => l, | ||||
| 				_ => panic!() | ||||
| 			}; | ||||
| 			return Err((*l, ParserError::Syntax)); | ||||
| @ -44,7 +44,7 @@ fn treeify_binary( | ||||
| 			&g_inner[i+1] | ||||
| 		} else { | ||||
| 			let l = match this { | ||||
| 				PreToken::PreOperator(l, _) => l, | ||||
| 				Token::PreOperator(l, _) => l, | ||||
| 				_ => panic!() | ||||
| 			}; | ||||
| 			return Err((*l, ParserError::Syntax)); | ||||
| @ -55,7 +55,7 @@ fn treeify_binary( | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if let PreToken::PreOperator(l, s) = left { | ||||
| 	if let Token::PreOperator(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 PreToken::PreOperator(l, s) = right { | ||||
| 	if let Token::PreOperator(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 PreToken::PreOperator(l, s) = this else {panic!()}; | ||||
| 		let Token::PreOperator(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 PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()}; | ||||
| 		let Token::PreOperator(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 PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()}; | ||||
| 		let Token::PreOperator(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()) | ||||
| @ -126,22 +126,22 @@ fn treeify_binary( | ||||
| 		let left_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 left: Token; let right: Token; | ||||
| 		if let PreToken::PreGroup(_, _) = right_pre { right = treeify(right_pre, context)?; } else {right = right_pre.to_token(context)?;} | ||||
| 		if let PreToken::PreGroup(_, _) = left_pre { left = treeify(left_pre, context)?; } else {left = left_pre.to_token(context)?;} | ||||
| 		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)?;} | ||||
|  | ||||
| 		let o = { | ||||
| 			let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | ||||
| 			let Token::PreOperator(_, s) = this_pre else {panic!()}; | ||||
| 			let o = Operator::from_string(&s); | ||||
| 			if o.is_none() { panic!() } | ||||
| 			o.unwrap() | ||||
| 		}; | ||||
|  | ||||
| 		let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(2); | ||||
| 		let mut new_token_args: VecDeque<Expression> = VecDeque::with_capacity(2); | ||||
| 		new_token_args.push_back(left); | ||||
| 		new_token_args.push_back(right); | ||||
|  | ||||
| 		g_inner.insert(i-1, PreToken::Container(o.into_token(new_token_args))); | ||||
| 		g_inner.insert(i-1, Token::Container(o.into_expression(new_token_args))); | ||||
|  | ||||
| 		return Ok(true); | ||||
| 	} else { | ||||
| @ -151,20 +151,20 @@ fn treeify_binary( | ||||
|  | ||||
| fn treeify_unary( | ||||
| 	i: usize, | ||||
| 	g_inner: &mut VecDeque<PreToken>, | ||||
| 	g_inner: &mut VecDeque<Token>, | ||||
| 	left_associative: bool, | ||||
| 	context: &Context | ||||
| ) -> Result<bool, (LineLocation, ParserError)> { | ||||
|  | ||||
| 	let this: &PreToken = &g_inner[i]; | ||||
| 	let next: &PreToken; | ||||
| 	let this: &Token = &g_inner[i]; | ||||
| 	let next: &Token; | ||||
| 	if left_associative { | ||||
| 		next = { | ||||
| 			if i > 0 { | ||||
| 				&g_inner[i-1] | ||||
| 			} else { | ||||
| 				let l = match this { | ||||
| 					PreToken::PreOperator(l, _) => l, | ||||
| 					Token::PreOperator(l, _) => l, | ||||
| 					_ => panic!() | ||||
| 				}; | ||||
| 				return Err((*l, ParserError::Syntax)); | ||||
| @ -176,7 +176,7 @@ fn treeify_unary( | ||||
| 				&g_inner[i+1] | ||||
| 			} else { | ||||
| 				let l = match this { | ||||
| 					PreToken::PreOperator(l, _) => l, | ||||
| 					Token::PreOperator(l, _) => l, | ||||
| 					_ => panic!() | ||||
| 				}; | ||||
| 				return Err((*l, ParserError::Syntax)); | ||||
| @ -186,7 +186,7 @@ fn treeify_unary( | ||||
|  | ||||
| 	// We need to check the element after unary operators too. | ||||
| 	// Bad syntax like `3!3` won't be caught otherwise. | ||||
| 	let prev: Option<&PreToken>; | ||||
| 	let prev: Option<&Token>; | ||||
| 	if left_associative { | ||||
| 		prev = if i < g_inner.len()-1 { Some(&g_inner[i+1]) } else {None}; | ||||
| 	} else { | ||||
| @ -194,7 +194,7 @@ fn treeify_unary( | ||||
| 	} | ||||
|  | ||||
| 	if prev.is_some() { | ||||
| 		if let PreToken::PreOperator(_,_) = prev.unwrap() { | ||||
| 		if let Token::PreOperator(_,_) = prev.unwrap() { | ||||
| 		} else { | ||||
| 			return Err(( | ||||
| 				*this.get_line_location(), | ||||
| @ -203,7 +203,7 @@ fn treeify_unary( | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if let PreToken::PreOperator(l, _) = next { | ||||
| 	if let Token::PreOperator(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 PreToken::PreOperator(l, s) = this else {panic!()}; | ||||
| 			let Token::PreOperator(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 PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()}; | ||||
| 				let Token::PreOperator(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 PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()}; | ||||
| 				let Token::PreOperator(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()) | ||||
| @ -239,28 +239,28 @@ fn treeify_unary( | ||||
|  | ||||
| 		if next_op.is_none() || this_op > next_op.unwrap() { | ||||
| 			let this_pre = g_inner.remove(i).unwrap(); | ||||
| 			let next_pre: PreToken; let next: Token; | ||||
| 			let next_pre: Token; let next: Expression; | ||||
| 			if left_associative { | ||||
| 				next_pre = g_inner.remove(i-1).unwrap(); | ||||
| 			} else { | ||||
| 				next_pre = g_inner.remove(i).unwrap(); | ||||
| 			} | ||||
| 			if let PreToken::PreGroup(_, _) = next_pre { next = treeify(next_pre, context)?; } else { next = next_pre.to_token(context)? } | ||||
| 			if let Token::PreGroup(_, _) = next_pre { next = treeify(next_pre, context)?; } else { next = next_pre.to_expression(context)? } | ||||
|  | ||||
| 			let o = { | ||||
| 				let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | ||||
| 				let Token::PreOperator(_, s) = this_pre else {panic!()}; | ||||
| 				let o = Operator::from_string(&s); | ||||
| 				if o.is_none() { panic!() } | ||||
| 				o.unwrap() | ||||
| 			}; | ||||
|  | ||||
| 			let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(3); | ||||
| 			let mut new_token_args: VecDeque<Expression> = VecDeque::with_capacity(3); | ||||
| 			new_token_args.push_back(next); | ||||
|  | ||||
| 			if left_associative { | ||||
| 				g_inner.insert(i-1, PreToken::Container(o.into_token(new_token_args))); | ||||
| 				g_inner.insert(i-1, Token::Container(o.into_expression(new_token_args))); | ||||
| 			} else { | ||||
| 				g_inner.insert(i, PreToken::Container(o.into_token(new_token_args))); | ||||
| 				g_inner.insert(i, Token::Container(o.into_expression(new_token_args))); | ||||
| 			} | ||||
|  | ||||
| 			return Ok(true); | ||||
| @ -274,12 +274,12 @@ fn treeify_unary( | ||||
|  | ||||
|  | ||||
| pub fn treeify( | ||||
| 	mut g: PreToken, | ||||
| 	mut g: Token, | ||||
| 	context: &Context | ||||
| ) -> Result<Token, (LineLocation, ParserError)> { | ||||
| ) -> Result<Expression, (LineLocation, ParserError)> { | ||||
|  | ||||
| 	let g_inner: &mut VecDeque<PreToken> = match g { | ||||
| 		PreToken::PreGroup(_, ref mut x) => x, | ||||
| 	let g_inner: &mut VecDeque<Token> = match g { | ||||
| 		Token::PreGroup(_, ref mut x) => x, | ||||
| 		_ => panic!() | ||||
| 	}; | ||||
|  | ||||
| @ -300,7 +300,7 @@ pub fn treeify( | ||||
| 		// Convert preoperators | ||||
| 		// If not an operator, move on. | ||||
| 		let this_op = match &g_inner[i] { | ||||
| 			PreToken::PreOperator(l, s) => { | ||||
| 			Token::PreOperator(l, s) => { | ||||
| 				let o = Operator::from_string(&s); | ||||
| 				if o.is_none() { return Err((*l, ParserError::Syntax)); } | ||||
| 				o.unwrap() | ||||
| @ -342,13 +342,13 @@ pub fn treeify( | ||||
| 	let g = g_inner.pop_front().unwrap(); | ||||
| 	return match g { | ||||
| 		// Catch edge cases | ||||
| 		PreToken::PreOperator(l, _) => { | ||||
| 		Token::PreOperator(l, _) => { | ||||
| 			Err((l, ParserError::Syntax)) | ||||
| 		}, | ||||
| 		PreToken::PreGroup(_,_) => { | ||||
| 		Token::PreGroup(_,_) => { | ||||
| 			treeify(g, context) | ||||
| 		}, | ||||
|  | ||||
| 		_ => { Ok(g.to_token(context)?) } | ||||
| 		_ => { Ok(g.to_expression(context)?) } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| @ -6,34 +6,34 @@ use crate::context::Context; | ||||
| use super::{ | ||||
| 	LineLocation, | ||||
| 	ParserError, | ||||
| 	Token, | ||||
| 	Expression, | ||||
| 	Constant | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum PreToken { | ||||
| pub enum Token { | ||||
| 	PreQuantity(LineLocation, String), | ||||
| 	PreWord(LineLocation, String), | ||||
| 	PreOperator(LineLocation, String), | ||||
| 
 | ||||
| 	PreGroupStart(LineLocation), | ||||
| 	PreGroupEnd(LineLocation), | ||||
| 	PreGroup(LineLocation, VecDeque<PreToken>), | ||||
| 	PreGroup(LineLocation, VecDeque<Token>), | ||||
| 
 | ||||
| 	Container(Token) | ||||
| 	Container(Expression) | ||||
| } | ||||
| 
 | ||||
| impl PreToken { | ||||
| impl Token { | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_line_location(&self) -> &LineLocation { | ||||
| 		match self { | ||||
| 			PreToken::PreQuantity(l, _) | ||||
| 			| PreToken::PreWord(l, _) | ||||
| 			| PreToken::PreOperator(l, _) | ||||
| 			| PreToken::PreGroupStart(l) | ||||
| 			| PreToken::PreGroupEnd(l) | ||||
| 			| PreToken::PreGroup(l, _) | ||||
| 			Token::PreQuantity(l, _) | ||||
| 			| Token::PreWord(l, _) | ||||
| 			| Token::PreOperator(l, _) | ||||
| 			| Token::PreGroupStart(l) | ||||
| 			| Token::PreGroupEnd(l) | ||||
| 			| Token::PreGroup(l, _) | ||||
| 			=> l, | ||||
| 
 | ||||
| 			_ => panic!() | ||||
| @ -43,12 +43,12 @@ impl PreToken { | ||||
| 	#[inline(always)] | ||||
| 	pub fn get_mut_line_location(&mut self) -> &mut LineLocation { | ||||
| 		match self { | ||||
| 			PreToken::PreQuantity(l, _) | ||||
| 			| PreToken::PreWord(l, _) | ||||
| 			| PreToken::PreOperator(l, _) | ||||
| 			| PreToken::PreGroupStart(l) | ||||
| 			| PreToken::PreGroupEnd(l) | ||||
| 			| PreToken::PreGroup(l, _) | ||||
| 			Token::PreQuantity(l, _) | ||||
| 			| Token::PreWord(l, _) | ||||
| 			| Token::PreOperator(l, _) | ||||
| 			| Token::PreGroupStart(l) | ||||
| 			| Token::PreGroupEnd(l) | ||||
| 			| Token::PreGroup(l, _) | ||||
| 			=> l, | ||||
| 
 | ||||
| 			_ => panic!() | ||||
| @ -56,9 +56,9 @@ impl PreToken { | ||||
| 	} | ||||
| 
 | ||||
| 	#[inline(always)] | ||||
| 	pub fn to_token(self, context: &Context) -> Result<Token, (LineLocation, ParserError)>{ | ||||
| 	pub fn to_expression(self, context: &Context) -> Result<Expression, (LineLocation, ParserError)>{ | ||||
| 		match self { | ||||
| 			PreToken::PreQuantity(l, mut s) => { | ||||
| 			Token::PreQuantity(l, mut s) => { | ||||
| 
 | ||||
| 				// The length check here ensures that
 | ||||
| 				// `.` is not parsed as `0.`
 | ||||
| @ -73,28 +73,28 @@ impl PreToken { | ||||
| 					return Err((l, ParserError::BadNumber)) | ||||
| 				} | ||||
| 
 | ||||
| 				return Ok(Token::Quantity(r.unwrap())); | ||||
| 				return Ok(Expression::Quantity(r.unwrap())); | ||||
| 			}, | ||||
| 
 | ||||
| 			PreToken::PreWord(_l, s) => { | ||||
| 			Token::PreWord(_l, s) => { | ||||
| 
 | ||||
| 				let c = Constant::from_string(&s); | ||||
| 				if c.is_some() { return Ok(Token::Constant(c.unwrap())); } | ||||
| 				if c.is_some() { return Ok(Expression::Constant(c.unwrap())); } | ||||
| 
 | ||||
| 				let c = Unit::from_string(&s); | ||||
| 				if c.is_some() { return Ok(Token::Quantity(c.unwrap())); } | ||||
| 				if c.is_some() { return Ok(Expression::Quantity(c.unwrap())); } | ||||
| 
 | ||||
| 				let c = context.get_variable(&s); | ||||
| 				if c.is_some() { return Ok(Token::Variable(s)); } | ||||
| 				return Ok(Token::Variable(s)); | ||||
| 				if c.is_some() { return Ok(Expression::Variable(s)); } | ||||
| 				return Ok(Expression::Variable(s)); | ||||
| 			} | ||||
| 
 | ||||
| 			PreToken::Container(v) => { return Ok(v); } | ||||
| 			Token::Container(v) => { return Ok(v); } | ||||
| 
 | ||||
| 			PreToken::PreOperator(_,_) | ||||
| 			| PreToken::PreGroupStart(_) | ||||
| 			| PreToken::PreGroupEnd(_) | ||||
| 			| PreToken::PreGroup(_, _) | ||||
| 			Token::PreOperator(_,_) | ||||
| 			| Token::PreGroupStart(_) | ||||
| 			| Token::PreGroupEnd(_) | ||||
| 			| Token::PreGroup(_, _) | ||||
| 			=> panic!() | ||||
| 		}; | ||||
| 	} | ||||
		Reference in New Issue
	
	Block a user