Reorganized variable code

pull/2/head
Mark 2023-06-14 16:15:51 -07:00
parent 5ffad0cc4e
commit 00a421756d
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
10 changed files with 39 additions and 47 deletions

View File

@ -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();

View File

@ -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<Token> {
pub fn get_variable(&self, s: &String) -> Option<Token> {
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 }

View File

@ -28,7 +28,7 @@ fn do_expression(
) -> Result<parser::Token, ()> {
#[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();
}
}
}

View File

@ -35,11 +35,7 @@ pub fn evaluate(t: &Token, context: &Context) -> Result<Token, EvalError> {
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() }
};
}

View File

@ -9,6 +9,5 @@ pub enum EvalError {
BadMath,
TooBig,
ZeroDivision,
IncompatibleUnit,
NoHistory
IncompatibleUnit
}

View File

@ -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<Token, (LineLocation, ParserError)> {
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<Token, (LineLocation, ParserError)> {
parse(s, &Context::new())
}
pub fn substitute(
s: &String, // The string to substitute

View File

@ -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<Token, (LineLocation, ParserError)>{
pub fn to_token(self, context: &Context) -> Result<Token, (LineLocation, ParserError)>{
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)));
}

View File

@ -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<PreToken>
g_inner: &mut VecDeque<PreToken>,
context: &Context
) -> Result<bool, (LineLocation, ParserError)> {
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<PreToken>,
left_associative: bool
left_associative: bool,
context: &Context
) -> Result<bool, (LineLocation, ParserError)> {
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<Token, (LineLocation, ParserError)> {
let g_inner: &mut VecDeque<PreToken> = 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)?) }
};
}

View File

@ -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"));

View File

@ -4,7 +4,7 @@ use crate::evaluate::evaluate;
use crate::context::Context;
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,
Err(_) => return Err(())
};