1.1 --- a/micropython/syspython.py Fri Nov 29 01:03:05 2013 +0100
1.2 +++ b/micropython/syspython.py Fri Nov 29 01:03:47 2013 +0100
1.3 @@ -86,17 +86,65 @@
1.4 module = self.dispatch(self.module.astnode)
1.5 stream.write(str(module))
1.6
1.7 - def get_original_arguments(self, argnames):
1.8 + def store_value(self, unit, scope, name, value):
1.9 +
1.10 + """
1.11 + In the given 'unit' and for the given 'scope', store for the given
1.12 + 'name' the given 'value'.
1.13 + """
1.14 +
1.15 + if scope == "local":
1.16 +
1.17 + # Function locals are stored using a function.
1.18 +
1.19 + if isinstance(unit, Function):
1.20 + return compiler.ast.CallFunc(
1.21 + special_name("storelocal"),
1.22 + [special_name(name), value]
1.23 + )
1.24 +
1.25 + # Class locals are class attribute references.
1.26 +
1.27 + elif isinstance(unit, Class):
1.28 + return compiler.ast.CallFunc(
1.29 + special_name("storeattrcontext"),
1.30 + [quoted_ref(unit), special_name(name), value]
1.31 + )
1.32 +
1.33 + # Module locals are module attribute references.
1.34
1.35 - # NOTE: The special context argument should not be reproduced.
1.36 - # NOTE: For "dynamic" functions, the context is used to access
1.37 - # NOTE: things like defaults, but could be extended for closures to
1.38 - # NOTE: refer to many namespaces.
1.39 + elif isinstance(unit, Module):
1.40 + return compiler.ast.CallFunc(
1.41 + special_name("storeattr"),
1.42 + [quoted_ref(unit), special_name(name), value]
1.43 + )
1.44 + else:
1.45 + raise TranslateError("Program unit has no local %r." % name)
1.46 +
1.47 + elif scope == "global":
1.48 +
1.49 + # Globals are references to module attributes.
1.50
1.51 - if argnames and argnames[0] == "<context>":
1.52 - return argnames[1:]
1.53 + return compiler.ast.CallFunc(
1.54 + special_name("storeattr"),
1.55 + [quoted_ref(self.get_module()), special_name(name), value]
1.56 + )
1.57 +
1.58 + elif scope == "builtin":
1.59 +
1.60 + # Builtins are accessed via the __builtins__ module.
1.61 +
1.62 + return compiler.ast.CallFunc(
1.63 + special_name("storeattr"),
1.64 + [special_name("__builtins__"), special_name(name), value]
1.65 + )
1.66 +
1.67 else:
1.68 - return argnames
1.69 + # NOTE: This may happen because a class attribute is optimised away.
1.70 + return compiler.ast.CallFunc(
1.71 + special_name("storeunknown"),
1.72 + [special_name(name), value]
1.73 + )
1.74
1.75 def NOP(self, node):
1.76 return node
1.77 @@ -342,22 +390,25 @@
1.78 self.units.append(node.unit)
1.79
1.80 try:
1.81 - # NOTE: Need to initialise any defaults outside a definition and to
1.82 - # NOTE: transfer defaults to locals inside a definition.
1.83 -
1.84 if not self.processing_definition(node):
1.85
1.86 - # Generate rebindings of functions.
1.87 + # Generate rebindings of functions where multiple definitions
1.88 + # exist within a scope. Also generate dynamic function object
1.89 + # initialisation.
1.90
1.91 fn = node.unit
1.92 - if fn.name == fn.original_name:
1.93 + if fn.name == fn.original_name and not fn.is_dynamic():
1.94 return compiler.ast.Stmt([])
1.95 else:
1.96 - return compiler.ast.CallFunc(
1.97 - special_name("storeattr"),
1.98 - [quoted_ref(fn.parent), special_name(fn.original_name),
1.99 - quoted_ref(fn)]
1.100 - )
1.101 + if fn.is_dynamic():
1.102 + ref = compiler.ast.CallFunc(
1.103 + special_name("makedynamic"),
1.104 + [quoted_ref(fn)] + fn.defaults
1.105 + )
1.106 + else:
1.107 + ref = quoted_ref(fn)
1.108 +
1.109 + return self.store_value(fn.parent, "local", fn.original_name, ref)
1.110 else:
1.111 return self._visitFunctionDefinition(node)
1.112 finally:
1.113 @@ -383,15 +434,23 @@
1.114 )
1.115 ] or []
1.116
1.117 + # Process any local class or function definitions.
1.118 +
1.119 + current = self.current_definition
1.120 + definitions = self.process_definitions(node)
1.121 + self.current_definition = current
1.122 +
1.123 defaults = [self.dispatch(n) for n in node.defaults]
1.124
1.125 + # NOTE: Any required defaults should be copied into the local namespace
1.126 + # NOTE: using the __context__ reference to the instance of the function.
1.127 +
1.128 # NOTE: Should generate guards for attribute usage operations.
1.129
1.130 code = self.dispatch(node.code)
1.131 - argnames = self.get_original_arguments(node.argnames)
1.132
1.133 - return compiler.ast.Function(node.decorators, node.name, argnames, defaults, node.flags, node.doc,
1.134 - compiler.ast.Stmt(localnames + globalnames + code.nodes))
1.135 + return compiler.ast.Function(node.decorators, node.name, node.argnames, defaults, node.flags, node.doc,
1.136 + compiler.ast.Stmt(localnames + globalnames + definitions + code.nodes))
1.137
1.138 visitGlobal = NOP
1.139
1.140 @@ -693,58 +752,8 @@
1.141
1.142 if scope == "constant":
1.143 return node
1.144 - elif scope == "local":
1.145 -
1.146 - # Function locals are stored using a function.
1.147 -
1.148 - if isinstance(unit, Function):
1.149 - return compiler.ast.CallFunc(
1.150 - special_name("storelocal"),
1.151 - [special_name(node.name), expr]
1.152 - )
1.153 -
1.154 - # Class locals are class attribute references.
1.155 -
1.156 - elif isinstance(unit, Class):
1.157 - return compiler.ast.CallFunc(
1.158 - special_name("storeattrcontext"),
1.159 - [quoted_ref(unit), special_name(node.name), expr]
1.160 - )
1.161 -
1.162 - # Module locals are module attribute references.
1.163 -
1.164 - elif isinstance(unit, Module):
1.165 - return compiler.ast.CallFunc(
1.166 - special_name("storeattr"),
1.167 - [quoted_ref(unit), special_name(node.name), expr]
1.168 - )
1.169 - else:
1.170 - raise TranslateError("Program unit has no local %r." % name)
1.171 -
1.172 - elif scope == "global":
1.173 -
1.174 - # Globals are references to module attributes.
1.175 -
1.176 - return compiler.ast.CallFunc(
1.177 - special_name("storeattr"),
1.178 - [quoted_ref(self.get_module()), special_name(node.name), expr]
1.179 - )
1.180 -
1.181 - elif scope == "builtin":
1.182 -
1.183 - # Builtins are accessed via the __builtins__ module.
1.184 -
1.185 - return compiler.ast.CallFunc(
1.186 - special_name("storeattr"),
1.187 - [special_name("__builtins__"), special_name(node.name), expr]
1.188 - )
1.189 -
1.190 else:
1.191 - # NOTE: This may happen because a class attribute is optimised away.
1.192 - return compiler.ast.CallFunc(
1.193 - special_name("storeunknown"),
1.194 - [special_name(node.name), expr]
1.195 - )
1.196 + return self.store_value(unit, scope, node.name, expr)
1.197
1.198 visitAssTuple = visitAssList
1.199
1.200 @@ -906,13 +915,12 @@
1.201 def visitLambda(self, node):
1.202 self.units.append(node.unit)
1.203
1.204 - # NOTE: Need to initialise any defaults.
1.205 + # NOTE: Need to initialise any defaults. Lambdas should probably be
1.206 + # NOTE: expanded to be "real" function definitions.
1.207
1.208 try:
1.209 - argnames = self.get_original_arguments(node.argnames)
1.210 -
1.211 return compiler.ast.Lambda(
1.212 - argnames,
1.213 + node.argnames,
1.214 [self.dispatch(n) for n in node.defaults],
1.215 node.flags,
1.216 self.dispatch(node.code)