Files
rlox/src/result.rs
T
Giulio Agostini a7df45dc72 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.
2025-10-03 19:07:12 +02:00

154 lines
4.7 KiB
Rust

use crate::frontend::source_registry::{SourcePosition, SourceRegistry, SourceSlice};
#[derive(Debug, Clone)]
pub enum LoxError {
LexicalError {
source_slice: SourceSlice,
message: String,
},
RuntimeError {
source_slice: SourceSlice,
message: String,
},
ParseError {
source_slice: SourceSlice,
message: String,
},
IoError {
message: String,
},
TypeMismatch {
source_slice: SourceSlice,
expected: String,
found: String,
},
}
impl LoxError {
pub fn get_message(&self) -> String {
match self {
LoxError::LexicalError { message, .. } => message.clone(),
LoxError::RuntimeError { message, .. } => message.clone(),
LoxError::ParseError { message, .. } => message.clone(),
LoxError::IoError { message } => message.clone(),
LoxError::TypeMismatch {
expected, found, ..
} => {
format!("expected {}, found {}", expected, found)
}
}
}
pub fn get_source_slice(&self) -> Option<SourceSlice> {
match self {
LoxError::LexicalError { source_slice, .. } => Some(source_slice.clone()),
LoxError::RuntimeError { source_slice, .. } => Some(source_slice.clone()),
LoxError::ParseError { source_slice, .. } => Some(source_slice.clone()),
LoxError::IoError { .. } => None,
LoxError::TypeMismatch { source_slice, .. } => Some(source_slice.clone()),
}
}
pub fn print_with_context(&self, source_registry: &SourceRegistry) {
match self.get_source_slice() {
Some(source_slice) => {
let source_code = source_registry.get_source_code(&source_slice);
println!(
"\n =============================================== \n DATA:{} \n CODE \n {} | {}",
self, source_slice.start_position.line ,source_code
);
}
None => println!("{}", self),
}
}
}
fn fetch_source_code(path: &str, start: SourcePosition, end: SourcePosition) -> LoxResult<String> {
let source_code = std::fs::read_to_string(path).map_err(|e| LoxError::IoError {
message: format!("Failed to read file: {}", e),
})?;
let lines: Vec<&str> = source_code.split('\n').collect();
// Verifica bounds
if start.line >= lines.len() || end.line >= lines.len() {
return Err(LoxError::IoError {
message: "Line number out of bounds".to_string(),
});
}
let mut result = String::new();
if start.line == end.line {
// Caso speciale: stessa riga
let line = lines[start.line];
if end.column <= line.len() && start.column <= end.column {
result.push_str(&line[start.column..end.column]);
}
} else {
// Caso generale: righe multiple
// Prima riga: da start.column alla fine della riga
let first_line = lines[start.line];
if start.column < first_line.len() {
result.push_str(&first_line[start.column..]);
}
result.push('\n');
// Righe intermedie: complete
for i in (start.line + 1)..end.line {
result.push_str(lines[i]);
result.push('\n');
}
// Ultima riga: dall'inizio fino a end.column
let last_line = lines[end.line];
if end.column <= last_line.len() {
result.push_str(&last_line[..end.column]);
}
}
Ok(result)
}
impl std::fmt::Display for LoxError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LoxError::LexicalError {
source_slice,
message,
} => {
write!(f, "Lexical error on {:?}: \n {}", source_slice, message)
}
LoxError::RuntimeError {
source_slice,
message,
} => {
write!(f, "Runtime error on {:?}: \n{}", source_slice, message)
}
LoxError::ParseError {
source_slice,
message,
} => {
write!(f, "Parse error on {:?}: \n{}", source_slice, message)
}
LoxError::IoError { message } => write!(f, "IO error: {}", message),
LoxError::TypeMismatch {
source_slice,
expected,
found,
} => {
write!(
f,
"Type mismatch on {:?}: \n expected {}, found {}",
source_slice, expected, found
)
}
}
}
}
impl std::error::Error for LoxError {}
pub type LoxResult<T> = Result<T, LoxError>;