mirror of
				https://github.com/rm-dr/daisy
				synced 2025-10-30 14:04:47 -07:00 
			
		
		
		
	Reorganized variable code
This commit is contained in:
		| @ -100,7 +100,7 @@ pub fn write(target: &Path) { | |||||||
|  |  | ||||||
| 	for c in constants { | 	for c in constants { | ||||||
| 		writeln!(file, | 		writeln!(file, | ||||||
| 			"\t\t\tConstant::{e} => parse(&String::from(\"{s}\")).unwrap(),", | 			"\t\t\tConstant::{e} => parse_no_context(&String::from(\"{s}\")).unwrap(),", | ||||||
| 			e = c["enum_name"].as_str().unwrap(), | 			e = c["enum_name"].as_str().unwrap(), | ||||||
| 			s = c["value"].as_str().unwrap() | 			s = c["value"].as_str().unwrap() | ||||||
| 		).unwrap(); | 		).unwrap(); | ||||||
|  | |||||||
| @ -16,14 +16,14 @@ impl Context { | |||||||
| 	pub fn push_var(&mut self, s: String, t: Token) { self.variables.insert(s, t); } | 	pub fn push_var(&mut self, s: String, t: Token) { self.variables.insert(s, t); } | ||||||
| 	pub fn del_var(&mut self, s: &String) { self.variables.remove(s); } | 	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<Token> { | ||||||
|  |  | ||||||
| 		let v: Option<&Token>; | 		let v: Option<&Token>; | ||||||
|  |  | ||||||
| 		if s == "ans" { | 		if s == "ans" { | ||||||
| 			v = self.history.last(); | 			v = self.history.last(); | ||||||
| 		} else { | 		} else { | ||||||
| 			v = self.variables.get(&s); | 			v = self.variables.get(s); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if v.is_some() { Some(v.unwrap().clone()) } else { None } | 		if v.is_some() { Some(v.unwrap().clone()) } else { None } | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ fn do_expression( | |||||||
| ) -> Result<parser::Token, ()> { | ) -> Result<parser::Token, ()> { | ||||||
| 	#[cfg(debug_assertions)] | 	#[cfg(debug_assertions)] | ||||||
| 	RawTerminal::suspend_raw_mode(&stdout).unwrap(); | 	RawTerminal::suspend_raw_mode(&stdout).unwrap(); | ||||||
| 	let g = parser::parse(&s); | 	let g = parser::parse(&s, context); | ||||||
| 	#[cfg(debug_assertions)] | 	#[cfg(debug_assertions)] | ||||||
| 	RawTerminal::activate_raw_mode(&stdout).unwrap(); | 	RawTerminal::activate_raw_mode(&stdout).unwrap(); | ||||||
|  |  | ||||||
| @ -118,16 +118,6 @@ fn do_expression( | |||||||
| 					style::Reset, | 					style::Reset, | ||||||
| 					color::Fg(color::Reset), | 					color::Fg(color::Reset), | ||||||
| 				).unwrap(); | 				).unwrap(); | ||||||
| 			}, |  | ||||||
|  |  | ||||||
| 			Err(EvalError::NoHistory) => { |  | ||||||
| 				write!( |  | ||||||
| 					stdout, "\n  {}{}Evaluation Error: {}There is no previous answer to reference{}\r\n\n", |  | ||||||
| 					style::Bold, |  | ||||||
| 					color::Fg(color::Red), |  | ||||||
| 					style::Reset, |  | ||||||
| 					color::Fg(color::Reset), |  | ||||||
| 				).unwrap(); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -35,11 +35,7 @@ pub fn evaluate(t: &Token, context: &Context) -> Result<Token, EvalError> { | |||||||
| 						Token::Constant(c) => { evaluate(&c.value(), context).unwrap() }, | 						Token::Constant(c) => { evaluate(&c.value(), context).unwrap() }, | ||||||
| 						Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }, | 						Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }, | ||||||
| 						Token::Operator(o, v) => { eval_operator(&o, &v)? }, | 						Token::Operator(o, v) => { eval_operator(&o, &v)? }, | ||||||
| 						Token::Variable(s) => { | 						Token::Variable(s) => { context.get_variable(&s).unwrap() } | ||||||
| 							if let Some(t) = context.get_variable(s) { t } else { |  | ||||||
| 								return Err(EvalError::NoHistory); |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					}; | 					}; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | |||||||
| @ -9,6 +9,5 @@ pub enum EvalError { | |||||||
| 	BadMath, | 	BadMath, | ||||||
| 	TooBig, | 	TooBig, | ||||||
| 	ZeroDivision, | 	ZeroDivision, | ||||||
| 	IncompatibleUnit, | 	IncompatibleUnit | ||||||
| 	NoHistory |  | ||||||
| } | } | ||||||
| @ -17,22 +17,26 @@ pub use self::{ | |||||||
| 	token::Function, | 	token::Function, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | use crate::context::Context; | ||||||
|  |  | ||||||
|  |  | ||||||
| pub fn parse( | pub fn parse( | ||||||
| 	s: &String | 	s: &String, context: &Context | ||||||
| ) -> Result< | ) -> Result<Token, (LineLocation, ParserError)> { | ||||||
| 	Token, |  | ||||||
| 	(LineLocation, ParserError) |  | ||||||
| > { |  | ||||||
|  |  | ||||||
| 	let tokens = stage::tokenize(s); | 	let tokens = stage::tokenize(s); | ||||||
| 	let (_, tokens) = stage::find_subs(tokens); | 	let (_, tokens) = stage::find_subs(tokens); | ||||||
| 	let g = stage::groupify(tokens)?; | 	let g = stage::groupify(tokens)?; | ||||||
| 	let g = stage::treeify(g)?; |  | ||||||
|  | 	let g = stage::treeify(g, context)?; | ||||||
|  |  | ||||||
| 	return Ok(g); | 	return Ok(g); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pub fn parse_no_context(s: &String) -> Result<Token, (LineLocation, ParserError)> { | ||||||
|  | 	parse(s, &Context::new()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| pub fn substitute( | pub fn substitute( | ||||||
| 	s: &String, // The string to substitute | 	s: &String, // The string to substitute | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| use std::collections::VecDeque; | use std::collections::VecDeque; | ||||||
| use crate::quantity::Unit; | use crate::quantity::Unit; | ||||||
| use crate::quantity::Quantity; | use crate::quantity::Quantity; | ||||||
|  | use crate::context::Context; | ||||||
|  |  | ||||||
| use super::{ | use super::{ | ||||||
| 	LineLocation, | 	LineLocation, | ||||||
| @ -55,7 +56,7 @@ impl PreToken { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	#[inline(always)] | 	#[inline(always)] | ||||||
| 	pub fn to_token(self) -> Result<Token, (LineLocation, ParserError)>{ | 	pub fn to_token(self, context: &Context) -> Result<Token, (LineLocation, ParserError)>{ | ||||||
| 		match self { | 		match self { | ||||||
| 			PreToken::PreQuantity(l, mut s) => { | 			PreToken::PreQuantity(l, mut s) => { | ||||||
|  |  | ||||||
| @ -74,17 +75,15 @@ impl PreToken { | |||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| 			PreToken::PreWord(l, s) => { | 			PreToken::PreWord(l, s) => { | ||||||
| 				let c = Constant::from_string(&s); |  | ||||||
|  |  | ||||||
| 				if c.is_some() { | 				let c = Constant::from_string(&s); | ||||||
| 					return Ok(Token::Constant(c.unwrap())); | 				if c.is_some() { return Ok(Token::Constant(c.unwrap())); } | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				let c = Unit::from_string(&s); | 				let c = Unit::from_string(&s); | ||||||
| 				if c.is_some() { return Ok(Token::Quantity(c.unwrap())); } | 				if c.is_some() { return Ok(Token::Quantity(c.unwrap())); } | ||||||
|  |  | ||||||
|  | 				let c = context.get_variable(&s); | ||||||
| 				if s == "ans" { return Ok(Token::Variable(String::from("ans"))); } | 				if c.is_some() { return Ok(Token::Variable(s)); } | ||||||
|  |  | ||||||
| 				return Err((l, ParserError::Undefined(s))); | 				return Err((l, ParserError::Undefined(s))); | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| use std::collections::VecDeque; | use std::collections::VecDeque; | ||||||
|  | use crate::context::Context; | ||||||
|  |  | ||||||
| use super::super::{ | use super::super::{ | ||||||
| 	PreToken, | 	PreToken, | ||||||
| @ -10,7 +11,8 @@ use super::super::{ | |||||||
|  |  | ||||||
| fn treeify_binary( | fn treeify_binary( | ||||||
| 	i: usize, | 	i: usize, | ||||||
| 	g_inner: &mut VecDeque<PreToken> | 	g_inner: &mut VecDeque<PreToken>, | ||||||
|  | 	context: &Context | ||||||
| ) -> Result<bool, (LineLocation, ParserError)> { | ) -> Result<bool, (LineLocation, ParserError)> { | ||||||
|  |  | ||||||
| 	let this: &PreToken = &g_inner[i]; | 	let this: &PreToken = &g_inner[i]; | ||||||
| @ -125,8 +127,8 @@ 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: Token; let right: Token; | 		let left: Token; let right: Token; | ||||||
| 		if let PreToken::PreGroup(_, _) = right_pre { right = treeify(right_pre)?; } else {right = right_pre.to_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)?; } else {left = left_pre.to_token()?;} | 		if let PreToken::PreGroup(_, _) = left_pre { left = treeify(left_pre, context)?; } else {left = left_pre.to_token(context)?;} | ||||||
|  |  | ||||||
| 		let o = { | 		let o = { | ||||||
| 			let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | 			let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | ||||||
| @ -150,7 +152,8 @@ fn treeify_binary( | |||||||
| fn treeify_unary( | fn treeify_unary( | ||||||
| 	i: usize, | 	i: usize, | ||||||
| 	g_inner: &mut VecDeque<PreToken>, | 	g_inner: &mut VecDeque<PreToken>, | ||||||
| 	left_associative: bool | 	left_associative: bool, | ||||||
|  | 	context: &Context | ||||||
| ) -> Result<bool, (LineLocation, ParserError)> { | ) -> Result<bool, (LineLocation, ParserError)> { | ||||||
|  |  | ||||||
| 	let this: &PreToken = &g_inner[i]; | 	let this: &PreToken = &g_inner[i]; | ||||||
| @ -242,7 +245,7 @@ fn treeify_unary( | |||||||
| 			} else { | 			} else { | ||||||
| 				next_pre = g_inner.remove(i).unwrap(); | 				next_pre = g_inner.remove(i).unwrap(); | ||||||
| 			} | 			} | ||||||
| 			if let PreToken::PreGroup(_, _) = next_pre { next = treeify(next_pre)?; } else { next = next_pre.to_token()? } | 			if let PreToken::PreGroup(_, _) = next_pre { next = treeify(next_pre, context)?; } else { next = next_pre.to_token(context)? } | ||||||
|  |  | ||||||
| 			let o = { | 			let o = { | ||||||
| 				let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | 				let PreToken::PreOperator(_, s) = this_pre else {panic!()}; | ||||||
| @ -272,6 +275,7 @@ fn treeify_unary( | |||||||
|  |  | ||||||
| pub fn treeify( | pub fn treeify( | ||||||
| 	mut g: PreToken, | 	mut g: PreToken, | ||||||
|  | 	context: &Context | ||||||
| ) -> Result<Token, (LineLocation, ParserError)> { | ) -> Result<Token, (LineLocation, ParserError)> { | ||||||
|  |  | ||||||
| 	let g_inner: &mut VecDeque<PreToken> = match g { | 	let g_inner: &mut VecDeque<PreToken> = match g { | ||||||
| @ -311,9 +315,9 @@ pub fn treeify( | |||||||
| 			let mut changed = false; | 			let mut changed = false; | ||||||
| 			if this_op.is_left_associative() { | 			if this_op.is_left_associative() { | ||||||
| 				if this_op.is_binary() { | 				if this_op.is_binary() { | ||||||
| 					changed = treeify_binary(i, g_inner)?; | 					changed = treeify_binary(i, g_inner, context)?; | ||||||
| 				} else { | 				} else { | ||||||
| 					changed = treeify_unary(i, g_inner, left_associative)?; | 					changed = treeify_unary(i, g_inner, left_associative, context)?; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -325,9 +329,9 @@ pub fn treeify( | |||||||
| 		} else { | 		} else { | ||||||
| 			if !this_op.is_left_associative() { | 			if !this_op.is_left_associative() { | ||||||
| 				if this_op.is_binary() { | 				if this_op.is_binary() { | ||||||
| 					treeify_binary(i, g_inner)?; | 					treeify_binary(i, g_inner, context)?; | ||||||
| 				} else { | 				} else { | ||||||
| 					treeify_unary(i, g_inner, left_associative)?; | 					treeify_unary(i, g_inner, left_associative, context)?; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			j -= 1 | 			j -= 1 | ||||||
| @ -342,9 +346,9 @@ pub fn treeify( | |||||||
| 			Err((l, ParserError::Syntax)) | 			Err((l, ParserError::Syntax)) | ||||||
| 		}, | 		}, | ||||||
| 		PreToken::PreGroup(_,_) => { | 		PreToken::PreGroup(_,_) => { | ||||||
| 			treeify(g) | 			treeify(g, context) | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		_ => { Ok(g.to_token()?) } | 		_ => { Ok(g.to_token(context)?) } | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,5 +7,5 @@ pub use self::function::Function; | |||||||
| pub use self::token::Token; | pub use self::token::Token; | ||||||
|  |  | ||||||
|  |  | ||||||
| use super::parse; | use super::parse_no_context; | ||||||
| include!(concat!(env!("OUT_DIR"), "/constants.rs")); | include!(concat!(env!("OUT_DIR"), "/constants.rs")); | ||||||
| @ -4,7 +4,7 @@ use crate::evaluate::evaluate; | |||||||
| use crate::context::Context; | use crate::context::Context; | ||||||
|  |  | ||||||
| fn eval_to_str(s: &str) -> Result<String, ()> { | fn eval_to_str(s: &str) -> Result<String, ()> { | ||||||
| 	let g = match parser::parse(&String::from(s)) { | 	let g = match parser::parse_no_context(&String::from(s)) { | ||||||
| 		Ok(x) => x, | 		Ok(x) => x, | ||||||
| 		Err(_) => return Err(()) | 		Err(_) => return Err(()) | ||||||
| 	}; | 	}; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user