Example #1
0
    def visit(self, node: LogicalExpression):
        self.visit(node[0])
        self.visit(node[2])
        op = node[1]

        if op == AND:
            self.context.add_opcode(OPCode(OPCodeType.BOOLEAN_AND))
        elif op == OR:
            self.context.add_opcode(OPCode(OPCodeType.BOOLEAN_OR))
Example #2
0
    def visit(self, node: ProcedureStatement):
        for child in node:
            self.visit(child)

        self.context.add_opcode(OPCode(OPCodeType.PUSH, [node.proc_name]))
        self.context.add_opcode(
            OPCode(OPCodeType.CALL, [
                len(node.arguments_node)
                if node.arguments_node is not None else 0
            ]))
Example #3
0
    def visit(self, node: AdditiveExpression):
        for index in range(0, len(node) - 1, 2):
            self.visit(node[index])
            self.visit(node[index + 2])
            op = node[index + 1]

            if op == ADD:
                self.context.add_opcode(OPCode(OPCodeType.SUM))
            elif op == SUB:
                self.context.add_opcode(OPCode(OPCodeType.SUBTRACT))
Example #4
0
    def visit(self, node: MultiplicativeExpression):
        for index in range(0, len(node) - 1, 2):
            self.visit(node[index])
            self.visit(node[index + 2])
            op = node[index + 1]

            if op == MUL:
                self.context.add_opcode(OPCode(OPCodeType.MULTIPLY))
            elif op == DIV:
                self.context.add_opcode(OPCode(OPCodeType.DIVIDE))
            elif op == MOD:
                self.context.add_opcode(OPCode(OPCodeType.MODULO))
Example #5
0
    def visit(self, node: SubprogramDeclaration):
        for child in node:
            self.visit(child)

        if node.header.is_function:
            # If function have return type - returning Variable with function name
            self.context.add_opcode(
                OPCode(OPCodeType.PUSH, [node.header.proc_name]))
            self.context.add_opcode(OPCode(OPCodeType.RETURN, [1]))
        else:
            # If function dont have return type - returning nil
            self.context.add_opcode(OPCode(OPCodeType.PUSH, ['nil']))
            self.context.add_opcode(OPCode(OPCodeType.RETURN, [1]))

        self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))
Example #6
0
    def visit(self, node: RelationalExpression):
        self.visit(node[0])
        self.visit(node[2])
        op = node[1]

        if op == LT:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_LT))
        elif op == LE:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_LE))
        elif op == GT:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_GT))
        elif op == GE:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_GE))
        elif op == EQ:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_EQ))
        elif op == NEQ:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_NEQ))
Example #7
0
    def visit(self, node: WhileStatement):
        self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))

        condition_address = self.context.current_address
        self.visit(node.cond_expr)
        self.context.add_opcode(OPCode(OPCodeType.JUMP_NEG, [-1]))
        jump_fail_opcode = self.context.current_opcode

        self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))
        self.visit(node.while_stmt)
        self.context.add_opcode(OPCode(OPCodeType.JUMP, [-1]))
        jump_condition_opcode = self.context.current_opcode
        self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))
        fail_address = self.context.current_address + 1

        jump_condition_opcode.args[0] = condition_address
        jump_fail_opcode.args[0] = fail_address

        self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))
Example #8
0
    def visit(self, node: IfStatement):
        self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))

        self.visit(node.cond_expr)
        self.context.add_opcode(OPCode(OPCodeType.JUMP_NEG, [-1]))
        jump_fail_opcode = self.context.current_opcode
        fail_address = self.context.current_address + 1

        self.visit(node.if_body_stmt)
        self.context.add_opcode(OPCode(OPCodeType.JUMP, [-1]))
        jump_complete_opcode = self.context.current_opcode

        self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))

        if node.else_body_stmt is not None:
            self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))
            fail_address = self.context.current_address + 1
            self.visit(node.else_body_stmt)
            self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))

        complete_address = self.context.current_address + 1

        jump_complete_opcode.args[0] = complete_address
        jump_fail_opcode.args[0] = fail_address
