1.1 --- a/README.txt Sat Jul 26 01:16:02 2008 +0200
1.2 +++ b/README.txt Sun Jul 27 02:00:31 2008 +0200
1.3 @@ -24,209 +24,6 @@
1.4 * Functions, if they share compatible signatures, could share parameter list
1.5 definitions.
1.6
1.7 -Data Structures
1.8 -===============
1.9 -
1.10 -The fundamental "value type" is a pair of references: one pointing to the
1.11 -referenced object represented by the interchangeable value; one referring to
1.12 -the context of the referenced object, typically the object through which the
1.13 -referenced object was acquired as an attribute.
1.14 -
1.15 -Value Layout
1.16 -------------
1.17 -
1.18 - 0 1
1.19 - object context
1.20 - reference reference
1.21 -
1.22 -Acquiring Values
1.23 -----------------
1.24 -
1.25 -Values are acquired through name lookups and attribute access, yielding
1.26 -the appropriate object reference together with a context reference as
1.27 -indicated in the following table:
1.28 -
1.29 - Type of Access Context Notes
1.30 - -------------- ------- -----
1.31 -
1.32 - Local name Preserved Functions provide no context
1.33 -
1.34 - Global name Preserved Modules provide no context
1.35 -
1.36 - Class-originating Accessor Class accessor preserves the stored
1.37 - attribute -or- context; instance accessor overrides
1.38 - Preserved the stored context if it is null or
1.39 - belongs to the instance's class
1.40 - hierarchy
1.41 -
1.42 - Instance-originating Preserved Methods retain their original context
1.43 - attribute
1.44 -
1.45 -There may be some scope for simplifying the above, to the detriment of Python
1.46 -compatibility, since the unbound vs. bound methods situation can be confusing.
1.47 -
1.48 -Manipulating Values
1.49 --------------------
1.50 -
1.51 -According to the table describing value acquisition, different instructions
1.52 -must implement different operations when acquiring values:
1.53 -
1.54 - Instruction Purpose Context Operations
1.55 - ----------- ------- ------------------
1.56 -
1.57 - LoadConst Load class, function, Combine null context with loaded
1.58 - module, constant object
1.59 -
1.60 - LoadAddress Load attribute from Classes, functions and modules
1.61 - known object stored as cause the loaded attribute to be
1.62 - an attribute retrieved unchanged; whereas
1.63 - constants (representing instances)
1.64 - cause the constant to override the
1.65 - attribute's own context (since all
1.66 - attributes should belong to the
1.67 - constant's class hierarchy)
1.68 -
1.69 - LoadAttr Load attribute from Attributes with null contexts or
1.70 - instance stored as an contexts compatible with the
1.71 - attribute instance cause loaded attributes
1.72 - to combine the instance as context
1.73 - with the object from the
1.74 - attribute; other attributes have
1.75 - their context preserved
1.76 -
1.77 - LoadAttrIndex Load attribute from Classes, functions and modules as
1.78 - unknown object stored the unknown object accessor cause
1.79 - as an attribute the loaded attribute to be
1.80 - retrieved unchanged; whereas
1.81 - instances cause the LoadAttr rules
1.82 - to apply
1.83 -
1.84 -Consequently, a certain amount of run-time testing is required for both
1.85 -LoadAttr and LoadAttrIndex.
1.86 -
1.87 -Objects
1.88 --------
1.89 -
1.90 -Since classes, functions and instances are all "objects", each must support
1.91 -certain features and operations in the same way.
1.92 -
1.93 -The __class__ Attribute
1.94 ------------------------
1.95 -
1.96 -All objects support the __class__ attribute:
1.97 -
1.98 -Class: refers to the type class (type.__class__ also refers to the type class)
1.99 -Function: refers to the function class
1.100 -Instance: refers to the class instantiated to make the object
1.101 -
1.102 -Invocation
1.103 -----------
1.104 -
1.105 -The following actions need to be supported:
1.106 -
1.107 -Class: create instance, call __init__ with instance, return object
1.108 -Function: call function body, return result
1.109 -Instance: call __call__ method, return result
1.110 -
1.111 -Structure Layout
1.112 -----------------
1.113 -
1.114 -A suitable structure layout might be something like this:
1.115 -
1.116 - Identifier Address Type Object ...
1.117 -
1.118 - 0 1 2 3 4
1.119 - classcode invocation __class__ attribute ...
1.120 - reference reference reference
1.121 -
1.122 -Here, the classcode refers to the attribute lookup table for the object. Since
1.123 -classes and instances share the same classcode, they might resemble the
1.124 -following:
1.125 -
1.126 -Class C:
1.127 -
1.128 - 0 1 2 3 4
1.129 - code for C __new__ class type attribute ...
1.130 - reference reference reference
1.131 -
1.132 -Instance of C:
1.133 -
1.134 - 0 1 2 3 4
1.135 - code for C C.__call__ class C attribute ...
1.136 - reference reference reference
1.137 - (if exists)
1.138 -
1.139 -The __new__ reference would lead to code consisting of the following
1.140 -instructions:
1.141 -
1.142 - create instance for C
1.143 - call C.__init__(instance, ...)
1.144 - return instance
1.145 -
1.146 -If C has a __call__ attribute, the invocation "slot" of C instances would
1.147 -refer to the same thing as C.__call__.
1.148 -
1.149 -For functions, the same general layout applies:
1.150 -
1.151 -Function f:
1.152 -
1.153 - 0 1 2 3 4
1.154 - code for code class attribute ...
1.155 - function reference function reference
1.156 - reference
1.157 -
1.158 -Here, the code reference would lead to code for the function. Note that the
1.159 -function locals are completely distinct from this structure and are not
1.160 -comparable to attributes.
1.161 -
1.162 -For modules, there is no meaningful invocation reference:
1.163 -
1.164 -Module m:
1.165 -
1.166 - 0 1 2 3 4
1.167 - code for m (unused) module type attribute ...
1.168 - reference (global)
1.169 - reference
1.170 -
1.171 -Both classes and modules have code in their definitions, but this would be
1.172 -generated in order and not referenced externally.
1.173 -
1.174 -Invocation Operation
1.175 ---------------------
1.176 -
1.177 -Consequently, regardless of the object an invocation is always done as
1.178 -follows:
1.179 -
1.180 - get invocation reference (at object+1)
1.181 - jump to reference
1.182 -
1.183 -Additional preparation is necessary before the above code: positional
1.184 -arguments must be saved to the parameter stack, and keyword arguments must be
1.185 -resolved and saved to the appropriate position in the parameter stack.
1.186 -
1.187 -Attribute Operations
1.188 ---------------------
1.189 -
1.190 -Attribute access needs to go through the attribute lookup table. Some
1.191 -optimisations are possible and are described in the appropriate section.
1.192 -
1.193 -One important aspect of attribute access is the appropriate setting of the
1.194 -context in the acquired attribute value. From the table describing the
1.195 -acquisition of values, it is clear that the principal exception is that where
1.196 -a class-originating attribute is accessed on an instance. Consequently, the
1.197 -following algorithm could be employed once an attribute has been located:
1.198 -
1.199 - 1. If the attribute's context is a special value, indicating that it should
1.200 - be replaced upon instance access, then proceed to the next step;
1.201 - otherwise, acquire both the context and the object as they are.
1.202 -
1.203 - 2. If the accessor is an instance, use that as the value's context, acquiring
1.204 - only the object from the attribute.
1.205 -
1.206 -Where accesses can be determined ahead of time (as discussed in the
1.207 -optimisations section), the above algorithm may not necessarily be employed in
1.208 -the generated code for some accesses.
1.209 -
1.210 Instruction Evaluation Model
1.211 ============================
1.212
2.1 --- a/docs/exceptions.txt Sat Jul 26 01:16:02 2008 +0200
2.2 +++ b/docs/exceptions.txt Sun Jul 27 02:00:31 2008 +0200
2.3 @@ -1,13 +1,15 @@
2.4 Exception Handling
2.5 ------------------
2.6
2.7 -Where exceptions may be raised, the following rules are applied:
2.8 +An exception handler stack is defined such that when a try...except or
2.9 +try...finally block is entered, a new handler is defined.
2.10
2.11 - 1. If exception labels exist, any raised exception causes a jump to the
2.12 - handler label.
2.13 +When an exception is raised, the program jumps to the most recently defined
2.14 +handler. Inside the handler, the stack entry for the handler will be removed.
2.15
2.16 - 2. If no exception labels exist, any raised exception causes the current
2.17 - function to be terminated with an exception condition.
2.18 +Depending on the nature of the handler and whether the exception is handled,
2.19 +the program may jump to the next most recent handler, and so on.
2.20
2.21 - 3. Where an invocation returns with an exception condition set, rules #1 and
2.22 - #2 are applied.
2.23 +If no handler is defined when an exception is raised or re-raised, the program
2.24 +should terminate. This might be done by having a "handler #0" which explicitly
2.25 +terminates the program.
3.1 --- a/docs/invocation.txt Sat Jul 26 01:16:02 2008 +0200
3.2 +++ b/docs/invocation.txt Sun Jul 27 02:00:31 2008 +0200
3.3 @@ -19,7 +19,7 @@
3.4
3.5 Least expensive cases:
3.6
3.7 - f(1, 2, 3) # put arguments on stack
3.8 + f(1, 2, 3) # put arguments in frame
3.9 # if f is not known, add arguments vs. parameters check
3.10 f(1, 2) # to handle defaults, introduce default "filling" where
3.11 # not enough arguments are given
3.12 @@ -27,7 +27,7 @@
3.13
3.14 More expensive cases:
3.15
3.16 - f(1, 2, c=3) # prepare stack using parameter details
3.17 + f(1, 2, c=3) # prepare frame using parameter details
3.18 # (provided c is a known parameter)
3.19 # if f is not known, this is obviously done at run-time
3.20 f(1, c=3) # as with the previous case, with default "filling" done
3.21 @@ -89,6 +89,16 @@
3.22 1 -> argument #3
3.23 2 -> argument #4
3.24
3.25 +Argument lists for classes:
3.26 +
3.27 + f(obj, 1, 2) # f known as C at compile-time
3.28 +
3.29 + f -> C.__new__ - don't get any context information
3.30 + -> any __init__ method will be called from C.__new__
3.31 + obj -> argument #1
3.32 + 1 -> argument #2
3.33 + 2 -> argument #3
3.34 +
3.35 Argument lists for unknown callables:
3.36
3.37 f(obj, 1, 2) # f not known at compile-time
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/docs/structures.txt Sun Jul 27 02:00:31 2008 +0200
4.3 @@ -0,0 +1,203 @@
4.4 +Data Structures
4.5 +===============
4.6 +
4.7 +The fundamental "value type" is a pair of references: one pointing to the
4.8 +referenced object represented by the interchangeable value; one referring to
4.9 +the context of the referenced object, typically the object through which the
4.10 +referenced object was acquired as an attribute.
4.11 +
4.12 +Value Layout
4.13 +------------
4.14 +
4.15 + 0 1
4.16 + object context
4.17 + reference reference
4.18 +
4.19 +Acquiring Values
4.20 +----------------
4.21 +
4.22 +Values are acquired through name lookups and attribute access, yielding
4.23 +the appropriate object reference together with a context reference as
4.24 +indicated in the following table:
4.25 +
4.26 + Type of Access Context Notes
4.27 + -------------- ------- -----
4.28 +
4.29 + Local name Preserved Functions provide no context
4.30 +
4.31 + Global name Preserved Modules provide no context
4.32 +
4.33 + Class-originating Accessor Class accessor preserves the stored
4.34 + attribute -or- context; instance accessor overrides
4.35 + Preserved the stored context if it is null or
4.36 + belongs to the instance's class
4.37 + hierarchy
4.38 +
4.39 + Instance-originating Preserved Methods retain their original context
4.40 + attribute
4.41 +
4.42 +There may be some scope for simplifying the above, to the detriment of Python
4.43 +compatibility, since the unbound vs. bound methods situation can be confusing.
4.44 +
4.45 +Manipulating Values
4.46 +-------------------
4.47 +
4.48 +According to the table describing value acquisition, different instructions
4.49 +must implement different operations when acquiring values:
4.50 +
4.51 + Instruction Purpose Context Operations
4.52 + ----------- ------- ------------------
4.53 +
4.54 + LoadConst Load class, function, Combine null context with loaded
4.55 + module, constant object
4.56 +
4.57 + LoadAddress Load attribute from Classes, functions and modules
4.58 + known object stored as cause the loaded attribute to be
4.59 + an attribute retrieved unchanged; whereas
4.60 + constants (representing instances)
4.61 + cause the constant to override the
4.62 + attribute's own context (since all
4.63 + attributes should belong to the
4.64 + constant's class hierarchy)
4.65 +
4.66 + LoadAttr Load attribute from Attributes with null contexts or
4.67 + instance stored as an contexts compatible with the
4.68 + attribute instance cause loaded attributes
4.69 + to combine the instance as context
4.70 + with the object from the
4.71 + attribute; other attributes have
4.72 + their context preserved
4.73 +
4.74 + LoadAttrIndex Load attribute from Classes, functions and modules as
4.75 + unknown object stored the unknown object accessor cause
4.76 + as an attribute the loaded attribute to be
4.77 + retrieved unchanged; whereas
4.78 + instances cause the LoadAttr rules
4.79 + to apply
4.80 +
4.81 +Consequently, a certain amount of run-time testing is required for both
4.82 +LoadAttr and LoadAttrIndex.
4.83 +
4.84 +Objects
4.85 +-------
4.86 +
4.87 +Since classes, functions and instances are all "objects", each must support
4.88 +certain features and operations in the same way.
4.89 +
4.90 +The __class__ Attribute
4.91 +-----------------------
4.92 +
4.93 +All objects support the __class__ attribute:
4.94 +
4.95 +Class: refers to the type class (type.__class__ also refers to the type class)
4.96 +Function: refers to the function class
4.97 +Instance: refers to the class instantiated to make the object
4.98 +
4.99 +Invocation
4.100 +----------
4.101 +
4.102 +The following actions need to be supported:
4.103 +
4.104 +Class: create instance, call __init__ with instance, return object
4.105 +Function: call function body, return result
4.106 +Instance: call __call__ method, return result
4.107 +
4.108 +Structure Layout
4.109 +----------------
4.110 +
4.111 +A suitable structure layout might be something like this:
4.112 +
4.113 + Identifier Address Type Object ...
4.114 +
4.115 + 0 1 2 3 4
4.116 + classcode invocation __class__ attribute ...
4.117 + reference reference reference
4.118 +
4.119 +Here, the classcode refers to the attribute lookup table for the object. Since
4.120 +classes and instances share the same classcode, they might resemble the
4.121 +following:
4.122 +
4.123 +Class C:
4.124 +
4.125 + 0 1 2 3 4
4.126 + code for C __new__ class type attribute ...
4.127 + reference reference reference
4.128 +
4.129 +Instance of C:
4.130 +
4.131 + 0 1 2 3 4
4.132 + code for C C.__call__ class C attribute ...
4.133 + reference reference reference
4.134 + (if exists)
4.135 +
4.136 +The __new__ reference would lead to code consisting of the following
4.137 +instructions:
4.138 +
4.139 + create instance for C
4.140 + call C.__init__(instance, ...)
4.141 + return instance
4.142 +
4.143 +If C has a __call__ attribute, the invocation "slot" of C instances would
4.144 +refer to the same thing as C.__call__.
4.145 +
4.146 +For functions, the same general layout applies:
4.147 +
4.148 +Function f:
4.149 +
4.150 + 0 1 2 3 4
4.151 + code for code class attribute ...
4.152 + function reference function reference
4.153 + reference
4.154 +
4.155 +Here, the code reference would lead to code for the function. Note that the
4.156 +function locals are completely distinct from this structure and are not
4.157 +comparable to attributes. Instead, attributes are reserved for default
4.158 +parameter values.
4.159 +
4.160 +For modules, there is no meaningful invocation reference:
4.161 +
4.162 +Module m:
4.163 +
4.164 + 0 1 2 3 4
4.165 + code for m (unused) module type attribute ...
4.166 + reference (global)
4.167 + reference
4.168 +
4.169 +Both classes and modules have code in their definitions, but this would be
4.170 +generated in order and not referenced externally.
4.171 +
4.172 +Invocation Operation
4.173 +--------------------
4.174 +
4.175 +Consequently, regardless of the object an invocation is always done as
4.176 +follows:
4.177 +
4.178 + get invocation reference (at object+1)
4.179 + jump to reference
4.180 +
4.181 +Additional preparation is necessary before the above code: positional
4.182 +arguments must be saved to the parameter stack, and keyword arguments must be
4.183 +resolved and saved to the appropriate position in the parameter stack.
4.184 +
4.185 +Attribute Operations
4.186 +--------------------
4.187 +
4.188 +Attribute access needs to go through the attribute lookup table. Some
4.189 +optimisations are possible and are described in the appropriate section.
4.190 +
4.191 +One important aspect of attribute access is the appropriate setting of the
4.192 +context in the acquired attribute value. From the table describing the
4.193 +acquisition of values, it is clear that the principal exception is that where
4.194 +a class-originating attribute is accessed on an instance. Consequently, the
4.195 +following algorithm could be employed once an attribute has been located:
4.196 +
4.197 + 1. If the attribute's context is a special value, indicating that it should
4.198 + be replaced upon instance access, then proceed to the next step;
4.199 + otherwise, acquire both the context and the object as they are.
4.200 +
4.201 + 2. If the accessor is an instance, use that as the value's context, acquiring
4.202 + only the object from the attribute.
4.203 +
4.204 +Where accesses can be determined ahead of time (as discussed in the
4.205 +optimisations section), the above algorithm may not necessarily be employed in
4.206 +the generated code for some accesses.
5.1 --- a/micropython/__init__.py Sat Jul 26 01:16:02 2008 +0200
5.2 +++ b/micropython/__init__.py Sun Jul 27 02:00:31 2008 +0200
5.3 @@ -194,9 +194,11 @@
5.4 pos += 1
5.5
5.6 # Append any default values to the image.
5.7 + # Only do this for named functions (not lambdas).
5.8
5.9 - image += obj.default_attrs
5.10 - pos += len(obj.default_attrs)
5.11 + if obj.name is not None:
5.12 + image += obj.default_attrs
5.13 + pos += len(obj.default_attrs)
5.14
5.15 # Append the function code to the image.
5.16
6.1 --- a/micropython/ast.py Sat Jul 26 01:16:02 2008 +0200
6.2 +++ b/micropython/ast.py Sun Jul 27 02:00:31 2008 +0200
6.3 @@ -305,7 +305,7 @@
6.4
6.5 "Return whether 'instruction' provides a simple input."
6.6
6.7 - return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress))
6.8 + return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress, MakeObject))
6.9
6.10 def _is_simple_input_user(self, instruction):
6.11
6.12 @@ -314,7 +314,7 @@
6.13 return isinstance(instruction, (
6.14 StoreTemp, StoreFrame, StoreResult, StoreException, # as the value being stored
6.15 LoadAddressContext, LoadAttr, LoadAttrIndex, # as the object being referenced
6.16 - StoreAttr, StoreAttrIndex # as the object being referenced
6.17 + StoreAttr, StoreAttrIndex, StoreCallable # as the object being referenced
6.18 ))
6.19
6.20 def _is_input(self, instruction):
6.21 @@ -409,7 +409,7 @@
6.22
6.23 if isinstance(target, Class):
6.24 target = target.get_instantiator()
6.25 - context = Instance()
6.26 + context = Undefined()
6.27
6.28 # A special context is chosen to avoid generating unnecessary
6.29 # context loading and checking instructions.
6.30 @@ -628,7 +628,7 @@
6.31 """
6.32
6.33 target, context, temp = self._generateCallFuncContext()
6.34 - self._generateCallFuncArgs(target, context, args, node)
6.35 + self._generateCallFuncArgs(target, context, temp, args, node)
6.36 return temp
6.37
6.38 def _generateCallFuncContext(self):
6.39 @@ -665,12 +665,13 @@
6.40
6.41 return target, context, temp
6.42
6.43 - def _generateCallFuncArgs(self, target, context, args, node):
6.44 + def _generateCallFuncArgs(self, target, context, temp, args, node):
6.45
6.46 """
6.47 - Given invocation 'target' and 'context' information, a list of nodes
6.48 - representing the 'args' (arguments), generate instructions which load
6.49 - the arguments for the invocation defined by the given 'node'.
6.50 + Given invocation 'target' and 'context' information, the 'temp'
6.51 + reference to the target, a list of nodes representing the 'args'
6.52 + (arguments), generate instructions which load the arguments for the
6.53 + invocation defined by the given 'node'.
6.54 """
6.55
6.56 # Evaluate the arguments.
6.57 @@ -819,15 +820,8 @@
6.58 "Too many arguments for %r: need at most %d arguments." % (target.name, nargs_max))
6.59
6.60 # Where defaults are involved, put them into the frame.
6.61 - # Here, we use negative index values to visit the right hand end of
6.62 - # the defaults list.
6.63
6.64 - for pos in range(nargs_min, nargs_max):
6.65 - if pos not in employed_positions:
6.66 - self.new_op(LoadAddress(target.default_attrs[pos - nargs_min]))
6.67 - self.new_op(StoreFrame(pos))
6.68 -
6.69 - frame_pos += 1
6.70 + self._generateCallFuncDefaultArgs(target, temp, nargs_min, nargs_max, employed_positions)
6.71
6.72 # Or generate instructions to do this at run-time.
6.73 # NOTE: CheckFrame has to check the number of arguments and to fill in
6.74 @@ -837,6 +831,32 @@
6.75 else:
6.76 self.new_op(CheckFrame())
6.77
6.78 + def _generateCallFuncDefaultArgs(self, target, temp, nargs_min, nargs_max, employed_positions):
6.79 +
6.80 + """
6.81 + For the given 'target' and 'temp' reference to the target, generate
6.82 + default arguments for those positions in the range 'nargs_min'...
6.83 + 'nargs_max' which are not present in the 'employed_positions'
6.84 + collection.
6.85 + """
6.86 +
6.87 + # Where a lambda is involved, construct a dynamic object to hold the
6.88 + # defaults.
6.89 +
6.90 + dynamic = target.name is None
6.91 +
6.92 + # Here, we use negative index values to visit the right hand end of
6.93 + # the defaults list.
6.94 +
6.95 + for pos in range(nargs_min, nargs_max):
6.96 + if pos not in employed_positions:
6.97 + if dynamic:
6.98 + self.new_op(temp)
6.99 + self.new_op(LoadAttr(target.default_attrs[pos - nargs_min]))
6.100 + else:
6.101 + self.new_op(LoadAddress(target.default_attrs[pos - nargs_min]))
6.102 + self.new_op(StoreFrame(pos))
6.103 +
6.104 def _doCallFunc(self, instruction):
6.105
6.106 "Make the invocation."
6.107 @@ -856,6 +876,44 @@
6.108 if instruction is not None:
6.109 self.discard_temp(instruction)
6.110
6.111 + def _generateFunctionDefaults(self, function):
6.112 +
6.113 + """
6.114 + Generate the default initialisation code for 'function', returning
6.115 + a temporary storage reference if a dynamic object was created for the
6.116 + function.
6.117 + """
6.118 +
6.119 + attr_to_default = zip(function.default_attrs, function.defaults)
6.120 + if not attr_to_default:
6.121 + return None
6.122 +
6.123 + # Where a lambda is involved, construct a dynamic object to hold the
6.124 + # defaults.
6.125 +
6.126 + dynamic = function.name is None
6.127 +
6.128 + if dynamic:
6.129 + self.new_op(MakeObject(len(attr_to_default)))
6.130 + temp = self.get_temp()
6.131 +
6.132 + for attr, default in attr_to_default:
6.133 + self.dispatch(default)
6.134 +
6.135 + self.record_value()
6.136 + if dynamic:
6.137 + self.new_op(temp)
6.138 + self.new_op(StoreAttr(attr))
6.139 + else:
6.140 + self.new_op(StoreAddress(attr))
6.141 + self.set_source()
6.142 + self.discard_value()
6.143 +
6.144 + if dynamic:
6.145 + return temp
6.146 + else:
6.147 + return None
6.148 +
6.149 def _visitName(self, node, classes):
6.150
6.151 """
6.152 @@ -1087,18 +1145,6 @@
6.153 self.discard_temp(temp1)
6.154 self.discard_temp(temp2)
6.155
6.156 - def _generateFunctionDefaults(self, function):
6.157 -
6.158 - "Generate the default initialisation code for 'function'."
6.159 -
6.160 - for attr, default in zip(function.default_attrs, function.defaults):
6.161 - self.dispatch(default)
6.162 -
6.163 - self.record_value()
6.164 - self.new_op(StoreAddress(attr))
6.165 - self.set_source()
6.166 - self.discard_value()
6.167 -
6.168 # Concrete visitor methods.
6.169
6.170 def visitAdd(self, node):
6.171 @@ -1375,9 +1421,21 @@
6.172 # outside.
6.173
6.174 if self.unit is not node.unit:
6.175 - self._generateFunctionDefaults(node.unit)
6.176 + temp = self._generateFunctionDefaults(node.unit)
6.177 self.new_op(LoadConst(node.unit))
6.178
6.179 + # Populate the new object required for the function.
6.180 +
6.181 + if temp is not None:
6.182 + self.record_value()
6.183 + self.new_op(temp)
6.184 + self.new_op(StoreCallable())
6.185 + self.set_source()
6.186 + self.discard_value()
6.187 +
6.188 + self.new_op(temp)
6.189 + self.discard_temp(temp)
6.190 +
6.191 # Visiting of the code occurs when get_code is invoked on this node.
6.192
6.193 else:
7.1 --- a/micropython/common.py Sat Jul 26 01:16:02 2008 +0200
7.2 +++ b/micropython/common.py Sun Jul 27 02:00:31 2008 +0200
7.3 @@ -139,4 +139,10 @@
7.4 else:
7.5 return self.parent.full_name()
7.6
7.7 +class Undefined:
7.8 +
7.9 + "A special class of undefined values."
7.10 +
7.11 + pass
7.12 +
7.13 # vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/micropython/inspect.py Sat Jul 26 01:16:02 2008 +0200
8.2 +++ b/micropython/inspect.py Sun Jul 27 02:00:31 2008 +0200
8.3 @@ -300,6 +300,8 @@
8.4 self.store(name, function)
8.5 else:
8.6 self.store_lambda(function)
8.7 + if node.defaults:
8.8 + return None # NOTE: See lambda code in the ast module.
8.9
8.10 return function
8.11
9.1 --- a/micropython/rsvp.py Sat Jul 26 01:16:02 2008 +0200
9.2 +++ b/micropython/rsvp.py Sun Jul 27 02:00:31 2008 +0200
9.3 @@ -162,7 +162,7 @@
9.4 class LoadAddress(Address): "Load the current value from the given fixed attribute address."
9.5 class StoreAddress(Address): "Store the source value into the given fixed attribute address."
9.6 class LoadAddressContext(Address): "Load the current value from the given fixed attribute address, making the current value the context."
9.7 -class MakeObject(Instruction): "Make a new object. There isn't a complementary DropObject."
9.8 +class MakeObject(Immediate): "Make a new object. There isn't a complementary DropObject."
9.9
9.10 # Access to address-relative data.
9.11
9.12 @@ -178,6 +178,7 @@
9.13 class StoreFrame(Immediate): "Store the current value as an argument for the parameter with the given position."
9.14 class StoreFrameIndex(Immediate): "Store the current value as an argument for the parameter with the given index."
9.15 class LoadCallable(Instruction): "Load the target of an invocation."
9.16 +class StoreCallable(Instruction): "Store the source value into the object referenced by the current value."
9.17 class LoadContext(Instruction): "Load the context of an invocation."
9.18 class CheckFrame(Instruction): "Check the invocation frame and context for the target."
9.19 class CheckSelf(Instruction): "Check the first argument of an invocation against the target."
11.1 --- a/tests/lambda.py Sat Jul 26 01:16:02 2008 +0200
11.2 +++ b/tests/lambda.py Sun Jul 27 02:00:31 2008 +0200
11.3 @@ -1,18 +1,18 @@
11.4 #!/usr/bin/env python
11.5
11.6 identity = lambda x: x
11.7 +add_2 = lambda a, b=2: a + b
11.8
11.9 -def f():
11.10 - return lambda a, b=2: a + b
11.11 -
11.12 -def f2(c):
11.13 +def f(c):
11.14 return lambda a, b=c: a + b
11.15
11.16 def g(f, x):
11.17 return f(x)
11.18
11.19 +identity(1)
11.20 +add_2(1)
11.21 g(identity, 1)
11.22 -g(f(), 1)
11.23 -g(f2(3), 1)
11.24 +g(add_2, 1)
11.25 +g(f(3), 1)
11.26
11.27 # vim: tabstop=4 expandtab shiftwidth=4