from xml.etree import ElementTree as ET from constants import GAZ_VAR_TAG, GAZ_ARG_TAG class Variable: def __init__(self, name: str, type: str, qualifier: str, value: any = None): self.name = name self.type = type self.value = value self.qualifier = qualifier self.xml = self._build_xml() def _build_xml(self): args = [ ('name', self.name), ('type', self.type), ('mut', self.qualifier), ] return build_xml_element(args, name=GAZ_VAR_TAG) class Argument: def __init__(self, name: str, type: str): self.name = name self.type = type self.xml = self._build_xml() def __str__(self): return self.type + " " + self.name def _build_xml(self): args = [ ('name', self.name), ('type', self.type), ] return build_xml_element(args, name=GAZ_ARG_TAG) class Routine: def __init__(self, name: str, type: str, return_type: str, args: list[Argument], xml: ET.Element = None): self.name = name self.type = type self.return_type = return_type self.arguments = args self.xml = xml self.xml = xml class Scope: def __init__(self, enclosing_scope, child_scope=None, associated_xml: ET.Element = None): self.symbols = {} self.enclosing_scope = enclosing_scope self.child_scope = child_scope self.xml = associated_xml def resolve(self, name) -> ET.Element or None: if name in self.symbols: return self.symbols[name] else: return None def append(self, name, item: Variable or Argument or Routine): self.symbols[name] = item def append_element(self, name, value: ET.Element): self.symbols[name] = value def set(self, name, value: ET.Element): self.symbols[name] = value def get_all_defined_mutable_vars(self) -> list[Variable]: if self.enclosing_scope is None: return self._get_mutable_vars() else: return self.enclosing_scope.get_all_defined_mutable_vars() + self._get_mutable_vars() def _get_mutable_vars(self) -> list[Variable]: mutable_vars = [] for name, var in self.symbols.items(): if not isinstance(var, Variable): continue if var.qualifier != 'const': mutable_vars.append(self.symbols[name]) return mutable_vars def get_top_scope(self): if self.enclosing_scope is None: return self else: return self.enclosing_scope.get_top_scope() def build_xml_element(*keys, name): elem = ET.Element(name) for key in list(keys)[0]: # TODO refactor elem.set(key[0], key[1]) return elem