diff --git a/auto_editor/lang/palet.py b/auto_editor/lang/palet.py index 21de45232..638a35d5f 100644 --- a/auto_editor/lang/palet.py +++ b/auto_editor/lang/palet.py @@ -765,8 +765,7 @@ def __call__(self, *args: Any) -> Any: largs = list(args) args = tuple([largs[len(self.parms) - 1 :]]) - inner_env = self.env.copy() - inner_env.update(dict(zip(self.parms, args))) + inner_env = Env(dict(zip(self.parms, args)), self.env) for item in self.body[0:-1]: my_eval(inner_env, item) @@ -1158,7 +1157,7 @@ def my_eval(env: Env, node: object) -> Any: # fmt: off -env = Env() +env = Env({}) env.update({ # constants "true": True, diff --git a/auto_editor/lib/data_structs.py b/auto_editor/lib/data_structs.py index e6cb1488c..6b80c955b 100644 --- a/auto_editor/lib/data_structs.py +++ b/auto_editor/lib/data_structs.py @@ -8,33 +8,43 @@ class Env: - __slots__ = "data" + __slots__ = ("data", "outer") - def __init__(self) -> None: - self.data: dict[str, Any] = {} + def __init__(self, data: dict[str, Any], outer: Env | None = None) -> None: + self.data = data + self.outer = outer def __getitem__(self, key: str) -> Any: - return self.data[key] + if key in self.data: + return self.data[key] + if self.outer is not None: + return self.outer[key] def __setitem__(self, key: str, val: Any) -> None: self.data[key] = val def __delitem__(self, key: str) -> None: - del self.data[key] - - def __contains__(self, item: Any) -> bool: - return item in self.data + if key in self.data: + del self.data[key] + elif self.outer is not None: + del self.outer[key] + + def __contains__(self, key: str) -> bool: + if key in self.data: + return True + if self.outer is not None: + return key in self.outer + return False def update(self, my_dict: dict[str, Any]) -> None: self.data.update(my_dict) def get(self, key: str) -> Any: - return self.data.get(key) - - def copy(self) -> Env: - new_env = Env() - new_env.update(self.data.copy()) - return new_env + if key in self.data: + return self.data[key] + if self.outer is not None: + return self.outer.get(key) + return None class Sym: diff --git a/auto_editor/utils/cmdkw.py b/auto_editor/utils/cmdkw.py index d39fffa1d..78d729657 100644 --- a/auto_editor/utils/cmdkw.py +++ b/auto_editor/utils/cmdkw.py @@ -121,11 +121,7 @@ def parse_with_palet( def go(text: str, c: Any) -> Any: try: - if isinstance(_env, Env): - env = _env - else: - env = Env() - env.update(_env) + env = _env if isinstance(_env, Env) else Env(_env) results = interpret(env, Parser(Lexer(build.name, text))) except MyError as e: raise ParserError(e)