mod backend; mod frontend; mod logging; mod prompt; mod result; use crate::{ backend::{ environment::Environment, interpreter::{EvaluateInterpreter, Interpreter}, }, frontend::{ lexer::Lexer, parser::Parser, source_registry::{SourceFile, SourceId, SourcePosition, SourceRegistry, SourceSlice}, }, prompt::prompt_lines, result::{LoxError, LoxResult}, }; use std::fs; use std::{env, error::Error}; fn main() -> LoxResult<()> { let args: Vec = env::args().collect(); let mut lox = LoxInterpreter::new(); if args.len() > 2 { eprintln!("Usage: {} [script]", args[0]); std::process::exit(64); } else if args.len() == 2 { // Esegui file lox.run_file(&args[1])?; } else { // Modalità interattiva lox.run_prompt()?; } Ok(()) } struct LoxInterpreter { source_registry: SourceRegistry, } impl LoxInterpreter { pub fn new() -> Self { LoxInterpreter { source_registry: SourceRegistry::new(), } } // ✅ Pipeline funzionale per file fn run_file(&mut self, path: &str) -> LoxResult<()> { fs::read_to_string(path) .map_err(|e| LoxError::IoError { message: e.to_string(), }) .and_then(|source| self.source_registry.add_source_string(source)) .and_then(|source_id| self.process_source(source_id)) .map(|result| println!("file {}", result)) } // ✅ Pipeline funzionale per prompt fn run_prompt(&mut self) -> LoxResult<()> { println!("Lox REPL - Type 'exit' to quit"); prompt_lines(|source| self.source_registry.add_source_string(source)) .for_each(|line| println!("hi: {}", line)); Ok(()) } fn process_source(&self, source_id: SourceId) -> LoxResult { let mut lexer = Lexer::new( self.source_registry.get_by_id(source_id).content.clone(), source_id, ); let res = lexer .scans_tokens() .and_then(|tokens| Parser::new(tokens).parse()) .and_then(|asts| { // println!("asts: {:?}", asts); Ok(asts) }) .and_then(|stmts| { let mut env = Environment::new(); let mut interpreter = Interpreter::new(&mut env); let mut result = None; for stmt in stmts { result = Some(interpreter.interpret(stmt)?); } match result { Some(res) => Ok(res), _ => Err(LoxError::RuntimeError { source_slice: SourceSlice::default(), message: "what?????".to_string(), }), } }) .and_then(|result| Ok(format!("{}", result))) .or_else(|err| { err.print_with_context(&self.source_registry); Err(err) }); // println!("result {}", res); res } }