Add static variable resolution with scope tracking
- Add distance-based get_at on EnvironmentStack - Add distance-based assign_at on EnvironmentStack - Introduce ErrorSink to accumulate diagnostics across passes - Implement Resolver with a ScopeStack and per-node distance map - Extend interpreter to store locals distances for runtime lookup - Add tests for resolution behavior and error accumulation Add static variable resolution with scope tracking
This commit is contained in:
+21
-1
@@ -15,6 +15,7 @@ use crate::{
|
||||
parser::Parser,
|
||||
source_registry::{SourceId, SourceRegistry},
|
||||
},
|
||||
middleend::variable_resolution::Resolver,
|
||||
};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
@@ -185,7 +186,11 @@ impl LoxInterpreter {
|
||||
|
||||
// Funzione per eseguire l'AST
|
||||
fn execute_ast(&self, ast: Vec<AstNode<Stmt>>, debug: bool) -> LoxResult<String> {
|
||||
// Static resolution pass: compute variable scope distances and report
|
||||
// any resolution errors before executing.
|
||||
let locals = self.resolve(&ast)?;
|
||||
let mut interpreter = Interpreter::new();
|
||||
interpreter.set_locals(locals);
|
||||
let mut result = None;
|
||||
|
||||
for (index, stmt) in ast.iter().enumerate() {
|
||||
@@ -204,6 +209,19 @@ impl LoxInterpreter {
|
||||
}
|
||||
}
|
||||
|
||||
// Static variable resolution; prints and returns the first error, if any.
|
||||
fn resolve(
|
||||
&self,
|
||||
ast: &[AstNode<Stmt>],
|
||||
) -> LoxResult<std::collections::HashMap<crate::common::ast::NodeId, usize>> {
|
||||
Resolver::resolve_program(ast).map_err(|errors| {
|
||||
for err in &errors {
|
||||
err.print_with_context(&self.source_registry);
|
||||
}
|
||||
errors.into_iter().next().unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
fn process_source(
|
||||
&self,
|
||||
source_id: SourceId,
|
||||
@@ -245,8 +263,10 @@ impl LoxInterpreter {
|
||||
return Ok(format_ast(&ast));
|
||||
}
|
||||
|
||||
// Stage 3: Interpretation
|
||||
// Stage 3: Resolution + Interpretation
|
||||
let locals = self.resolve(&ast)?;
|
||||
let mut interpreter = Interpreter::new();
|
||||
interpreter.set_locals(locals);
|
||||
let mut result = None;
|
||||
|
||||
for (index, stmt) in ast.iter().enumerate() {
|
||||
|
||||
Reference in New Issue
Block a user