Пример #1
0
    def exitWhile_stmt(self, ctx: LittleParser.While_stmtContext):
        self.exitScope()

        while_node = ASTNode(node_enum(14).name, [])
        end_node = ASTNode(node_enum(16).name, [])
        end_label = ASTNode(node_enum(10).name, "label" + self.getScopeNum())

        # grab nodes from the stack needed to create a WHILE node
        stmt_list = ast_stack.pop()
        comp_op = ast_stack.pop()  # add the end label to the comp-op node
        comp_op.val_type = end_label

        w_label = ast_stack.pop()

        # END node contains the while label and the endwhile label
        end_node.value.append(w_label)
        end_node.value.append(end_label)
        end_node.val_type = 'while'

        # WHILE.value = [comp_op, stmt_list, end]
        while_node.value.append(comp_op)
        while_node.value.append(stmt_list)
        while_node.value.append(end_node)
        while_node.val_type = w_label

        ast_stack.push(while_node)
Пример #2
0
 def enterFactor_prefix(self, ctx: LittleParser.Factor_prefixContext):
     # If the expr_prefix has no children(is NULL) add a Null node to the stack
     if ctx.getChildCount() != 0 and ctx.getChild(0).getChildCount() == 0:
         node = ASTNode(node_enum(0).name, "")  #NullNode
         ast_stack.push(node)
     elif ctx.getChildCount() == 0:
         node = ASTNode(node_enum(6).name, "")  #Placeholder node
         ast_stack.push(node)
Пример #3
0
 def exitElse_part(self, ctx: LittleParser.Else_partContext):
     self.exitScope()
     if ast_stack.peek().node_type == node_enum(6).name:
         pass
     else:
         stmtList = ast_stack.pop()
         label = ast_stack.pop()
         node = ASTNode(node_enum(15).name, [stmtList], label)
         ast_stack.push(node)
Пример #4
0
 def enterElse_part(self, ctx: LittleParser.Else_partContext):
     if ctx.getChildCount() == 0:
         node = ASTNode(node_enum(6).name, "")  #Placeholder node
         ast_stack.push(node)
     else:
         num = self.getScopeNum()
         name = "BLOCK " + num
         self.enterScope(name)
         ast_stack.push(ASTNode(node_enum(10).name, "label" + num))
Пример #5
0
    def enterWrite_stmt(self, ctx: LittleParser.Write_stmtContext):
        currentScope = self.getCurrentScope()
        node = ASTNode(node_enum(8).name, [], "")
        i = 0
        while i < ctx.getChild(2).getChildCount():
            var = ctx.getChild(2).getChild(i).getText()
            var = var.split(",")
            if len(var) > 1:
                for v in var:
                    if (v != ""):
                        if v in symbolTable[currentScope]:
                            var_type = symbolTable[currentScope][v][0]
                        elif v in symbolTable['GLOBAL']:
                            var_type = symbolTable['GLOBAL'][v][0]
                        node.value.append((v, var_type))
            else:
                if (var[0] != ""):
                    # get the type for node, first check if its in the current scope else get it from global scope
                    if var[0] in symbolTable[currentScope]:
                        var_type = symbolTable[currentScope][var[0]][0]
                    elif var[0] in symbolTable['GLOBAL']:
                        var_type = symbolTable['GLOBAL'][var[0]][0]

                    node.value.append((var[0], var_type))
                    # statements_node.add("", node)
            i += 1

        ast_stack.push(node)
Пример #6
0
    def exitStmt_list(self, ctx: LittleParser.Stmt_listContext):

        # If node is a Placeholder
        if ast_stack.peek().node_type == node_enum(6).name:
            ast_stack.pop()
            node = ASTNode(node_enum(5).name, [])
            ast_stack.push(node)

        # add a statement to the statement list and push back on to stack
        else:
            sl = ast_stack.pop()
            stmt = ast_stack.pop()

            sl.value.insert(0, stmt)

            ast_stack.push(sl)
Пример #7
0
    def exitFactor_prefix(self, ctx: LittleParser.Factor_prefixContext):
        if ast_stack.peek().node_type == node_enum(
                6).name:  # if a placeholder node
            ast_stack.pop()
        else:
            mulop_node = ast_stack.pop()
            postfix_node = ast_stack.pop()
            fact_prefix_node = ast_stack.pop()

            if fact_prefix_node.node_type == node_enum(0).name:
                mulop_node.leftChild = postfix_node

            else:
                fact_prefix_node.rightChild = postfix_node
                mulop_node.leftChild = fact_prefix_node

            ast_stack.push(mulop_node)
