Beispiel #1
0
    def __init__(self, debug=False, banner=BANNER, ps1=PS1, ps2=PS2):
        self.debug = debug
        self.banner = banner
        self.ps1 = ps1
        self.ps2 = ps2

        self.frame = Frame()
        self.compiler = Compiler()
Beispiel #2
0
class Interpreter(object):

    def __init__(self, debug=False, banner=BANNER, ps1=PS1, ps2=PS2):
        self.debug = debug
        self.banner = banner
        self.ps1 = ps1
        self.ps2 = ps2

        self.frame = Frame()
        self.compiler = Compiler()

    def runstring(self, s):
        ast = parse(s)

        bc = self.compiler.compile(ast)
        if self.debug:  # pragma: no cover
            print bc.dump()

        return self.run(bc)

    def runfile(self, filename):
        f = open_file_as_stream(filename)
        s = f.readall()
        f.close()

        return self.runstring(s)

    def repl(self, banner=None, ps1=None, ps2=None):  # pragma: no cover
        banner = banner or self.banner
        ps1 = ps1 or self.ps1
        ps2 = ps2 or self.ps2

        print banner

        while True:
            try:
                s = readline(ps1).strip()
            except EOFError:
                break

            self.runstring(s)

    def run(self, bc):  # noqa
        frame = self.frame
        code = bc.code
        pc = 0

        while True:
            # required hint indicating this is the top of the opcode dispatch
            driver.jit_merge_point(
               pc=pc, code=code, bc=bc, frame=frame, self=self
            )

            c = ord(code[pc])
            arg = ord(code[pc + 1])
            pc += 2

            if c == bytecode.LOAD_CONSTANT:
                w_constant = bc.constants[arg]
                frame.push(w_constant)
            elif c == bytecode.LOAD_STRING:
                w_constant = bc.strconstants[arg]
                frame.push(w_constant)
            elif c == bytecode.DISCARD_TOP:
                frame.pop()
            elif c == bytecode.RETURN:
                return
            elif c == bytecode.BINARY_ADD:
                right = frame.pop()
                left = frame.pop()
                w_res = left.add(right)
                frame.push(w_res)
            elif c == bytecode.BINARY_LT:
                right = frame.pop()
                left = frame.pop()
                frame.push(left.lt(right))
            elif c == bytecode.JUMP_IF_FALSE:
                if not frame.pop().is_true():
                    pc = arg
            elif c == bytecode.JUMP_BACKWARD:
                pc = arg
                # required hint indicating this is the end of a loop
                driver.can_enter_jit(
                  pc=pc, code=code, bc=bc, frame=frame, self=self
                )
            elif c == bytecode.PRINT:
                item = frame.pop()
                print item.str()
            elif c == bytecode.ASSIGN:
                frame.vars[arg] = frame.pop()
            elif c == bytecode.LOAD_VAR:
                frame.push(frame.vars[arg])
            elif c == bytecode.LOAD_FUNC:
                w_function = bc.functions[arg]
                frame.push(w_function)
            elif c == bytecode.CALL:
                w_function = frame.pop()
                frame.push(self.run(w_function.bc))
            else:  # pragma: no cover
                # This should never happen!
                assert False