예제 #1
0
 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('---------------------------------------------')
예제 #2
0
    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)
예제 #3
0
 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]]
예제 #4
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)
예제 #5
0
 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)
예제 #6
0
 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]]
예제 #7
0
 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]]
예제 #8
0
 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
예제 #9
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 TypeMismatchInStatement(ast)
     elif ast.varDimen:
         typeVar = ArrayType(ast.varDimen, Unknown())
     else:
         typeVar = Unknown()
     c[varName] = Symbol(varName, typeVar)