# HG changeset patch # User Paul Boddie # Date 1240709052 -7200 # Node ID 7165b3c8dca892dc9b1066fc52df30c9d56ebf9a # Parent 7c52463d3038ff047e1276ec13ca0fc7dd7d8d72 Fixed basestring.__radd__ duplication. Fixed the StoreTemp RSVP instruction (which uses the current value). Removed various unnecessary default objects. Removed code generation of instantiators for built-in classes. Removed direct calling of __init__ methods where class invocation is detected. Introduced a size member to object headers which may be overridden by the MakeObject instruction. Added RSVP support for the list instantiator. Added empty and minimal test programs. diff -r 7c52463d3038 -r 7165b3c8dca8 docs/concepts.txt --- a/docs/concepts.txt Thu Apr 23 00:52:33 2009 +0200 +++ b/docs/concepts.txt Sun Apr 26 03:24:12 2009 +0200 @@ -189,13 +189,13 @@ certain common features and operations are supported in the same way for all of these things. To permit this, a common data structure format is used. - Header........................................ Attributes................. + Header............................................................................ Attributes................. - Identifier Identifier Address Details Object Object ... + Identifier Identifier Address Details Flag Identifier Size Object Object ... - 0 1 2 3 4 5 6 - classcode attrcode invocation invocation __class__ attribute ... - reference #args, reference reference + 0 1 2 3 4 5 6 7 8 9 + classcode attrcode invocation invocation instance funccode size __class__ attribute ... + reference #args, status reference reference defaults reference @@ -207,34 +207,34 @@ Class C: - 0 1 2 3 4 5 6 - classcode attrcode __new__ __new__ class type attribute ... - for C for C reference #args, reference reference + 0 1 2 3 4 5 6 7 8 9 + classcode attrcode __new__ __new__ false size class type attribute ... + for C for C reference #args, reference reference defaults reference Instance of C: - 0 1 2 3 4 5 6 - classcode attrcode C.__call__ C.__call__ class C attribute ... - for C for C reference #args, reference reference + 0 1 2 3 4 5 6 7 8 9 + classcode attrcode C.__call__ C.__call__ true size class C attribute ... + for C for C reference #args, reference reference (if exists) defaults reference Function f: - 0 1 2 3 4 5 6 - classcode attrcode code code class attribute ... - for for reference #args, function (default) - function function defaults reference reference + 0 1 2 3 4 5 6 7 8 9 + classcode attrcode code code true funccode size class attribute ... + for for reference #args, function (default) + function function defaults reference reference reference Module m: - 0 1 2 3 4 5 6 - classcode attrcode (unused) (unused) module type attribute ... - for m for m reference (global) - reference + 0 1 2 3 4 5 6 7 8 9 + classcode attrcode (unused) (unused) true module type attribute ... + for m for m reference (global) + reference The __class__ Attribute ----------------------- @@ -246,6 +246,13 @@ Function: refers to the function class Instance: refers to the class instantiated to make the object +Lists and Tuples +---------------- + +The built-in list and tuple sequences employ variable length structures using +the attribute locations to store their elements, where each element is a +reference to a separately stored object. + Testing Instance Compatibility with Classes (attrcode) ------------------------------------------------------ diff -r 7c52463d3038 -r 7165b3c8dca8 lib/builtins.py --- a/lib/builtins.py Thu Apr 23 00:52:33 2009 +0200 +++ b/lib/builtins.py Sun Apr 26 03:24:12 2009 +0200 @@ -32,7 +32,7 @@ def __add__(self, other): pass def __radd__(self, other): pass def __mul__(self, other): pass - def __radd__(self, other): pass + def __rmul__(self, other): pass def __mod__(self, other): pass def __rmod__(self, other): pass def __lt__(self, other): pass @@ -266,7 +266,7 @@ # Various types. -class ellipsis: pass +#class ellipsis: pass class NoneType: pass class NotImplementedType: pass @@ -333,13 +333,14 @@ # should be predefined constants. function -list -tuple -xrange AttributeError StopIteration TypeError -ellipsis -bool + +list +tuple +#xrange +#ellipsis +#bool # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7c52463d3038 -r 7165b3c8dca8 micropython/__init__.py --- a/micropython/__init__.py Thu Apr 23 00:52:33 2009 +0200 +++ b/micropython/__init__.py Sun Apr 26 03:24:12 2009 +0200 @@ -140,6 +140,11 @@ self.code += obj.attributes_as_list() pos += len(attributes.keys()) + # Omit built-in function code where requested. + + if not with_builtins and module.name == "__builtins__": + continue + # Generate the instantiator/initialiser. # Append the function code to the image. @@ -270,7 +275,7 @@ elif isinstance(item, micropython.data.Class): assert item.instance_template_location == len(self.raw_code) - self.raw_code += item.as_raw(objtable, paramtable) + self.raw_code += item.as_raw(objtable, paramtable, with_builtins or item.module.name != "__builtins__") assert item.location == len(self.raw_code) - 1 elif isinstance(item, micropython.data.Const): @@ -378,7 +383,7 @@ "None" : None, "True" : True, "False" : False, - "Ellipsis" : Ellipsis, + #"Ellipsis" : Ellipsis, "NotImplemented" : NotImplemented } diff -r 7c52463d3038 -r 7165b3c8dca8 micropython/data.py --- a/micropython/data.py Thu Apr 23 00:52:33 2009 +0200 +++ b/micropython/data.py Sun Apr 26 03:24:12 2009 +0200 @@ -462,8 +462,9 @@ objtable.get_index(self.value_type_name()), None, None, - 1, - self.value_type_name() + 1, # instance + self.value_type_name(), + 1 # size ) ] + self.raw_data() @@ -550,7 +551,7 @@ def __shortrepr__(self): return "Class(%r, %s)" % (self.name, shortrepr(self.parent)) - def as_raw(self, objtable, paramtable): + def as_raw(self, objtable, paramtable, with_instantiator=1): classcode = objtable.as_list().get_code(self.full_name()) attrcode = objtable.get_index(self.full_name()) @@ -562,7 +563,10 @@ # NOTE: The instantiator code is the first block of the class. - instantiator_code_location = self.get_instantiator().blocks[0].location + if not with_instantiator: + instantiator_code_location = self.full_name() + else: + instantiator_code_location = self.get_instantiator().blocks[0].location return [ @@ -574,8 +578,9 @@ call_method_value and len(call_method_value.positional_names), call_method_value and len(call_method_value.defaults) ), - 1, - self.full_name() + 1, # instance + self.full_name(), + len(self.instance_attributes()) + 1 # size ), # Class... @@ -586,8 +591,9 @@ len(self.get_instantiator().positional_names), len(self.get_instantiator().defaults) ), - 0, - self.full_name() + 0, # not instance + self.full_name(), + len(self.class_attributes()) + 1 # size ) ] @@ -958,7 +964,7 @@ ) def as_raw(self, objtable, paramtable): - # NOTE: Need class and parameter details! Should arguably be types.FunctionType. + # NOTE: Need class and parameter details! Should arguably be an instance of types.FunctionType. return [ DataObject( objtable.as_list().get_code("__builtins__.function"), @@ -968,8 +974,9 @@ len(self.positional_names), len(self.defaults) ), - 0, + 1, # instance "__builtins__.function", + len(self.defaults) + 1, # size paramtable.as_list().get_code(self.full_name()) ) ] @@ -1072,7 +1079,7 @@ "Make a function from a method." - function = Function(self.name, self.parent, self.argnames[1:], self.defaults, + function = Function(self.name + " (function)", self.parent, self.argnames[1:], self.defaults, self.has_star, self.has_dstar, self.module, self.astnode) function.default_attrs = self.default_attrs return function @@ -1169,8 +1176,9 @@ None, # module name not used as an attribute None, None, - 0, - self.full_name() + 1, # instance + self.full_name(), + len(self.module_attributes()) + 1 # size ) ] diff -r 7c52463d3038 -r 7165b3c8dca8 micropython/program.py --- a/micropython/program.py Thu Apr 23 00:52:33 2009 +0200 +++ b/micropython/program.py Sun Apr 26 03:24:12 2009 +0200 @@ -25,16 +25,22 @@ "A representation of a raw program data object." - def __init__(self, classcode, attrcode, codeaddr, codedetails, instance, name, funccode=None): + def __init__(self, classcode, attrcode, codeaddr, codedetails, instance, name, size, funccode=None): self.classcode = classcode self.attrcode = attrcode self.codeaddr = codeaddr self.codedetails = codedetails self.instance = instance self.name = name + self.size = size self.funccode = funccode + def with_size(self, size): + return DataObject(self.classcode, self.attrcode, self.codeaddr, self.codedetails, self.instance, self.name, size, self.funccode) + def __repr__(self): - return "%r # %s" % ((self.classcode, self.attrcode, self.codeaddr, self.codedetails, self.instance, self.funccode), self.name) + return "%r # %s" % ( + (self.classcode, self.attrcode, self.codeaddr, self.codedetails, self.instance, self.funccode, self.size), self.name + ) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7c52463d3038 -r 7165b3c8dca8 micropython/trans.py --- a/micropython/trans.py Thu Apr 23 00:52:33 2009 +0200 +++ b/micropython/trans.py Sun Apr 26 03:24:12 2009 +0200 @@ -508,13 +508,6 @@ self.new_op(LoadContext()) self.new_op(StoreFrame(0)) - # For known instantiations, provide a new object as the first argument - # to the __init__ method. - - elif isinstance(target, Class): - self.make_object(target, len(target.instance_attributes())) - self.new_op(StoreFrame(0)) - # Otherwise omit the context. else: @@ -552,11 +545,12 @@ expect_context = 0 # Handle calls to classes. + # The resulting target must match that used in the actual invocation. elif isinstance(target, Class): - ncontext = 1 + ncontext = 0 expect_context = 0 - target = target.get_init_method() + target = target.get_instantiator() # Method calls via classes. @@ -771,10 +765,14 @@ "Make the invocation." + # For classes, the target itself is used, since the instantiator will be + # obtained via the class. + if isinstance(target, Class): - self.new_op(LoadConst(target.get_init_method())) + self.new_op(LoadConst(target)) else: self.new_op(instruction) + self.new_op(LoadCallable()) self.new_op(JumpWithFrame()) @@ -789,9 +787,6 @@ "Finish the invocation and tidy up afterwards." - if isinstance(target, Class): - self.new_op(LoadName(target.get_init_method().all_locals()["self"])) # load the context in the invocation frame - self.new_op(StoreResult()) self.new_op(DropFrame()) if load_result: self.new_op(LoadResult()) diff -r 7c52463d3038 -r 7165b3c8dca8 rsvp.py --- a/rsvp.py Thu Apr 23 00:52:33 2009 +0200 +++ b/rsvp.py Sun Apr 26 03:24:12 2009 +0200 @@ -129,6 +129,8 @@ cls = objlist.access("__builtins__", "int") self.int_class_location = cls and cls.get_value() and cls.get_value().location self.int_instance_location = cls and cls.get_value() and cls.get_value().instance_template_location + cls = objlist.access("__builtins__", "list") + self.list_instance_location = cls and cls.get_value() and cls.get_value().instance_template_location # Debugging attributes. @@ -338,7 +340,10 @@ self.frame_stack[frame + self.operand] = self.source LoadTemp = LoadName - StoreTemp = StoreName + + def StoreTemp(self): + frame = self.local_sp_stack[-1] + self.frame_stack[frame + self.operand] = self.value def LoadAddress(self): # Preserve context (potentially null). @@ -616,10 +621,11 @@ return attr_index == data.attrcode def _MakeObject(self, size, ref): + # Load the template. data = self.load(ref) addr = self.new(size) - # Set the header to resemble the class. - self.save(addr, data) + # Save the header, overriding the size. + self.save(addr, data.with_size(size)) return addr def _LoadAddressContextCond(self, context, ref, inst_context, inst_ref): @@ -634,12 +640,6 @@ # 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] @@ -706,12 +706,25 @@ left_context, left = self.frame_stack[frame] self.result = left, left + def builtins_list_new(self): + frame = self.local_sp_stack[-1] + + # NOTE: Specific copying of tuples/lists. + + args_context, args = self.frame_stack[frame] + header = self.load(args) + + list = self._MakeObject(header.size, self.list_instance_location) + for i in range(1, header.size): + self.save(list + i, self.load(args + i)) + + self.result = list, list + native_functions = { - "__builtins__.object.__init__" : builtins_object_init, - "__builtins__.int.__init__" : builtins_int_init, "__builtins__.int.__add__" : builtins_int_add, "__builtins__.int.__bool__" : builtins_int_bool, "__builtins__.bool.__bool__" : builtins_bool_bool, + "__builtins__.list" : builtins_list_new, } # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7c52463d3038 -r 7165b3c8dca8 tests/empty.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/empty.py Sun Apr 26 03:24:12 2009 +0200 @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +# An empty program, not even having a docstring. + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7c52463d3038 -r 7165b3c8dca8 tests/minimal.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/minimal.py Sun Apr 26 03:24:12 2009 +0200 @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +"A minimal program. The docstring introduces some content." + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7c52463d3038 -r 7165b3c8dca8 tests/op_add_call.py --- a/tests/op_add_call.py Thu Apr 23 00:52:33 2009 +0200 +++ b/tests/op_add_call.py Sun Apr 26 03:24:12 2009 +0200 @@ -1,11 +1,11 @@ #!/usr/bin/env python def f(x, y): - pass + return x + y a = 1 b = 2 c = 3 -f(a + b, b + c) +d = f(a + b, b + c) # vim: tabstop=4 expandtab shiftwidth=4