feat(checker): add environment manager
adapted from Pebble
This commit is contained in:
52
midas/checker/environment.py
Normal file
52
midas/checker/environment.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from midas.checker.types import Type
|
||||
|
||||
|
||||
class Environment:
|
||||
def __init__(self, enclosing: Optional[Environment] = None) -> None:
|
||||
self.enclosing: Optional[Environment] = enclosing
|
||||
self.values: dict[str, Type] = {}
|
||||
|
||||
def define(self, name: str, value: Type):
|
||||
self.values[name] = value
|
||||
|
||||
def get(self, name: str) -> Optional[Type]:
|
||||
if name in self.values:
|
||||
return self.values[name]
|
||||
if self.enclosing is not None:
|
||||
return self.enclosing.get(name)
|
||||
# raise NameError(f"Undefined variable '{name}'")
|
||||
return None
|
||||
|
||||
def assign(self, name: str, value: Type) -> bool:
|
||||
if name not in self.values:
|
||||
if self.enclosing is None:
|
||||
return False
|
||||
if self.enclosing.assign(name, value):
|
||||
return True
|
||||
self.values[name] = value
|
||||
return True
|
||||
|
||||
def clear(self):
|
||||
self.values = {}
|
||||
|
||||
def get_at(self, distance: int, name: str) -> Optional[Type]:
|
||||
return self.ancestor(distance).values.get(name)
|
||||
|
||||
def assign_at(self, distance: int, name: str, value: Type):
|
||||
self.ancestor(distance).values[name] = value
|
||||
|
||||
def ancestor(self, distance: int) -> Environment:
|
||||
env: Environment = self
|
||||
for _ in range(distance):
|
||||
assert env.enclosing is not None
|
||||
env = env.enclosing
|
||||
return env
|
||||
|
||||
def flat_dict(self) -> dict:
|
||||
if self.enclosing is None:
|
||||
return self.values
|
||||
return self.enclosing.flat_dict() | self.values
|
||||
Reference in New Issue
Block a user