69 lines
2 KiB
Rust
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
|
|
}
|
|
}
|