1.1 --- a/micropython/ast.py Sat Jan 19 01:06:21 2008 +0100
1.2 +++ b/micropython/ast.py Tue Jan 22 01:07:06 2008 +0100
1.3 @@ -122,6 +122,9 @@
1.4 def new_op(self, op):
1.5 self.code.append(op)
1.6
1.7 + def last_op(self):
1.8 + return self.code[-1]
1.9 +
1.10 # Visitor methods.
1.11
1.12 def default(self, node, *args):
1.13 @@ -214,6 +217,14 @@
1.14
1.15 self.dispatch(node.node)
1.16
1.17 + # NOTE: Only simple cases are used for optimisations.
1.18 +
1.19 + last = self.last_op()
1.20 + if isinstance(last, (LoadName, LoadAttr)) and last.attr.assignments == 1:
1.21 + target = last.attr.value
1.22 + else:
1.23 + target = None
1.24 +
1.25 # Evaluate the arguments.
1.26
1.27 positional = 1
1.28 @@ -226,15 +237,27 @@
1.29
1.30 self.dispatch(arg.expr)
1.31
1.32 - # Combine the target details with the name to get the location.
1.33 - # See the access method on the Table class.
1.34 + # Optimise where the target is known now.
1.35 +
1.36 + if target is not None:
1.37 + pos = self.paramtable.table[target.full_name()][arg.name]
1.38 + self.new_op(StoreFrame(pos))
1.39 +
1.40 + # Otherwise, generate the code needed to obtain the details of
1.41 + # the parameter location.
1.42 +
1.43 + else:
1.44
1.45 - paramindex = self.paramtable.get_index(arg.name)
1.46 - self.new_op(StoreFrame(paramindex))
1.47 + # Combine the target details with the name to get the location.
1.48 + # See the access method on the List class.
1.49 +
1.50 + paramindex = self.paramtable.get_index(arg.name)
1.51
1.52 - # use (callable+0)+paramindex+table
1.53 - # checks embedded offset against (callable+0)
1.54 - # moves the top of stack to frame+position
1.55 + self.new_op(StoreFrameIndex(paramindex))
1.56 +
1.57 + # use (callable+0)+paramindex+table
1.58 + # checks embedded offset against (callable+0)
1.59 + # moves the top of stack to frame+position
1.60
1.61 else:
1.62 self.dispatch(arg)
2.1 --- a/micropython/inspect.py Sat Jan 19 01:06:21 2008 +0100
2.2 +++ b/micropython/inspect.py Tue Jan 22 01:07:06 2008 +0100
2.3 @@ -131,13 +131,14 @@
2.4
2.5 "An attribute entry."
2.6
2.7 - def __init__(self, position, parent, value=None):
2.8 + def __init__(self, position, parent, assignments=None, value=None):
2.9 self.position = position
2.10 self.parent = parent
2.11 + self.assignments = assignments
2.12 self.value = value
2.13
2.14 def __repr__(self):
2.15 - return "Attr(%d, %r, %r)" % (self.position, self.parent, self.value)
2.16 + return "Attr(%d, %r, %r, %r)" % (self.position, self.parent, self.assignments, self.value)
2.17
2.18 class Const:
2.19
2.20 @@ -212,7 +213,7 @@
2.21 self.classattr_names = self.keys()
2.22
2.23 for i, name in enumerate(self.classattr_names):
2.24 - self.classattr[name] = Attr(i, self, self[name])
2.25 + self.classattr[name] = Attr(i, self, self.assignments[name], self[name])
2.26
2.27 return self.classattr
2.28
2.29 @@ -451,7 +452,7 @@
2.30 self.modattr = {}
2.31 self.modattr_names = self.keys()
2.32 for i, name in enumerate(self.modattr_names):
2.33 - self.modattr[name] = Attr(i, self, self[name])
2.34 + self.modattr[name] = Attr(i, self, self.assignments[name], self[name])
2.35
2.36 return self.modattr
2.37
3.1 --- a/micropython/rsvp.py Sat Jan 19 01:06:21 2008 +0100
3.2 +++ b/micropython/rsvp.py Tue Jan 22 01:07:06 2008 +0100
3.3 @@ -27,30 +27,34 @@
3.4 self.attr = attr
3.5
3.6 def __repr__(self):
3.7 - return "%s(%r)" % (self.__class__.__name__, self.attr)
3.8 + if self.attr is not None:
3.9 + return "%s(%r)" % (self.__class__.__name__, self.attr)
3.10 + else:
3.11 + return "%s()" % self.__class__.__name__
3.12
3.13 # Instructions operating on the value stack.
3.14
3.15 -class LoadConst(Instruction): pass
3.16 +class LoadConst(Instruction): "Load the constant from the specified location."
3.17
3.18 # Access within an invocation frame.
3.19
3.20 -class LoadName(Instruction): pass
3.21 -class StoreName(Instruction): pass
3.22 +class LoadName(Instruction): "Load the object from the given local attribute."
3.23 +class StoreName(Instruction): "Store the object in the given local attribute."
3.24
3.25 # Access to address-relative data.
3.26
3.27 -class MakeObject(Instruction): pass
3.28 -# ... DropObject not defined: assume garbage collection.
3.29 -class LoadAttr(Instruction): pass
3.30 -class StoreAttr(Instruction): pass
3.31 +class MakeObject(Instruction): "Make a new object."
3.32 +# ... DropObject not defined: Assume garbage collection.
3.33 +class LoadAttr(Instruction): "Load the object from the given attribute."
3.34 +class StoreAttr(Instruction): "Store the object in the given attribute."
3.35
3.36 # Access to invocation frames in preparation.
3.37
3.38 -class MakeFrame(Instruction): pass
3.39 -class ReserveFrame(Instruction): pass
3.40 -class DropFrame(Instruction): pass
3.41 -class StoreFrame(Instruction): pass
3.42 +class MakeFrame(Instruction): "Make a new invocation frame."
3.43 +class ReserveFrame(Instruction): "Reserve the given number of entries for the invocation frame."
3.44 +class DropFrame(Instruction): "Drop an invocation frame."
3.45 +class StoreFrame(Instruction): "Store an argument at the given frame location."
3.46 +class StoreFrameIndex(Instruction): "Store an argument for the parameter with the given index."
3.47
3.48 # Invocation-related instructions.
3.49
4.1 --- a/tests/call_func.py Sat Jan 19 01:06:21 2008 +0100
4.2 +++ b/tests/call_func.py Tue Jan 22 01:07:06 2008 +0100
4.3 @@ -7,4 +7,12 @@
4.4 f(1, b=2, c=3)
4.5 f(c=3, b=2, a=1)
4.6
4.7 +g = f
4.8 +g(1, c=3, b=2)
4.9 +
4.10 +def g(a, c, b):
4.11 + pass
4.12 +
4.13 +g(1, c=3, b=2)
4.14 +
4.15 # vim: tabstop=4 expandtab shiftwidth=4