1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/micropython/ast.py Fri Nov 09 00:19:03 2007 +0100
1.3 @@ -0,0 +1,284 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +Translate the AST of a Python program into a more interpretable representation.
1.8 +
1.9 +Copyright (C) 2007 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This program is free software; you can redistribute it and/or modify it under
1.12 +the terms of the GNU General Public License as published by the Free Software
1.13 +Foundation; either version 3 of the License, or (at your option) any later
1.14 +version.
1.15 +
1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.19 +details.
1.20 +
1.21 +You should have received a copy of the GNU General Public License along with
1.22 +this program. If not, see <http://www.gnu.org/licenses/>.
1.23 +"""
1.24 +
1.25 +import micropython.inspect
1.26 +from micropython.rsvp import *
1.27 +import compiler.ast
1.28 +from compiler.visitor import ASTVisitor
1.29 +try:
1.30 + set
1.31 +except NameError:
1.32 + from sets import Set as set
1.33 +
1.34 +class TranslateError(Exception):
1.35 +
1.36 + "A translation error."
1.37 +
1.38 + pass
1.39 +
1.40 +# Program visitors.
1.41 +
1.42 +class Translation(ASTVisitor):
1.43 +
1.44 + "A translated module."
1.45 +
1.46 + def __init__(self, module):
1.47 + ASTVisitor.__init__(self)
1.48 + self.visitor = self
1.49 + self.module = module
1.50 + self.unit = None
1.51 +
1.52 + def get_module_code(self):
1.53 +
1.54 + "Return the top-level module code."
1.55 +
1.56 + self.unit = self.module
1.57 + return self.dispatch(self.module.module)
1.58 +
1.59 + def get_code(self, unit):
1.60 +
1.61 + "Return the code for the given 'unit'."
1.62 +
1.63 + self.unit = unit
1.64 + return self.dispatch(unit.node)
1.65 +
1.66 + def __repr__(self):
1.67 + return "Translation(%r)" % self.module
1.68 +
1.69 + def get_scope(self, name):
1.70 + if self.unit.has_key(name):
1.71 + return "local"
1.72 + elif self.module.has_key(name):
1.73 + return "global"
1.74 + else:
1.75 + return "builtins"
1.76 +
1.77 + # Visitor methods.
1.78 +
1.79 + def default(self, node, *args):
1.80 + raise TranslateError, node.__class__
1.81 +
1.82 + def dispatch(self, node, *args):
1.83 + return ASTVisitor.dispatch(self, node, *args)
1.84 +
1.85 + def _visitName(self, node, classes):
1.86 + name = node.name
1.87 + scope = self.get_scope(name)
1.88 + NameInstruction, AttrInstruction = classes
1.89 +
1.90 + if scope == "local":
1.91 + unit = self.unit
1.92 + if isinstance(unit, micropython.inspect.Function):
1.93 + return [NameInstruction(unit.locals()[name])]
1.94 + elif isinstance(unit, micropython.inspect.Class):
1.95 + return [AttrInstruction(unit.all_class_attributes()[name])]
1.96 + elif isinstance(unit, micropython.inspect.Module):
1.97 + return [AttrInstruction(unit.module_attributes()[name])]
1.98 + else:
1.99 + raise TranslateError, "Program unit %r has no local %r" % (unit, name)
1.100 +
1.101 + elif scope == "global":
1.102 + globals = self.module.module_attributes()
1.103 + if globals.has_key(name):
1.104 + return [AttrInstruction(globals[name])]
1.105 + else:
1.106 + raise TranslateError, "Module %r has no attribute %r" % (self.module, name)
1.107 +
1.108 + else:
1.109 + builtins = micropython.inspect.builtins.module_attributes()
1.110 + return [AttrInstruction(builtins[name])]
1.111 +
1.112 + def visitAdd(self, node): return []
1.113 +
1.114 + """
1.115 + _t1 = node.left
1.116 + _t2 = node.right
1.117 + try:
1.118 + _t1.__add__(_t2)
1.119 + except AttributeError:
1.120 + _t2.__radd__(_t1)
1.121 + """
1.122 +
1.123 + def visitAnd(self, node): return []
1.124 +
1.125 + def visitAssert(self, node): return []
1.126 +
1.127 + def visitAssign(self, node):
1.128 + results = []
1.129 + results += self.dispatch(node.expr)
1.130 + for n in node.nodes:
1.131 + results += self.dispatch(n)
1.132 + return results
1.133 +
1.134 + def visitAssAttr(self, node): return []
1.135 +
1.136 + def visitAssList(self, node): return []
1.137 +
1.138 + def visitAssName(self, node):
1.139 + return self._visitName(node, (StoreName, StoreAttr))
1.140 +
1.141 + visitAssTuple = visitAssList
1.142 +
1.143 + def visitAugAssign(self, node): return []
1.144 +
1.145 + def visitBackquote(self, node): return []
1.146 +
1.147 + def visitBitand(self, node): return []
1.148 +
1.149 + def visitBitor(self, node): return []
1.150 +
1.151 + def visitBitxor(self, node): return []
1.152 +
1.153 + def visitBreak(self, node): return []
1.154 +
1.155 + def visitCallFunc(self, node): return []
1.156 +
1.157 + def visitClass(self, node): return []
1.158 +
1.159 + def visitCompare(self, node): return []
1.160 +
1.161 + def visitConst(self, node): return []
1.162 +
1.163 + def visitContinue(self, node): return []
1.164 +
1.165 + def visitDecorators(self, node): return []
1.166 +
1.167 + def visitDict(self, node): return []
1.168 +
1.169 + def visitDiscard(self, node): return []
1.170 +
1.171 + def visitDiv(self, node): return []
1.172 +
1.173 + def visitEllipsis(self, node): return []
1.174 +
1.175 + def visitExec(self, node): return []
1.176 +
1.177 + def visitExpression(self, node): return []
1.178 +
1.179 + def visitFloorDiv(self, node): return []
1.180 +
1.181 + def visitFor(self, node): return []
1.182 +
1.183 + def visitFrom(self, node): return []
1.184 +
1.185 + def visitFunction(self, node):
1.186 +
1.187 + # Only store the name when visiting this node from outside.
1.188 +
1.189 + if self.unit is self.module:
1.190 + return self._visitName(node, (StoreName, StoreAttr))
1.191 + else:
1.192 + return self.dispatch(node.code)
1.193 +
1.194 + def visitGenExpr(self, node): return []
1.195 +
1.196 + def visitGenExprFor(self, node): return []
1.197 +
1.198 + def visitGenExprIf(self, node): return []
1.199 +
1.200 + def visitGenExprInner(self, node): return []
1.201 +
1.202 + def visitGetattr(self, node): return []
1.203 +
1.204 + def visitGlobal(self, node): return []
1.205 +
1.206 + def visitIf(self, node):
1.207 + for test, body in node.tests:
1.208 + self.dispatch(body)
1.209 + if node.else_ is not None:
1.210 + self.dispatch(node.else_)
1.211 + return None
1.212 +
1.213 + def visitImport(self, node): return []
1.214 +
1.215 + def visitInvert(self, node): return []
1.216 +
1.217 + def visitKeyword(self, node): return []
1.218 +
1.219 + def visitLambda(self, node): return []
1.220 +
1.221 + def visitLeftShift(self, node): return []
1.222 +
1.223 + def visitList(self, node): return []
1.224 +
1.225 + def visitListComp(self, node): return []
1.226 +
1.227 + def visitListCompFor(self, node): return []
1.228 +
1.229 + def visitListCompIf(self, node): return []
1.230 +
1.231 + def visitMod(self, node): return []
1.232 +
1.233 + def visitModule(self, node):
1.234 + return self.dispatch(node.node)
1.235 +
1.236 + def visitMul(self, node): return []
1.237 +
1.238 + def visitName(self, node):
1.239 + return self._visitName(node, (LoadName, LoadAttr))
1.240 +
1.241 + def visitNot(self, node): return []
1.242 +
1.243 + def visitOr(self, node): return []
1.244 +
1.245 + def visitPass(self, node): return []
1.246 +
1.247 + def visitPower(self, node): return []
1.248 +
1.249 + def visitPrint(self, node): return []
1.250 +
1.251 + def visitPrintnl(self, node): return []
1.252 +
1.253 + def visitRaise(self, node): return []
1.254 +
1.255 + def visitReturn(self, node): return []
1.256 +
1.257 + def visitRightShift(self, node): return []
1.258 +
1.259 + def visitSlice(self, node): return []
1.260 +
1.261 + def visitStmt(self, node):
1.262 + result = []
1.263 + for n in node.nodes:
1.264 + result += self.dispatch(n)
1.265 + return result
1.266 +
1.267 + def visitSub(self, node): return []
1.268 +
1.269 + def visitSubscript(self, node): return []
1.270 +
1.271 + def visitTryExcept(self, node): return []
1.272 +
1.273 + def visitTryFinally(self, node): return []
1.274 +
1.275 + def visitTuple(self, node): return []
1.276 +
1.277 + def visitUnaryAdd(self, node): return []
1.278 +
1.279 + def visitUnarySub(self, node): return []
1.280 +
1.281 + def visitWhile(self, node): return []
1.282 +
1.283 + def visitWith(self, node): return []
1.284 +
1.285 + def visitYield(self, node): return []
1.286 +
1.287 +# vim: tabstop=4 expandtab shiftwidth=4