diff options
Diffstat (limited to 'src/math/function.rs')
| -rw-r--r-- | src/math/function.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/math/function.rs b/src/math/function.rs new file mode 100644 index 0000000..bd782f3 --- /dev/null +++ b/src/math/function.rs @@ -0,0 +1,68 @@ +use crate::math::{complex::Complex, context::Context}; + +pub struct FunctionArgument { + args : Vec<Complex>, +} + +impl FunctionArgument { + pub fn new(args: Vec<Complex>) -> Self { + Self { args } + } + + pub fn get(&self, i : usize) -> Complex { + self.args[i] + } + + pub fn len(&self) -> usize { + self.args.len() + } + + pub fn is_empty(&self) -> bool { + self.args.len() == 0 + } + + pub fn data(&self) -> &[Complex] { + &self.args + } +} + +pub trait Function { + fn eval(&self, args: FunctionArgument, ctx: &Context) -> Result<Complex, String>; +} + +#[macro_export] +macro_rules! functions { + {$($x:expr => $y:expr), *} => { + { + let mut h : HashMap<String, Arc<dyn Function>> = HashMap::new(); + $( + h.insert($x.to_string(), Arc::new($y)); + )* + h + } + }; +} + + +// Some default implementations +impl<T> Function for T +where + T: Fn(Complex) -> Complex, +{ + fn eval(&self, args: FunctionArgument, _ctx: &Context) -> Result<Complex, String> { + if args.len() == 1 { + Ok(self(args.get(0))) + } else { + Err("too many arguments".to_string()) + } + } +} + + +pub struct EmptyFunction {} + +impl Function for EmptyFunction { + fn eval(&self, _args: FunctionArgument, _ctx: &Context) -> Result<Complex, String> { + Err("function not implemented in this scope".to_string()) + } +} |