Files
rlox/src/main.rs
T

111 lines
3.2 KiB
Rust
Raw Normal View History

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<String> = env::args().collect();
let mut lox = LoxInterpreter::new();
2025-10-04 19:02:33 +02:00
let _ = if args.len() > 2 {
eprintln!("Usage: {} [script]", args[0]);
std::process::exit(64);
} else if args.len() == 2 {
// Esegui file
2025-10-04 19:02:33 +02:00
lox.run_file(&args[1])
} else {
// Modalità interattiva
2025-10-04 19:02:33 +02:00
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<String> {
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;
2025-10-04 19:02:33 +02:00
for (index, stmt) in stmts.iter().enumerate() {
println!("executing stmt {}: {:?}", index, stmt);
result = Some(interpreter.interpret(stmt.clone())?);
}
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
}
}