Пример #8
0
    def exitExpr_prefix(self, ctx: LittleParser.Expr_prefixContext):

        if ast_stack.peek().node_type == node_enum(
                6).name:  # if a placeholder node
            ast_stack.pop()
        else:
            addop_node = ast_stack.pop()
            factor_node = ast_stack.pop()
            prefix_node = ast_stack.pop()

            if prefix_node.node_type == node_enum(0).name:
                addop_node.leftChild = factor_node

            else:
                prefix_node.rightChild = factor_node
                addop_node.leftChild = prefix_node

            ast_stack.push(addop_node)
Пример #9
0
    def exitFactor(self, ctx: LittleParser.FactorContext):
        postfix_node = ast_stack.pop()

        factor_prefix_node = ast_stack.pop()
        if factor_prefix_node.node_type == node_enum(0).name:
            ast_stack.push(postfix_node)

        else:
            factor_prefix_node.rightChild = postfix_node
            ast_stack.push(factor_prefix_node)
Пример #10
0
    def enterAssign_expr(self, ctx: LittleParser.Assign_exprContext):
        # print(";Enter Assignment")
        var1 = ctx.getChild(0).getText()
        var2 = ctx.getChild(1).getText()
        var_type = ""
        currentScope = self.getCurrentScope()

        # get the type for id_node, first check if its in the current scope else get it from global scope
        if var1 in symbolTable[currentScope]:
            var_type = symbolTable[currentScope][var1][0]
        elif var1 in symbolTable['GLOBAL']:
            var_type = symbolTable['GLOBAL'][var1][0]

        # create varref node
        id_node = ASTNode(node_enum(3).name, var1, var_type)
        ast_stack.push(id_node)

        # create assexp node
        node = ASTNode(node_enum(4).name, var2)
        ast_stack.push(node)
Пример #11
0
    def exitExpr(self, ctx: LittleParser.ExprContext):

        factor_node = ast_stack.pop()

        expr_prefix_node = ast_stack.pop()
        if expr_prefix_node.node_type == node_enum(0).name:
            ast_stack.push(factor_node)

        else:
            expr_prefix_node.rightChild = factor_node

            ast_stack.push(expr_prefix_node)
Пример #12
0
    def exitIf_stmt(self, ctx: LittleParser.If_stmtContext):
        self.exitScope()
        if_node = ASTNode(node_enum(13).name, [], "")
        end_node = ASTNode(node_enum(16).name, [])

        else_node = ast_stack.pop()
        sl_node = ast_stack.pop()
        comp_node = ast_stack.pop()

        if_label = ast_stack.pop()
        end_label = ASTNode(node_enum(10).name, "label" + self.getScopeNum())

        end_node.value.append(if_label)
        end_node.value.append(end_label)
        end_node.val_type = 'if'

        if_node.val_type = if_label
        if_node.value.append(comp_node)
        if_node.value.append(sl_node)

        # if not a placeholder node,
        # assign the else label to the cop_op node, add the end node to the else values
        # add else node to the end of if's value list
        if else_node.node_type != node_enum(6).name:
            eend_node = ASTNode(node_enum(16).name, [if_label, end_label])
            eend_node.val_type = 'else'
            else_label = else_node.val_type
            comp_node.val_type = else_label
            else_node.value.append(end_node)
            if_node.value.append(eend_node)
            if_node.value.append(else_node)
        else:
            comp_node.val_type = end_label

        if_node.value.append(end_node)
        ast_stack.push(if_node)
Пример #13
0
    def postOrder(self, root):
        if root != None:
            print("ENTER root")
            root.pprint()
            left_obj = self.postOrder(root.leftChild)
            print("LEFT_OBJ: ")
            print(left_obj)
            right_obj = self.postOrder(root.rightChild)
            print("RIGHT_OBJ: ")
            print(right_obj)

            tempLoc = ""
            tempType = ""
            current_code = []

            # if the root has a type if not, it's a const. and create a temp to store.
            if root.node_type == node_enum(3).name and root.val_type == "":
                tempLoc = self.getTemp()  #gets a new temp value
                tempType = ""
                print("Ready to append IR Node")
                current_code.append(IRNode("STORE", root.value, "", tempLoc))
            elif root.node_type == node_enum(3).name:
                tempLoc = root.value
                tempType = root.val_type

            if root.leftChild:
                for code in left_obj.getCode():
                    current_code.append(code)
            if root.rightChild:
                for code in right_obj.getCode():
                    current_code.append(code)

            return CodeObject(current_code, tempLoc, tempType)
            #if root has type, check if its node_type is VARREF
            # IRNode "LOAD"
        print("ROOT is None, return")
