feat(interpreter): add enclosing environment parameter

This commit is contained in:
2026-02-05 23:29:20 +01:00
parent 059798e157
commit f2e996aaa9
2 changed files with 37 additions and 23 deletions

View File

@@ -0,0 +1,34 @@
from __future__ import annotations
from typing import Any, Optional
from src.interpreter.error import PebbleRuntimeError
from src.token import Token
class Environment:
def __init__(self, enclosing: Optional[Environment] = None):
self.enclosing: Optional[Environment] = enclosing
self.values: dict[str, Any] = {}
def define(self, name: str, value: Any):
self.values[name] = value
def get(self, name: Token) -> Any:
try:
return self.values[name.lexeme]
except IndexError:
if self.enclosing is not None:
return self.enclosing.get(name)
raise PebbleRuntimeError(name, f"Undefined variable '{name.lexeme}'.")
def assign(self, name: Token, value: Any):
if name.lexeme not in self.values:
if self.enclosing is not None:
self.enclosing.assign(name, value)
return
raise PebbleRuntimeError(name, f"Undefined variable '{name.lexeme}'.")
self.values[name.lexeme] = value
def clear(self):
self.values = {}

View File

@@ -1,36 +1,16 @@
from typing import Any
from src.ast.expr import LiteralExpr, GroupingExpr, UnaryExpr, BinaryExpr, Expr, VariableExpr, AssignExpr
from src.ast.stmt import Stmt, PrintStmt, T, ExpressionStmt, LetStmt
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt
from src.interpreter.environment import Environment
from src.interpreter.error import PebbleRuntimeError
from src.pebble import Pebble
from src.token import TokenType, Token
class Interpreter(Expr.Visitor[Any], Stmt.Visitor[None]):
class Environment:
def __init__(self):
self.values: dict[str, Any] = {}
def define(self, name: str, value: Any):
self.values[name] = value
def get(self, name: Token) -> Any:
try:
return self.values[name.lexeme]
except IndexError:
raise PebbleRuntimeError(name, f"Undefined variable '{name.lexeme}'.")
def assign(self, name: Token, value: Any):
if name.lexeme not in self.values:
raise PebbleRuntimeError(name, f"Undefined variable '{name.lexeme}'.")
self.values[name.lexeme] = value
def clear(self):
self.values = {}
def __init__(self):
self.env: Interpreter.Environment = Interpreter.Environment()
self.env: Environment = Environment()
def interpret(self, statements: list[Stmt]) -> None:
self.env.clear()