aboutsummaryrefslogtreecommitdiff
path: root/src/math/function.rs
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-01-19 19:06:09 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2024-01-19 19:06:09 +0100
commit52e4dfc10616accaa6e4dcdbfc4a706e94dbcdc9 (patch)
tree3f6c7d7886774f1c10b77e7782b071aca7d4d31a /src/math/function.rs
parent22c656d0be6dd5356f8839fae716174a9fe474c7 (diff)
math: pregenerate eval tree
Diffstat (limited to 'src/math/function.rs')
-rw-r--r--src/math/function.rs51
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())
}
}