def visitBinaryOp(self, ast, c): op = ast.op opInt = ['+', '-', '*', '\\', '%', '==', '!=', '<', '>', '<=', '>='] resIntBool = ['==', '!=', '<', '>', '<=', '>='] opFloat = ['+.', '-.', '*.', '\\.', '=/=', '<.', '>.', '<=.', '>=.'] resFloatBool = ['=/=', '<.', '>.', '<=.', '>=.'] opBool = ['&&', '||'] if (op in opInt): leftType = self.visit(ast.left, (c[0], IntType())) rightType = self.visit(ast.right, (c[0], IntType())) if (type(leftType) is IntType and type(rightType) is IntType): if (op in resIntBool): return BoolType() return IntType() raise TypeMismatchInExpression(ast) if (op in opBool): leftType = self.visit(ast.left, (c[0], BoolType())) rightType = self.visit(ast.right, (c[0], BoolType())) if (type(leftType) is BoolType and type(rightType) is BoolType): return BoolType() raise TypeMismatchInExpression(ast) if (op in opFloat): leftType = self.visit(ast.left, (c[0], FloatType())) rightType = self.visit(ast.right, (c[0], FloatType())) if (type(leftType) is FloatType and type(rightType) is FloatType): if (op in resFloatBool): return BoolType() return FloatType() raise TypeMismatchInExpression(ast)
def visitArrayCell(self, ast, c): # try: print(4444) if len(c) == 3: arrMtype = self.visit( ast.arr, (c[0], ArrayType([0] * len(ast.idx), c[1]), c[2])) else: arrMtype = self.visit(ast.arr, (c[0], ArrayType([0] * len(ast.idx), c[1]))) # except TypeMismatchInExpression: print(5555) # raise TypeMismatchInExpression(ast) if type(arrMtype) != ArrayType: raise TypeMismatchInExpression(ast) if (len(arrMtype.dimen) is not len(ast.idx)): raise TypeMismatchInExpression(ast) for i in ast.idx: idxType = self.visit(i, (c[0], IntType())) if (type(idxType) is not IntType): raise TypeMismatchInExpression(ast) if type(arrMtype.eletype) is Unknown and type( c[1]) not in [Unknown, ArrayType]: arrMtype.eletype = c[1] return arrMtype.eletype
def visitCallExpr(self, ast, c): functionName = ast.method.name if functionName not in c[0]: raise Undeclared(Function(), functionName) symbolFunction = c[0][functionName] funcMtype = symbolFunction.mtype #co the la VarDecl trung name, raise Undeclared(Function(), functionName) if type(funcMtype) is not MType: raise Undeclared(Function(), functionName) funcIntype = funcMtype.intype if (len(funcIntype) is not len(ast.param)): raise TypeMismatchInExpression(ast) for index in range(len(funcIntype)): # print(6666) paramType = funcIntype[index] # print(paramType, paramType.mtype) referType = self.visit(ast.param[index], (c[0], paramType.mtype)) # print(111111111011111111) if type(referType) is ArrayType: if type(paramType.mtype) is not ArrayType: raise TypeMismatchInExpression(ast) # print(111111111211111111) # if type(paramType.mtype) is ArrayType: # if type(referType.eletype) == type(paramType.mtype.eletype) and type(referType.eletype) == Unknown: # # print(111111111111111111) # raise TypeCannotBeInferred(ast) if (type(paramType.mtype) is ArrayType and type(paramType.mtype.eletype) is Unknown): paramType.mtype.eletype = referType.eletype elif (type(paramType.mtype) is ArrayType and type(referType.eletype) is Unknown): referType.eletype = paramType.mtype.eletype elif (type(paramType.mtype) is ArrayType and type( referType.eletype) != type(paramType.mtype.eletype)): raise TypeMismatchInExpression(ast) elif type(referType) is not Unknown: if type(paramType.mtype) is Unknown: paramType.mtype = referType elif type(paramType.mtype) not in [ArrayType, Unknown]: referType = paramType.mtype if type(paramType.mtype) is not type(referType): raise TypeMismatchInExpression(ast) if ((type(paramType.mtype) is Unknown) or (type(paramType.mtype) is ArrayType and type(paramType.mtype.eletype) is Unknown)): #them if type(referType) == ArrayType: if type(referType) is ArrayType and type( referType.eletype) is Unknown: raise TypeCannotBeInferred(ast) elif type(paramType.mtype) == Unknown and type( referType.eletype) != Unknown: paramType.mtype = referType else: raise TypeCannotBeInferred(ast) if (type(funcMtype.restype) is Unknown and type(c[1]) is not Unknown): funcMtype.restype = c[1] return funcMtype.restype
def visitArrayCell(self, ast, c): arrMtype = self.visit(ast.arr, (c[0], ArrayType([0] * len(ast.idx), c[1]))) if (len(arrMtype.dimen) is not len(ast.idx)): raise TypeMismatchInExpression(ast) for i in ast.idx: idxType = self.visit(i, (c[0], IntType())) if (type(idxType) is not IntType): raise TypeMismatchInExpression(ast) if type(arrMtype.eletype) is Unknown and type( c[1]) not in [Unknown, ArrayType]: arrMtype.eletype = c[1] return arrMtype.eletype
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 visitUnaryOp(self, ast, c): op = ast.op if (op == "-"): bodyType = self.visit(ast.body, (c[0], IntType())) if (type(bodyType) is IntType): return IntType() if (op == '-.'): bodyType = self.visit(ast.body, (c[0], FloatType())) if (type(bodyType) is FloatType): return FloatType() if (op == '!'): bodyType = self.visit(ast.body, (c[0], BoolType())) if (type(bodyType) is BoolType): return BoolType() raise TypeMismatchInExpression(ast)
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 TypeMismatchInExpression(ast) elif ast.varDimen: typeVar = ArrayType(ast.varDimen, Unknown()) else: typeVar = Unknown() c[varName] = Symbol(varName, typeVar) [print(x, y) for x, y in c.items()]