100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
|
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
|