Пример #14
0
    def enterPrimary(self, ctx: LittleParser.PrimaryContext):
        if ctx.getChildCount() > 1:
            pass
        else:
            var = ctx.getChild(0).getText()
            var_type = ""
            currentScope = self.getCurrentScope()

            # get the type for id_node, first check if its in the current scope else get it from global scope
            if var in symbolTable[currentScope]:
                var_type = symbolTable[currentScope][var][0]
            elif var in symbolTable['GLOBAL']:
                var_type = symbolTable['GLOBAL'][var][0]

            node = ASTNode(node_enum(3).name, var, var_type)

            ast_stack.push(node)
Пример #15
0
    def enterRead_stmt(self, ctx: LittleParser.Read_stmtContext):
        i = 0
        # A read node's values will be a list of tuples [(variable, type), (var, type)]
        node = ASTNode(node_enum(7).name, [], "")
        while i < ctx.getChild(2).getChildCount():
            var = ctx.getChild(2).getChild(i).getText()
            var = var.strip(",")
            var_type = ""
            currentScope = self.getCurrentScope()

            # get the type for node, first check if its in the current scope else get it from global scope
            if var in symbolTable[currentScope]:
                var_type = symbolTable[currentScope][var][0]
            elif var in symbolTable['GLOBAL']:
                var_type = symbolTable['GLOBAL'][var][0]

            if var != "":
                node.value.append((var, var_type))
            i += 1

        ast_stack.push(node)
