Initial commit - fix problems & refactor code
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
from typing import Any, Callable, Optional
|
||||
from string import whitespace
|
||||
|
||||
from core.primitives.symbol import symbolKey, isSymbol
|
||||
from core.printer import Representation
|
||||
from core.primitives.list import NIL
|
||||
|
||||
class Environment:
|
||||
"""Environment for variable bindings with lexical scoping."""
|
||||
|
||||
frame: dict[str, Any]
|
||||
parent: Environment | None
|
||||
|
||||
def __init__(self, parent: Environment | None) -> None:
|
||||
self.frame: dict[str, Any] = {}
|
||||
self.parent: Environment | None = parent
|
||||
|
||||
def add(self, symbol_key: Any, value: Any) -> None:
|
||||
"""Add a new binding to the current environment frame."""
|
||||
self.frame[symbolKey(symbol_key)] = value
|
||||
|
||||
def set(self, symbol_key: Any, value: Any) -> None:
|
||||
"""Set a binding in the environment chain."""
|
||||
key: str = symbolKey(symbol_key)
|
||||
currentEnvironment: Environment = self
|
||||
while currentEnvironment is not None:
|
||||
if key in currentEnvironment.frame:
|
||||
currentEnvironment.frame[key] = value
|
||||
return
|
||||
assert currentEnvironment is Environment
|
||||
currentEnvironment = currentEnvironment.parent
|
||||
raise SyntaxError(f"no such symbol: {key}")
|
||||
|
||||
def get(self, symbol_key: Any) -> Any:
|
||||
"""Get a binding from the environment chain."""
|
||||
key: str = symbolKey(symbol_key)
|
||||
currentEnvironment: Environment | None = self
|
||||
while currentEnvironment is not None:
|
||||
if key in currentEnvironment.frame:
|
||||
return currentEnvironment.frame[key]
|
||||
currentEnvironment = currentEnvironment.parent
|
||||
return symbol_key
|
||||
|
||||
EVAL_NIL: Callable[[], Any] = lambda: NIL
|
||||
ENV: Environment = Environment(None)
|
||||
|
||||
MEANINGFUL: str = "\"();'"
|
||||
IGNORE: str = whitespace + ","
|
||||
|
||||
RepresentateAST: Callable[[Any], str] = lambda value: (
|
||||
value if type(value) is str and not isSymbol(value) else Representation(value)
|
||||
)
|
||||
TCO: bool = True
|
||||
Reference in New Issue
Block a user