use std::{cell::RefCell, rc::Rc}; use crate::{value::Value, lexer::Lexer, parser::Parser, eval::{eval_stmt, eval_expr}, expr::Stmt, env::{EnvRef, Environment}}; pub fn interpret(src: &str, fname: Option, env: Option, repl: bool) -> Result> { let ctx_name = if repl { "" } else { fname.as_ref().map(|s| s.as_ref()).unwrap_or("") }; let mut lexer = Lexer::new(src, fname.clone()); lexer.lex()?; let mut parser = Parser::new(lexer.into_tokens(), repl); let ast = parser.parse()?; let environ; if let Some(env) = env { environ = env; } else { environ = Rc::new(RefCell::new(Environment::new())); } let mut result = Value::Nil; for stmt in ast { if let Stmt::Expr{expr} = stmt { result = eval_expr(&expr, environ.clone()).map_err(|e| e.finish(Some(Rc::from(ctx_name))))?; } else { eval_stmt(&stmt, environ.clone()).map_err(|e| e.as_error().finish(Some(Rc::from(ctx_name))))?; result = Value::Nil; } } Ok(result) }