def jmp(vm): if not (isinstance(vm.top, int) or isinstance(vm.top, long)): raise errors.MachineError("Jump address must be an integer: %s" % str(vm.top)) addr = vm.pop() if 0 <= addr < len(vm.code): vm.instruction_pointer = addr else: raise errors.MachineError("Jump address out of range: %s" % str(addr))
def mod(vm): a = vm.pop() b = vm.pop() _assert_number(a, b) if a == 0: raise errors.MachineError(ZeroDivisionError("Division by zero")) vm.push(b % a)
def div(vm): divisor = vm.pop() dividend = vm.pop() _assert_number(dividend, divisor) if divisor == 0: raise errors.MachineError(ZeroDivisionError("Division by zero")) vm.push(dividend / divisor)
def cast_bool(vm): try: bool(vm.top) except ValueError: raise errors.MachineError("Cannot be cast to bool: '%s'" % str(vm.top)) else: vm.push(bool(vm.pop()))
def cast_int(vm): try: int(vm.top) except ValueError: raise errors.MachineError("Cannot be cast to int: '%s'" % str(vm.top)) else: vm.push(int(vm.pop()))
def pop(self): """Pops the data stack, returning the value.""" try: return self.data_stack.pop() except errors.MachineError as e: raise errors.MachineError( "%s: At index %d in code: %s" % (e, self.instruction_pointer, self.code_string))
def dot(vm, flush=True): write(vm, flush=False) try: if vm.output is not None: vm.output.write("\n") if flush: vm.output.flush() except IOError: raise errors.MachineError(IOError)
def write(vm, flush=True): value = str(vm.pop()) try: if vm.output is not None: vm.output.write(value) if flush: vm.output.flush() except IOError: raise errors.MachineError(StopIteration)
def lookup(instruction, instructions = None): """Looks up instruction, which can either be a function or a string. If it's a string, returns the corresponding method. If it's a function, returns the corresponding name. """ if instructions is None: instructions = default_instructions if isinstance(instruction, str): return instructions[instruction] elif hasattr(instruction, "__call__"): rev = dict(((v,k) for (k,v) in instructions.items())) return rev[instruction] else: raise errors.MachineError(KeyError("Unknown instruction: %s" % str(instruction)))
def _assert_number(*args): from crianza import interpreter for arg in args: if not interpreter.isnumber(arg): raise errors.MachineError("Not an integer: %s" % str(arg))
def _assert_binary(*args): from crianza import interpreter for arg in args: if not interpreter.isbinary(arg): raise errors.MachineError("Not boolean or numerical: %s" % str(arg))
def cast_str(vm): try: vm.push(str(vm.pop())) except ValueError as e: raise errors.MachineError(e)
def cast_float(vm): try: float(vm.top) except ValueError: raise errors.MachineError("Cannot be cast to float: '%s'" % str(vm.top))
def _assert_bool(*args): from crianza import interpreter for arg in args: if not interpreter.isbool(arg): raise errors.MachineError("Not a boolean: %s" % str(arg))