diff options
Diffstat (limited to 'src/math/function.rs')
| -rw-r--r-- | src/math/function.rs | 51 |
1 files changed, 35 insertions, 16 deletions
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<Expression>), + ValueArgument(Vec<Complex>), +} pub struct FunctionArgument { - args : Vec<Complex>, + args: FunctionArgumentType, + len: usize, } impl FunctionArgument { - pub fn new(args: Vec<Complex>) -> Self { - Self { args } + pub fn from_expressions(args: Vec<Expression>) -> 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<Complex>) -> 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<Vec<Complex>, 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<Complex, String>; + fn eval(&self, args: &FunctionArgument, ctx: &Context) -> Result<Complex, String>; } #[macro_export] @@ -43,26 +61,27 @@ macro_rules! functions { }; } - // Some default implementations impl<T> Function for T where T: Fn(Complex) -> Complex, { - fn eval(&self, args: FunctionArgument, _ctx: &Context) -> Result<Complex, String> { + fn eval(&self, args: &FunctionArgument, ctx: &Context) -> Result<Complex, String> { 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<Complex, String> { + fn eval(&self, _args: &FunctionArgument, _ctx: &Context) -> Result<Complex, String> { Err("function not implemented in this scope".to_string()) } } |