# HG changeset patch # User Paul Boddie # Date 1203375922 -3600 # Node ID 27ab716dcedb9a6e8636544bb1c407b4a67b73d8 # Parent 136f6bf70d3fc9122ded82a369a565973e65c4e4 Added notes, support, instructions related to proper method invocations. diff -r 136f6bf70d3f -r 27ab716dcedb README.txt --- a/README.txt Mon Feb 18 01:22:25 2008 +0100 +++ b/README.txt Tue Feb 19 00:05:22 2008 +0100 @@ -27,6 +27,21 @@ Data Structures =============== +The fundamental "value type" is a pair of references: one pointing to the +referenced object represented by the interchangeable value; one referring to +the context of the referenced object, typically the object through which the +referenced object was acquired as an attribute.A + +Value Layout +------------ + + 0 1 + object context + reference reference + +Objects +------- + Since classes, functions and instances are all "objects", each must support certain features and operations in the same way. @@ -190,6 +205,27 @@ Keyword arguments are set using an attribute-like mechanism, though, where the position of each argument discovered using the parameter table. +Method invocations incorporate an implicit first argument which is obtained +from the context of the method: + + method(a, b, d=1, e=2, c=3) -> method(self, a, b, c, d, e) + + Value Stack + ----------- + + ... + method + context of method + a + b + 3 + 1 + 2 + +Although it could be possible to permit any object to be provided as the first +argument, in order to optimise instance attribute access in methods, we should +seek to restrict the object type. + Tuples, Frames and Allocation ----------------------------- diff -r 136f6bf70d3f -r 27ab716dcedb micropython/ast.py --- a/micropython/ast.py Mon Feb 18 01:22:25 2008 +0100 +++ b/micropython/ast.py Tue Feb 19 00:05:22 2008 +0100 @@ -278,18 +278,18 @@ the correct location, then invoke the function. """ - # Record the location of the invocation. + # Mark the frame, evaluate the target, generate the call. + + self._startCallFunc() + self.dispatch(node.node) + self._generateCallFunc(node.args, node) + + def _startCallFunc(self): + + "Record the location of the invocation." self.new_op(MakeFrame()) # records the start of the frame - # Evaluate the target. - - self.dispatch(node.node) - - # Generate the call. - - self._generateCallFunc(node.args, node) - def _generateCallFunc(self, args, node): # NOTE: Only simple cases are used for optimisations. @@ -297,8 +297,24 @@ last = self.last_op() if isinstance(last, (LoadName, LoadAttr)) and last.attr.assignments == 1: target = last.attr.value + context = last.attr.parent else: target = None + context = None + + # Where a target is known and has a known context, avoid generating any + # first argument. + + if context is not None: + pass # NOTE: Class methods should be supported. + else: + continue_label = self.new_label() + self.new_op(LoadContext()) + self.new_op(CheckContext()) + self.new_op(JumpIfTrue(continue_label)) + self.new_op(LoadConst("TypeError")) # NOTE: Do this properly! + self.new_op(RaiseException()) + self.set_label(continue_label) # Evaluate the arguments. @@ -418,6 +434,7 @@ # Get the "list" to be iterated over, obtain its iterator. + self._startCallFunc() self.dispatch(node.list) self._generateAttr("__iter__", (LoadAttr, LoadAttrIndex)) self._generateCallFunc([], node) @@ -429,6 +446,7 @@ # Use the iterator to get the next value. + self._startCallFunc() self.new_op(Duplicate()) self._generateAttr("next", (LoadAttr, LoadAttrIndex)) self._generateCallFunc([], node) diff -r 136f6bf70d3f -r 27ab716dcedb micropython/rsvp.py --- a/micropython/rsvp.py Mon Feb 18 01:22:25 2008 +0100 +++ b/micropython/rsvp.py Tue Feb 19 00:05:22 2008 +0100 @@ -62,11 +62,14 @@ # Invocation-related instructions. -class Jump(Instruction): pass -class JumpIfFalse(Instruction): pass -class JumpIfTrue(Instruction): pass -class LoadCallable(Instruction): pass -class Return(Instruction): pass -class CheckException(Instruction): pass +class Jump(Instruction): "Jump unconditionally." +class JumpIfFalse(Instruction): "Jump if the last evaluation gave a false result." +class JumpIfTrue(Instruction): "Jump if the last evaluation gave a true result." +class LoadCallable(Instruction): "Load the target of an invocation." +class LoadContext(Instruction): "Load the context of an invocation." +class CheckContext(Instruction): "Check the context of an invocation against the target." +class RaiseException(Instruction): "Raise an exception." +class Return(Instruction): "Return a value from a subprogram." +class CheckException(Instruction): "Check the raised exception against another." # vim: tabstop=4 expandtab shiftwidth=4