1.1 --- a/micropython/syspython.py Sun Jun 30 01:52:11 2013 +0200
1.2 +++ b/micropython/syspython.py Sun Jun 30 22:46:32 2013 +0200
1.3 @@ -582,10 +582,22 @@
1.4 def visitAnd(self, node):
1.5 return compiler.ast.And([self.dispatch(n) for n in node.nodes])
1.6
1.7 - def visitAssAttr(self, node, expr):
1.8 + def visitAssAttr(self, node, expr=None):
1.9 +
1.10 + # Handle deletion.
1.11 +
1.12 + if compiler.ast.is_deletion(node):
1.13 + return compiler.ast.Stmt([])
1.14 +
1.15 return self._visitAttr(node, expr)
1.16
1.17 - def visitAssList(self, node, expr):
1.18 + def visitAssList(self, node, expr=None):
1.19 +
1.20 + # Handle deletion.
1.21 +
1.22 + if compiler.ast.is_deletion(compiler.ast.flatten_assignment(node)):
1.23 + return compiler.ast.Stmt([])
1.24 +
1.25 return compiler.ast.Stmt([
1.26 self.dispatch(n, compiler.ast.CallFunc(
1.27 module_attribute("operator", "getitem"),
1.28 @@ -594,7 +606,13 @@
1.29 for (i, n) in enumerate(node.nodes)
1.30 ])
1.31
1.32 - def visitAssName(self, node, expr):
1.33 + def visitAssName(self, node, expr=None):
1.34 +
1.35 + # Handle deletion.
1.36 +
1.37 + if compiler.ast.is_deletion(node):
1.38 + return compiler.ast.Stmt([])
1.39 +
1.40 unit = self.get_unit()
1.41
1.42 # Generate appropriate name access operation.
1.43 @@ -674,8 +692,8 @@
1.44 return compiler.ast.CallFunc(
1.45 self.dispatch(node.node),
1.46 [self.dispatch(arg) for arg in node.args],
1.47 - node.star_args and [self.dispatch(arg) for arg in node.star_args],
1.48 - node.dstar_args and [self.dispatch(arg) for arg in node.dstar_args]
1.49 + node.star_args and self.dispatch(node.star_args),
1.50 + node.dstar_args and self.dispatch(node.dstar_args)
1.51 )
1.52
1.53 def visitCompare(self, node):
1.54 @@ -709,9 +727,10 @@
1.55 return compiler.ast.GenExpr(self.dispatch(node.code))
1.56
1.57 def visitGenExprFor(self, node):
1.58 + expr = self.dispatch(node.iter)
1.59 return compiler.ast.GenExprFor(
1.60 - self.dispatch(node.assign), # NOTE: Needs to dispatch to AssName/AssTuple/AssList with an expression.
1.61 - self.dispatch(node.iter),
1.62 + self.dispatch(node.assign, expr), # NOTE: Needs to dispatch to AssName/AssTuple/AssList with an expression.
1.63 + expr,
1.64 [self.dispatch(n) for n in node.ifs]
1.65 )
1.66
1.67 @@ -762,22 +781,143 @@
1.68 return compiler.ast.List([self.dispatch(n) for n in node.nodes])
1.69
1.70 def visitListComp(self, node):
1.71 - return compiler.ast.ListComp(
1.72 - self.dispatch(node.expr),
1.73 - [self.dispatch(n) for n in node.quals]
1.74 +
1.75 + """
1.76 + Convert from...
1.77 +
1.78 + [<expr> for <assign> in <list> [ for <assign> in <list> ]... [ if <test> ]... ]
1.79 +
1.80 + ...to...
1.81 +
1.82 + _out = []
1.83 + ...
1.84 + """
1.85 +
1.86 + unit = self.get_unit()
1.87 + temp = quoted_name(unit.temp_usage)
1.88 + unit.temp_usage += 1
1.89 +
1.90 + return compiler.ast.Stmt([
1.91 + # __storetemp__(_out, __loadattr__(__builtins__, list)())
1.92 + compiler.ast.CallFunc(special_name("__storetemp__"), [
1.93 + temp,
1.94 + compiler.ast.CallFunc(
1.95 + compiler.ast.CallFunc(special_name("__loadattr__"),
1.96 + [special_name("__builtins__"), special_name("list")]
1.97 + ),
1.98 + []
1.99 + )
1.100 + ]),
1.101 + # ...
1.102 + self.dispatch(node.quals[0], temp, node.expr, node.quals[1:])
1.103 + ])
1.104 +
1.105 + def visitListCompFor(self, node, out_temp, expr, quals):
1.106 +
1.107 + """
1.108 + Convert from...
1.109 +
1.110 + [<expr> for <assign> in <list> ...]
1.111 +
1.112 + ...to...
1.113 +
1.114 + _it = iter(<list>)
1.115 + while True:
1.116 + try:
1.117 + <assign> = _it.next()
1.118 + except StopIteration:
1.119 + break
1.120 + else:
1.121 + ...
1.122 + _out.append(<expr>)
1.123 + """
1.124 +
1.125 + unit = self.get_unit()
1.126 + temp = quoted_name(unit.temp_usage)
1.127 + unit.temp_usage += 1
1.128 +
1.129 + # Either generate more "for" or "if" constructs.
1.130 +
1.131 + if node.ifs or quals:
1.132 + nodes = node.ifs + quals
1.133 + body = self.dispatch(nodes[0], out_temp, expr, nodes[1:])
1.134 +
1.135 + # Or generate the append statement.
1.136 +
1.137 + else:
1.138 + body = self._visitListCompExpr(out_temp, expr)
1.139 +
1.140 + # Wrap the above body in the loop construct.
1.141 +
1.142 + return compiler.ast.Stmt([
1.143 + # __storetemp__(_it, __loadattr__(__builtins__, iter)(<list>))
1.144 + compiler.ast.CallFunc(special_name("__storetemp__"), [
1.145 + temp,
1.146 + compiler.ast.CallFunc(
1.147 + compiler.ast.CallFunc(special_name("__loadattr__"),
1.148 + [special_name("__builtins__"), special_name("iter")]
1.149 + ),
1.150 + [self.dispatch(node.list)]
1.151 + )
1.152 + ]),
1.153 + # while True: ...
1.154 + compiler.ast.While(
1.155 + special_name("True"),
1.156 + # try: ...
1.157 + compiler.ast.TryExcept(
1.158 + compiler.ast.Stmt([
1.159 + # <assign> = ...
1.160 + self.dispatch(node.assign,
1.161 + # _it.next()
1.162 + compiler.ast.CallFunc(
1.163 + compiler.ast.CallFunc(special_name("__loadattr__"), [
1.164 + compiler.ast.CallFunc(special_name("__loadtemp__"), [temp]),
1.165 + special_name("next")
1.166 + ]),
1.167 + []
1.168 + )
1.169 + )
1.170 + ]),
1.171 + # except StopIteration: ...
1.172 + [(special_name("StopIteration"), None, compiler.ast.Stmt([compiler.ast.Break()]))],
1.173 + # else: ...
1.174 + body
1.175 + ),
1.176 + None
1.177 + )
1.178 + ])
1.179 +
1.180 + def visitListCompIf(self, node, out_temp, expr, quals):
1.181 +
1.182 + # Either generate more "for" or "if" constructs.
1.183 +
1.184 + if quals:
1.185 + body = self.dispatch(quals[0], out_temp, expr, quals[1:])
1.186 +
1.187 + # Or generate the append statement.
1.188 +
1.189 + else:
1.190 + body = self._visitListCompExpr(out_temp, expr)
1.191 +
1.192 + return compiler.ast.If(
1.193 + [(self.dispatch(node.test), body)],
1.194 + None
1.195 )
1.196
1.197 - def visitListCompFor(self, node):
1.198 - return compiler.ast.ListCompFor(
1.199 - self.dispatch(node.assign), # NOTE: Needs to dispatch to AssName/AssTuple/AssList with an expression.
1.200 - self.dispatch(node.list),
1.201 - [self.dispatch(n) for n in node.ifs]
1.202 - )
1.203 + def _visitListCompExpr(self, out_temp, expr):
1.204 +
1.205 + "To the 'out_temp' object, append the result of 'expr'."
1.206
1.207 - def visitListCompIf(self, node):
1.208 - return compiler.ast.ListCompIf(
1.209 - self.dispatch(node.test)
1.210 - )
1.211 + return compiler.ast.Stmt([
1.212 + # _out.append(<expr>)
1.213 + compiler.ast.CallFunc(
1.214 + compiler.ast.CallFunc(special_name("__loadattr__"), [
1.215 + compiler.ast.CallFunc(special_name("__loadtemp__"), [out_temp]),
1.216 + special_name("append")
1.217 + ]),
1.218 + [self.dispatch(expr)]
1.219 + )
1.220 + ])
1.221
1.222 def visitMod(self, node):
1.223 return self._visitBinary(node)
1.224 @@ -805,12 +945,20 @@
1.225
1.226 # Other attributes should already be resolved.
1.227
1.228 - elif attr is not None:
1.229 + elif attr is not None and not isinstance(attr, Instance):
1.230 return compiler.ast.CallFunc(
1.231 special_name("__loadattr__"),
1.232 [quoted_ref(attr.parent), special_name(node.name)]
1.233 )
1.234
1.235 + # Function globals are referenced via the module.
1.236 +
1.237 + elif scope == "global":
1.238 + return compiler.ast.CallFunc(
1.239 + special_name("__loadattr__"),
1.240 + [quoted_ref(self.get_module()), special_name(node.name)]
1.241 + )
1.242 +
1.243 # NOTE: Unknown attributes may arise because a class attribute has been
1.244 # NOTE: optimised away.
1.245