From 52e4dfc10616accaa6e4dcdbfc4a706e94dbcdc9 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Fri, 19 Jan 2024 19:06:09 +0100 Subject: math: pregenerate eval tree --- src/math/function.rs | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/math/function.rs') diff --git a/src/math/function.rs b/src/math/function.rs index bd782f3..93d288c 100644 --- a/src/math/function.rs +++ b/src/math/function.rs @@ -1,33 +1,51 @@ -use crate::math::{complex::Complex, context::Context}; +use super::expression::Expression; +use super::{complex::Complex, context::Context}; + +enum FunctionArgumentType { + ExpressionArgument(Vec), + ValueArgument(Vec), +} pub struct FunctionArgument { - args : Vec, + args: FunctionArgumentType, + len: usize, } impl FunctionArgument { - pub fn new(args: Vec) -> Self { - Self { args } + pub fn from_expressions(args: Vec) -> Self { + Self { + len: args.len(), + args: FunctionArgumentType::ExpressionArgument(args), + } } - pub fn get(&self, i : usize) -> Complex { - self.args[i] + pub fn from_values(args: Vec) -> Self { + Self { + len: args.len(), + args: FunctionArgumentType::ValueArgument(args), + } } pub fn len(&self) -> usize { - self.args.len() + self.len } pub fn is_empty(&self) -> bool { - self.args.len() == 0 + self.len == 0 } - pub fn data(&self) -> &[Complex] { - &self.args + pub fn eval_args(&self, ctx: &Context) -> Result, String> { + match &self.args { + FunctionArgumentType::ExpressionArgument(args) => { + args.iter().map(|a| a.evaluate(ctx)).collect() + } + FunctionArgumentType::ValueArgument(args) => Ok(args.to_vec()), + } } } pub trait Function { - fn eval(&self, args: FunctionArgument, ctx: &Context) -> Result; + fn eval(&self, args: &FunctionArgument, ctx: &Context) -> Result; } #[macro_export] @@ -43,26 +61,27 @@ macro_rules! functions { }; } - // Some default implementations impl Function for T where T: Fn(Complex) -> Complex, { - fn eval(&self, args: FunctionArgument, _ctx: &Context) -> Result { + fn eval(&self, args: &FunctionArgument, ctx: &Context) -> Result { if args.len() == 1 { - Ok(self(args.get(0))) + match args.eval_args(ctx) { + Ok(args) => Ok(self(args[0])), + Err(e) => Err(e), + } } else { Err("too many arguments".to_string()) } } } - pub struct EmptyFunction {} impl Function for EmptyFunction { - fn eval(&self, _args: FunctionArgument, _ctx: &Context) -> Result { + fn eval(&self, _args: &FunctionArgument, _ctx: &Context) -> Result { Err("function not implemented in this scope".to_string()) } } -- cgit v1.2.3-70-g09d2