Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- This is a quick experiment in implementing a stack machine that
- executes a set of given op codes. Just for fun.
- """
- class VMError(Exception):
- def __init__(self, kind):
- self.kind = kind
- self.message = ''
- def __str__(self):
- print "MICROVM", self.kind, self.message
- def __call__(self, message):
- self.message = message
- return self
- StackError = VMError('StackError')
- class Stack(list):
- def __init__(self, parent=None):
- self.parent = parent
- def pop(self):
- try:
- return super(Stack, self).pop()
- except:
- raise StackError('stack is empty')
- class MicroOp(object):
- """ MicroOp is the implementation of an OpCode """
- def __init__(self, bytecode, mnemonic):
- self.bytecode = bytecode
- self.mnemonic = mnemonic
- def execute(self, *args, **kwargs):
- pass
- class ADD(MicroOp):
- def execute(self, *args, **kwargs):
- stack = kwargs.get('stack')
- opnum = args[0]
- opargs = [stack.pop() for i in range(opnum)]
- result = sum(opargs)
- stack.append(result)
- return result
- class PUSH(MicroOp):
- def execute(self, *args, **kwargs):
- stack = kwargs.get('stack')
- stack.extend(args)
- class PRINT(MicroOp):
- def execute(self, *args, **kwargs):
- stack = kwargs.get('stack')
- opnum = args[0] if args else 1
- opargs = [str(stack.pop()).replace('"', '').replace("'", '') for i in range(opnum)]
- print ' '.join(opargs)
- OPCODES = {
- 0x01 : PUSH(0x01, 'PUSH'),
- 0x10 : ADD(0x10, 'ADD'),
- 0x20 : PRINT(0x20, 'PRINT'),
- }
- MNEMONICS = { microop.mnemonic : opcode for opcode, microop in OPCODES.iteritems() }
- class VM(object):
- """ A VM provides the execution context to run a byte code program """
- def __init__(self):
- self.stack = Stack()
- def run(self, code):
- for op, args in code:
- OPCODES[op].execute(*args, stack=self.stack)
- class Compiler(object):
- """ The compiler takes source code and produces byte code """
- def _native_value(self, value):
- tries = [int, float, str]
- for t in tries:
- try:
- return t(value)
- except:
- pass
- return value
- def compile(self, source):
- code = []
- for loc, line in enumerate(source.split('\n')):
- if not line:
- continue
- parsed = line.split(' ', 1)
- mnemonic, args = parsed[0], parsed[1:]
- args = [self._native_value(arg) for arg in args]
- opcode = MNEMONICS.get(mnemonic)
- if opcode:
- code.append((opcode, args))
- else:
- raise SyntaxError("%d: invalid statement >%s<" % (loc, line))
- return code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement