From 00a421756df6f6f333c170ce18de72bf2601960e Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 14 Jun 2023 16:15:51 -0700 Subject: [PATCH] Reorganized variable code --- buildscript/constants.rs | 2 +- src/context.rs | 4 ++-- src/entry/unix/unix.rs | 12 +----------- src/evaluate/evaluate.rs | 6 +----- src/evaluate/mod.rs | 3 +-- src/parser/mod.rs | 16 ++++++++++------ src/parser/pretoken.rs | 13 ++++++------- src/parser/stage/treeify.rs | 26 +++++++++++++++----------- src/parser/token/mod.rs | 2 +- src/tests.rs | 2 +- 10 files changed, 39 insertions(+), 47 deletions(-) diff --git a/buildscript/constants.rs b/buildscript/constants.rs index add75c0..109a2d5 100644 --- a/buildscript/constants.rs +++ b/buildscript/constants.rs @@ -100,7 +100,7 @@ pub fn write(target: &Path) { for c in constants { 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(), s = c["value"].as_str().unwrap() ).unwrap(); diff --git a/src/context.rs b/src/context.rs index 879eac1..aad6f5d 100644 --- a/src/context.rs +++ b/src/context.rs @@ -16,14 +16,14 @@ impl Context { 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 get_variable(&self, s: String) -> Option { + pub fn get_variable(&self, s: &String) -> Option { let v: Option<&Token>; if s == "ans" { v = self.history.last(); } else { - v = self.variables.get(&s); + v = self.variables.get(s); } if v.is_some() { Some(v.unwrap().clone()) } else { None } diff --git a/src/entry/unix/unix.rs b/src/entry/unix/unix.rs index 0be7ea8..cfe2c89 100644 --- a/src/entry/unix/unix.rs +++ b/src/entry/unix/unix.rs @@ -28,7 +28,7 @@ fn do_expression( ) -> Result { #[cfg(debug_assertions)] RawTerminal::suspend_raw_mode(&stdout).unwrap(); - let g = parser::parse(&s); + let g = parser::parse(&s, context); #[cfg(debug_assertions)] RawTerminal::activate_raw_mode(&stdout).unwrap(); @@ -118,16 +118,6 @@ fn do_expression( style::Reset, color::Fg(color::Reset), ).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(); } } } diff --git a/src/evaluate/evaluate.rs b/src/evaluate/evaluate.rs index 31cb77e..2ae133e 100644 --- a/src/evaluate/evaluate.rs +++ b/src/evaluate/evaluate.rs @@ -35,11 +35,7 @@ pub fn evaluate(t: &Token, context: &Context) -> Result { Token::Constant(c) => { evaluate(&c.value(), context).unwrap() }, Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }, Token::Operator(o, v) => { eval_operator(&o, &v)? }, - Token::Variable(s) => { - if let Some(t) = context.get_variable(s) { t } else { - return Err(EvalError::NoHistory); - } - } + Token::Variable(s) => { context.get_variable(&s).unwrap() } }; } diff --git a/src/evaluate/mod.rs b/src/evaluate/mod.rs index 605203d..4e5cca9 100644 --- a/src/evaluate/mod.rs +++ b/src/evaluate/mod.rs @@ -9,6 +9,5 @@ pub enum EvalError { BadMath, TooBig, ZeroDivision, - IncompatibleUnit, - NoHistory + IncompatibleUnit } \ No newline at end of file diff --git a/src/parser/mod.rs b/src/parser/mod.rs index cb7ea5e..1333bd3 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -17,22 +17,26 @@ pub use self::{ token::Function, }; +use crate::context::Context; + pub fn parse( - s: &String -) -> Result< - Token, - (LineLocation, ParserError) -> { + s: &String, context: &Context +) -> Result { let tokens = stage::tokenize(s); let (_, tokens) = stage::find_subs(tokens); let g = stage::groupify(tokens)?; - let g = stage::treeify(g)?; + + let g = stage::treeify(g, context)?; return Ok(g); } +pub fn parse_no_context(s: &String) -> Result { + parse(s, &Context::new()) +} + pub fn substitute( s: &String, // The string to substitute diff --git a/src/parser/pretoken.rs b/src/parser/pretoken.rs index 0338907..f151467 100644 --- a/src/parser/pretoken.rs +++ b/src/parser/pretoken.rs @@ -1,6 +1,7 @@ use std::collections::VecDeque; use crate::quantity::Unit; use crate::quantity::Quantity; +use crate::context::Context; use super::{ LineLocation, @@ -55,7 +56,7 @@ impl PreToken { } #[inline(always)] - pub fn to_token(self) -> Result{ + pub fn to_token(self, context: &Context) -> Result{ match self { PreToken::PreQuantity(l, mut s) => { @@ -74,17 +75,15 @@ impl PreToken { }, PreToken::PreWord(l, s) => { - let c = Constant::from_string(&s); - if c.is_some() { - return Ok(Token::Constant(c.unwrap())); - } + let c = Constant::from_string(&s); + if c.is_some() { return Ok(Token::Constant(c.unwrap())); } let c = Unit::from_string(&s); if c.is_some() { return Ok(Token::Quantity(c.unwrap())); } - - if s == "ans" { return Ok(Token::Variable(String::from("ans"))); } + let c = context.get_variable(&s); + if c.is_some() { return Ok(Token::Variable(s)); } return Err((l, ParserError::Undefined(s))); } diff --git a/src/parser/stage/treeify.rs b/src/parser/stage/treeify.rs index ca9559b..cfafb89 100644 --- a/src/parser/stage/treeify.rs +++ b/src/parser/stage/treeify.rs @@ -1,4 +1,5 @@ use std::collections::VecDeque; +use crate::context::Context; use super::super::{ PreToken, @@ -10,7 +11,8 @@ use super::super::{ fn treeify_binary( i: usize, - g_inner: &mut VecDeque + g_inner: &mut VecDeque, + context: &Context ) -> Result { let this: &PreToken = &g_inner[i]; @@ -125,8 +127,8 @@ fn treeify_binary( 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)?; } else {right = right_pre.to_token()?;} - if let PreToken::PreGroup(_, _) = left_pre { left = treeify(left_pre)?; } else {left = left_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, context)?; } else {left = left_pre.to_token(context)?;} let o = { let PreToken::PreOperator(_, s) = this_pre else {panic!()}; @@ -150,7 +152,8 @@ fn treeify_binary( fn treeify_unary( i: usize, g_inner: &mut VecDeque, - left_associative: bool + left_associative: bool, + context: &Context ) -> Result { let this: &PreToken = &g_inner[i]; @@ -242,7 +245,7 @@ fn treeify_unary( } else { 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 PreToken::PreOperator(_, s) = this_pre else {panic!()}; @@ -272,6 +275,7 @@ fn treeify_unary( pub fn treeify( mut g: PreToken, + context: &Context ) -> Result { let g_inner: &mut VecDeque = match g { @@ -311,9 +315,9 @@ pub fn treeify( let mut changed = false; if this_op.is_left_associative() { if this_op.is_binary() { - changed = treeify_binary(i, g_inner)?; + changed = treeify_binary(i, g_inner, context)?; } 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 { if !this_op.is_left_associative() { if this_op.is_binary() { - treeify_binary(i, g_inner)?; + treeify_binary(i, g_inner, context)?; } else { - treeify_unary(i, g_inner, left_associative)?; + treeify_unary(i, g_inner, left_associative, context)?; } } j -= 1 @@ -342,9 +346,9 @@ pub fn treeify( Err((l, ParserError::Syntax)) }, PreToken::PreGroup(_,_) => { - treeify(g) + treeify(g, context) }, - _ => { Ok(g.to_token()?) } + _ => { Ok(g.to_token(context)?) } }; } diff --git a/src/parser/token/mod.rs b/src/parser/token/mod.rs index 0aec541..915cdd9 100644 --- a/src/parser/token/mod.rs +++ b/src/parser/token/mod.rs @@ -7,5 +7,5 @@ pub use self::function::Function; pub use self::token::Token; -use super::parse; +use super::parse_no_context; include!(concat!(env!("OUT_DIR"), "/constants.rs")); \ No newline at end of file diff --git a/src/tests.rs b/src/tests.rs index 386d31b..b677739 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -4,7 +4,7 @@ use crate::evaluate::evaluate; use crate::context::Context; fn eval_to_str(s: &str) -> Result { - let g = match parser::parse(&String::from(s)) { + let g = match parser::parse_no_context(&String::from(s)) { Ok(x) => x, Err(_) => return Err(()) };