# HG changeset patch # User Paul Boddie # Date 1232929530 -3600 # Node ID 168c6f68045d406a0d2252cb141f179a71764655 # Parent 831ab0ba3de61ba9b7cba1db5d45c60edf121e5a Fixed the output representation of Block instances. Added support for some native methods, changing the invocation mechanism to use a special dictionary for mapping method names to method implementations. Moved run-time constant initialisation into the RSVPMachine class. Fixed the CheckException instruction, made _CheckInstance return a value, added a _MakeObject method. Added notes about the current solution for instance/class compatibility testing. diff -r 831ab0ba3de6 -r 168c6f68045d docs/structures.txt --- a/docs/structures.txt Sun Jan 25 02:56:16 2009 +0100 +++ b/docs/structures.txt Mon Jan 26 01:25:30 2009 +0100 @@ -273,6 +273,8 @@ effectively be a matrix with each dimension indexed using the same sequence of codes for each of the classes in a program. -An alternative might be to insert descendants as special attributes into the -object/attribute lookup table. This would also require an extra key to be -retained, since each class would have its own attribute code. +The current solution is to insert descendants as special attributes into the +object/attribute lookup table. This requires an extra key to be retained, +since each class must provide its own attribute code such that upon an +instance/class compatibility test, the code may be obtained and used in the +object table. diff -r 831ab0ba3de6 -r 168c6f68045d micropython/rsvp.py --- a/micropython/rsvp.py Sun Jan 25 02:56:16 2009 +0100 +++ b/micropython/rsvp.py Mon Jan 26 01:25:30 2009 +0100 @@ -20,11 +20,12 @@ """ from micropython.data import Attr, Const +from micropython.common import Block def name(attr): if isinstance(attr, Attr): return attr.name or "" - elif isinstance(attr, Const): + elif isinstance(attr, (Block, Const)): return attr else: return attr.full_name() or "" diff -r 831ab0ba3de6 -r 168c6f68045d rsvp.py --- a/rsvp.py Sun Jan 25 02:56:16 2009 +0100 +++ b/rsvp.py Mon Jan 26 01:25:30 2009 +0100 @@ -73,7 +73,7 @@ "A really simple virtual processor." - def __init__(self, memory, objlist, paramlist, attr_error, type_error, pc=None, debug=0): + def __init__(self, memory, objlist, paramlist, pc=None, debug=0): """ Initialise the processor with a 'memory' (a list of values containing @@ -81,8 +81,8 @@ """ self.memory = memory - self.objlist = objlist - self.paramlist = paramlist + self.objlist = objlist.as_raw() + self.paramlist = paramlist.as_raw() self.pc = pc or 0 self.debug = debug @@ -109,8 +109,12 @@ # Constants. - self.attr_error = attr_error - self.type_error = type_error + self.attr_error = objlist.access("__builtins__", "AttributeError").value.location + self.type_error = objlist.access("__builtins__", "TypeError").value.location + + # Native class constants. + + self.int_class = objlist.access("__builtins__", "int").value.location # Debugging methods. @@ -280,8 +284,11 @@ PC to 'next' afterwards; otherwise, set PC to 'addr'. """ + # Trap library functions introduced through the use of strings instead + # of proper locations. + if isinstance(addr, str): - getattr(self, addr)() + self.native_functions[addr](self) return next else: self.push_pc(self.pc + 1) @@ -319,10 +326,7 @@ def MakeObject(self): size = self.operand context, ref = self.value - classcode, attrcode, codeaddr, codedetails, instance = self.load(ref) - addr = self.new(size) - # Set the header to resemble the class. - self.save(addr, (classcode, attrcode, None, None, 1)) # NOTE: __call__ method not yet provided. + addr = self._MakeObject(size, ref) # Introduce null context for new object. self.value = None, addr @@ -438,7 +442,7 @@ # Check the details of the proposed context and the target's context. - self._CheckInstance(ref, target_context) + self.status = self._CheckInstance(ref, target_context) def JumpWithFrame(self): codeaddr, codedetails = self.callable @@ -498,7 +502,7 @@ self.handler_stack.pop() def CheckException(self): - self._CheckInstance(self.exception, self.value[1]) + self.status = self.exception is not None and self._CheckInstance(self.exception, self.value[1]) def TestIdentity(self): self.status = self.value[1] == self.source[1] @@ -522,9 +526,55 @@ element = self.objlist[target_classcode + attrcode] attr_index, class_attr, replace_context, offset = element - if attr_index == attrcode: - self.status = 1 - else: - self.status = 0 + return attr_index == attrcode + + def _MakeObject(self, size, ref): + classcode, attrcode, codeaddr, codedetails, instance = self.load(ref) + addr = self.new(size) + # Set the header to resemble the class. + self.save(addr, (classcode, attrcode, None, None, 1)) # NOTE: __call__ method not yet provided. + return addr + + # Native function implementations. + + def builtins_object_init(self): + pass + + def builtins_int_init(self): + pass + + def builtins_int_add(self): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + right_context, right = self.frame_stack[frame + 1] + + # Test operand suitability. + + if not self._CheckInstance(left, self.int_class) and self._CheckInstance(right, self.int_class): + self.exception = self.type_error + return self.RaiseException() + + # NOTE: Assume single location for data. + + left_data = left + 1 + right_data = right + 1 + + # Make a new object. + + addr = self._MakeObject(2, self.int_class) + self.save(addr + 1, self.load(left_data) + self.load(right_data)) + + # Return the new object (with a null context). + + self.result = None, addr + + native_functions = { + "__builtins__.object.__init__" : builtins_object_init, + "__builtins__.int.__init__" : builtins_int_init, + "__builtins__.int.__add__" : builtins_int_add, + } # vim: tabstop=4 expandtab shiftwidth=4 diff -r 831ab0ba3de6 -r 168c6f68045d test.py --- a/test.py Sun Jan 25 02:56:16 2009 +0100 +++ b/test.py Mon Jan 26 01:25:30 2009 +0100 @@ -37,12 +37,10 @@ pt = program.get_parameter_table() objlist = ot.as_list() paramlist = pt.as_list() - attr_error = objlist.access("__builtins__", "AttributeError").value.location - type_error = objlist.access("__builtins__", "TypeError").value.location print "Getting raw image..." rc = program.get_raw_image() print "Initialising the machine..." - rm = rsvp.RSVPMachine(rc, objlist.as_raw(), paramlist.as_raw(), attr_error, type_error, debug=debug) + rm = rsvp.RSVPMachine(rc, objlist, paramlist, debug=debug) rm.pc = program.code_location return rm