1.1 --- a/rsvp.py Sun Jan 25 02:56:16 2009 +0100
1.2 +++ b/rsvp.py Mon Jan 26 01:25:30 2009 +0100
1.3 @@ -73,7 +73,7 @@
1.4
1.5 "A really simple virtual processor."
1.6
1.7 - def __init__(self, memory, objlist, paramlist, attr_error, type_error, pc=None, debug=0):
1.8 + def __init__(self, memory, objlist, paramlist, pc=None, debug=0):
1.9
1.10 """
1.11 Initialise the processor with a 'memory' (a list of values containing
1.12 @@ -81,8 +81,8 @@
1.13 """
1.14
1.15 self.memory = memory
1.16 - self.objlist = objlist
1.17 - self.paramlist = paramlist
1.18 + self.objlist = objlist.as_raw()
1.19 + self.paramlist = paramlist.as_raw()
1.20 self.pc = pc or 0
1.21 self.debug = debug
1.22
1.23 @@ -109,8 +109,12 @@
1.24
1.25 # Constants.
1.26
1.27 - self.attr_error = attr_error
1.28 - self.type_error = type_error
1.29 + self.attr_error = objlist.access("__builtins__", "AttributeError").value.location
1.30 + self.type_error = objlist.access("__builtins__", "TypeError").value.location
1.31 +
1.32 + # Native class constants.
1.33 +
1.34 + self.int_class = objlist.access("__builtins__", "int").value.location
1.35
1.36 # Debugging methods.
1.37
1.38 @@ -280,8 +284,11 @@
1.39 PC to 'next' afterwards; otherwise, set PC to 'addr'.
1.40 """
1.41
1.42 + # Trap library functions introduced through the use of strings instead
1.43 + # of proper locations.
1.44 +
1.45 if isinstance(addr, str):
1.46 - getattr(self, addr)()
1.47 + self.native_functions[addr](self)
1.48 return next
1.49 else:
1.50 self.push_pc(self.pc + 1)
1.51 @@ -319,10 +326,7 @@
1.52 def MakeObject(self):
1.53 size = self.operand
1.54 context, ref = self.value
1.55 - classcode, attrcode, codeaddr, codedetails, instance = self.load(ref)
1.56 - addr = self.new(size)
1.57 - # Set the header to resemble the class.
1.58 - self.save(addr, (classcode, attrcode, None, None, 1)) # NOTE: __call__ method not yet provided.
1.59 + addr = self._MakeObject(size, ref)
1.60 # Introduce null context for new object.
1.61 self.value = None, addr
1.62
1.63 @@ -438,7 +442,7 @@
1.64
1.65 # Check the details of the proposed context and the target's context.
1.66
1.67 - self._CheckInstance(ref, target_context)
1.68 + self.status = self._CheckInstance(ref, target_context)
1.69
1.70 def JumpWithFrame(self):
1.71 codeaddr, codedetails = self.callable
1.72 @@ -498,7 +502,7 @@
1.73 self.handler_stack.pop()
1.74
1.75 def CheckException(self):
1.76 - self._CheckInstance(self.exception, self.value[1])
1.77 + self.status = self.exception is not None and self._CheckInstance(self.exception, self.value[1])
1.78
1.79 def TestIdentity(self):
1.80 self.status = self.value[1] == self.source[1]
1.81 @@ -522,9 +526,55 @@
1.82
1.83 element = self.objlist[target_classcode + attrcode]
1.84 attr_index, class_attr, replace_context, offset = element
1.85 - if attr_index == attrcode:
1.86 - self.status = 1
1.87 - else:
1.88 - self.status = 0
1.89 + return attr_index == attrcode
1.90 +
1.91 + def _MakeObject(self, size, ref):
1.92 + classcode, attrcode, codeaddr, codedetails, instance = self.load(ref)
1.93 + addr = self.new(size)
1.94 + # Set the header to resemble the class.
1.95 + self.save(addr, (classcode, attrcode, None, None, 1)) # NOTE: __call__ method not yet provided.
1.96 + return addr
1.97 +
1.98 + # Native function implementations.
1.99 +
1.100 + def builtins_object_init(self):
1.101 + pass
1.102 +
1.103 + def builtins_int_init(self):
1.104 + pass
1.105 +
1.106 + def builtins_int_add(self):
1.107 + frame = self.local_sp_stack[-1]
1.108 +
1.109 + # Get operands addresses.
1.110 +
1.111 + left_context, left = self.frame_stack[frame]
1.112 + right_context, right = self.frame_stack[frame + 1]
1.113 +
1.114 + # Test operand suitability.
1.115 +
1.116 + if not self._CheckInstance(left, self.int_class) and self._CheckInstance(right, self.int_class):
1.117 + self.exception = self.type_error
1.118 + return self.RaiseException()
1.119 +
1.120 + # NOTE: Assume single location for data.
1.121 +
1.122 + left_data = left + 1
1.123 + right_data = right + 1
1.124 +
1.125 + # Make a new object.
1.126 +
1.127 + addr = self._MakeObject(2, self.int_class)
1.128 + self.save(addr + 1, self.load(left_data) + self.load(right_data))
1.129 +
1.130 + # Return the new object (with a null context).
1.131 +
1.132 + self.result = None, addr
1.133 +
1.134 + native_functions = {
1.135 + "__builtins__.object.__init__" : builtins_object_init,
1.136 + "__builtins__.int.__init__" : builtins_int_init,
1.137 + "__builtins__.int.__add__" : builtins_int_add,
1.138 + }
1.139
1.140 # vim: tabstop=4 expandtab shiftwidth=4