Пример #16
0
    def postOrder(self, root):
        if root != None:
            left_obj = self.postOrder(root.leftChild)
            right_obj = self.postOrder(root.rightChild)

            tempLoc = ""
            tempType = ""
            current_code = []

            # if the root is a VARREF node and it does not have a type, it's a const.
            # Create a temp, determine the type, store code in IRnode.
            if root.node_type == node_enum(3).name and root.val_type == "":
                tempLoc = self.getTemp()  #gets a new temp value
                tempType = ""
                # determine if the const is an int or a float to get the correct instruction
                tempType = self.is_number(root.value)
                # get the correct instruction depending on the type
                op = self.returnOperator("STORE", tempType)
                node = IRNode(op, root.value, tempType, tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is a VARREF variable, store its value and type
            elif root.node_type == node_enum(3).name:
                tempLoc = root.value
                tempType = root.val_type

            # for READ nodes, iterate through value, type tuples
            elif root.node_type == node_enum(7).name:
                for tup in root.value:
                    tempLoc = tup[0]
                    tempType = tup[1]
                    #get the correct instruction depending on the type
                    op = self.returnOperator("READ", tempType)
                    node = IRNode(op, tempLoc, "", tempLoc)
                    tiny_list.append(node.operator_map[op](node))
                    current_code.append(node)

            # if the root is an assignment statement, store the result from the right child
            # into the variable of the left child
            elif root.node_type == node_enum(4).name:
                tempLoc = root.leftChild.value
                tempType = left_obj.resType
                #get the correct instruction depending on the type
                op = self.returnOperator("STORE", tempType)
                node = IRNode(op, right_obj.resultLoc, "", tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is an ADDOP, add/subtract the memory locations together
            # and store in a new temp
            elif root.node_type == node_enum(1).name:
                tempLoc = self.getTemp()
                tempType = left_obj.resType
                #get the correct instruction depending on the type
                opType = self.getOpType(root.value)
                op = self.returnOperator(opType, tempType)
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc,
                              tempLoc)

                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is a MULOP, multiply/divide the child memory locations together
            # and store in a new temp
            elif root.node_type == node_enum(2).name:
                tempLoc = self.getTemp()
                tempType = right_obj.resType
                #get the correct instruction depending on the type
                opType = self.getOpType(root.value)
                op = self.returnOperator(opType, tempType)
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc,
                              tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # for WRITE nodes, iterate through value, type tuples
            elif root.node_type == node_enum(8).name:
                for tup in root.value:
                    tempLoc = tup[0]
                    tempType = tup[1]
                    op = self.returnOperator("WRITE", tempType)
                    node = IRNode(op, "", "", tempLoc)
                    tiny_list.append(node.operator_map[op](node))
                    current_code.append(node)

            elif root.node_type == node_enum(10).name:
                node = IRNode("LABEL", '', '', root.value)
                tiny_list.append(node.operator_map["LABEL"](node))
                current_code.append(node)

            # iterate through statement list node - not sure what functionality to add here
            elif root.node_type == node_enum(5).name:
                for value in root.value:
                    self.postOrder(value)

            # if the node is a WHILE node
            elif root.node_type == node_enum(14).name:
                comp = root.value[0].value
                tiny_code = 'label ' + root.val_type.value
                tiny_list.append(tiny_code)

                #recurse on the nodes in the value list
                for value in root.value:
                    self.postOrder(value)

            #if the node is a COMPOP, find its value and create an IR node
            elif root.node_type == node_enum(9).name:
                tempType = left_obj.resType
                opType = self.getOpType(root.value)
                op = self.returnOperator(opType, tempType)
                result = root.val_type.value
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc,
                              result)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            #if the node if an IF node
            elif root.node_type == node_enum(13).name:
                # tiny_code = 'label ' + root.val_type.value
                # tiny_list.append(tiny_code)
                #recurse on the nodes in the value list
                for value in root.value:
                    self.postOrder(value)

            #if the node is an ELSE node
            elif root.node_type == node_enum(15).name:
                # jump = root.value[1].value[1].value
                tiny_code = 'label %s' % (root.val_type.value)
                tiny_list.append(tiny_code)
                #recurse on the nodes in the value list
                for value in root.value:
                    self.postOrder(value)

            #if the node is an END node
            elif root.node_type == node_enum(16).name:
                nodes = root.value
                if root.val_type == 'while':
                    jump = nodes[0].value
                    label = nodes[1].value
                    tiny_code = 'jmp %s\nlabel %s' % (jump, label)
                    tiny_list.append(tiny_code)
                elif root.val_type == 'if':
                    label = nodes[1].value
                    tiny_code = 'label %s' % (label)
                    if self.dupCode(tiny_code, tiny_list):
                        pass
                    else:
                        tiny_list.append(tiny_code)
                elif root.val_type == 'else':
                    # print("in else end")
                    label = nodes[1].value
                    # print(label)
                    tiny_code = 'jmp %s' % (label)
                    tiny_list.append(tiny_code)

            # adding the code objects to the new list I created
            co = CodeObject(current_code, tempLoc, tempType)
            if co is not None:
                code_objects.append(co)
            return co
Пример #17
0
 def enterFunc_decl(self, ctx: LittleParser.Func_declContext):
     name = ctx.getChild(2).getText()
     self.enterScope(name)
     ast_stack.push(ASTNode(node_enum(10).name, name))
Пример #18
0
    def enterStmt_list(self, ctx: LittleParser.Stmt_listContext):

        if ctx.getChildCount() == 0:
            node = ASTNode(node_enum(6).name, [])
            ast_stack.push(node)
Пример #19
0
    def enterCompop(self, ctx: LittleParser.CompopContext):

        # The label to jump to will be added in the exit while and exit if functions as the val_type
        node = ASTNode(node_enum(9).name, ctx.getText())
        ast_stack.push(node)
Пример #20
0
 def enterMulop(self, ctx: LittleParser.MulopContext):
     node = ASTNode(node_enum(2).name, ctx.getChild(0).getText())
     ast_stack.push(node)
Пример #21
0
 def enterWhile_stmt(self, ctx: LittleParser.While_stmtContext):
     num = self.getScopeNum()
     name = "BLOCK " + num
     self.enterScope(name)
     ast_stack.push(ASTNode(node_enum(10).name, "label" + num))
