535 lines
12 KiB
Python
535 lines
12 KiB
Python
from abc import ABC, abstractmethod, ABCMeta
|
|
# from Visitor import Visitor
|
|
|
|
# cheated = True
|
|
cheated = False
|
|
|
|
|
|
class AST(ABC):
|
|
def __eq__(self, other):
|
|
return self.__dict__ == other.__dict__
|
|
|
|
@abstractmethod
|
|
def accept(self, v, param):
|
|
return v.visit(self, param)
|
|
|
|
|
|
class Type(AST):
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class IntType(Type):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "IntType"
|
|
else:
|
|
return "IntType()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitIntType(self, param)
|
|
|
|
|
|
class FloatType(Type):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "FloatType"
|
|
else:
|
|
return "FloatType()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitFloatType(self, param)
|
|
|
|
|
|
class BoolType(Type):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "BoolType"
|
|
else:
|
|
return "BoolType()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitBoolType(self, param)
|
|
|
|
|
|
class StringType(Type):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "StringType"
|
|
else:
|
|
return "StringType()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitStringType(self, param)
|
|
|
|
|
|
class ArrayType(Type):
|
|
global cheated
|
|
# lower:int
|
|
# upper:int
|
|
# eleType:Type
|
|
|
|
def __init__(self, lower, upper, eleType):
|
|
self.lower = lower
|
|
self.upper = upper
|
|
self.eleType = eleType
|
|
|
|
def __str__(self):
|
|
return "ArrayType(" + str(self.lower) + "," + \
|
|
str(self.upper) + "," + str(self.eleType) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitArrayType(self, param)
|
|
|
|
|
|
class VoidType(Type):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
return "VoidType()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitVoidType(self, param)
|
|
|
|
|
|
class Program(AST):
|
|
global cheated
|
|
# decl:list(Decl)
|
|
|
|
def __init__(self, decl):
|
|
self.decl = decl
|
|
|
|
def __str__(self):
|
|
return "Program([" + ','.join(str(i) for i in self.decl) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitProgram(self, param)
|
|
|
|
|
|
class Decl(AST):
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class VarDecl(Decl):
|
|
global cheated
|
|
# variable:Id
|
|
# varType: Type
|
|
|
|
def __init__(self, variable, varType):
|
|
self.variable = variable
|
|
self.varType = varType
|
|
|
|
def __str__(self):
|
|
return "VarDecl(" + str(self.variable) + "," + str(self.varType) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitVarDecl(self, param)
|
|
|
|
|
|
class FuncDecl(Decl):
|
|
global cheated
|
|
# name: Id
|
|
# param: list(VarDecl)
|
|
# returnType: Type => VoidType for Procedure
|
|
# local:list(VarDecl)
|
|
# body: list(Stmt)
|
|
|
|
def __init__(self, name, param, local, body, returnType=VoidType()):
|
|
self.name = name
|
|
self.param = param
|
|
self.returnType = returnType
|
|
self.local = local
|
|
self.body = body
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "FuncDecl(" + str(self.name) + ",[" + \
|
|
','.join(str(i) for i in self.param) + "]," + \
|
|
str(self.returnType) + ",[" + \
|
|
','.join(str(i) for i in self.local) + "],[" + \
|
|
','.join(str(i) for i in self.body) + "])"
|
|
else:
|
|
return "FuncDecl(" + str(self.name) + ",[" + \
|
|
','.join(str(i) for i in self.param) + "],[" + \
|
|
','.join(str(i) for i in self.local) + "],[" + \
|
|
','.join(str(i) for i in self.body) + "]," + \
|
|
str(self.returnType) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitFuncDecl(self, param)
|
|
|
|
|
|
class Stmt(AST):
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class Assign(Stmt):
|
|
global cheated
|
|
# lhs:Expr
|
|
# exp:Expr
|
|
|
|
def __init__(self, lhs, exp):
|
|
self.lhs = lhs
|
|
self.exp = exp
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "AssignStmt(" + str(self.lhs) + "," + str(self.exp) + ")"
|
|
else:
|
|
return "Assign(" + str(self.lhs) + "," + str(self.exp) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitAssign(self, param)
|
|
|
|
|
|
class If(Stmt):
|
|
global cheated
|
|
# expr:Expr
|
|
# thenStmt:list(Stmt)
|
|
# elseStmt:list(Stmt)
|
|
|
|
def __init__(self, expr, thenStmt, elseStmt=[]):
|
|
self.expr = expr
|
|
self.thenStmt = thenStmt
|
|
self.elseStmt = elseStmt
|
|
|
|
def __str__(self):
|
|
return "If(" + str(self.expr) + ",[" + \
|
|
','.join(str(i) for i in self.thenStmt) + "],[" + \
|
|
','.join(str(i) for i in self.elseStmt) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitIf(self, param)
|
|
|
|
|
|
class While(Stmt):
|
|
global cheated
|
|
# sl:list(Stmt)
|
|
# exp: Expr
|
|
|
|
def __init__(self, exp, sl):
|
|
self.sl = sl
|
|
self.exp = exp
|
|
|
|
def __str__(self):
|
|
return "While(" + str(self.exp) + \
|
|
",[" + ','.join(str(i) for i in self.sl) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitWhile(self, param)
|
|
|
|
|
|
class For(Stmt):
|
|
global cheated
|
|
# id:Id
|
|
# expr1,expr2:Expr
|
|
# loop:list(Stmt)
|
|
# up:Boolean #True => increase; False => decrease
|
|
|
|
def __init__(self, id, expr1, expr2, up, loop):
|
|
self.id = id
|
|
self.expr1 = expr1
|
|
self.expr2 = expr2
|
|
self.up = up
|
|
self.loop = loop
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "For(" + str(self.id) + ","\
|
|
+ str(self.expr1) + "," \
|
|
+ str(self.expr2) + ","\
|
|
+ str(self.up) + ',[' \
|
|
+ ','.join(str(i) for i in self.loop) + "])"
|
|
else:
|
|
return "For(" + str(self.id) + ","\
|
|
+ str(self.expr1) + "," \
|
|
+ str(self.expr2) + ","\
|
|
+ str(self.up) + ',[' \
|
|
+ ','.join(str(i) for i in self.loop) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitFor(self, param)
|
|
|
|
|
|
class Break(Stmt):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "Break"
|
|
else:
|
|
return "Break()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitBreak(self, param)
|
|
|
|
|
|
class Continue(Stmt):
|
|
global cheated
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "Continue"
|
|
else:
|
|
return "Continue()"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitContinue(self, param)
|
|
|
|
|
|
class Return(Stmt):
|
|
global cheated
|
|
# expr:Expr
|
|
|
|
def __init__(self, expr=None):
|
|
self.expr = expr
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "Return(" + ("None" if (self.expr is None)
|
|
else "Some(" + str(self.expr) + ")") + ")"
|
|
else:
|
|
return "Return()" if self.expr is None \
|
|
else "Return(" + str(self.expr) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitReturn(self, param)
|
|
|
|
|
|
class With(Stmt):
|
|
global cheated
|
|
# decl:list(VarDecl)
|
|
# stmt:list(Stmt)
|
|
|
|
def __init__(self, decl, stmt):
|
|
self.decl = decl
|
|
self.stmt = stmt
|
|
|
|
def __str__(self):
|
|
return "With([" + ','.join(str(i) for i in self.decl) + \
|
|
"],[" + ','.join(str(i) for i in self.stmt) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitWith(self, param)
|
|
|
|
|
|
class CallStmt(Stmt):
|
|
global cheated
|
|
# method:Id
|
|
# param:list(Expr)
|
|
|
|
def __init__(self, method, param):
|
|
self.method = method
|
|
self.param = param
|
|
|
|
def __str__(self):
|
|
return "CallStmt(" + str(self.method) + \
|
|
",[" + ','.join(str(i) for i in self.param) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitCallStmt(self, param)
|
|
|
|
|
|
class Expr(AST):
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class BinaryOp(Expr):
|
|
global cheated
|
|
# op:string: AND THEN => andthen; OR ELSE => orelse; other => keep it
|
|
# left:Expr
|
|
# right:Expr
|
|
|
|
def __init__(self, op, left, right):
|
|
self.op = op
|
|
self.left = left
|
|
self.right = right
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "BinaryOp(" + self.op + "," + str(self.left) + \
|
|
"," + str(self.right) + ")"
|
|
else:
|
|
return "BinaryOp(\"" + self.op + "\"," + str(self.left) + \
|
|
"," + str(self.right) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitBinaryOp(self, param)
|
|
|
|
|
|
class UnaryOp(Expr):
|
|
global cheated
|
|
# op:string
|
|
# body:Expr
|
|
|
|
def __init__(self, op, body):
|
|
self.op = op
|
|
self.body = body
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "UnaryOp(" + self.op + "," + str(self.body) + ")"
|
|
else:
|
|
return "UnaryOp(\"" + self.op + "\"," + str(self.body) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitUnaryOp(self, param)
|
|
|
|
|
|
class CallExpr(Expr):
|
|
global cheated
|
|
# method:Id
|
|
# param:list(Expr)
|
|
|
|
def __init__(self, method, param):
|
|
self.method = method
|
|
self.param = param
|
|
|
|
def __str__(self):
|
|
return "CallExpr(" + str(self.method) + \
|
|
",[" + ','.join(str(i) for i in self.param) + "])"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitCallExpr(self, param)
|
|
|
|
|
|
class LHS(Expr):
|
|
global cheated
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class Id(LHS):
|
|
global cheated
|
|
# name:string
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "Id(" + self.name + ")"
|
|
else:
|
|
return "Id(\"" + self.name + "\")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitId(self, param)
|
|
|
|
|
|
class ArrayCell(LHS):
|
|
global cheated
|
|
# arr:Expr
|
|
# idx:Expr
|
|
|
|
def __init__(self, arr, idx):
|
|
self.arr = arr
|
|
self.idx = idx
|
|
|
|
def __str__(self):
|
|
return "ArrayCell(" + str(self.arr) + "," + str(self.idx) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitArrayCell(self, param)
|
|
|
|
|
|
class Literal(Expr):
|
|
global cheated
|
|
__metaclass__ = ABCMeta
|
|
pass
|
|
|
|
|
|
class IntLiteral(Literal):
|
|
global cheated
|
|
# value:int
|
|
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
def __str__(self):
|
|
return "IntLiteral(" + str(self.value) + ")"
|
|
|
|
def accept(self, v, param):
|
|
|
|
return v.visitIntLiteral(self, param)
|
|
|
|
|
|
class FloatLiteral(Literal):
|
|
global cheated
|
|
# value:float
|
|
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
def __str__(self):
|
|
return "FloatLiteral(" + str(self.value) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitFloatLiteral(self, param)
|
|
|
|
|
|
class StringLiteral(Literal):
|
|
global cheated
|
|
# value:string
|
|
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
def __str__(self):
|
|
if not cheated:
|
|
return "StringLiteral(" + self.value + ")"
|
|
else:
|
|
return "StringLiteral(\"" + self.value + "\")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitStringLiteral(self, param)
|
|
|
|
|
|
class BooleanLiteral(Literal):
|
|
global cheated
|
|
# value:boolean
|
|
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
def __str__(self):
|
|
return "BooleanLiteral(" + str(self.value) + ")"
|
|
|
|
def accept(self, v, param):
|
|
return v.visitBooleanLiteral(self, param)
|
|
|
|
|
|
class ArrayPointerType(Type):
|
|
def __init__(self, ctype):
|
|
# cname: String
|
|
self.eleType = ctype
|
|
|
|
def __str__(self):
|
|
return "ArrayPointerType({0})".format(
|
|
str(self.eleType)
|
|
)
|
|
|
|
def accept(self, v, param):
|
|
return None
|
|
|
|
|
|
class ClassType(Type):
|
|
def __init__(self, cname):
|
|
self.cname = cname
|
|
|
|
def __str__(self):
|
|
return "Class({0})".format(str(self.cname))
|
|
|
|
def accept(self, v, param):
|
|
return None
|