class EXPRESSION: pp_count = 0 def __init__(self): self.pp = EXPRESSION.pp_count EXPRESSION.pp_count += 1 @staticmethod def copy(): return EXPRESSION() def allNodes(self): ret = [self] for node in (self.__getattribute__(a) for a in self.__dict__.keys()): if isinstance(node, EXPRESSION): ret += node.allNodes() if isinstance(node, list): for n in node: if isinstance(n, EXPRESSION): ret += n.allNodes() return ret def children(self): """Return a list of (name, childNode).""" out = [] for key, value in self.__dict__.items(): if key == "pp": continue if isinstance(value, EXPRESSION): out.append((key, value)) elif isinstance(value, list): for i, elem in enumerate(value): if isinstance(elem, EXPRESSION): out.append((f"{key}[{i}]", elem)) return out def to_dot(self, out): # node label is class name or class name + value label = type(self).__name__ if hasattr(self, "operator"): # AOP/EQOP/COMP/LOP label += f"({self.operator})" if hasattr(self, "name"): # ID label += f"({self.name})" if hasattr(self, "value"): # CONST label += f"({self.value})" out.write(f' node{self.pp} [label="{label}"];\n') for (edge_name, child) in self.children(): out.write(f' node{self.pp} -> node{child.pp} [label="{edge_name}"];\n') child.to_dot(out) class LET(EXPRESSION): def __init__(self, declarations, body): super().__init__() self.declarations = declarations self.body = body def __str__(self): return "let " + ", ".join(str(d) for d in self.declarations) + " in " + str(self.body) class DECL(EXPRESSION): def __init__(self, f_name, params, body): super().__init__() self.f_name = f_name self.params = params self.body = body def __str__(self): return f"{self.f_name}({self.params}) {{ {self.body} }}" class CALL(EXPRESSION): def __init__(self, f_name, arguments): super().__init__() self.f_name = f_name self.arguments = arguments def __str__(self): return self.f_name + "(" + ",".join(str(a) for a in self.arguments) + ")" class ID(EXPRESSION): def __init__(self, name): super().__init__() self.name = name def __str__(self): return self.name class CONST(EXPRESSION): def __init__(self, value): super().__init__() self.value = value def __str__(self): return str(self.value) class AOP(EXPRESSION): def __init__(self, operator, arg1, arg2): super().__init__() self.operator = operator self.arg1 = arg1 self.arg2 = arg2 def __str__(self): return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" class EQOP(EXPRESSION): def __init__(self, operator, arg1, arg2): super().__init__() self.operator = operator self.arg1 = arg1 self.arg2 = arg2 def __str__(self): return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" class COMP(EXPRESSION): def __init__(self, operator, arg1, arg2): super().__init__() self.operator = operator self.arg1 = arg1 self.arg2 = arg2 def __str__(self): return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" class LOP(EXPRESSION): def __init__(self, operator, arg1, arg2): super().__init__() self.operator = operator self.arg1 = arg1 self.arg2 = arg2 def __str__(self): return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" class ASSIGN(EXPRESSION): def __init__(self, variable, expression): super().__init__() self.variable = variable self.expression = expression def __str__(self): return self.variable.name + " = " + str(self.expression) class SEQ(EXPRESSION): def __init__(self, exp1, exp2): super().__init__() self.exp1 = exp1 self.exp2 = exp2 def __str__(self): return str(self.exp1) + "; " + str(self.exp2) class IF(EXPRESSION): def __init__(self, condition, exp1, exp2): super().__init__() self.condition = condition self.exp1 = exp1 self.exp2 = exp2 def __str__(self): return "if (" + str(self.condition) + ") then { " + str(self.exp1) + " } else { " + str(self.exp2) + " }" class WHILE(EXPRESSION): def __init__(self, condition, body): super().__init__() self.condition = condition self.body = body def __str__(self): return "while (" + str(self.condition) + ") do { " + str(self.body) + " }"