mirror of https://github.com/rm-dr/daisy
Improved evaluator errors
parent
0134bc5c12
commit
ad3ae83c66
|
@ -11,6 +11,7 @@ use termion::{
|
|||
style,
|
||||
};
|
||||
|
||||
use crate::tokens::EvalError;
|
||||
use super::promptbuffer::PromptBuffer;
|
||||
use crate::parser;
|
||||
|
||||
|
@ -103,9 +104,19 @@ pub fn main() -> Result<(), std::io::Error> {
|
|||
)?;
|
||||
},
|
||||
|
||||
Err(_) => {
|
||||
Err(EvalError::BadMath) => {
|
||||
write!(
|
||||
stdout, "\n {}{}Mathematical Error: {}Failed to evaluate expression.{}\r\n\n",
|
||||
stdout, "\n {}{}Mathematical Error: {}Failed to evaluate expression{}\r\n\n",
|
||||
style::Bold,
|
||||
color::Fg(color::Red),
|
||||
style::Reset,
|
||||
color::Fg(color::Reset),
|
||||
)?;
|
||||
},
|
||||
|
||||
Err(EvalError::IncompatibleUnit) => {
|
||||
write!(
|
||||
stdout, "\n {}{}Evaluation Error: {}Incompatible units{}\r\n\n",
|
||||
style::Bold,
|
||||
color::Fg(color::Red),
|
||||
style::Reset,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use crate::tokens::Token;
|
||||
use crate::tokens::EvalError;
|
||||
use crate::tokens::Operator;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -65,13 +66,13 @@ impl Function {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn apply(&self, args: &VecDeque<Token>) -> Result<Token, ()> {
|
||||
pub fn apply(&self, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
||||
if args.len() != 1 {panic!()};
|
||||
let a = args[0].as_number();
|
||||
let Token::Number(q) = a else {panic!()};
|
||||
|
||||
if !q.unitless() {
|
||||
return Err(());
|
||||
return Err(EvalError::IncompatibleUnit);
|
||||
}
|
||||
|
||||
match self {
|
||||
|
|
|
@ -5,3 +5,8 @@ mod token;
|
|||
pub use crate::tokens::token::Token;
|
||||
pub use crate::tokens::function::Function;
|
||||
pub use crate::tokens::operator::Operator;
|
||||
|
||||
pub enum EvalError {
|
||||
BadMath,
|
||||
IncompatibleUnit
|
||||
}
|
|
@ -3,8 +3,10 @@ use std::cmp::Ordering;
|
|||
|
||||
use crate::tokens::Token;
|
||||
use crate::tokens::Function;
|
||||
use crate::tokens::EvalError;
|
||||
use crate::quantity::Quantity;
|
||||
|
||||
|
||||
/// Operator types, in order of increasing priority.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone)]
|
||||
|
@ -331,7 +333,7 @@ impl Operator {
|
|||
}
|
||||
|
||||
impl Operator{
|
||||
pub fn apply(&self, args: &VecDeque<Token>) -> Result<Token, ()> {
|
||||
pub fn apply(&self, args: &VecDeque<Token>) -> Result<Token, EvalError> {
|
||||
match self {
|
||||
Operator::ImplicitMultiply |
|
||||
Operator::Sqrt |
|
||||
|
@ -352,7 +354,7 @@ impl Operator{
|
|||
let args = args[0].as_number();
|
||||
|
||||
if let Token::Number(v) = args {
|
||||
if v.is_zero() { return Err(()); }
|
||||
if v.is_zero() { return Err(EvalError::BadMath); }
|
||||
return Ok(Token::Number(
|
||||
Quantity::new_rational(1f64).unwrap()/v
|
||||
));
|
||||
|
@ -371,7 +373,7 @@ impl Operator{
|
|||
if let Token::Number(v) = j {
|
||||
|
||||
if sum.unit() != v.unit() {
|
||||
return Err(());
|
||||
return Err(EvalError::IncompatibleUnit);
|
||||
}
|
||||
|
||||
sum += v;
|
||||
|
@ -406,12 +408,12 @@ impl Operator{
|
|||
if let Token::Number(vb) = b {
|
||||
|
||||
if !(va.unitless() && vb.unitless()) {
|
||||
return Err(());
|
||||
return Err(EvalError::IncompatibleUnit);
|
||||
}
|
||||
|
||||
if vb <= Quantity::new_rational(1f64).unwrap() { return Err(()); }
|
||||
if va.fract() != Quantity::new_rational(0f64).unwrap() { return Err(()); }
|
||||
if vb.fract() != Quantity::new_rational(0f64).unwrap() { return Err(()); }
|
||||
if vb <= Quantity::new_rational(1f64).unwrap() { return Err(EvalError::BadMath); }
|
||||
if va.fract() != Quantity::new_rational(0f64).unwrap() { return Err(EvalError::BadMath); }
|
||||
if vb.fract() != Quantity::new_rational(0f64).unwrap() { return Err(EvalError::BadMath); }
|
||||
|
||||
return Ok(Token::Number(va%vb));
|
||||
} else { panic!(); }
|
||||
|
@ -427,11 +429,11 @@ impl Operator{
|
|||
if let Token::Number(vb) = b {
|
||||
|
||||
if va.unit() != vb.unit() {
|
||||
return Err(());
|
||||
return Err(EvalError::IncompatibleUnit);
|
||||
}
|
||||
|
||||
let p = va.pow(vb);
|
||||
if p.is_nan() {return Err(());}
|
||||
if p.is_nan() {return Err(EvalError::BadMath);}
|
||||
return Ok(Token::Number(p));
|
||||
} else { panic!(); }
|
||||
} else { panic!(); }
|
||||
|
@ -444,11 +446,11 @@ impl Operator{
|
|||
if let Token::Number(v) = args {
|
||||
|
||||
if !v.unitless() {
|
||||
return Err(());
|
||||
return Err(EvalError::IncompatibleUnit);
|
||||
}
|
||||
|
||||
if !v.fract().is_zero() { return Err(()); }
|
||||
if v > Quantity::new_rational(50_000f64).unwrap() { return Err(()); }
|
||||
if !v.fract().is_zero() { return Err(EvalError::BadMath); }
|
||||
if v > Quantity::new_rational(50_000f64).unwrap() { return Err(EvalError::IncompatibleUnit); }
|
||||
|
||||
let mut prod = Quantity::new_rational(1f64).unwrap();
|
||||
let mut u = v.clone();
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use crate::tokens::EvalError;
|
||||
use crate::tokens::Operator;
|
||||
use crate::quantity::Quantity;
|
||||
|
||||
|
||||
/// Tokens represent logical objects in an expession.
|
||||
///
|
||||
/// Tokens starting with `Pre*` are intermediate tokens, and
|
||||
|
@ -60,7 +62,7 @@ impl Token {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn eval(&self) -> Result<Token, ()> {
|
||||
pub fn eval(&self) -> Result<Token, EvalError> {
|
||||
Ok(match self {
|
||||
Token::Number(_) => { self.clone() },
|
||||
Token::Constant(v,_) => { Token::Number(v.clone()) },
|
||||
|
@ -96,7 +98,7 @@ impl Token {
|
|||
}
|
||||
|
||||
|
||||
pub fn evaluate(&self) -> Result<Token, ()> {
|
||||
pub fn evaluate(&self) -> Result<Token, EvalError> {
|
||||
let mut g = self.clone();
|
||||
let mut coords: Vec<usize> = Vec::with_capacity(16);
|
||||
coords.push(0);
|
||||
|
|
Loading…
Reference in New Issue