Files
rlox/src/backend/environment.rs
T

72 lines
1.9 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
use crate::{
common::{
base_value::BaseValue,
lox_result::{runtime_error, LoxResult},
},
frontend::source_registry::SourceSlice,
};
2025-10-06 18:52:32 +02:00
#[derive(Debug, Clone, PartialEq)]
pub struct EnvironmentStack {
stack: Vec<HashMap<String, BaseValue>>,
}
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<BaseValue> {
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 declare(&mut self, name: String, value: BaseValue) -> LoxResult<BaseValue> {
2025-10-06 18:52:32 +02:00
self.stack.last_mut().unwrap().insert(name, value.clone());
Ok(value)
}
pub fn set(&mut self, name: String, value: BaseValue) -> LoxResult<BaseValue> {
2025-10-06 18:52:32 +02:00
let size = self.stack.len();
for i in (0..size).rev() {
if let Some(_) = self.stack[i].get(&name) {
let mut founded = false;
self.stack[i].entry(name.clone()).and_modify(|v| {
*v = value.clone();
founded = true;
});
if founded {
return Ok(value);
}
}
}
runtime_error(
SourceSlice::default(), // todo change this to the actual source slice
format!("Undefined variable '{}'", name),
)
}
}