def visitAssign(self, ast, c): try: print(111) lhs = self.visit(ast.lhs, (c[0], Unknown())) print('---------------------------------------------') print(2222) print(lhs) print('---------------------------------------------') rhs = self.visit(ast.rhs, (c[0], lhs)) print(rhs) print('---------------------------------------------') lhs = self.visit(ast.lhs, (c[0], rhs)) print(lhs) print('---------------------------------------------') except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if type(lhs) is VoidType: raise TypeMismatchInStatement(ast) if type(lhs) is not type(rhs): raise TypeMismatchInStatement(ast) if type(lhs) is Unknown or (type(lhs) is ArrayType and type(lhs.eletype) is Unknown): raise TypeCannotBeInferred(ast) [print(x, y) for x, y in c[0].items()] print('---------------------------------------------')
def visitReturn(self, ast, c): reType = VoidType() if ast.expr: try: reType = self.visit(ast.expr, (c[0], Unknown())) except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if type(reType) == Unknown and type(c[2].mtype.restype) == Unknown: raise TypeCannotBeInferred(ast) if type(reType) == Unknown: reType = c[2].mtype.restype if type(c[2].mtype.restype) is Unknown: c[2].mtype.restype = reType if type(c[2].mtype.restype) is not type(reType): raise TypeMismatchInStatement(ast) if type(reType) is ArrayType and type(c[2].mtype.restype) is ArrayType: if len(reType.dimen) != len(c[2].mtype.restype.dimen): raise TypeMismatchInStatement(ast) elif type(reType.eletype) == Unknown and type(c[2].mtype.restype.eletype) == Unknown: raise TypeCannotBeInferred(ast) elif type(reType.eletype) == Unknown: reType.eletype = c[2].mtype.restype.eletype elif type(c[2].mtype.restype.eletype) == Unknown: c[2].mtype.restype.eletype = reType.eletype elif type(c[2].mtype.restype.eletype) != type(reType.eletype): raise TypeMismatchInStatement(ast)
def visitIf(self, ast, c): for ifthenStmt in ast.ifthenStmt: try: expr = self.visit(ifthenStmt[0], (c[0], BoolType())) except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if (type(expr) is not BoolType): raise TypeMismatchInStatement(ast) varLocal = {} [self.visit(x, varLocal) for x in ifthenStmt[1]] # merge 2 dict for name, symbol in c[0].items(): if name not in varLocal: varLocal[name] = symbol [ self.visit(x, (varLocal, VoidType(), c[2])) for x in ifthenStmt[2] ] varLocal = {} [self.visit(x, varLocal) for x in ast.elseStmt[0]] # merge 2 dict for name, symbol in c[0].items(): if name not in varLocal: varLocal[name] = symbol [self.visit(i, (varLocal, Unknown(), c[2])) for i in ast.elseStmt[1]]
def visitCallStmt(self, ast, c): try: CallStmtType = self.visitCallExpr(ast, (c[0], VoidType(), c[2])) if type(CallStmtType) is not VoidType: raise TypeMismatchInStatement(ast) except TypeMismatchInExpression as error: if error.exp is ast: raise TypeMismatchInStatement(ast) else: raise TypeMismatchInExpression(error.exp)
def visitAssign(self, ast, c): try: lhs = self.visit(ast.lhs, (c[0], Unknown(), False)) rhs = self.visit(ast.rhs, (c[0], lhs)) lhs = self.visit(ast.lhs, (c[0], rhs)) except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if type(lhs) is VoidType: raise TypeMismatchInStatement(ast) if type(lhs) is not type(rhs): raise TypeMismatchInStatement(ast) if type(lhs) is Unknown or (type(lhs) is ArrayType and type(lhs.eletype) is Unknown): raise TypeCannotBeInferred(ast)
def visitWhile(self, ast, c): try: expr = self.visit(ast.exp, (c[0], BoolType())) except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if type(expr) is not BoolType: raise TypeMismatchInStatement(ast) varLocal = {} [self.visit(x, varLocal) for x in ast.sl[0]] # merge 2 dict for name, symbol in c[0].items(): if name not in varLocal: varLocal[name] = symbol [self.visit(x, (varLocal, VoidType(), c[2])) for x in ast.sl[1]]
def visitFor(self, ast, c): try: id = self.visit(ast.idx1, (c[0], IntType())) e1 = self.visit(ast.expr1, (c[0], IntType())) e2 = self.visit(ast.expr2, (c[0], BoolType())) e3 = self.visit(ast.expr3, (c[0], IntType())) except TypeCannotBeInferred: raise TypeCannotBeInferred(ast) except TypeMismatchInStatement: raise TypeMismatchInStatement(ast) if type(id) is not IntType or type(e1) is not IntType or type(e2) is not BoolType or type(e3) is not IntType: raise TypeMismatchInStatement(ast) varLocal = {} [self.visit(x, varLocal) for x in ast.loop[0]] # merge 2 dict for name, symbol in c[0].items(): if name not in varLocal: varLocal[name] = symbol [self.visit(x, (varLocal, VoidType(), c[2])) for x in ast.loop[1]]
def visitId(self, ast, c): idName = ast.name if idName not in c[0]: raise Undeclared(Identifier(), idName) typeId = c[0][idName] if type(typeId.mtype) is Unknown and type( c[1]) is not Unknown and type(c[1]) is not ArrayType: typeId.mtype = c[1] elif type(typeId.mtype) == ArrayType and type(c[1]) == ArrayType: if len(typeId.mtype.dimen) != len(c[1].dimen): raise TypeMismatchInStatement(ast) if type(typeId.mtype.eletype) == type(c[1].eletype) and type( typeId.mtype.eletype) == Unknown: raise TypeCannotBeInferred(ast) if type(typeId.mtype.eletype) == Unknown: typeId.mtype.eletype = c[1].eletype elif type(c[1].eletype) == Unknown: c[1].eletype = typeId.mtype.eletype elif type(typeId.mtype.eletype) != type(c[1].eletype): raise TypeMismatchInStatement(ast) return typeId.mtype
def visitVarDecl(self, ast, c): varName = ast.variable.name if varName in c: raise Redeclared(Variable(), varName) if ast.varInit: # lay kieu cuar init typeVar = self.visit(ast.varInit, c) if ast.varDimen and ast.varDimen != typeVar.dimen: raise TypeMismatchInStatement(ast) elif ast.varDimen: typeVar = ArrayType(ast.varDimen, Unknown()) else: typeVar = Unknown() c[varName] = Symbol(varName, typeVar)