Example #9
0
 def visit(self, node: Program):
     self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))
     for child in node:
         self.visit(child)
     self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))
Example #10
0
    def visit(self, node: SubprogramHeader):
        self.context.add_opcode(OPCode(OPCodeType.FUNCTION, [node.proc_name]))
        self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))

        if node.proc_params is not None:
            self.visit(node.proc_params)
Example #11
0
    def visit(self, node: Factor):
        for child in node:
            self.visit(child)

        if isinstance(node[0], Not):
            self.context.add_opcode(OPCode(OPCodeType.BOOLEAN_NOT))
Example #12
0
 def visit(self, node: VariableDeclaration):
     for var_name in node.var_identifiers:
         self.context.add_opcode(
             OPCode(OPCodeType.DECLARE_LOCAL, [var_name]))
Example #13
0
    def visit(self, node: SignedFactor):
        for child in node:
            self.visit(child)

        self.context.add_opcode(OPCode(OPCodeType.MINUS))
Example #14
0
 def visit(self, node: BooleanConstant):
     self.context.add_opcode(
         OPCode(OPCodeType.PUSH, [str(node.value).lower()]))
Example #15
0
 def visit(self, node: StringConstant):
     self.context.add_opcode(
         OPCode(OPCodeType.PUSH, ["\"" + str(node.value).lower() + "\""]))
Example #16
0
    def visit(self, node: ForStatement):
        self.context.add_opcode(OPCode(OPCodeType.BEGIN_SCOPE))

        self.visit(node.initial_expression)
        self.context.add_opcode(
            OPCode(OPCodeType.ASSIGN, [node.variable.variable_name]))
        loop_iteration_address = self.context.current_address + 1
        self.visit(node.final_expression)

        self.context.add_opcode(
            OPCode(OPCodeType.PUSH, [node.variable.variable_name]))

        if (node.to_downto == 'to'):
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_GE))
        else:
            self.context.add_opcode(OPCode(OPCodeType.COMPARE_LE))

        self.context.add_opcode(OPCode(OPCodeType.JUMP_NEG, [-1]))

        jump_to_loop_end_opcode = self.context.current_opcode

        self.visit(node.for_stmt)

        if (node.to_downto == 'to'):
            self.context.add_opcode(OPCode(OPCodeType.PUSH, ['1']))
            self.context.add_opcode(
                OPCode(OPCodeType.PUSH, [node.variable.variable_name]))
            self.context.add_opcode(OPCode(OPCodeType.SUM))
        else:
            self.context.add_opcode(
                OPCode(OPCodeType.PUSH, [node.variable.variable_name]))
            self.context.add_opcode(OPCode(OPCodeType.PUSH, ['1']))
            self.context.add_opcode(OPCode(OPCodeType.SUBTRACT))

        self.context.add_opcode(
            OPCode(OPCodeType.ASSIGN, [node.variable.variable_name]))
        self.context.add_opcode(
            OPCode(OPCodeType.JUMP, [loop_iteration_address]))
        self.context.add_opcode(OPCode(OPCodeType.END_SCOPE))
        jump_to_loop_end_opcode.args[0] = self.context.current_address
Example #17
0
 def visit(self, node: Parameters):
     for ident in reversed(node[:-1]):
         self.context.add_opcode(OPCode(OPCodeType.ASSIGN, [ident[0]]))
Example #18
0
 def visit(self, node: AssignmentStatement):
     self.visit(node.right)
     self.context.add_opcode(
         OPCode(OPCodeType.ASSIGN, [node.left.variable_name]))
Example #19
0
 def visit(self, node: EntireVariable):
     self.context.add_opcode(OPCode(OPCodeType.PUSH, [node.variable_name]))