1.1 --- a/README.txt Mon Feb 18 01:22:25 2008 +0100
1.2 +++ b/README.txt Tue Feb 19 00:05:22 2008 +0100
1.3 @@ -27,6 +27,21 @@
1.4 Data Structures
1.5 ===============
1.6
1.7 +The fundamental "value type" is a pair of references: one pointing to the
1.8 +referenced object represented by the interchangeable value; one referring to
1.9 +the context of the referenced object, typically the object through which the
1.10 +referenced object was acquired as an attribute.A
1.11 +
1.12 +Value Layout
1.13 +------------
1.14 +
1.15 + 0 1
1.16 + object context
1.17 + reference reference
1.18 +
1.19 +Objects
1.20 +-------
1.21 +
1.22 Since classes, functions and instances are all "objects", each must support
1.23 certain features and operations in the same way.
1.24
1.25 @@ -190,6 +205,27 @@
1.26 Keyword arguments are set using an attribute-like mechanism, though, where the
1.27 position of each argument discovered using the parameter table.
1.28
1.29 +Method invocations incorporate an implicit first argument which is obtained
1.30 +from the context of the method:
1.31 +
1.32 + method(a, b, d=1, e=2, c=3) -> method(self, a, b, c, d, e)
1.33 +
1.34 + Value Stack
1.35 + -----------
1.36 +
1.37 + ...
1.38 + method
1.39 + context of method
1.40 + a
1.41 + b
1.42 + 3
1.43 + 1
1.44 + 2
1.45 +
1.46 +Although it could be possible to permit any object to be provided as the first
1.47 +argument, in order to optimise instance attribute access in methods, we should
1.48 +seek to restrict the object type.
1.49 +
1.50 Tuples, Frames and Allocation
1.51 -----------------------------
1.52
2.1 --- a/micropython/ast.py Mon Feb 18 01:22:25 2008 +0100
2.2 +++ b/micropython/ast.py Tue Feb 19 00:05:22 2008 +0100
2.3 @@ -278,18 +278,18 @@
2.4 the correct location, then invoke the function.
2.5 """
2.6
2.7 - # Record the location of the invocation.
2.8 + # Mark the frame, evaluate the target, generate the call.
2.9 +
2.10 + self._startCallFunc()
2.11 + self.dispatch(node.node)
2.12 + self._generateCallFunc(node.args, node)
2.13 +
2.14 + def _startCallFunc(self):
2.15 +
2.16 + "Record the location of the invocation."
2.17
2.18 self.new_op(MakeFrame()) # records the start of the frame
2.19
2.20 - # Evaluate the target.
2.21 -
2.22 - self.dispatch(node.node)
2.23 -
2.24 - # Generate the call.
2.25 -
2.26 - self._generateCallFunc(node.args, node)
2.27 -
2.28 def _generateCallFunc(self, args, node):
2.29
2.30 # NOTE: Only simple cases are used for optimisations.
2.31 @@ -297,8 +297,24 @@
2.32 last = self.last_op()
2.33 if isinstance(last, (LoadName, LoadAttr)) and last.attr.assignments == 1:
2.34 target = last.attr.value
2.35 + context = last.attr.parent
2.36 else:
2.37 target = None
2.38 + context = None
2.39 +
2.40 + # Where a target is known and has a known context, avoid generating any
2.41 + # first argument.
2.42 +
2.43 + if context is not None:
2.44 + pass # NOTE: Class methods should be supported.
2.45 + else:
2.46 + continue_label = self.new_label()
2.47 + self.new_op(LoadContext())
2.48 + self.new_op(CheckContext())
2.49 + self.new_op(JumpIfTrue(continue_label))
2.50 + self.new_op(LoadConst("TypeError")) # NOTE: Do this properly!
2.51 + self.new_op(RaiseException())
2.52 + self.set_label(continue_label)
2.53
2.54 # Evaluate the arguments.
2.55
2.56 @@ -418,6 +434,7 @@
2.57
2.58 # Get the "list" to be iterated over, obtain its iterator.
2.59
2.60 + self._startCallFunc()
2.61 self.dispatch(node.list)
2.62 self._generateAttr("__iter__", (LoadAttr, LoadAttrIndex))
2.63 self._generateCallFunc([], node)
2.64 @@ -429,6 +446,7 @@
2.65
2.66 # Use the iterator to get the next value.
2.67
2.68 + self._startCallFunc()
2.69 self.new_op(Duplicate())
2.70 self._generateAttr("next", (LoadAttr, LoadAttrIndex))
2.71 self._generateCallFunc([], node)
3.1 --- a/micropython/rsvp.py Mon Feb 18 01:22:25 2008 +0100
3.2 +++ b/micropython/rsvp.py Tue Feb 19 00:05:22 2008 +0100
3.3 @@ -62,11 +62,14 @@
3.4
3.5 # Invocation-related instructions.
3.6
3.7 -class Jump(Instruction): pass
3.8 -class JumpIfFalse(Instruction): pass
3.9 -class JumpIfTrue(Instruction): pass
3.10 -class LoadCallable(Instruction): pass
3.11 -class Return(Instruction): pass
3.12 -class CheckException(Instruction): pass
3.13 +class Jump(Instruction): "Jump unconditionally."
3.14 +class JumpIfFalse(Instruction): "Jump if the last evaluation gave a false result."
3.15 +class JumpIfTrue(Instruction): "Jump if the last evaluation gave a true result."
3.16 +class LoadCallable(Instruction): "Load the target of an invocation."
3.17 +class LoadContext(Instruction): "Load the context of an invocation."
3.18 +class CheckContext(Instruction): "Check the context of an invocation against the target."
3.19 +class RaiseException(Instruction): "Raise an exception."
3.20 +class Return(Instruction): "Return a value from a subprogram."
3.21 +class CheckException(Instruction): "Check the raised exception against another."
3.22
3.23 # vim: tabstop=4 expandtab shiftwidth=4