1.1 --- a/micropython/ast.py Sat Jul 26 01:16:02 2008 +0200
1.2 +++ b/micropython/ast.py Sun Jul 27 02:00:31 2008 +0200
1.3 @@ -305,7 +305,7 @@
1.4
1.5 "Return whether 'instruction' provides a simple input."
1.6
1.7 - return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress))
1.8 + return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadAddress, MakeObject))
1.9
1.10 def _is_simple_input_user(self, instruction):
1.11
1.12 @@ -314,7 +314,7 @@
1.13 return isinstance(instruction, (
1.14 StoreTemp, StoreFrame, StoreResult, StoreException, # as the value being stored
1.15 LoadAddressContext, LoadAttr, LoadAttrIndex, # as the object being referenced
1.16 - StoreAttr, StoreAttrIndex # as the object being referenced
1.17 + StoreAttr, StoreAttrIndex, StoreCallable # as the object being referenced
1.18 ))
1.19
1.20 def _is_input(self, instruction):
1.21 @@ -409,7 +409,7 @@
1.22
1.23 if isinstance(target, Class):
1.24 target = target.get_instantiator()
1.25 - context = Instance()
1.26 + context = Undefined()
1.27
1.28 # A special context is chosen to avoid generating unnecessary
1.29 # context loading and checking instructions.
1.30 @@ -628,7 +628,7 @@
1.31 """
1.32
1.33 target, context, temp = self._generateCallFuncContext()
1.34 - self._generateCallFuncArgs(target, context, args, node)
1.35 + self._generateCallFuncArgs(target, context, temp, args, node)
1.36 return temp
1.37
1.38 def _generateCallFuncContext(self):
1.39 @@ -665,12 +665,13 @@
1.40
1.41 return target, context, temp
1.42
1.43 - def _generateCallFuncArgs(self, target, context, args, node):
1.44 + def _generateCallFuncArgs(self, target, context, temp, args, node):
1.45
1.46 """
1.47 - Given invocation 'target' and 'context' information, a list of nodes
1.48 - representing the 'args' (arguments), generate instructions which load
1.49 - the arguments for the invocation defined by the given 'node'.
1.50 + Given invocation 'target' and 'context' information, the 'temp'
1.51 + reference to the target, a list of nodes representing the 'args'
1.52 + (arguments), generate instructions which load the arguments for the
1.53 + invocation defined by the given 'node'.
1.54 """
1.55
1.56 # Evaluate the arguments.
1.57 @@ -819,15 +820,8 @@
1.58 "Too many arguments for %r: need at most %d arguments." % (target.name, nargs_max))
1.59
1.60 # Where defaults are involved, put them into the frame.
1.61 - # Here, we use negative index values to visit the right hand end of
1.62 - # the defaults list.
1.63
1.64 - for pos in range(nargs_min, nargs_max):
1.65 - if pos not in employed_positions:
1.66 - self.new_op(LoadAddress(target.default_attrs[pos - nargs_min]))
1.67 - self.new_op(StoreFrame(pos))
1.68 -
1.69 - frame_pos += 1
1.70 + self._generateCallFuncDefaultArgs(target, temp, nargs_min, nargs_max, employed_positions)
1.71
1.72 # Or generate instructions to do this at run-time.
1.73 # NOTE: CheckFrame has to check the number of arguments and to fill in
1.74 @@ -837,6 +831,32 @@
1.75 else:
1.76 self.new_op(CheckFrame())
1.77
1.78 + def _generateCallFuncDefaultArgs(self, target, temp, nargs_min, nargs_max, employed_positions):
1.79 +
1.80 + """
1.81 + For the given 'target' and 'temp' reference to the target, generate
1.82 + default arguments for those positions in the range 'nargs_min'...
1.83 + 'nargs_max' which are not present in the 'employed_positions'
1.84 + collection.
1.85 + """
1.86 +
1.87 + # Where a lambda is involved, construct a dynamic object to hold the
1.88 + # defaults.
1.89 +
1.90 + dynamic = target.name is None
1.91 +
1.92 + # Here, we use negative index values to visit the right hand end of
1.93 + # the defaults list.
1.94 +
1.95 + for pos in range(nargs_min, nargs_max):
1.96 + if pos not in employed_positions:
1.97 + if dynamic:
1.98 + self.new_op(temp)
1.99 + self.new_op(LoadAttr(target.default_attrs[pos - nargs_min]))
1.100 + else:
1.101 + self.new_op(LoadAddress(target.default_attrs[pos - nargs_min]))
1.102 + self.new_op(StoreFrame(pos))
1.103 +
1.104 def _doCallFunc(self, instruction):
1.105
1.106 "Make the invocation."
1.107 @@ -856,6 +876,44 @@
1.108 if instruction is not None:
1.109 self.discard_temp(instruction)
1.110
1.111 + def _generateFunctionDefaults(self, function):
1.112 +
1.113 + """
1.114 + Generate the default initialisation code for 'function', returning
1.115 + a temporary storage reference if a dynamic object was created for the
1.116 + function.
1.117 + """
1.118 +
1.119 + attr_to_default = zip(function.default_attrs, function.defaults)
1.120 + if not attr_to_default:
1.121 + return None
1.122 +
1.123 + # Where a lambda is involved, construct a dynamic object to hold the
1.124 + # defaults.
1.125 +
1.126 + dynamic = function.name is None
1.127 +
1.128 + if dynamic:
1.129 + self.new_op(MakeObject(len(attr_to_default)))
1.130 + temp = self.get_temp()
1.131 +
1.132 + for attr, default in attr_to_default:
1.133 + self.dispatch(default)
1.134 +
1.135 + self.record_value()
1.136 + if dynamic:
1.137 + self.new_op(temp)
1.138 + self.new_op(StoreAttr(attr))
1.139 + else:
1.140 + self.new_op(StoreAddress(attr))
1.141 + self.set_source()
1.142 + self.discard_value()
1.143 +
1.144 + if dynamic:
1.145 + return temp
1.146 + else:
1.147 + return None
1.148 +
1.149 def _visitName(self, node, classes):
1.150
1.151 """
1.152 @@ -1087,18 +1145,6 @@
1.153 self.discard_temp(temp1)
1.154 self.discard_temp(temp2)
1.155
1.156 - def _generateFunctionDefaults(self, function):
1.157 -
1.158 - "Generate the default initialisation code for 'function'."
1.159 -
1.160 - for attr, default in zip(function.default_attrs, function.defaults):
1.161 - self.dispatch(default)
1.162 -
1.163 - self.record_value()
1.164 - self.new_op(StoreAddress(attr))
1.165 - self.set_source()
1.166 - self.discard_value()
1.167 -
1.168 # Concrete visitor methods.
1.169
1.170 def visitAdd(self, node):
1.171 @@ -1375,9 +1421,21 @@
1.172 # outside.
1.173
1.174 if self.unit is not node.unit:
1.175 - self._generateFunctionDefaults(node.unit)
1.176 + temp = self._generateFunctionDefaults(node.unit)
1.177 self.new_op(LoadConst(node.unit))
1.178
1.179 + # Populate the new object required for the function.
1.180 +
1.181 + if temp is not None:
1.182 + self.record_value()
1.183 + self.new_op(temp)
1.184 + self.new_op(StoreCallable())
1.185 + self.set_source()
1.186 + self.discard_value()
1.187 +
1.188 + self.new_op(temp)
1.189 + self.discard_temp(temp)
1.190 +
1.191 # Visiting of the code occurs when get_code is invoked on this node.
1.192
1.193 else: