From 234b2ef2dc302aa5c7a4b2a123d35a6b0c553055 Mon Sep 17 00:00:00 2001 From: ozzy <2+ozzy@noreply.localhost> Date: Sat, 26 Sep 2026 14:51:33 -0500 Subject: [PATCH] feat(eval): add extremely basic evaluation added a basic `eval_expr` function that evaluates an expression. it still does not reduce/simplify anything, and it cannot evaluate to fractions yet --- Cargo.toml | 2 +- src/main.rs | 2 +- src/math/eval.rs | 37 +++++++++++++++++++++++++++++++++++++ src/math/mod.rs | 5 +++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/math/eval.rs diff --git a/Cargo.toml b/Cargo.toml index 37c989b..84642ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] -rust_decimal = { version = "1.43.0", features = ["macros"] } +rust_decimal = { version = "1.43.0", features = ["macros", "maths"] } diff --git a/src/main.rs b/src/main.rs index 9970096..b8c783b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ fn main() -> io::Result<()> { let line = line.unwrap(); let parsed = math::parse(line.trim()); - println!("{}", parsed); + println!("{}", math::eval(parsed)); prompt()?; } diff --git a/src/math/eval.rs b/src/math/eval.rs new file mode 100644 index 0000000..6c0145f --- /dev/null +++ b/src/math/eval.rs @@ -0,0 +1,37 @@ +use rust_decimal::MathematicalOps; + +use crate::math::types::{Expression, Operator}; + +pub fn eval_expr(expr: Expression) -> Expression { + match expr { + Expression::Number(_) => expr, + Expression::Variable(_) => expr, + Expression::Fraction(numberator, denominator) => { + // TODO: implement proper fraction handling + eval_expr(Expression::Operation( + Operator::Divide, + numberator, + denominator, + )) + } + Expression::Operation(operator, left, right) => eval_operation(operator, *left, *right), + Expression::Function(_name, _params) => todo!(), + } +} + +fn eval_operation(operator: Operator, left: Expression, right: Expression) -> Expression { + let left = eval_expr(left); + let right = eval_expr(right); + match (&left, &right) { + (Expression::Number(left), Expression::Number(right)) => match operator { + Operator::Add => Expression::Number(left + right), + Operator::Subtract => Expression::Number(left - right), + Operator::Multiply => Expression::Number(left * right), + Operator::Divide => Expression::Number(left / right), + Operator::Modulo => Expression::Number(left % right), + Operator::Power => Expression::Number(left.powd(*right)), + }, + // TODO: implement handling for variables + _ => Expression::Operation(operator, Box::new(left), Box::new(right)), + } +} diff --git a/src/math/mod.rs b/src/math/mod.rs index 65368d0..c272e33 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,6 +1,7 @@ use crate::math::types::Expression; mod display; +mod eval; mod lexer; mod parser; @@ -11,3 +12,7 @@ pub fn parse(source: &str) -> Expression { let mut parser = parser::from(lexer.collect()); parser.parse() } + +pub fn eval(expr: Expression) -> Expression { + eval::eval_expr(expr) +}