From 311d3ae9a3b0a014e14e885ddbdf35a6c1cfd3ce Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Thu, 30 May 2024 23:50:59 -0700 Subject: Add bytecode. A recursive AST is kind of annoying to evaluate without recursion. Bytecode is cooler anyway. --- src/op.rs | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/op.rs (limited to 'src/op.rs') diff --git a/src/op.rs b/src/op.rs new file mode 100644 index 0000000..6a2d00f --- /dev/null +++ b/src/op.rs @@ -0,0 +1,93 @@ +use crate::eval::Num; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UnOp { + Neg, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Sqrt, + Log, + Log10, + Log2, + Floor, + Ceil, + Round, + Abs, +} + +impl UnOp { + 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(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum BinOp { + Pow, + Mul, + Div, + IntDiv, + Mod, + Add, + Sub, +} + +impl BinOp { + 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), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Op { + Num(Num), + Un(UnOp), + Bin(BinOp), +} + +pub fn eval(ops: &[Op]) -> Num { + let mut stack = Vec::new(); + for op in ops { + match op { + Op::Num(n) => stack.push(*n), + Op::Un(op) => { + let n = stack.pop().unwrap(); + stack.push(op.eval(n)); + } + Op::Bin(op) => { + let n2 = stack.pop().unwrap(); + let n1 = stack.pop().unwrap(); + stack.push(op.eval(n1, n2)); + } + } + } + stack[0] +} -- cgit v1.3.1