mirror of https://github.com/rm-dr/daisy
Reorganized variable code
parent
5ffad0cc4e
commit
00a421756d
|
@ -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();
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,5 @@ pub enum EvalError {
|
|||
BadMath,
|
||||
TooBig,
|
||||
ZeroDivision,
|
||||
IncompatibleUnit,
|
||||
NoHistory
|
||||
IncompatibleUnit
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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)?) }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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"));
|
|
@ -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(())
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue