ganit_core/eval/functions/
mod.rs1pub mod financial;
2pub mod logical;
3pub mod math;
4pub mod statistical;
5pub mod text;
6
7use std::collections::HashMap;
8use crate::eval::context::Context;
9use crate::parser::ast::Expr;
10use crate::types::{ErrorKind, Value};
11
12pub struct EvalCtx<'r> {
17 pub ctx: Context,
18 pub registry: &'r Registry,
19}
20
21impl<'r> EvalCtx<'r> {
22 pub fn new(ctx: Context, registry: &'r Registry) -> Self {
23 Self { ctx, registry }
24 }
25}
26
27pub type EagerFn = fn(&[Value]) -> Value;
32
33pub type LazyFn = fn(&[Expr], &mut EvalCtx<'_>) -> Value;
36
37pub enum FunctionKind {
38 Eager(EagerFn),
39 Lazy(LazyFn),
40}
41
42pub struct Registry {
46 functions: HashMap<String, FunctionKind>,
47}
48
49impl Registry {
50 pub fn new() -> Self {
51 let mut r = Self { functions: HashMap::new() };
52 math::register_math(&mut r);
53 logical::register_logical(&mut r);
54 text::register_text(&mut r);
55 financial::register_financial(&mut r);
56 statistical::register_statistical(&mut r);
57 r
58 }
59
60 pub fn register_eager(&mut self, name: &str, f: EagerFn) {
61 self.functions.insert(name.to_uppercase(), FunctionKind::Eager(f));
62 }
63
64 pub fn register_lazy(&mut self, name: &str, f: LazyFn) {
65 self.functions.insert(name.to_uppercase(), FunctionKind::Lazy(f));
66 }
67
68 pub fn get(&self, name: &str) -> Option<&FunctionKind> {
69 self.functions.get(&name.to_uppercase())
70 }
71}
72
73impl Default for Registry {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79pub fn check_arity(args: &[Value], min: usize, max: usize) -> Option<Value> {
82 if args.len() < min || args.len() > max {
83 Some(Value::Error(ErrorKind::Value))
84 } else {
85 None
86 }
87}
88
89pub fn check_arity_len(count: usize, min: usize, max: usize) -> Option<Value> {
92 if count < min || count > max {
93 Some(Value::Error(ErrorKind::Value))
94 } else {
95 None
96 }
97}