Files
rlox/src/backend/environment.rs
T
Giulio Agostini 827349cbad Refactor environment to use stack-based scoping
The commit rewrites the environment to use a stack of hash maps for
managing variable scopes. This replaces the old parent-reference
approach with a simpler and more efficient stack-based model.

Key changes: - Rename Environment to EnvironmentStack - Store scopes in
a Vec of HashMaps - Add push/pop scope operations for block handling -
Update interpreter to properly manage scope lifetimes - Clean up error
handling with helper functions
2025-10-04 21:05:00 +02:00

46 lines
1.1 KiB
Rust

use std::collections::HashMap;
use crate::{
frontend::{source_registry::SourceSlice, tokens::LiteralValue},
result::{runtime_error, LoxResult},
};
#[derive(Debug, Clone)]
pub struct EnvironmentStack {
stack: Vec<HashMap<String, LiteralValue>>,
}
impl EnvironmentStack {
pub fn new() -> Self {
EnvironmentStack {
stack: vec![HashMap::new()],
}
}
pub fn push_new_scope(&mut self) {
self.stack.push(HashMap::new());
}
pub fn pop_scope(&mut self) {
self.stack.pop();
}
pub fn get(&self, name: &str) -> LoxResult<LiteralValue> {
let size = self.stack.len();
for i in (0..size).rev() {
if let Some(value) = self.stack[i].get(name) {
return Ok(value.clone());
}
}
runtime_error(
SourceSlice::default(), // todo change this to the actual source slice
format!("Undefined variable '{}'", name),
)
}
pub fn set(&mut self, name: String, value: LiteralValue) {
self.stack.last_mut().unwrap().insert(name, value);
}
}