コード例 #1
0
    def visitWhileStmt(self, ctx: DecafParser.WhileStmtContext):
        self.enterScope('whileblock' + str(self.anonCounter))
        self.anonCounter += 1

        whileNode = ICNode('while')
        code = []

        conditionlabel = self.gen_label()
        elselabel = self.gen_label()

        expr = self.visit(ctx.expression())

        condition = expr.lt
        self.free_temporal(condition)

        code.append(conditionlabel)
        code += expr.code

        code.append('IFNOT ' + condition + ' goto ' + elselabel)

        whileblock = self.visit(ctx.block())
        code += whileblock.code

        code.append('goto ' + conditionlabel)
        code.append(elselabel)

        whileNode.code = code

        self.exitScope()

        return whileNode
コード例 #2
0
    def visitBlock(self, ctx: DecafParser.BlockContext):
        blockNode = ICNode('none')
        code = []

        for statement in ctx.statement():
            v = self.visitStatement(statement)
            code += v.code if v else []

        blockNode.code = code

        return blockNode
コード例 #3
0
    def visitNegationExpr(self, ctx: DecafParser.NegativeExprContext):
        t = self.visit(ctx.expression)
        new_temp = self.get_temporal()
        code = []
        negated = ICNode('!', right=t)
        code += t.code
        code.append(new_temp + ' = NOT ' + t.lt)
        self.free_temporal(t.lt)

        negated.code = code
        negated.lt = new_temp

        return negated
コード例 #4
0
    def visitReturnStmt(self, ctx: DecafParser.ReturnStmtContext):
        expr = self.visit(ctx.expression())
        returnNode = ICNode('return')
        code = []

        code += expr.code
        code.append(self.gen_code(RETURN_REGISTER, expr.lt, '', ''))
        self.free_temporal(expr.lt)
        code.append('BX LR')

        returnNode.code = code

        return returnNode
コード例 #5
0
    def visitAssignStmt(self, ctx: DecafParser.AssignStmtContext):
        destination = self.visit(ctx.left)
        right = self.visit(ctx.right)

        loc = destination

        assignNode = ICNode('=', left=destination, right=right)
        code = []

        code += right.code

        if not isinstance(destination, str):
            code += destination.code
            loc = destination.lt

        code.append(self.gen_code(loc, right.lt, '', ''))
        self.free_temporal(right.lt)

        assignNode.code = code
        return assignNode
コード例 #6
0
    def visitMethodCall(self, ctx: DecafParser.MethodCallExprContext):
        methodCallNode = ICNode('call')
        code = []

        method_label = str(ctx.ID())
        scope = self.scopes.peek()
        method = scope.typeExists(method_label, 'method')

        for argument in ctx.arg():
            argNode = self.visitArg(argument)
            code += argNode.code
            code.append('PushParam ' + argNode.lt)
            self.free_temporal(argNode.lt)

        code.append('LCall ' + method_label)

        code.append('PopParams ' + str(method.size))

        methodCallNode.lt = RETURN_REGISTER
        methodCallNode.code = code

        return methodCallNode
コード例 #7
0
    def visitIfStmt(self, ctx: DecafParser.IfStmtContext):
        self.enterScope('ifblock' + str(self.anonCounter))
        self.anonCounter += 1

        ifNode = ICNode('if')
        code = []

        elselabel = self.gen_label()

        expr = self.visit(ctx.expression())

        condition = expr.lt
        self.free_temporal(condition)

        code += expr.code

        code.append('IFNOT ' + condition + ' goto ' + elselabel)

        ifblock = self.visit(ctx.ifblock)
        code += ifblock.code

        if ctx.elseblock:
            endlabel = self.gen_label()
            code.append('goto ' + endlabel)

            code.append(elselabel)
            elseblock = self.visit(ctx.elseblock)
            code += elseblock.code

            code.append(endlabel)
        else:
            code.append(elselabel)

        ifNode.code = code

        self.exitScope()

        return ifNode
コード例 #8
0
    def visitRelationOp(self, ctx: DecafParser.RelationOpContext):
        op = ctx.op.getText()

        left_node = self.visit(ctx.left)
        right_node = self.visit(ctx.right)

        self.free_temporal(left_node.lt)
        self.free_temporal(right_node.lt)

        rel = ICNode(op, right_node, left_node)

        code = []
        code += left_node.code
        code += right_node.code

        new_temp = self.get_temporal()

        code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt))

        rel.code = code
        rel.lt = new_temp

        return rel
コード例 #9
0
    def visitArithOp(self, ctx: DecafParser.ArithOpContext):
        op = ctx.op.getText()

        left_node = self.visit(ctx.left)
        right_node = self.visit(ctx.right)

        self.free_temporal(left_node.lt)
        self.free_temporal(right_node.lt)

        arith = ICNode(op, right_node, left_node)

        code = []
        code += left_node.code
        code += right_node.code

        new_temp = self.get_temporal()

        code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt))

        arith.code = code
        arith.lt = new_temp

        return arith
コード例 #10
0
    def visitEqualityOp(self, ctx: DecafParser.EqualityOpContext):
        op = ctx.op.getText()

        left_node = self.visit(ctx.left)
        right_node = self.visit(ctx.right)

        self.free_temporal(left_node.lt)
        self.free_temporal(right_node.lt)

        eq = ICNode(op, right_node, left_node)

        code = []
        code += left_node.code
        code += right_node.code

        new_temp = self.get_temporal()

        code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt))

        eq.code = code
        eq.lt = new_temp

        return eq
コード例 #11
0
    def visitLocation(self, ctx: DecafParser.LocationExprContext, struct=None):
        var_name = ctx.name.text
        scope = self.scopes.peek()
        var, scopeName = scope.lookup(var_name)
        tokenEXPR = ctx.expr
        tokenLOC = ctx.loc
        locNode = ICNode('location')

        if not tokenEXPR and not tokenLOC:
            locNode.lt = self.get_location(scopeName, var.offset)
            return locNode

        #We have a list
        elif tokenEXPR and not tokenLOC:
            size = scope.typeTable.getSize(var.stype)

            # EZ index is a number
            if (index := ctx.expr.getText()).isnumeric():
                locNode.lt = self.get_location(scopeName,
                                               var.offset + size * int(index))
                return locNode

            # Index is an expression
            code = []
            expr = self.visit(tokenEXPR)
            # 2 new temporals, to compute the new offset
            new_temp = self.get_temporal()
            new_temp2 = self.get_temporal()
            # if expression is a location, we get a string, if not we get an ICNode
            location = expr
            if not isinstance(expr, str):
                code += expr.code
                location = expr.lt
                self.free_temporal(expr.lt)

            code.append(self.gen_code(new_temp, location, '*', size))
            code.append(self.gen_code(new_temp2, new_temp, '+', var.offset))

            self.free_temporal(new_temp)
            self.free_temporal(new_temp2)

            locNode.code = code
            locNode.lt = self.get_location(scopeName, new_temp2)

            return locNode
コード例 #12
0
 def visitBool_literal(self, ctx: DecafParser.Bool_literalContext):
     if ctx.getText() == 'true':
         return ICNode(None, lt='1')
     return ICNode(None, lt='0')
コード例 #13
0
 def visitChar_literal(self, ctx: DecafParser.Char_literalContext):
     return ICNode(None, lt=ctx.getText())