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
This commit is contained in:
Giulio Agostini
2025-10-04 21:05:00 +02:00
parent 41253e932a
commit 827349cbad
11 changed files with 165 additions and 243 deletions
+3 -25
View File
@@ -3,10 +3,7 @@
//! This module provides elegant and functional printing capabilities for AST objects,
//! inspired by Rust's debug formatting but optimized for readability and analysis.
use crate::frontend::{
ast::{AstNode, AstNodeKind, Expr, Stmt},
source_registry::SourceSlice,
};
use crate::frontend::ast::{AstNode, AstNodeKind, Expr, Stmt};
use std::fmt::{self, Write};
/// Configuration for pretty printing output
@@ -39,6 +36,7 @@ impl Default for PrettyConfig {
}
}
#[allow(dead_code)]
impl PrettyConfig {
/// Create a compact configuration
pub fn compact() -> Self {
@@ -471,6 +469,7 @@ impl<T: AstNodeKind + fmt::Debug + fmt::Display + PrettyPrint> PrettyPrint for A
}
// Extension trait for convenience methods
#[allow(dead_code)]
pub trait PrettyPrintExt {
fn pretty(&self) -> String;
fn pretty_compact(&self) -> String;
@@ -531,24 +530,3 @@ impl<T: AstNodeKind + fmt::Debug + fmt::Display + PrettyPrint> PrettyPrintExt fo
pretty_print_with_config(self, config)
}
}
/// Convenience functions for quick pretty printing
pub fn pretty_expr(expr: &Expr) -> String {
pretty_print(expr)
}
pub fn pretty_stmt(stmt: &Stmt) -> String {
pretty_print(stmt)
}
pub fn pretty_expr_compact(expr: &Expr) -> String {
pretty_print_with_config(expr, &PrettyConfig::compact())
}
pub fn pretty_stmt_compact(stmt: &Stmt) -> String {
pretty_print_with_config(stmt, &PrettyConfig::compact())
}
pub fn pretty_tree<T: PrettyPrint>(item: &T) -> String {
pretty_print_with_config(item, &PrettyConfig::tree())
}
+4 -41
View File
@@ -3,11 +3,7 @@
//! This module provides elegant and functional printing capabilities for Token objects,
//! inspired by Rust's debug formatting but optimized for readability and analysis.
use crate::frontend::{
source_registry::SourceSlice,
tokens::{LiteralValue, Token, TokenType},
};
use std::fmt;
use crate::frontend::tokens::{Token, TokenType};
/// Configuration for pretty printing tokens
#[derive(Clone, Debug)]
@@ -199,12 +195,12 @@ impl Token {
TokenType::Var => "VAR",
TokenType::Val => "VAL",
TokenType::Eof => "EOF",
TokenType::In => "IN",
}
}
fn colored_type(&self) -> String {
let (color_code, symbol) = match self.token_type {
// Operators - Red
TokenType::Plus
| TokenType::Minus
| TokenType::Star
@@ -218,8 +214,6 @@ impl Token {
| TokenType::GreaterEqual
| TokenType::Less
| TokenType::LessEqual => ("\x1b[31m", self.token_type_symbol()),
// Keywords - Blue
TokenType::And
| TokenType::Class
| TokenType::False
@@ -239,13 +233,9 @@ impl Token {
| TokenType::This
| TokenType::Var
| TokenType::Val => ("\x1b[34m", self.token_type_symbol()),
// Literals - Green
TokenType::Identifier | TokenType::String | TokenType::Number => {
("\x1b[32m", self.token_type_symbol())
}
// Punctuation - Gray
TokenType::LeftParen
| TokenType::RightParen
| TokenType::LeftBrace
@@ -255,12 +245,9 @@ impl Token {
| TokenType::Comma
| TokenType::Dot
| TokenType::Semicolon => ("\x1b[37m", self.token_type_symbol()),
// Block delimiters - Magenta
TokenType::StartBlock | TokenType::EndBlock => ("\x1b[35m", self.token_type_symbol()),
// EOF - Yellow
TokenType::Eof => ("\x1b[33m", self.token_type_symbol()),
TokenType::In => ("\x1b[36m", self.token_type_symbol()),
};
format!("{}{}\x1b[0m", color_code, symbol)
@@ -298,6 +285,7 @@ pub fn pretty_print_tokens(tokens: &[Token], config: &TokenPrettyConfig) -> Stri
}
/// Extension trait for convenience methods
#[allow(dead_code)]
pub trait TokenPrettyPrintExt {
fn pretty(&self) -> String;
fn pretty_compact(&self) -> String;
@@ -358,28 +346,3 @@ impl TokenPrettyPrintExt for Vec<Token> {
pretty_print_tokens(self, config)
}
}
/// Convenience functions for quick pretty printing
pub fn pretty_token(token: &Token) -> String {
token.pretty()
}
pub fn pretty_token_compact(token: &Token) -> String {
token.pretty_compact()
}
pub fn pretty_token_minimal(token: &Token) -> String {
token.pretty_minimal()
}
pub fn pretty_tokens(tokens: &[Token]) -> String {
pretty_print_tokens(tokens, &TokenPrettyConfig::default())
}
pub fn pretty_tokens_compact(tokens: &[Token]) -> String {
pretty_print_tokens(tokens, &TokenPrettyConfig::compact())
}
pub fn pretty_tokens_colored(tokens: &[Token]) -> String {
pretty_print_tokens(tokens, &TokenPrettyConfig::colored())
}