mirror of https://github.com/rm-dr/daisy
Evaluate module cleanup
parent
5c2dab4b53
commit
368c178ddc
|
@ -22,7 +22,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "daisy"
|
name = "daisy"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"rug",
|
"rug",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "daisy"
|
name = "daisy"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
use crate::parser::Token;
|
||||||
|
use crate::parser::Constant;
|
||||||
|
use crate::quantity::Quantity;
|
||||||
|
|
||||||
|
use super::EvalError;
|
||||||
|
|
||||||
|
pub fn eval_constant(c: &Constant) -> Result<Token, EvalError> {
|
||||||
|
Ok(match c {
|
||||||
|
// Mathematical constants
|
||||||
|
// 100 digits of each.
|
||||||
|
Constant::Pi => { Token::Quantity(Quantity::new_float_from_string(
|
||||||
|
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"
|
||||||
|
).unwrap())},
|
||||||
|
|
||||||
|
Constant::E => { Token::Quantity(Quantity::new_float_from_string(
|
||||||
|
"2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"
|
||||||
|
).unwrap()) },
|
||||||
|
|
||||||
|
Constant::Phi => { Token::Quantity(Quantity::new_float_from_string(
|
||||||
|
"1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"
|
||||||
|
).unwrap()) },
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::parser::Token;
|
use crate::parser::Token;
|
||||||
use crate::parser::Constant;
|
use crate::parser::Operator;
|
||||||
use crate::quantity::Quantity;
|
|
||||||
|
|
||||||
use super::operator::op_apply;
|
use super::operator::eval_operator;
|
||||||
|
use super::constant::eval_constant;
|
||||||
|
use super::function::eval_function;
|
||||||
use super::EvalError;
|
use super::EvalError;
|
||||||
|
|
||||||
|
|
||||||
pub fn evaluate(t: &Token) -> Result<Token, EvalError> {
|
pub fn evaluate(t: &Token) -> Result<Token, EvalError> {
|
||||||
let mut g = t.clone();
|
let mut g = t.clone();
|
||||||
let mut coords: Vec<usize> = Vec::with_capacity(16);
|
let mut coords: Vec<usize> = Vec::with_capacity(16);
|
||||||
|
@ -21,30 +23,21 @@ pub fn evaluate(t: &Token) -> Result<Token, EvalError> {
|
||||||
|
|
||||||
|
|
||||||
let p = Token::get_at_coords(&mut g, &coords);
|
let p = Token::get_at_coords(&mut g, &coords);
|
||||||
|
let mut e = p.clone();
|
||||||
|
|
||||||
let e: Token = match p {
|
// Evaluate until we get a single number.
|
||||||
Token::Quantity(_) => { p.clone() },
|
// This loop is necessary because some eval_* functions
|
||||||
Token::Constant(c) => {
|
// May return an incomplete result.
|
||||||
match c {
|
// ( For example, csc(x) is treated as 1/sin(x) )
|
||||||
// Mathematical constants
|
loop {
|
||||||
// 100 digits of each.
|
e = match e {
|
||||||
Constant::Pi => { Token::Quantity(Quantity::new_float_from_string(
|
Token::Quantity(_) => { break; },
|
||||||
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"
|
Token::Constant(c) => { eval_constant(&c)? }
|
||||||
).unwrap())},
|
Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }
|
||||||
|
Token::Operator(o, v) => { eval_operator(&o, &v)? }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Constant::E => { Token::Quantity(Quantity::new_float_from_string(
|
|
||||||
"2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"
|
|
||||||
).unwrap()) },
|
|
||||||
|
|
||||||
Constant::Phi => { Token::Quantity(Quantity::new_float_from_string(
|
|
||||||
"1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"
|
|
||||||
).unwrap()) },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Token::Operator(o,v) => { op_apply(o, &v)? }
|
|
||||||
};
|
|
||||||
|
|
||||||
//let e = p.eval()?;
|
|
||||||
*p = e;
|
*p = e;
|
||||||
|
|
||||||
if coords.len() == 0 { break 'outer; }
|
if coords.len() == 0 { break 'outer; }
|
||||||
|
|
|
@ -4,18 +4,9 @@ use crate::parser::Token;
|
||||||
use crate::parser::Function;
|
use crate::parser::Function;
|
||||||
use crate::parser::Operator;
|
use crate::parser::Operator;
|
||||||
use super::EvalError;
|
use super::EvalError;
|
||||||
use super::operator::op_apply;
|
|
||||||
use crate::quantity::Quantity;
|
|
||||||
|
|
||||||
fn eval(t: Token) -> Result<Token, EvalError> {
|
|
||||||
Ok(match t {
|
|
||||||
Token::Quantity(_) => { t },
|
|
||||||
Token::Constant(_) => { Token::Quantity( Quantity::new_rational_from_string("1").unwrap() ) },
|
|
||||||
Token::Operator(mut o, v) => { op_apply(&mut o, &v)? }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn func_apply(f: &Function, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
pub fn eval_function(f: &Function, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
||||||
if args.len() != 1 {panic!()};
|
if args.len() != 1 {panic!()};
|
||||||
let a = &args[0];
|
let a = &args[0];
|
||||||
let Token::Quantity(q) = a else {panic!()};
|
let Token::Quantity(q) = a else {panic!()};
|
||||||
|
@ -42,26 +33,26 @@ pub fn func_apply(f: &Function, args: &VecDeque<Token>) -> Result<Token, EvalErr
|
||||||
|
|
||||||
Function::Csc => {
|
Function::Csc => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.sin())))
|
VecDeque::from(vec!(Token::Quantity(q.sin())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Function::Sec => {
|
Function::Sec => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.cos())))
|
VecDeque::from(vec!(Token::Quantity(q.cos())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Function::Cot => {
|
Function::Cot => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.tan())))
|
VecDeque::from(vec!(Token::Quantity(q.tan())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -75,26 +66,26 @@ pub fn func_apply(f: &Function, args: &VecDeque<Token>) -> Result<Token, EvalErr
|
||||||
|
|
||||||
Function::Csch => {
|
Function::Csch => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.sinh())))
|
VecDeque::from(vec!(Token::Quantity(q.sinh())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Function::Sech => {
|
Function::Sech => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.cosh())))
|
VecDeque::from(vec!(Token::Quantity(q.cosh())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Function::Coth => {
|
Function::Coth => {
|
||||||
return Ok(
|
return Ok(
|
||||||
eval(Token::Operator(
|
Token::Operator(
|
||||||
Operator::Flip,
|
Operator::Flip,
|
||||||
VecDeque::from(vec!(Token::Quantity(q.tanh())))
|
VecDeque::from(vec!(Token::Quantity(q.tanh())))
|
||||||
))?
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
mod operator;
|
mod operator;
|
||||||
mod function;
|
mod function;
|
||||||
|
mod constant;
|
||||||
mod evaluate;
|
mod evaluate;
|
||||||
|
|
||||||
pub use self::evaluate::evaluate;
|
pub use self::evaluate::evaluate;
|
||||||
|
|
||||||
pub enum EvalError {
|
pub enum EvalError {
|
||||||
|
|
|
@ -4,11 +4,15 @@ use crate::quantity::Quantity;
|
||||||
use crate::parser::Operator;
|
use crate::parser::Operator;
|
||||||
use crate::parser::Token;
|
use crate::parser::Token;
|
||||||
use super::EvalError;
|
use super::EvalError;
|
||||||
use super::function::func_apply;
|
|
||||||
|
|
||||||
|
pub fn eval_operator(op: &Operator, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
||||||
pub fn op_apply(op: &mut Operator, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
|
||||||
match op {
|
match op {
|
||||||
|
|
||||||
|
// Handled seperately in evaluate.rs
|
||||||
|
Operator::Function(_) |
|
||||||
|
|
||||||
|
// These are never evaluated,
|
||||||
|
// but are converted to one of the following instead.
|
||||||
Operator::ImplicitMultiply |
|
Operator::ImplicitMultiply |
|
||||||
Operator::Sqrt |
|
Operator::Sqrt |
|
||||||
Operator::Divide |
|
Operator::Divide |
|
||||||
|
@ -156,10 +160,6 @@ pub fn op_apply(op: &mut Operator, args: &VecDeque<Token>) -> Result<Token, Eval
|
||||||
|
|
||||||
return Ok(Token::Quantity(prod));
|
return Ok(Token::Quantity(prod));
|
||||||
} else { panic!(); }
|
} else { panic!(); }
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Function(f) => {
|
|
||||||
return func_apply(f, args);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue