openbirch-rs/src/lib/node/function.rs
2025-02-24 15:26:49 +01:00

69 lines
2 KiB
Rust

use std::rc::Rc;
use crate::environment::Environment;
use super::{symbol::Symbol, Node, NodeEnum, Precedence};
pub type NativeFunctionType =
fn(&Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>, String>;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum FunctionType {
Native(&'static str, NativeFunctionType),
UserFunction(Rc<NodeEnum>, Vec<Symbol>),
}
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Function {
function: FunctionType,
}
impl Node for Function {
fn evaluate(&self, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
Ok(Rc::new(self.clone().into()))
// Ok(Rc::new(
// Self {
// function: match &self.function {
// FunctionType::Native(_, _) => self.function.clone(),
// FunctionType::UserFunction(node_enum, symbols) => {
// env.disable_calls();
// let evaluated = node_enum.evaluate(env)?;
// env.enable_calls();
// FunctionType::UserFunction(evaluated, symbols.clone())
// }
// },
// }
// .into(),
// ))
}
fn as_string(&self, env: Option<&Environment>) -> String {
match &self.function {
FunctionType::Native(name, _) => format!("(Native Function `{name}`)"),
FunctionType::UserFunction(body, args) => format!(
"([{}] -> {})",
args.iter()
.map(|x| x.as_string(env))
.reduce(|acc, e| format!("{acc}, {e}"))
.unwrap_or("[]".to_owned()),
body.as_string(env)
),
}
}
fn precedence(&self) -> Precedence {
Precedence::Call
}
}
impl Function {
pub fn new(t: FunctionType) -> Rc<NodeEnum> {
Rc::new(Self { function: t }.into())
}
pub fn get_body(&self) -> &FunctionType {
&self.function
}
}