diff --git a/src/interpreter/interpretable.rs b/src/interpreter/interpretable.rs index 43ef08b..1edb826 100644 --- a/src/interpreter/interpretable.rs +++ b/src/interpreter/interpretable.rs @@ -7,6 +7,8 @@ use crate::{ tokens::{Token, TokenType}, }; +use super::functions::Function; + /// Evaluate an interpretable, returning its value. pub fn evaluate(err_hdl: &mut ErrorHandler, ast: &dyn Interpretable) -> Option { let env = Rc::new(RefCell::new(Environment::default())); @@ -89,9 +91,12 @@ impl Interpretable for ast::ProgramNode { impl Interpretable for ast::StmtNode { fn interpret(&self, environment: &EnvironmentRef) -> InterpreterResult { match self { + ast::StmtNode::VarDecl(name, expr) => self.on_var_decl(environment, name, expr), + ast::StmtNode::FunDecl { name, params, body } => { + self.on_fun_decl(environment, name, params, body) + } ast::StmtNode::Expression(expr) => expr.interpret(environment), ast::StmtNode::Print(expr) => self.on_print(environment, expr), - ast::StmtNode::VarDecl(name, expr) => self.on_var_decl(environment, name, expr), ast::StmtNode::Block(statements) => self.on_block(environment, statements), ast::StmtNode::IfStmt { condition, @@ -143,6 +148,21 @@ impl ast::StmtNode { Ok(InterpreterFlowControl::default()) } + /// Handle a function declaration. + fn on_fun_decl( + &self, + environment: &EnvironmentRef, + name: &Token, + params: &Vec, + body: &Vec, + ) -> InterpreterResult { + let fun = Function::new(name, params, body); + environment + .borrow_mut() + .define(name, Some(Value::Callable(fun)))?; + Ok(InterpreterFlowControl::default()) + } + /// Execute the contents of a block. fn on_block(&self, environment: &EnvironmentRef, stmts: &[ast::StmtNode]) -> InterpreterResult { let child = Environment::create_child(environment);