コード例 #1
0
    def gen_asm(self):
        """
        returns a list of 'Instruction' and 'JumpFlag'
        """
        jump_id = Memory.gen_jump_name()
        inst = [Instruction("BRA", jump=jump_id, comment="jump over memory")]

        for idx, m in enumerate(self.memory):
            ref = self.memory[m]

            i = Instruction("MEM", adr=ref["value"], comment="<{0}>".format(m))
            inst.append(i)

            # Update the memory table so that we can use it
            # as a lookup table with for it's location in the file.
            #
            # Memory is always the first thing in the file, so
            # we can safely say the first index + 1 (jump over the BRA instruction)
            # will make it align properly.
            #
            ref["line"] = idx + 1
            self.memory[m] = ref

        inst.append(JumpFlag(jump_id))
        return inst
コード例 #2
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
    def visit_Assign(self, node):
        if isinstance(node.value, ast.Dict):
            variable = self.fp.get_variable(node.targets[0].id, True)
            variable.type = 'map'
            if len(variable.value) == 0:
                variable.value = {}
            # if self.context is None:
            #     variable.isGlobal = True
            self.fp.add_variable(variable)

        elif isinstance(node.targets[0], ast.Subscript):  # assign to map item
            gv = self.fp.new_guard_variable()
            inst = Instruction(
                self.guardStack[-1],
                [self.visit(node.value),
                 self.visit(node.targets[0])], [gv], 'neq')
            self.fp.add_instruction(inst)
            self.guardStack.append(gv)

            var = self.fp.new_variable()
            inst = Instruction(self.guardStack[-1], [
                self.fp.get_variable(node.targets[0].value.id),
                self.visit(node.targets[0].slice.value)
            ], [var], 'varof')
            self.fp.add_instruction(inst)
            inst = Instruction(self.guardStack[-1],
                               [self.fp.get_variable(node.value.id)], [var],
                               'assign')
            self.fp.add_instruction(inst)
            self.guardStack.pop()
        else:
            var = self.fp.get_variable(node.targets[0].id, True)
            inst = Instruction(self.guardStack[-1], [self.visit(node.value)],
                               [var], 'assign')
            self.fp.add_instruction(inst)
コード例 #3
0
    def gen_runtime_expression(self,
                               tokens,
                               memory,
                               functions=None,
                               *,
                               result_var=None):
        rpn_notation = self._apply_shunting_yard(tokens,
                                                 None,
                                                 substitute_vars=False)

        stack = Stack()
        asm = AsmExpressionContainer(tokens)

        # print("rpn_notation: " + str([str(t.value) for t in rpn_notation])) # debug

        temp = Memory.gen_temp_name()
        memory.add_reference(temp)

        for t in rpn_notation:
            if t.token == TokenType.Identifier:
                stack.push(t)
            elif self._is_operator(t):
                # take N arguments off the stack
                # TODO: Expand to include functions
                var2 = stack.pop()
                var1 = stack.pop()

                if var1.value.isdigit():  #var1.token == TokenType.IntValue:
                    var1_name = Memory.gen_temp_name()
                    memory.add_reference(var1_name, var1.value)
                else:
                    var1_name = var1.value

                if var2.value.isdigit():  #.token == TokenType.IntValue:
                    var2_name = Memory.gen_temp_name()
                    memory.add_reference(var2_name, var2.value)
                else:
                    var2_name = var2.value

                if t.token == TokenType.Add:
                    asm.load(var1_name)
                    asm.add(Instruction("ADD", variable=var2_name))
                    asm.store(temp)
                elif t.token == TokenType.Sub:
                    asm.load(var1_name)
                    asm.add(Instruction("SUB", variable=var2_name))
                    asm.store(temp)

                stack.push(Token(temp, TokenType.Identifier))

            else:
                print("ERROR: " + token.value)

        asm.load(temp)
        asm.store(result_var)

        return asm
コード例 #4
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
    def visit_Return(self, node):
        ret_val = self.fp.get_variable('return')
        if ret_val is None:
            ret_val = self.fp.new_variable('return')

        if isinstance(node.value, ast.Subscript):
            inst = Instruction(self.guardStack[-1], [
                self.fp.get_variable(node.value.value.id),
                self.visit(node.value.slice.value)
            ], [ret_val], 'varof')
        else:
            inst = Instruction(self.guardStack[-1], [self.visit(node.value)],
                               [ret_val], 'assign')
        self.fp.add_instruction(inst)
コード例 #5
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
 def visit_Subscript(self, node):
     var = self.fp.new_variable()
     inst = Instruction(self.guardStack[-1], [
         self.fp.get_variable(node.value.id),
         self.visit(node.slice.value)
     ], [var], 'varof')
     self.fp.add_instruction(inst)
     return var
