예제 #1
0
 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)
예제 #2
0
    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
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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()]