use crate::{ backend::environment::EnvironmentStack, common::{ ast::{AstNode, AstNodeKind, Expr, Stmt}, base_value::{BaseValue, NativeFunction, Number, Truthy}, lox_result::{runtime_error, LoxError, LoxResult}, }, frontend::{source_registry::SourceSlice, tokens::TokenType}, }; use std::fmt::{Debug, Display}; pub struct Interpreter { enviorment: EnvironmentStack, } pub trait EvaluateInterpreter { fn evaluate(&mut self, stmt: T) -> LoxResult; } impl<'a, R: AstNodeKind + Clone + Debug + Display> EvaluateInterpreter> for Interpreter where Interpreter: EvaluateInterpreter, { fn evaluate(&mut self, stmt: AstNode) -> LoxResult { match self.evaluate(stmt.node.clone()) { Ok(value) => Ok(value), Err(err) => runtime_error(stmt.source_slice, err.get_message()), } } } // Direct Expr evaluation to avoid infinite recursion impl EvaluateInterpreter for Interpreter { fn evaluate(&mut self, expr: Expr) -> LoxResult { match expr { Expr::Literal { value } => match value { BaseValue::Function(mut func) => { func.closure = Some(self.enviorment.clone()); println!("Closure created"); println!("current enviorment: {:?}", self.enviorment); Ok(BaseValue::Function(func)) } _ => Ok(value), }, Expr::Identifier { name } => self.enviorment.get(&name), Expr::Binary { left, operator, right, } => { let left_val = self.evaluate(*left)?; let right_val = self.evaluate(*right)?; self.evaluate_binary(left_val, operator, right_val) } Expr::Unary { operator, operand } => { let operand_val = self.evaluate(*operand)?; self.evaluate_unary(operator, operand_val) } Expr::Grouping { expression } => self.evaluate(*expression), Expr::Call { callee, arguments } => self.evaluate_call(callee, arguments), } } } impl EvaluateInterpreter> for Interpreter { fn evaluate(&mut self, node: AstNode) -> LoxResult { let stmt = node.node; let result = self.interpret_stmt_inner(stmt); match result { Ok(value) => Ok(value), Err(LoxError::RuntimeError { message, source_slice, }) if source_slice == SourceSlice::default() => { runtime_error(node.source_slice.clone(), message) } Err(err) => Err(err), } } } impl Interpreter { pub fn new() -> Self { let mut env = EnvironmentStack::new(); let _ = env.declare( "clock".to_string(), BaseValue::NativeFunction(NativeFunction::new(Vec::default(), |_args| { BaseValue::Number(Number::U128( std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_millis(), )) })), ); Self { enviorment: env } } fn evaluate_call( &mut self, callee: Box>, arguments: Vec>, ) -> LoxResult { let source_slice = callee.source_slice.clone(); // Estrai il nome della variabile se il callee è un identificatore let function_name = match &callee.node { Expr::Identifier { name } => Some(name.clone()), _ => None, }; let function = if let Some(name) = function_name { // Se abbiamo un nome di variabile, ottieni la funzione dall'ambiente self.enviorment.get(&name)? } else { // Altrimenti valuta l'espressione callee (per casi più complessi) self.evaluate(*callee)? }; if !function.is_callable() { return runtime_error(source_slice, "Can only call functions"); } let evaluated_arguments = arguments .iter() .map(|arg| self.evaluate(arg.clone())) .collect::, LoxError>>()?; match function { BaseValue::NativeFunction(func) => Ok((func.function)(&evaluated_arguments)), BaseValue::Function(func) => { // Save the current environment let saved_env = self.enviorment.clone(); // If the function captured a closure, use it as the base environment if let Some(closure_env) = func.closure { self.enviorment = closure_env; } // Push a new scope for the function's parameters self.enviorment.push_new_scope(); // Declare parameters in the new scope for (index, par) in func.parameters.iter().enumerate() { let value = evaluated_arguments.get(index).unwrap(); self.enviorment.declare(par.0.clone(), value.clone())?; } // Execute the function body let result = match self.evaluate(func.body) { Ok(value) => Ok(value), Err(LoxError::Return { value, .. }) => Ok(value), Err(err) => Err(err), }; // Restore the original environment (cleanup is automatic) self.enviorment = saved_env; result } _ => runtime_error( source_slice.clone(), "This is callable, but apparently is not implemented", ), } } fn evaluate_binary( &mut self, left: BaseValue, operator: TokenType, right: BaseValue, ) -> LoxResult { match operator { TokenType::Plus => left + right, TokenType::Minus => left - right, TokenType::Star => left * right, TokenType::Slash => left / right, TokenType::Greater => Ok(BaseValue::Boolean(left > right)), TokenType::GreaterEqual => Ok(BaseValue::Boolean(left >= right)), TokenType::Less => Ok(BaseValue::Boolean(left < right)), TokenType::LessEqual => Ok(BaseValue::Boolean(left <= right)), TokenType::EqualEqual => Ok(BaseValue::Boolean(left == right)), TokenType::BangEqual => Ok(BaseValue::Boolean(left != right)), TokenType::And => Ok(BaseValue::Boolean(left.is_truthy() && right.is_truthy())), TokenType::Or => Ok(BaseValue::Boolean(left.is_truthy() || right.is_truthy())), _ => Err(LoxError::RuntimeError { source_slice: SourceSlice::default(), message: format!("Unsupported binary operator: {:?}", operator), }), } } fn evaluate_unary(&mut self, operator: TokenType, operand: BaseValue) -> LoxResult { match operator { TokenType::Minus => match operand { BaseValue::Number(n) => Ok(BaseValue::Number(n.neg())), _ => Err(LoxError::RuntimeError { source_slice: SourceSlice::default(), message: "Cannot negate non-numeric value".to_string(), }), }, TokenType::Bang => Ok(!operand), _ => Err(LoxError::RuntimeError { source_slice: SourceSlice::default(), message: format!("Unsupported unary operator: {:?}", operator), }), } } fn interpret_stmt_inner(&mut self, stmt: Stmt) -> LoxResult { match stmt { Stmt::Expression { expression, .. } => self.evaluate(*expression), Stmt::Print { expression, .. } => { let value = self.evaluate(*expression)?; println!("{}", value); Ok(BaseValue::Nil) } Stmt::Block { statements, .. } => self.evaluate_block(*statements), Stmt::Return { expression, .. } => self.evaluate(*expression), Stmt::VarDeclaration { name, initializer, .. } => { let value = match initializer { Some(expr_node) => self.evaluate(*expr_node)?, None => BaseValue::Nil, }; self.enviorment.declare(name.clone(), value) } Stmt::VarAssigment { name, value, .. } => { let result = self.evaluate(*value)?; self.enviorment.set(name.clone(), result) } Stmt::If { condition, then_branch, elif_branch, else_branch, .. } => self.evaluate_if(condition, then_branch, elif_branch, else_branch), Stmt::While { condition, body, .. } => { let mut ret = BaseValue::Nil; while self.evaluate(*condition.clone())?.is_truthy() { match self.evaluate(*body.clone()) { Ok(val) => ret = val, Err(LoxError::Return { value, .. }) => { ret = value; break; } Err(err) => return Err(err), }; } Ok(ret) } Stmt::For { variable, condition, increment, body, .. } => { let source_slice = variable.source_slice.clone(); let val = self.evaluate(*variable)?; if !matches!(val, BaseValue::Number(..)) { return runtime_error(source_slice, "Expected number literal"); } let mut ret = BaseValue::Nil; while self.evaluate(*condition.clone())?.is_truthy() { match self.evaluate(*body.clone()) { Ok(val) => ret = val, Err(LoxError::Return { value, .. }) => { ret = value; break; } Err(err) => return Err(err), }; self.evaluate(*increment.clone())?; } Ok(ret) } } } fn evaluate_if( &mut self, condition: Box>, then_branch: Box>, elif_branch: Vec<(Box>, Box>)>, else_branch: Option>>, ) -> LoxResult { let condition = self.evaluate(*condition)?; match condition { BaseValue::Boolean(true) => self.evaluate(*then_branch), BaseValue::Boolean(false) => { for (elif_condition, elif_then_branch) in elif_branch { let condition = self.evaluate(*elif_condition)?; match condition { BaseValue::Boolean(true) => { return self.evaluate(*elif_then_branch); } BaseValue::Boolean(false) => continue, _ => { return Err(LoxError::TypeMismatch { source_slice: SourceSlice::default(), // todo change this to the actual source slice expected: "boolean".to_string(), found: condition.to_string(), }); } }; } if let Some(else_block) = else_branch { self.evaluate(*else_block) } else { Ok(BaseValue::Nil) } } _ => Err(LoxError::TypeMismatch { source_slice: SourceSlice::default(), // todo change this to the actual source slice expected: "boolean".to_string(), found: condition.to_string(), }), } } fn evaluate_block(&mut self, statements: Vec>) -> LoxResult { self.enviorment.push_new_scope(); // Ora elements è sempre disponibile let mut result = Ok(BaseValue::Nil); for statement in statements.iter() { let node = statement.node.clone(); match node { Stmt::Return { expression, .. } => { let value = self.evaluate(*expression)?; result = Err(LoxError::Return { source_slice: statement.source_slice.clone(), value: value, return_label: "Hi".to_string(), }); break; } _ => result = self.evaluate((*statement).clone()), }; } self.enviorment.pop_scope(); result } }