コード例 #6
0
ファイル: compiler.py プロジェクト: Syntox32/LittleMan
    def _handle_if(self, ex):
        # skip the identifier and the '=' char
        relevant_tokens = ex.tokens[2:len(ex.tokens) - 1]

        asm = AsmExpressionContainer(ex)
        result_var = ""

        if len(relevant_tokens) == 1 and relevant_tokens[0].token == TokenType.Identifier \
                and not relevant_tokens[0].value.isdigit():
            # single token with a value, should be dynamic
            #print("IT'S AN IDENTIFIER")
            var_name = str(relevant_tokens[0].value)
            result_var = var_name
            #self.mem.add_reference(temp, self.mem.get_reference(relevant_tokens[0].value))
        else:
            temp = Memory.gen_temp_name()
            #val = int(self.solver.solve_expr(ex.tokens[2:len(ex.tokens)-1], self.mem, None))
            #ex.value = val
            #var_name = add_mem_ref(val)
            if len(relevant_tokens) == 1 and relevant_tokens[0].value.isdigit(
            ):
                # one token that is an int value
                self.mem.add_reference(temp, relevant_tokens[0].value)
            elif len(relevant_tokens) == 1 and self.mem.has_reference(
                    relevant_tokens[0].value):
                # one token that is an identifier
                #self.mem.add_reference(temp, self.mem.get_reference(relevant_tokens[0].value))
                temp = relevant_tokens[0].value
            else:
                # several tokens, let's solve it
                self.mem.add_reference(temp)
                instructions = self.solver.gen_runtime_expression(
                    relevant_tokens, self.mem, result_var=temp)
                asm.merge(instructions)
            result_var = temp

        asm.load(result_var)
        #print("a.load(var_name); == " + var_name)
        jp_name = Memory.gen_jump_name()
        #asm.load(temp)
        asm.add(Instruction("BRZ", jump=jp_name, comment="jump if zero"))

        for e in ex.expressions:
            ae = self._handle_expr(e)
            if ae is not None:
                asm.asm_expressions.append(ae)

        for aa in asm.asm_expressions:
            instrs = aa.get_instructions()
            for i in instrs:
                asm.add(i)

        asm.add(JumpFlag(jp_name))

        return asm
コード例 #7
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
    def visit_If(self, node):
        gv = self.fp.new_guard_variable()
        mapping = self.get_mapping(node.test.ops[0])
        inst = Instruction(
            self.guardStack[-1],
            [self.visit(node.test.left),
             self.visit(node.test.comparators[0])], [gv], mapping)
        self.fp.add_instruction(inst)
        self.guardStack.append(gv)
        for b in node.body:
            self.visit(b)
        o = self.guardStack.pop()

        if len(node.orelse) > 0:
            elsegv = self.fp.new_guard_variable()
            inst = Instruction(self.guardStack[-1], [o], [elsegv], 'not')
            self.fp.add_instruction(inst)
            self.guardStack.append(elsegv)
            self.visit(node.orelse[0])
            self.guardStack.pop()
コード例 #8
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
    def visit_Call(self, node):
        if isinstance(node.func, ast.Attribute):
            if node.func.attr == 'insert':
                gv = self.fp.new_guard_variable()
                var = self.fp.new_variable()
                inst = Instruction(
                    self.guardStack[-1],
                    [self.visit(node.func.value),
                     self.visit(node.args[0])], [var], 'varof')
                self.fp.add_instruction(inst)
                inst = Instruction(self.guardStack[-1],
                                   [var, self.visit(node.args[1])], [gv],
                                   'neq')
                self.fp.add_instruction(inst)
                self.guardStack.append(gv)

                inst = Instruction(self.guardStack[-1], [
                    self.fp.get_variable('pkt'),
                    self.fp.get_variable('inport')
                ], [var], 'toController')
                self.fp.add_instruction(inst)
                self.guardStack.pop()
            elif node.func.attr == 'lpm':
                var = self.fp.new_variable()
                inst = Instruction(self.guardStack[-1], [
                    self.fp.get_variable(node.func.value.id, True),
                    self.visit(node.args[0])
                ], [var], 'lpmvarof')
                self.fp.add_instruction(inst)
                return var
        else:
            var = self.fp.new_variable()
            args = []
            for arg in node.args:
                args.append(self.visit(arg))
            inst = Instruction(self.guardStack[-1], args, [var], node.func.id)
            self.fp.add_instruction(inst)
            return var
コード例 #9
0
ファイル: compiler.py プロジェクト: Syntox32/LittleMan
    def _handle_func_call(self, ex):
        # TODO: function lookup table with arument count and such
        #       cause right now all we have is "print" and "read"

        identifier = str(ex.tokens[2].value)
        a = AsmExpressionContainer(ex)
        name = str(ex.tokens[0].value)

        if name == "print":
            # identifier is a constant
            # so we just print it
            if identifier.isdigit():
                temp = Memory.gen_temp_name()
                self.mem.add_reference(temp, identifier)
                a.load(temp)
                a.do_print()
            else:
                a.load(identifier)
                a.do_print()

        elif name == "read":
            a.do_read()

            if self.mem.has_reference(identifier):
                temp = Memory.gen_temp_name()
                self.mem.add_reference(temp)

                a.add(Instruction("STA", variable=temp, comment="store input"))
                a.add(
                    Instruction("LDA",
                                variable=temp,
                                comment="variable 're-assignment'"))
                a.add(Instruction("STA", variable=identifier))
            else:
                print("im so done with this shit")

        return a