Пример #22
0
    def postOrder(self, root):
        if root != None:
            left_obj = self.postOrder(root.leftChild)
            right_obj = self.postOrder(root.rightChild)

            tempLoc = ""
            tempType = ""
            current_code = []

            # if the root is a VARREF node and it does not have a type, it's a const.
            # Create a temp, determine the type, store code in IRnode.
            if root.node_type == node_enum(3).name and root.val_type == "":
                tempLoc = self.getTemp()  #gets a new temp value
                tempType = ""
                # determine if the const is an int or a float to get the correct instruction
                tempType = self.is_number(root.value)
                # get the correct instruction depending on the type
                op = self.returnOperator("STORE", tempType)
                node = IRNode(op, root.value, tempType, tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is a VARREF variable, store its value and type
            # do we not create an ir node yet??
            elif root.node_type == node_enum(3).name:
                tempLoc = root.value
                tempType = root.val_type

            # **** Is there a reason we aren't storing the type here?
            # for READ nodes, iterate through value, type tuples
            elif root.node_type == node_enum(7).name:
                for value in root.value:
                    tempLoc = root.value[0]
                    tempType = root.value[1]
                    #get the correct instruction depending on the type
                    op = self.returnOperator("READ", tempType)
                    node = IRNode(op, tempLoc, "", tempLoc)
                    tiny_list.append(node.operator_map[op](node))
                    current_code.append(node)

            # if the root is an assignment statement, store the result from the right child
            # into the variable of the left child
            elif root.node_type == node_enum(4).name:
                tempLoc = root.leftChild.value
                tempType = left_obj.resType
                #get the correct instruction depending on the type
                op = self.returnOperator("STORE", tempType)
                node = IRNode(op, right_obj.resultLoc, "", tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is an ADDOP, add/subtract the memory locations together
            # and store in a new temp
            elif root.node_type == node_enum(1).name:
                tempLoc = self.getTemp()
                tempType = left_obj.resType
                #get the correct instruction depending on the type
                opType = self.getOpType(root.value)
                op = self.returnOperator(opType, tempType)
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc,
                              tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # if the root is a MULOP, multiply/divide the child memory locations together
            # and store in a new temp
            elif root.node_type == node_enum(2).name:
                tempLoc = self.getTemp()
                tempType = right_obj.resType
                #get the correct instruction depending on the type
                opType = self.getOpType(root.value)
                op = self.returnOperator(opType, tempType)
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc,
                              tempLoc)
                tiny_list.append(node.operator_map[op](node))
                current_code.append(node)

            # for WRITE nodes, iterate through value, type tuples
            elif root.node_type == node_enum(8).name:
                for value in root.value:
                    tempLoc = root.value[0]
                    tempType = root.val_type[1]
                    op = self.returnOperator("WRITE", tempType)
                    node = IRNode(op, "", "", tempLoc)
                    tiny_list.append(node.operator_map[op](node))
                    current_code.append(node)

            elif root.node_type == node_enum(10).name:
                node = IRNode("LABEL", '', '', root.value)
                tiny_list.append(node.operator_map["LABEL"](node))
                current_code.append(node)
                # print("Write node contents: " + root.val_type + " " + root.value)

            # iterate through statement list node - not sure what functionality to add here
            elif root.node_type == node_enum(5).name:
                for value in root.value:
                    self.postOrder(value)

            # if the node is a while node
            elif root.node_type == node_enum(14).name:
                #use the while label to find the destination label
                tempLoc = jumpLabel(root.val_type.value)
                #get the comparison operator
                comp = value[0].value
                #not super sure if I need to do this
                #if so, recurse on the nodes in the value list
                for value in root.value:
                    self.postOrder(value)
                #for the IRNodes that are in the current_code list, find the node for the comparison operator
                for code in current_code:
                    # if you find the correct node, remove the node so it can be modified
                    if comp == code.operation:
                        node = current_code.remove(code)
                #set the node's destination location with the label
                node.result = tempLoc
                current_code.append(node)
                tiny_list.append(node.operator_map["JUMP"](node))

            elif root.node_type == node_enum(9).name:
                tempType = left_obj.resType
                opType = self.getOpType(root.value)
                node = IRNode(op, left_obj.resultLoc, right_obj.resultLoc, "")
                current_code.append(node)

            # I commented this out because it ended up storing the instructions in the incorrect order
            # if root.leftChild:
            #     for code in left_obj.getCode():
            #         current_code.append(code)
            # if root.rightChild:
            #     for code in right_obj.getCode():
            #         current_code.append(code)

            # adding the code objects to the new list I created
            co = CodeObject(current_code, tempLoc, tempType)
            if co is not None:
                code_objects.append(co)
            return co
Пример #23
0
 def enterExpr(self, ctx: LittleParser.ExprContext):
     if ctx.getChild(0).getChildCount() == 0:
         ast_stack.push(ASTNode(node_enum(0).name, ""))  #push