2.1 --- a/micropython/ast.py Tue Nov 20 00:36:00 2007 +0100
2.2 +++ b/micropython/ast.py Wed Nov 21 01:30:12 2007 +0100
2.3 @@ -34,6 +34,17 @@
2.4
2.5 pass
2.6
2.7 +class Label:
2.8 +
2.9 + "A reference to a location."
2.10 +
2.11 + def __init__(self, number, location=None):
2.12 + self.number = number
2.13 + self.location = location
2.14 +
2.15 + def __repr__(self):
2.16 + return "Label(%r, location=%r)" % (self.number, self.location)
2.17 +
2.18 # Program visitors.
2.19
2.20 class Translation(ASTVisitor):
2.21 @@ -49,19 +60,29 @@
2.22 self.module = module
2.23 self.unit = None
2.24
2.25 + # Wiring within the code.
2.26 +
2.27 + self.labels = {}
2.28 + self.label_number = 0
2.29 + self.code = None
2.30 +
2.31 def get_module_code(self):
2.32
2.33 "Return the top-level module code."
2.34
2.35 self.unit = self.module
2.36 - return self.dispatch(self.module.module)
2.37 + self.code = []
2.38 + self.dispatch(self.module.module)
2.39 + return self.code
2.40
2.41 def get_code(self, unit):
2.42
2.43 "Return the code for the given 'unit'."
2.44
2.45 self.unit = unit
2.46 - return self.dispatch(unit.node)
2.47 + self.code = []
2.48 + self.dispatch(unit.node)
2.49 + return self.code
2.50
2.51 def __repr__(self):
2.52 return "Translation(%r)" % self.module
2.53 @@ -74,6 +95,27 @@
2.54 else:
2.55 return "builtins"
2.56
2.57 + # Code writing methods.
2.58 +
2.59 + def new_label(self):
2.60 + number = self.label_number
2.61 + label = Label(number)
2.62 + self.labels[label] = label
2.63 + self.label_number += 1
2.64 + return label
2.65 +
2.66 + def set_label(self, label):
2.67 +
2.68 + """
2.69 + Set the location of 'label' to that within the entire image: the
2.70 + location within the code combined with location of the code unit.
2.71 + """
2.72 +
2.73 + label.location = len(self.code) + self.unit.code_location
2.74 +
2.75 + def new_op(self, op):
2.76 + self.code.append(op)
2.77 +
2.78 # Visitor methods.
2.79
2.80 def default(self, node, *args):
2.81 @@ -90,26 +132,26 @@
2.82 if scope == "local":
2.83 unit = self.unit
2.84 if isinstance(unit, micropython.inspect.Function):
2.85 - return [NameInstruction(unit.locals()[name])]
2.86 + self.new_op(NameInstruction(unit.locals()[name]))
2.87 elif isinstance(unit, micropython.inspect.Class):
2.88 - return [AttrInstruction(unit.all_class_attributes()[name])]
2.89 + self.new_op(AttrInstruction(unit.all_class_attributes()[name]))
2.90 elif isinstance(unit, micropython.inspect.Module):
2.91 - return [AttrInstruction(unit.module_attributes()[name])]
2.92 + self.new_op(AttrInstruction(unit.module_attributes()[name]))
2.93 else:
2.94 raise TranslateError, "Program unit %r has no local %r" % (unit, name)
2.95
2.96 elif scope == "global":
2.97 globals = self.module.module_attributes()
2.98 if globals.has_key(name):
2.99 - return [AttrInstruction(globals[name])]
2.100 + self.new_op(AttrInstruction(globals[name]))
2.101 else:
2.102 raise TranslateError, "Module %r has no attribute %r" % (self.module, name)
2.103
2.104 else:
2.105 builtins = micropython.inspect.builtins.module_attributes()
2.106 - return [AttrInstruction(builtins[name])]
2.107 + self.new_op(AttrInstruction(builtins[name]))
2.108
2.109 - def visitAdd(self, node): return []
2.110 + def visitAdd(self, node): pass
2.111
2.112 """
2.113 _t1 = node.left
2.114 @@ -120,169 +162,177 @@
2.115 _t2.__radd__(_t1)
2.116 """
2.117
2.118 - def visitAnd(self, node): return []
2.119 + def visitAnd(self, node): pass
2.120
2.121 - def visitAssert(self, node): return []
2.122 + def visitAssert(self, node): pass
2.123
2.124 def visitAssign(self, node):
2.125 - results = []
2.126 - results += self.dispatch(node.expr)
2.127 + self.dispatch(node.expr)
2.128 for n in node.nodes:
2.129 - results += self.dispatch(n)
2.130 - return results
2.131 + self.dispatch(n)
2.132
2.133 - def visitAssAttr(self, node): return []
2.134 + def visitAssAttr(self, node): pass
2.135
2.136 - def visitAssList(self, node): return []
2.137 + def visitAssList(self, node): pass
2.138
2.139 def visitAssName(self, node):
2.140 - return self._visitName(node, (StoreName, StoreAttr))
2.141 + self._visitName(node, (StoreName, StoreAttr))
2.142
2.143 visitAssTuple = visitAssList
2.144
2.145 - def visitAugAssign(self, node): return []
2.146 + def visitAugAssign(self, node): pass
2.147
2.148 - def visitBackquote(self, node): return []
2.149 + def visitBackquote(self, node): pass
2.150
2.151 - def visitBitand(self, node): return []
2.152 + def visitBitand(self, node): pass
2.153
2.154 - def visitBitor(self, node): return []
2.155 + def visitBitor(self, node): pass
2.156
2.157 - def visitBitxor(self, node): return []
2.158 + def visitBitxor(self, node): pass
2.159
2.160 - def visitBreak(self, node): return []
2.161 + def visitBreak(self, node): pass
2.162
2.163 - def visitCallFunc(self, node): return []
2.164 + def visitCallFunc(self, node): pass
2.165
2.166 - def visitClass(self, node): return []
2.167 + def visitClass(self, node): pass
2.168
2.169 - def visitCompare(self, node): return []
2.170 + def visitCompare(self, node): pass
2.171
2.172 - def visitConst(self, node): return []
2.173 + def visitConst(self, node): pass
2.174
2.175 - def visitContinue(self, node): return []
2.176 + def visitContinue(self, node): pass
2.177
2.178 - def visitDecorators(self, node): return []
2.179 + def visitDecorators(self, node): pass
2.180
2.181 - def visitDict(self, node): return []
2.182 + def visitDict(self, node): pass
2.183
2.184 def visitDiscard(self, node):
2.185 - return self.dispatch(node.expr)
2.186 + self.dispatch(node.expr)
2.187
2.188 - def visitDiv(self, node): return []
2.189 + def visitDiv(self, node): pass
2.190
2.191 - def visitEllipsis(self, node): return []
2.192 + def visitEllipsis(self, node): pass
2.193
2.194 - def visitExec(self, node): return []
2.195 + def visitExec(self, node): pass
2.196
2.197 - def visitExpression(self, node): return []
2.198 + def visitExpression(self, node): pass
2.199
2.200 - def visitFloorDiv(self, node): return []
2.201 + def visitFloorDiv(self, node): pass
2.202
2.203 - def visitFor(self, node): return []
2.204 + def visitFor(self, node): pass
2.205
2.206 - def visitFrom(self, node): return []
2.207 + def visitFrom(self, node): pass
2.208
2.209 def visitFunction(self, node):
2.210
2.211 # Only store the name when visiting this node from outside.
2.212
2.213 if self.unit is self.module:
2.214 - return self._visitName(node, (StoreName, StoreAttr))
2.215 + self._visitName(node, (StoreName, StoreAttr))
2.216 else:
2.217 - return self.dispatch(node.code)
2.218 + self.dispatch(node.code)
2.219
2.220 - def visitGenExpr(self, node): return []
2.221 + def visitGenExpr(self, node): pass
2.222
2.223 - def visitGenExprFor(self, node): return []
2.224 + def visitGenExprFor(self, node): pass
2.225
2.226 - def visitGenExprIf(self, node): return []
2.227 + def visitGenExprIf(self, node): pass
2.228
2.229 - def visitGenExprInner(self, node): return []
2.230 + def visitGenExprInner(self, node): pass
2.231
2.232 - def visitGetattr(self, node): return []
2.233 + def visitGetattr(self, node): pass
2.234
2.235 - def visitGlobal(self, node): return []
2.236 + def visitGlobal(self, node): pass
2.237
2.238 def visitIf(self, node):
2.239 - for test, body in node.tests:
2.240 - self.dispatch(body)
2.241 - if node.else_ is not None:
2.242 - self.dispatch(node.else_)
2.243 - return None
2.244 + first = 1
2.245 + exit_label = self.new_label()
2.246
2.247 - def visitImport(self, node): return []
2.248 + for test, body in node.tests + [(None, node.else_)]:
2.249 + if body is None:
2.250 + break
2.251 + if not first:
2.252 + self.set_label(next_label)
2.253 + if test is not None:
2.254 + self.dispatch(test)
2.255 + next_label = self.new_label()
2.256 + self.new_op(Jump(next_label))
2.257 + self.dispatch(body)
2.258 + self.new_op(Jump(exit_label))
2.259 + first = 0
2.260
2.261 - def visitInvert(self, node): return []
2.262 -
2.263 - def visitKeyword(self, node): return []
2.264 + self.set_label(exit_label)
2.265
2.266 - def visitLambda(self, node): return []
2.267 + def visitImport(self, node): pass
2.268 +
2.269 + def visitInvert(self, node): pass
2.270
2.271 - def visitLeftShift(self, node): return []
2.272 + def visitKeyword(self, node): pass
2.273
2.274 - def visitList(self, node): return []
2.275 + def visitLambda(self, node): pass
2.276 +
2.277 + def visitLeftShift(self, node): pass
2.278
2.279 - def visitListComp(self, node): return []
2.280 + def visitList(self, node): pass
2.281
2.282 - def visitListCompFor(self, node): return []
2.283 + def visitListComp(self, node): pass
2.284
2.285 - def visitListCompIf(self, node): return []
2.286 + def visitListCompFor(self, node): pass
2.287
2.288 - def visitMod(self, node): return []
2.289 + def visitListCompIf(self, node): pass
2.290 +
2.291 + def visitMod(self, node): pass
2.292
2.293 def visitModule(self, node):
2.294 - return self.dispatch(node.node)
2.295 + self.dispatch(node.node)
2.296
2.297 - def visitMul(self, node): return []
2.298 + def visitMul(self, node): pass
2.299
2.300 def visitName(self, node):
2.301 - return self._visitName(node, (LoadName, LoadAttr))
2.302 + self._visitName(node, (LoadName, LoadAttr))
2.303
2.304 - def visitNot(self, node): return []
2.305 + def visitNot(self, node): pass
2.306
2.307 - def visitOr(self, node): return []
2.308 + def visitOr(self, node): pass
2.309
2.310 - def visitPass(self, node): return []
2.311 + def visitPass(self, node): pass
2.312
2.313 - def visitPower(self, node): return []
2.314 + def visitPower(self, node): pass
2.315
2.316 - def visitPrint(self, node): return []
2.317 + def visitPrint(self, node): pass
2.318
2.319 - def visitPrintnl(self, node): return []
2.320 + def visitPrintnl(self, node): pass
2.321
2.322 - def visitRaise(self, node): return []
2.323 + def visitRaise(self, node): pass
2.324
2.325 - def visitReturn(self, node): return []
2.326 + def visitReturn(self, node): pass
2.327
2.328 - def visitRightShift(self, node): return []
2.329 + def visitRightShift(self, node): pass
2.330
2.331 - def visitSlice(self, node): return []
2.332 + def visitSlice(self, node): pass
2.333
2.334 def visitStmt(self, node):
2.335 - result = []
2.336 for n in node.nodes:
2.337 - result += self.dispatch(n)
2.338 - return result
2.339 + self.dispatch(n)
2.340 +
2.341 + def visitSub(self, node): pass
2.342
2.343 - def visitSub(self, node): return []
2.344 + def visitSubscript(self, node): pass
2.345
2.346 - def visitSubscript(self, node): return []
2.347 + def visitTryExcept(self, node): pass
2.348
2.349 - def visitTryExcept(self, node): return []
2.350 + def visitTryFinally(self, node): pass
2.351
2.352 - def visitTryFinally(self, node): return []
2.353 + def visitTuple(self, node): pass
2.354
2.355 - def visitTuple(self, node): return []
2.356 + def visitUnaryAdd(self, node): pass
2.357
2.358 - def visitUnaryAdd(self, node): return []
2.359 + def visitUnarySub(self, node): pass
2.360
2.361 - def visitUnarySub(self, node): return []
2.362 -
2.363 - def visitWhile(self, node): return []
2.364 + def visitWhile(self, node): pass
2.365
2.366 - def visitWith(self, node): return []
2.367 + def visitWith(self, node): pass
2.368
2.369 - def visitYield(self, node): return []
2.370 + def visitYield(self, node): pass
2.371
2.372 # vim: tabstop=4 expandtab shiftwidth=4