コード例 #10
0
ファイル: node_visitor.py プロジェクト: guodong/magellan-pcl
    def visit_FunctionDef(self, node):
        if node.name == 'on_packet':
            for arg in node.args.args:
                variable = Variable(arg.arg)
                self.fp.add_variable(variable)

            gv = self.fp.new_guard_variable()
            var = self.visit(node.args.args[1].annotation)
            inst = Instruction(self.guardStack[-1],
                               [self.fp.new_variable('inport_label'), var],
                               [gv], 'eq')
            self.fp.add_instruction(inst)
            self.guardStack.append(gv)
            self.generic_visit(node)
            self.guardStack.pop()
コード例 #11
0
ファイル: compiler.py プロジェクト: Syntox32/LittleMan
    def _parse(self, tokens):
        exprs = self._parse_expr_recursive(tokens)
        asm_list = []  # AsmExpression

        for ex in exprs:
            asm_expr = self._handle_expr(ex)

            if Utils.check_none_critical(asm_expr):
                Utils.debug("Compiler Error!: 'asm_expr' cannot be None.")

            asm_list.append(asm_expr)

        g = []
        mem_asm = self.mem.gen_asm()

        g.extend(mem_asm)
        # get the rest of the instructions
        for expr in asm_list:
            g.extend(expr.get_instructions())

        g.append(Instruction("HLT", comment="exit"))

        print("\nDebug preview:\n")
        for idx, gg in enumerate(g):
            print(str(idx) + ": " + str(gg))

        instructions = self._merge_jumps(g)

        instructions = self.mem.bind_mem(instructions)
        if instructions is None:
            print("Critical Error!: Memory bindings.")
            return None

        instructions = self._bind_jumps(instructions)
        if Utils.check_none_critical(instructions):
            print("Critical Error!: Jump bindings.")
            return None

        assembly = "\n".join([a.asm() for a in instructions])
        print("\nCompiled:\n")
        for idx, gg in enumerate(instructions):
            print(str(idx) + ": " + str(gg))

        return [], assembly
コード例 #12
0
ファイル: compiler.py プロジェクト: Syntox32/LittleMan
    def _handle_assignment(self, ex):
        """
        if the identifier does not exist, create a reference,
        solve the expression with the 'result_var' set to this identifier.

        if the identifier exists, create a temp reference to add the
        expression result into, then add the instructions to move the temp
        result variable into the reference.
        """
        identifier = str(ex.tokens[0].value)
        # skip the identifier and the '=' char
        relevant_tokens = ex.tokens[2:]

        asm = AsmExpressionContainer(ex)

        # reference does not exist
        if not self.mem.has_reference(identifier):
            if len(relevant_tokens) == 1 and relevant_tokens[0].value.isdigit(
            ):
                # one token that is an int value
                self.mem.add_reference(identifier, relevant_tokens[0].value)
            elif len(relevant_tokens) == 1 and self.mem.has_reference(
                    relevant_tokens[0].value):
                # one token that is an identifier
                self.mem.add_reference(
                    identifier,
                    self.mem.get_reference(relevant_tokens[0].value))
            else:
                # several tokens, let's solve it
                self.mem.add_reference(identifier)
                instructions = self.solver.gen_runtime_expression(
                    relevant_tokens, self.mem, result_var=identifier)
                asm.merge(instructions)

        # reference exists
        else:
            temp = Memory.gen_temp_name()
            #self.mem.add_reference(temp)

            if len(relevant_tokens) == 1 and relevant_tokens[0].value.isdigit(
            ):
                # one token that is an int value
                self.mem.add_reference(temp, relevant_tokens[0].value)
            elif len(relevant_tokens) == 1 and self.mem.has_reference(
                    relevant_tokens[0].value):
                # one token that is an identifier
                self.mem.add_reference(
                    temp, self.mem.get_reference(relevant_tokens[0].value))
            else:
                # several tokens, let's solve it
                self.mem.add_reference(temp)
                instructions = self.solver.gen_runtime_expression(
                    relevant_tokens, self.mem, result_var=temp)
                asm.merge(instructions)

            # the 'temp' variabel may be loaded in the
            # AC, but just to be sure we do it again.
            asm.add(
                Instruction("LDA",
                            variable=temp,
                            comment="variable 're-assignment'"))
            asm.add(Instruction("STA", variable=identifier))

        return asm