1.1 --- a/micropython/ast.py Mon Sep 01 01:32:32 2008 +0200
1.2 +++ b/micropython/ast.py Thu Sep 04 19:44:39 2008 +0200
1.3 @@ -159,12 +159,12 @@
1.4
1.5 # Make an object.
1.6
1.7 - self.new_op(MakeObject(len(cls.instance_attributes())))
1.8 + self.make_object(cls, len(cls.instance_attributes()))
1.9 self.new_op(StoreFrame(0))
1.10
1.11 # Invoke the appropriate initialiser.
1.12
1.13 - self.new_op(LoadAddress(init_method))
1.14 + self.new_op(LoadConst(init_method))
1.15 self.new_op(LoadCallable())
1.16 self.new_op(JumpWithFrame())
1.17
1.18 @@ -176,6 +176,19 @@
1.19
1.20 return self.code
1.21
1.22 + # Allocation-related methods.
1.23 +
1.24 + def make_object(self, cls, n):
1.25 +
1.26 + """
1.27 + Request a new object with the given class 'cls' and with 'n' attributes.
1.28 + """
1.29 +
1.30 + # NOTE: Object headers are one location.
1.31 +
1.32 + self.new_op(LoadConst(cls))
1.33 + self.new_op(MakeObject(n + 1))
1.34 +
1.35 # Name-related methods.
1.36
1.37 def get_scope(self, name):
1.38 @@ -195,6 +208,9 @@
1.39
1.40 self.new_op(LoadAddress(self.get_builtin(name, node)))
1.41
1.42 + def get_builtin_class(self, name, node):
1.43 + return self.get_builtin(name, node).value
1.44 +
1.45 def get_builtin(self, name, node):
1.46
1.47 """
1.48 @@ -418,7 +434,7 @@
1.49 instruction).
1.50 """
1.51
1.52 - return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress, MakeObject))
1.53 + return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress))
1.54
1.55 def _is_simple_input_user(self, instruction):
1.56
1.57 @@ -430,7 +446,7 @@
1.58 StoreAttr, StoreAttrIndex, StoreCallable, # as the object being referenced
1.59 LoadCallable,
1.60 TestIdentity, TestIdentityAddress, CheckSelf, # as one of the operands
1.61 - CheckFrame,
1.62 + CheckFrame, MakeObject,
1.63 LoadContext # as the object providing the result
1.64 ))
1.65
1.66 @@ -851,7 +867,7 @@
1.67 # to the __init__ method.
1.68
1.69 elif isinstance(target, Class):
1.70 - self.new_op(MakeObject(len(target.instance_attributes())))
1.71 + self.make_object(target, len(target.instance_attributes()))
1.72 self.new_op(StoreFrame(0))
1.73
1.74 # Otherwise omit the context.
1.75 @@ -1107,7 +1123,7 @@
1.76 "Make the invocation."
1.77
1.78 if isinstance(target, Class):
1.79 - self.new_op(LoadAddress(target.get_init_method()))
1.80 + self.new_op(LoadConst(target.get_init_method()))
1.81 else:
1.82 self.new_op(instruction)
1.83 self.new_op(LoadCallable())
1.84 @@ -1154,7 +1170,7 @@
1.85 dynamic = function.name is None
1.86
1.87 if dynamic:
1.88 - self.new_op(MakeObject(("function", len(attr_to_default))))
1.89 + self.make_object(self.get_builtin_class("function", function), len(attr_to_default))
1.90 temp = self.get_temp()
1.91
1.92 for attr, default in attr_to_default:
1.93 @@ -1398,7 +1414,7 @@
1.94
1.95 "Make a sequence of 'sequence_type' for the given program 'node'."
1.96
1.97 - self.new_op(MakeObject((sequence_type, len(node.nodes))))
1.98 + self.make_object(self.get_builtin(sequence_type, node), len(node.nodes))
1.99 temp = self.get_temp()
1.100
1.101 for i, n in enumerate(node.nodes):
2.1 --- a/micropython/rsvp.py Mon Sep 01 01:32:32 2008 +0200
2.2 +++ b/micropython/rsvp.py Thu Sep 04 19:44:39 2008 +0200
2.3 @@ -33,11 +33,13 @@
2.4 elif isinstance(item, Class):
2.5 # NOTE: Need initialiser details!
2.6 new_code.append((
2.7 - objtable.as_list().get_code(item.full_name()),
2.8 - objtable.get_index(item.full_name()),
2.9 - item.get_instantiator().code_location,
2.10 - len(item.get_instantiator().positional_names)
2.11 - ))
2.12 + objtable.as_list().get_code(item.full_name()),
2.13 + objtable.get_index(item.full_name()),
2.14 + item.get_instantiator().code_location,
2.15 + (
2.16 + len(item.get_instantiator().positional_names),
2.17 + len(item.get_instantiator().defaults)
2.18 + )))
2.19 elif isinstance(item, Const):
2.20 # NOTE: Need class details!
2.21 new_code.append((
2.22 @@ -51,8 +53,10 @@
2.23 objtable.as_list().get_code("__builtins__.function"),
2.24 objtable.get_index("__builtins__.function"),
2.25 item.code_location,
2.26 - len(item.positional_names)
2.27 - ))
2.28 + (
2.29 + len(item.positional_names),
2.30 + len(item.defaults)
2.31 + )))
2.32 else:
2.33 new_code.append(item)
2.34 return new_code
2.35 @@ -200,6 +204,11 @@
2.36 class LoadAttrIndex(Immediate): "Load into the current value the attribute of the current value with the given index."
2.37 class StoreAttrIndex(Immediate): "Store an object in the attribute with the given index."
2.38
2.39 +# Access to object details.
2.40 +
2.41 +class LoadCallable(Instruction): "Load the target of an invocation."
2.42 +class StoreCallable(Instruction): "Store the source value into the object referenced by the current value."
2.43 +
2.44 # Access to invocation frames in preparation.
2.45
2.46 class MakeFrame(Immediate): "Make a new invocation frame."
2.47 @@ -207,8 +216,6 @@
2.48 class RecoverFrame(Instruction): "Recover the current frame as an invocation frame."
2.49 class StoreFrame(Immediate): "Store the current value as an argument for the parameter with the given position."
2.50 class StoreFrameIndex(Immediate): "Store the current value as an argument for the parameter with the given index."
2.51 -class LoadCallable(Instruction): "Load the target of an invocation."
2.52 -class StoreCallable(Instruction): "Store the source value into the object referenced by the current value."
2.53 class LoadContext(Instruction): "Load the context of an invocation."
2.54 class CheckFrame(Immediate): "Check the invocation frame and context for the target."
2.55 class CheckSelf(Instruction): "Check the first argument of an invocation against the target."
3.1 --- a/micropython/table.py Mon Sep 01 01:32:32 2008 +0200
3.2 +++ b/micropython/table.py Thu Sep 04 19:44:39 2008 +0200
3.3 @@ -202,6 +202,7 @@
3.4 self.objnames = []
3.5 self.names = []
3.6 self.displaced_list = None
3.7 + self.raw = None
3.8
3.9 def add(self, objname, attributes):
3.10
3.11 @@ -321,7 +322,9 @@
3.12
3.13 "Return the raw contents of the table as a list of values."
3.14
3.15 - return self.as_list().as_raw()
3.16 + if self.raw is None:
3.17 + self.raw = self.as_list().as_raw()
3.18 + return self.raw
3.19
3.20 class ObjectTable(Table):
3.21
4.1 --- a/rsvp.py Mon Sep 01 01:32:32 2008 +0200
4.2 +++ b/rsvp.py Thu Sep 04 19:44:39 2008 +0200
4.3 @@ -58,7 +58,7 @@
4.4
4.5 "A really simple virtual processor."
4.6
4.7 - def __init__(self, memory, objtable, paramtable, pc=None, debug=0):
4.8 + def __init__(self, memory, objlist, paramlist, pc=None, debug=0):
4.9
4.10 """
4.11 Initialise the processor with a 'memory' (a list of values containing
4.12 @@ -66,8 +66,8 @@
4.13 """
4.14
4.15 self.memory = memory
4.16 - self.objtable = objtable
4.17 - self.paramtable = paramtable
4.18 + self.objlist = objlist
4.19 + self.paramlist = paramlist
4.20 self.pc = pc or 0
4.21 self.debug = debug
4.22
4.23 @@ -91,7 +91,7 @@
4.24 self.exception = None
4.25
4.26 def dump(self):
4.27 - print "PC", self.pc
4.28 + print "PC", self.pc, "->", self.load(self.pc)
4.29 print "PC stack", self.pc_stack
4.30 print "Frame stack", self.frame_stack
4.31 print "Local stack pointers", self.local_sp_stack
4.32 @@ -107,6 +107,10 @@
4.33 print "Result", self.result
4.34 print "Exception", self.exception
4.35
4.36 + def step(self):
4.37 + self.execute()
4.38 + self.dump()
4.39 +
4.40 def load(self, address):
4.41
4.42 "Return the value at the given 'address'."
4.43 @@ -226,7 +230,7 @@
4.44 getattr(self, addr)()
4.45 return next
4.46 else:
4.47 - self.push_pc(self.pc + 2)
4.48 + self.push_pc(self.pc + 1)
4.49 return addr
4.50
4.51 # Instructions.
4.52 @@ -259,8 +263,14 @@
4.53 self.save(self.operand, self.value)
4.54
4.55 def MakeObject(self):
4.56 + size = self.operand
4.57 + context, ref = self.value
4.58 + classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.59 + addr = self.new(size)
4.60 + # Set the header to resemble the class.
4.61 + self.save(addr, (classcode, attrcode, None, None)) # NOTE: __call__ method not yet provided.
4.62 # Introduce null context for new object.
4.63 - self.value = None, self.new(self.operand)
4.64 + self.value = None, addr
4.65
4.66 def LoadAttr(self):
4.67 context, ref = self.value
4.68 @@ -275,7 +285,7 @@
4.69 def LoadAttrIndex(self):
4.70 context, ref = self.value
4.71 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.72 - element = self.objtable[classcode + self.operand]
4.73 + element = self.objlist[classcode + self.operand]
4.74 attr_index, class_attr, replace_context, offset = element
4.75 if attr_index == self.operand:
4.76 if class_attr:
4.77 @@ -293,7 +303,7 @@
4.78 def StoreAttrIndex(self):
4.79 context, ref = self.value
4.80 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.81 - element = self.objtable[classcode + self.operand]
4.82 + element = self.objlist[classcode + self.operand]
4.83 attr_index, class_attr, replace_context, offset = element
4.84 if attr_index == self.operand:
4.85 if class_attr:
4.86 @@ -327,7 +337,7 @@
4.87 def StoreFrameIndex(self):
4.88 frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame
4.89 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.90 - element = self.objtable[classcode + self.operand]
4.91 + element = self.objlist[classcode + self.operand]
4.92 attr_index, offset = element
4.93 if attr_index == self.operand:
4.94 self.frame_stack[frame + offset] = self.value
4.95 @@ -359,11 +369,11 @@
4.96 # Support sliding of the frame to exclude any inappropriate context.
4.97
4.98 if context is None:
4.99 - frame = frame[1:]
4.100 + self.invocation_sp_stack[-1] += 1
4.101 operand -= 1
4.102 else:
4.103 if contexttype == self.typetype:
4.104 - frame = frame[1:]
4.105 + self.invocation_sp_stack[-1] += 1
4.106 operand -= 1
4.107
4.108 nargs, ndefaults = codedetails
4.109 @@ -383,7 +393,7 @@
4.110
4.111 # Find the table entry for the descendant.
4.112
4.113 - element = self.objtable[target_classcode + attrcode]
4.114 + element = self.objlist[target_classcode + attrcode]
4.115 attr_index, class_attr, replace_context, offset = element
4.116 if attr_index == attrcode:
4.117 self.status = 1
4.118 @@ -391,23 +401,23 @@
4.119 self.status = 0
4.120
4.121 def JumpWithFrame(self):
4.122 + codeaddr, codedetails = self.callable
4.123 self.local_sp_stack.append(self.invocation_sp_stack[-1]) # adopt the invocation frame
4.124 - return self.jump(self.callable, self.pc + 1) # return to the instruction after this one
4.125 + return self.jump(codeaddr, self.pc + 1) # return to the instruction after this one
4.126
4.127 def ExtendFrame(self):
4.128 - frame = self.local_sp_stack[-1]
4.129 - frame.extend([None] * self.operand)
4.130 + self.frame_stack.extend([None] * self.operand)
4.131
4.132 def AdjustFrame(self):
4.133 if self.operand > 0:
4.134 - frame.append([None] * self.operand)
4.135 + self.frame_stack.append([None] * self.operand)
4.136 elif self.operand == -1:
4.137 self.invocation_sp_stack[-1] -= 1
4.138 else:
4.139 raise Exception, "AdjustFrame %r" % self.operand
4.140
4.141 def Return(self):
4.142 - self.pc = self.pull_pc()
4.143 + return self.pull_pc()
4.144
4.145 def LoadResult(self):
4.146 self.value = self.result
5.1 --- a/test.py Mon Sep 01 01:32:32 2008 +0200
5.2 +++ b/test.py Thu Sep 04 19:44:39 2008 +0200
5.3 @@ -27,15 +27,17 @@
5.4 print "%6d" % (len(table_slice) - table_slice.count(None)), \
5.5 "".join(entry and "#" or "_" for entry in table_slice)
5.6
5.7 -def machine(importer):
5.8 +def machine(importer, with_builtins=0, optimisations=None):
5.9 print "Making the image..."
5.10 - make(importer)
5.11 - rc = raw(importer.get_image())
5.12 - print "Getting raw tables..."
5.13 - objtable = importer.get_object_table().as_raw()
5.14 - paramtable = importer.get_parameter_table().as_raw()
5.15 + make(importer, with_builtins, optimisations)
5.16 + print "Getting raw structures..."
5.17 + ot = importer.get_object_table()
5.18 + pt = importer.get_parameter_table()
5.19 + objlist = ot.as_raw()
5.20 + paramlist = pt.as_raw()
5.21 + rc = raw(importer.get_image(), ot, pt)
5.22 print "Initialising the machine..."
5.23 - rm = rsvp.RSVPMachine(rc, objtable, paramtable)
5.24 + rm = rsvp.RSVPMachine(rc, objlist, paramlist)
5.25 rm.pc = importer.code_location
5.26 return rm
5.27
6.1 --- a/tests/list.py Mon Sep 01 01:32:32 2008 +0200
6.2 +++ b/tests/list.py Thu Sep 04 19:44:39 2008 +0200
6.3 @@ -3,5 +3,6 @@
6.4 [1, 2, 3]
6.5 a = [1, 2, 3]
6.6 [1, [2, 3], 4, 5]
6.7 +b = list((9, 8, 7))
6.8
6.9 # vim: tabstop=4 expandtab shiftwidth=4