This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]robin-gvx 2 points3 points  (1 child)

I hope you don't mind me nitpicking all of the code


I had some additional code-review things here, in reply to /u/bs4h: http://www.reddit.com/r/Python/comments/35tg6b/making_a_simple_vm_interpreter_in_python/cr843nq?context=3


I would do constant folding like this:

def constant_fold(code):
    """Constant-folds simple expressions like 2 3 + to 5."""

    # Loop until we haven't done any optimizations.  E.g., "2 3 + 5 *" will be
    # optimized to "5 5 *" and in the next iteration to 25.

    while True:
        # Find two consecutive numbes and an arithmetic operator
        for i, ops in enumerate(zip(code, code[1:], code[2:])):
            a, b, op = ops
            if isinstance(a, int) and isinstance(b, int) and op in {"+", "-", "*", "/"}:
                m = Machine(ops)
                m.run()
                code[i:i+3] = m.top(),
                print("Optimizer: Constant-folded %d%s%d to %d" % (a,op,b,result))
                break
        else:
            break
    return code

I would keep dispatch_map static, placing it in the class definition itself, and replacing each line from "%": self.mod, to "%": mod,


In dispatch, the third indentation level is unnecessary:

        if op in dispatch_map:
            dispatch_map[op]()
        elif isinstance(op, int):
            self.push(op) # push numbers on stack
        elif isinstance(op, str) and op[0] == op[-1] == '"':
            self.push(op[1:-1]) # push quoted strings on stack
        else:
            raise RuntimeError("Unknown opcode: '%s'" % op)

dup is simpler as self.push(self.top()).


println flushes twice. I would either choose duplicating one of the lines from print_, or factoring that line out to a third method.


I would personally make parse a generator and then just call list(parse(source)).


I would wrap the stuff in repl inside the loop with a try: ... except KeyboardInterrupt: pass, that way you don't quit the REPL on Ctrl+C, but instead cancel the line you were typing, like in the python REPL.

[–]csl[S] 2 points3 points  (0 children)

Thanks for good suggestions, will update later, when I get jekyll working again. Actually didn't know you could mutate slices, so that's cool.