Finish main task, start refactoring
This commit is contained in:
@@ -1,132 +1,190 @@
|
||||
|
||||
# (c) Stephan Diehl, University of Trier, Germany, 2025
|
||||
|
||||
class EXPRESSION:
|
||||
ppcount=0
|
||||
pp_count = 0
|
||||
|
||||
def __init__(self):
|
||||
self.pp=EXPRESSION.ppcount
|
||||
EXPRESSION.ppcount=EXPRESSION.ppcount+1
|
||||
self.pp = EXPRESSION.pp_count
|
||||
EXPRESSION.pp_count += 1
|
||||
|
||||
def copy(self):
|
||||
@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 = ret + node.allNodes()
|
||||
ret += node.allNodes()
|
||||
if isinstance(node, list):
|
||||
for n in node:
|
||||
if isinstance(n, EXPRESSION):
|
||||
ret = ret + n.allNodes()
|
||||
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
|
||||
self.declarations = declarations
|
||||
self.body = body
|
||||
|
||||
def __str__(self): return "let " \
|
||||
+','.join([ str(decl) for decl in self.declarations ]) \
|
||||
+ " in " + str(self.body)
|
||||
def __str__(self):
|
||||
return "let " + ", ".join(str(d) for d in self.declarations) + " in " + str(self.body)
|
||||
|
||||
class DECL(EXPRESSION):
|
||||
def __init__(self, fname, params, body):
|
||||
self.fname=fname
|
||||
self.params=params
|
||||
self.body=body
|
||||
def __init__(self, f_name, params, body):
|
||||
super().__init__()
|
||||
self.f_name = f_name
|
||||
self.params = params
|
||||
self.body = body
|
||||
|
||||
def __str__(self): return self.fname+"(" \
|
||||
+','.join([ str(param) for param in self.params ]) \
|
||||
+"){ "+str(self.body)+" }"
|
||||
def __str__(self):
|
||||
return f"{self.f_name}(" + ",".join(str(p) for p in self.params) + ") { " + str(self.body) + " }"
|
||||
|
||||
class CALL(EXPRESSION):
|
||||
def __init__(self, fname, arguments):
|
||||
def __init__(self, f_name, arguments):
|
||||
super().__init__()
|
||||
self.fname=fname
|
||||
self.arguments=arguments
|
||||
self.f_name = f_name
|
||||
self.arguments = arguments
|
||||
|
||||
def __str__(self): return self.fname+"(" \
|
||||
+','.join([ str(arg) for arg in self.arguments ]) +")"
|
||||
def __str__(self):
|
||||
return self.f_name + "(" + ",".join(str(a) for a in self.arguments) + ")"
|
||||
|
||||
|
||||
class VAR(EXPRESSION):
|
||||
def __init__(self,name):
|
||||
class ID(EXPRESSION):
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self.name=name
|
||||
self.name = name
|
||||
|
||||
def __str__(self): return self.name
|
||||
|
||||
class BINOP(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)+self.operator+str(self.arg2)+")"
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class CONST(EXPRESSION):
|
||||
def __init__(self,value):
|
||||
def __init__(self, value):
|
||||
super().__init__()
|
||||
self.value=value
|
||||
self.value = value
|
||||
|
||||
def __str__(self): return str(self.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
|
||||
self.variable = variable
|
||||
self.expression = expression
|
||||
|
||||
def __str__(self): return self.variable.name+"="+str(self.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
|
||||
self.exp1 = exp1
|
||||
self.exp2 = exp2
|
||||
|
||||
def __str__(self): return str(self.exp1)+";"+str(self.exp2)
|
||||
def __str__(self):
|
||||
return str(self.exp1) + "; " + str(self.exp2)
|
||||
|
||||
class IF(EXPRESSION):
|
||||
def __init__(self,condition,exp1,exp2):
|
||||
def __init__(self, condition, exp1, exp2):
|
||||
super().__init__()
|
||||
self.condition=condition
|
||||
self.exp1=exp1
|
||||
self.exp2=exp2
|
||||
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 DO(EXPRESSION):
|
||||
def __init__(self,body,condition):
|
||||
super().__init__()
|
||||
self.body=body
|
||||
self.condition=condition
|
||||
|
||||
def __str__(self): return "do { "+str(self.body)+" } while "+str(self.condition)
|
||||
def __str__(self):
|
||||
return "if (" + str(self.condition) + ") then { " + str(self.exp1) + " } else { " + str(self.exp2) + " }"
|
||||
|
||||
class WHILE(EXPRESSION):
|
||||
def __init__(self,condition,body):
|
||||
def __init__(self, condition, body):
|
||||
super().__init__()
|
||||
self.condition=condition
|
||||
self.body=body
|
||||
self.condition = condition
|
||||
self.body = body
|
||||
|
||||
def __str__(self): return "while "+str(self.condition)+" do { "+str(self.body)+" }"
|
||||
|
||||
# see https://stackoverflow.com/questions/51753937/python-pretty-print-nested-objects
|
||||
def __str__(self):
|
||||
return "while (" + str(self.condition) + ") do { " + str(self.body) + " }"
|
||||
|
||||
def pretty_print(clas, indent=0):
|
||||
print(' ' * indent + type(clas).__name__ + ':')
|
||||
print(' ' * indent + type(clas).__name__ + ':')
|
||||
indent += 4
|
||||
for k,v in clas.__dict__.items():
|
||||
if '__dict__' in dir(v):
|
||||
pretty_print(v,indent)
|
||||
for k, v in clas.__dict__.items():
|
||||
if isinstance(v, EXPRESSION):
|
||||
pretty_print(v, indent)
|
||||
else:
|
||||
print(' ' * indent + k + ': ' + str(v))
|
||||
|
||||
|
||||
print(' ' * indent + f"{k}: {v}")
|
||||
|
||||
def export_dot(ast, filename="ast.dot"):
|
||||
with open(filename, "w") as f:
|
||||
f.write("digraph AST {\n")
|
||||
f.write(" node [shape=box];\n")
|
||||
ast.to_dot(f)
|
||||
f.write("}\n")
|
||||
|
||||
Reference in New Issue
Block a user