Initialize Rust implementation of Lox interpreter
This initial commit sets up the basic structure for a Rust implementation of the Lox interpreter, including: - Lexer for tokenizing source code - Parser for building AST - Basic interpreter functionality - Environment for variable storage The core components include source tracking, error handling, and basic expression evaluation.
This commit is contained in:
+109
@@ -0,0 +1,109 @@
|
||||
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();
|
||||
|
||||
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<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;
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user