From 88eacc9c6a95d2147ec7f6005014891667da7f1e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Sat, 17 Feb 2024 13:45:25 -0800 Subject: [PATCH] feat: evaluation logic --- program/src/context.rs | 2 +- program/src/eval.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ program/src/lib.rs | 3 ++- program/src/program.rs | 10 ++++---- program/src/value.rs | 45 ++++++++------------------------- 5 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 program/src/eval.rs diff --git a/program/src/context.rs b/program/src/context.rs index 0618b4f..e44457b 100644 --- a/program/src/context.rs +++ b/program/src/context.rs @@ -1,5 +1,5 @@ pub struct Context { - + } impl Default for Context { diff --git a/program/src/eval.rs b/program/src/eval.rs new file mode 100644 index 0000000..80e45be --- /dev/null +++ b/program/src/eval.rs @@ -0,0 +1,57 @@ +use crate::{value::Value, Context}; +use parser::{ArithmeticOp, Atom, Expression, RelationOp}; + +impl From for Value { + fn from(atom: Atom) -> Self { + match atom { + Atom::Int(i) => Value::Int(i), + Atom::UInt(ui) => Value::UInt(ui), + Atom::Float(f) => Value::Float(f), + Atom::Bool(b) => Value::Bool(b), + Atom::Null => Value::Null, + Atom::Bytes(b) => Value::Bytes(b), + Atom::String(s) => Value::String(s), + } + } +} + +pub struct Eval { + ctx: Context, +} + +impl Eval { + pub fn new(ctx: Context) -> Self { + Eval { ctx } + } + pub fn eval(&self, expr: Expression) -> Value { + match expr { + Expression::Atom(atom) => atom.into(), + Expression::Relation(left, op, right) => { + let left = self.eval(*left); + let right = self.eval(*right); + let result = match op { + RelationOp::Equals => left.eq(&right), + RelationOp::LessThan => todo!("lt"), + RelationOp::LessThanEq => todo!("lte"), + RelationOp::GreaterThan => todo!("gt"), + RelationOp::GreaterThanEq => todo!("gte"), + RelationOp::NotEquals => todo!("ne"), + RelationOp::In => todo!("in"), + }; + Value::Bool(result) + } + Expression::Arithmetic(left, op, right) => { + let left = self.eval(*left); + let right = self.eval(*right); + match op { + ArithmeticOp::Add => left + right, + ArithmeticOp::Subtract => left - right, + ArithmeticOp::Divide => left / right, + ArithmeticOp::Multiply => left * right, + ArithmeticOp::Modulus => todo!("modulus"), + } + } + _ => todo!(), + } + } +} diff --git a/program/src/lib.rs b/program/src/lib.rs index 94096cc..04195a3 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -2,4 +2,5 @@ pub mod context; pub mod program; pub use crate::program::Program; pub use crate::context::Context; -mod value; \ No newline at end of file +mod value; +mod eval; \ No newline at end of file diff --git a/program/src/program.rs b/program/src/program.rs index 0f49fba..da97fe7 100644 --- a/program/src/program.rs +++ b/program/src/program.rs @@ -1,11 +1,10 @@ -use parser::{Expression}; +use parser::Expression; use parser::parser::ExpressionParser; - use std::fmt; - use std::result::Result; use crate::context::Context; use crate::value::Value; +use crate::eval::Eval; pub struct Program { expr: Expression @@ -31,8 +30,9 @@ impl Program { } } - pub fn execute(&self, context: Context) -> bool { - match Value::from(&self.expr) { + pub fn execute(self, context: Context) -> bool { + let e = Eval::new(context); + match e.eval(self.expr) { Value::Bool(b) => b, _ => panic!("this was not supposed to happen!") } diff --git a/program/src/value.rs b/program/src/value.rs index 6ff70af..2fffcc6 100644 --- a/program/src/value.rs +++ b/program/src/value.rs @@ -12,44 +12,19 @@ pub enum Value { String(Rc), } -impl From<&Atom> for Value { - fn from(atom: &Atom) -> Self { - match atom { - Atom::Int(i) => Value::Int(*i), - Atom::UInt(ui) => Value::UInt(*ui), - Atom::Float(f) => Value::Float(*f), - Atom::Bool(b) => Value::Bool(*b), - Atom::Bytes(b) => Value::Bytes(b.clone()), - Atom::Null => Value::Null, - Atom::String(s) => Value::String(s.clone()), - } +impl std::ops::Mul for Value { + type Output = Value; + + fn mul(self, rhs: Self) -> Self::Output { + todo!() } } -impl<'a> Value { - pub fn from(expr: &'a Expression) -> Value { - match expr { - Expression::Atom(atom) => atom.into(), - Expression::Relation(left, op, right) => { - let left = Value::from(left); - let right = Value::from(right); - let result = match op { - RelationOp::Equals => left.eq(&right), - _ => unimplemented!(), - }; - Value::Bool(result) - } - Expression::Arithmetic(left, op, right) => { - let left = Value::from(left); - let right = Value::from(right); - match op { - ArithmeticOp::Add => left + right, - ArithmeticOp::Subtract => left - right, - _ => todo!(), - } - } - _ => todo!(), - } +impl std::ops::Div for Value { + type Output = Value; + + fn div(self, rhs: Self) -> Self::Output { + todo!() } }