Implementing Brainfuck loops in an interpreter

前端 未结 5 2301
隐瞒了意图╮
隐瞒了意图╮ 2021-02-20 07:53

I want to build a Brainfuck (Damn that name) interpreter in my freshly created programming language to prove it\'s turing-completeness.

Now, everything is clear so far (

5条回答
  •  遇见更好的自我
    2021-02-20 08:41

    Here is my "optimizing" version of interpreter, that pre-compiles the loop jumps.

    def interpret2(code):
        data = [0] * 5000   # data memory
        cp = 0              # code pointer
        dp = 0              # data pointer
        # pre-compile a jump table
        stack = []
        jump = [None] * len(code)
        for i,o in enumerate(code):
            if o=='[':
                stack.append(i)
            elif o==']':
                jump[i] = stack.pop()
                jump[jump[i]] = i
        # execute
        while cp < len(code):
            cmd = code[cp]
            if   cmd == '>': dp += 1
            elif cmd == '<': dp -= 1
            elif cmd == '+': data[dp] += 1 
            elif cmd == '-': data[dp] -= 1 
            elif cmd == '.': stdout.write(chr(data[dp]))
            elif cmd == ',': data[dp] = ord(stdin.read(1))
            elif cmd == '[' and not data[dp]: # skip loop if ==0
                cp = jump[cp]
            elif cmd == ']' and data[dp]:     # loop back if !=0
                cp = jump[cp]
            cp += 1
    

    It does a dry run of the code, keeping track of the brackets (in a stack) and marks the goto addresses in parallel jump array which is later consulted during execution.

    I compared the execution speed on long-running BF program (calculate N digits of Pi) and this increased the speed 2x compared to an innocent implementation in which source is scanned forward to exit [ and scanned backwards to loop on ].

提交回复
热议问题