aboutsummaryrefslogtreecommitdiff
path: root/src/math/expression_function.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/expression_function.rs')
-rw-r--r--src/math/expression_function.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/math/expression_function.rs b/src/math/expression_function.rs
new file mode 100644
index 0000000..20f4816
--- /dev/null
+++ b/src/math/expression_function.rs
@@ -0,0 +1,60 @@
+use std::iter::zip;
+use std::sync::Arc;
+
+use crate::math::{
+ complex::Complex,
+ context::Context,
+ expression::Expression,
+ function::{Function, FunctionArgument, EmptyFunction}
+};
+
+#[derive(Default)]
+pub struct ExpressionFunction {
+ expr: Expression,
+ name: String,
+ args: Vec<String>,
+}
+
+impl ExpressionFunction {
+ pub fn from_string(str: String) -> Self {
+ let str = str.replace(' ', "");
+ let (lhs, expr) = str.split_once('=').unwrap();
+ let (name, a) = lhs.split_once('(').unwrap();
+ let args: Vec<String> = a[0..a.len() - 1]
+ .split(',')
+ .map(|s| s.to_string())
+ .collect();
+ Self {
+ expr: Expression::from_string(expr),
+ name: name.to_string(),
+ args,
+ }
+ }
+
+ pub fn name(&self) -> &str {
+ &self.name
+ }
+
+ pub fn content(&self) -> &str {
+ &self.expr.content()
+ }
+}
+
+impl Function for ExpressionFunction {
+ fn eval(&self, args: FunctionArgument, ctx: &Context) -> Result<Complex, String> {
+ if args.len() == self.args.len() {
+ let mut nctx = ctx.clone();
+ for (n, v) in zip(self.args.iter(), args.data().iter()) {
+ nctx.set_variable(n, *v)
+ }
+ nctx.set_function(self.name(), Arc::new(EmptyFunction {}));
+ self.expr.evaluate(&nctx)
+ } else {
+ Err(format!(
+ "{} takes {} parameters",
+ self.name,
+ self.args.len()
+ ))
+ }
+ }
+}