pub mod ast;
mod value;
use ast::{
parser::{AnnotatedExprParser, ExprParser},
AnnotatedError, ParseError as UserParseError,
};
use lalrpop_util::ParseError;
pub(crate) use value::Result;
pub use value::{ArithmeticError, Error as ValueError, ParseValueError, Value};
#[derive(Default)]
pub struct Context {
pub history: Vec<Value>,
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Parsing")]
Parse(#[from] ParseError<usize, &'static str, UserParseError>),
#[error("Evaluating")]
Eval(#[from] ValueError),
#[error("Formatting")]
Format(#[source] num_runtime_fmt::Error),
}
impl From<AnnotatedError> for Error {
fn from(err: AnnotatedError) -> Self {
match err {
AnnotatedError::Calculation(err) => Self::Eval(err),
AnnotatedError::Format(err) => Self::Format(err),
}
}
}
impl Context {
pub fn evaluate(&mut self, expr: &str) -> Result<Value, Error> {
let parser = ExprParser::new();
let expr = parser.parse(expr).map_err(|err| err.map_token(|_| ""))?;
let result = expr.evaluate(self).map_err(Error::Eval)?;
self.history.push(result);
Ok(result)
}
}
impl Context {
pub fn evaluate_annotated(&mut self, expr: &str) -> Result<String, Error> {
let parser = AnnotatedExprParser::new();
let expr = parser.parse(expr).map_err(|err| err.map_token(|_| ""))?;
let (result, formatted) = expr.evaluate(self)?;
self.history.push(result);
Ok(formatted)
}
}