aboutsummaryrefslogtreecommitdiff
path: root/src/math/function.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/function.rs')
-rw-r--r--src/math/function.rs68
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())
+ }
+}