From 5e88902a161674605c6835c7be96d412d82e7dd4 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Thu, 30 May 2024 20:00:08 -0700 Subject: Write tests for parser. --- src/expr.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/expr.rs (limited to 'src/expr.rs') diff --git a/src/expr.rs b/src/expr.rs new file mode 100644 index 0000000..1022de4 --- /dev/null +++ b/src/expr.rs @@ -0,0 +1,106 @@ +use crate::eval::Num; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum BinOp { + Pow, + Mul, + Div, + IntDiv, + Mod, + Add, + Sub, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UnOp { + Neg, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Sqrt, + Log, + Log10, + Log2, + Floor, + Ceil, + Round, + Abs, +} + +#[derive(Debug, PartialEq)] +pub enum Expr { + Num(Num), + UnOp { + op: UnOp, + x: Box, + }, + BinOp { + op: BinOp, + x: Box, + y: Box, + }, +} + +impl BinOp { + pub fn expr(self, x: Expr, y: Expr) -> Expr { + Expr::BinOp { + op: self, + x: Box::new(x), + y: Box::new(y), + } + } + + fn eval(self, x: Num, y: Num) -> Num { + match self { + BinOp::Pow => x.pow(y), + BinOp::Mul => x.mul(y), + BinOp::Div => x.div(y), + BinOp::IntDiv => x.int_div(y), + BinOp::Mod => x.modulo(y), + BinOp::Add => x.add(y), + BinOp::Sub => x.sub(y), + } + } +} + +impl UnOp { + pub fn expr(self, x: Expr) -> Expr { + Expr::UnOp { + op: self, + x: Box::new(x), + } + } + + fn eval(self, x: Num) -> Num { + match self { + UnOp::Neg => Num::Int(0).sub(x), + UnOp::Sin => x.sin(), + UnOp::Cos => x.cos(), + UnOp::Tan => x.tan(), + UnOp::Asin => x.asin(), + UnOp::Acos => x.acos(), + UnOp::Atan => x.atan(), + UnOp::Sqrt => x.sqrt(), + UnOp::Log => x.log(), + UnOp::Log10 => x.log10(), + UnOp::Log2 => x.log2(), + UnOp::Floor => x.floor(), + UnOp::Ceil => x.ceil(), + UnOp::Round => x.round(), + UnOp::Abs => x.abs(), + } + } +} + +impl Expr { + pub fn eval(&self) -> Num { + match self { + Expr::Num(n) => *n, + Expr::UnOp { op, x } => op.eval(x.eval()), + Expr::BinOp { op, x, y } => op.eval(x.eval(), y.eval()), + } + } +} -- cgit v1.3.1