2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/micropython/ast.py Fri Nov 09 00:19:03 2007 +0100
2.3 @@ -0,0 +1,284 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Translate the AST of a Python program into a more interpretable representation.
2.8 +
2.9 +Copyright (C) 2007 Paul Boddie <paul@boddie.org.uk>
2.10 +
2.11 +This program is free software; you can redistribute it and/or modify it under
2.12 +the terms of the GNU General Public License as published by the Free Software
2.13 +Foundation; either version 3 of the License, or (at your option) any later
2.14 +version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful, but WITHOUT
2.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.19 +details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License along with
2.22 +this program. If not, see <http://www.gnu.org/licenses/>.
2.23 +"""
2.24 +
2.25 +import micropython.inspect
2.26 +from micropython.rsvp import *
2.27 +import compiler.ast
2.28 +from compiler.visitor import ASTVisitor
2.29 +try:
2.30 + set
2.31 +except NameError:
2.32 + from sets import Set as set
2.33 +
2.34 +class TranslateError(Exception):
2.35 +
2.36 + "A translation error."
2.37 +
2.38 + pass
2.39 +
2.40 +# Program visitors.
2.41 +
2.42 +class Translation(ASTVisitor):
2.43 +
2.44 + "A translated module."
2.45 +
2.46 + def __init__(self, module):
2.47 + ASTVisitor.__init__(self)
2.48 + self.visitor = self
2.49 + self.module = module
2.50 + self.unit = None
2.51 +
2.52 + def get_module_code(self):
2.53 +
2.54 + "Return the top-level module code."
2.55 +
2.56 + self.unit = self.module
2.57 + return self.dispatch(self.module.module)
2.58 +
2.59 + def get_code(self, unit):
2.60 +
2.61 + "Return the code for the given 'unit'."
2.62 +
2.63 + self.unit = unit
2.64 + return self.dispatch(unit.node)
2.65 +
2.66 + def __repr__(self):
2.67 + return "Translation(%r)" % self.module
2.68 +
2.69 + def get_scope(self, name):
2.70 + if self.unit.has_key(name):
2.71 + return "local"
2.72 + elif self.module.has_key(name):
2.73 + return "global"
2.74 + else:
2.75 + return "builtins"
2.76 +
2.77 + # Visitor methods.
2.78 +
2.79 + def default(self, node, *args):
2.80 + raise TranslateError, node.__class__
2.81 +
2.82 + def dispatch(self, node, *args):
2.83 + return ASTVisitor.dispatch(self, node, *args)
2.84 +
2.85 + def _visitName(self, node, classes):
2.86 + name = node.name
2.87 + scope = self.get_scope(name)
2.88 + NameInstruction, AttrInstruction = classes
2.89 +
2.90 + if scope == "local":
2.91 + unit = self.unit
2.92 + if isinstance(unit, micropython.inspect.Function):
2.93 + return [NameInstruction(unit.locals()[name])]
2.94 + elif isinstance(unit, micropython.inspect.Class):
2.95 + return [AttrInstruction(unit.all_class_attributes()[name])]
2.96 + elif isinstance(unit, micropython.inspect.Module):
2.97 + return [AttrInstruction(unit.module_attributes()[name])]
2.98 + else:
2.99 + raise TranslateError, "Program unit %r has no local %r" % (unit, name)
2.100 +
2.101 + elif scope == "global":
2.102 + globals = self.module.module_attributes()
2.103 + if globals.has_key(name):
2.104 + return [AttrInstruction(globals[name])]
2.105 + else:
2.106 + raise TranslateError, "Module %r has no attribute %r" % (self.module, name)
2.107 +
2.108 + else:
2.109 + builtins = micropython.inspect.builtins.module_attributes()
2.110 + return [AttrInstruction(builtins[name])]
2.111 +
2.112 + def visitAdd(self, node): return []
2.113 +
2.114 + """
2.115 + _t1 = node.left
2.116 + _t2 = node.right
2.117 + try:
2.118 + _t1.__add__(_t2)
2.119 + except AttributeError:
2.120 + _t2.__radd__(_t1)
2.121 + """
2.122 +
2.123 + def visitAnd(self, node): return []
2.124 +
2.125 + def visitAssert(self, node): return []
2.126 +
2.127 + def visitAssign(self, node):
2.128 + results = []
2.129 + results += self.dispatch(node.expr)
2.130 + for n in node.nodes:
2.131 + results += self.dispatch(n)
2.132 + return results
2.133 +
2.134 + def visitAssAttr(self, node): return []
2.135 +
2.136 + def visitAssList(self, node): return []
2.137 +
2.138 + def visitAssName(self, node):
2.139 + return self._visitName(node, (StoreName, StoreAttr))
2.140 +
2.141 + visitAssTuple = visitAssList
2.142 +
2.143 + def visitAugAssign(self, node): return []
2.144 +
2.145 + def visitBackquote(self, node): return []
2.146 +
2.147 + def visitBitand(self, node): return []
2.148 +
2.149 + def visitBitor(self, node): return []
2.150 +
2.151 + def visitBitxor(self, node): return []
2.152 +
2.153 + def visitBreak(self, node): return []
2.154 +
2.155 + def visitCallFunc(self, node): return []
2.156 +
2.157 + def visitClass(self, node): return []
2.158 +
2.159 + def visitCompare(self, node): return []
2.160 +
2.161 + def visitConst(self, node): return []
2.162 +
2.163 + def visitContinue(self, node): return []
2.164 +
2.165 + def visitDecorators(self, node): return []
2.166 +
2.167 + def visitDict(self, node): return []
2.168 +
2.169 + def visitDiscard(self, node): return []
2.170 +
2.171 + def visitDiv(self, node): return []
2.172 +
2.173 + def visitEllipsis(self, node): return []
2.174 +
2.175 + def visitExec(self, node): return []
2.176 +
2.177 + def visitExpression(self, node): return []
2.178 +
2.179 + def visitFloorDiv(self, node): return []
2.180 +
2.181 + def visitFor(self, node): return []
2.182 +
2.183 + def visitFrom(self, node): return []
2.184 +
2.185 + def visitFunction(self, node):
2.186 +
2.187 + # Only store the name when visiting this node from outside.
2.188 +
2.189 + if self.unit is self.module:
2.190 + return self._visitName(node, (StoreName, StoreAttr))
2.191 + else:
2.192 + return self.dispatch(node.code)
2.193 +
2.194 + def visitGenExpr(self, node): return []
2.195 +
2.196 + def visitGenExprFor(self, node): return []
2.197 +
2.198 + def visitGenExprIf(self, node): return []
2.199 +
2.200 + def visitGenExprInner(self, node): return []
2.201 +
2.202 + def visitGetattr(self, node): return []
2.203 +
2.204 + def visitGlobal(self, node): return []
2.205 +
2.206 + def visitIf(self, node):
2.207 + for test, body in node.tests:
2.208 + self.dispatch(body)
2.209 + if node.else_ is not None:
2.210 + self.dispatch(node.else_)
2.211 + return None
2.212 +
2.213 + def visitImport(self, node): return []
2.214 +
2.215 + def visitInvert(self, node): return []
2.216 +
2.217 + def visitKeyword(self, node): return []
2.218 +
2.219 + def visitLambda(self, node): return []
2.220 +
2.221 + def visitLeftShift(self, node): return []
2.222 +
2.223 + def visitList(self, node): return []
2.224 +
2.225 + def visitListComp(self, node): return []
2.226 +
2.227 + def visitListCompFor(self, node): return []
2.228 +
2.229 + def visitListCompIf(self, node): return []
2.230 +
2.231 + def visitMod(self, node): return []
2.232 +
2.233 + def visitModule(self, node):
2.234 + return self.dispatch(node.node)
2.235 +
2.236 + def visitMul(self, node): return []
2.237 +
2.238 + def visitName(self, node):
2.239 + return self._visitName(node, (LoadName, LoadAttr))
2.240 +
2.241 + def visitNot(self, node): return []
2.242 +
2.243 + def visitOr(self, node): return []
2.244 +
2.245 + def visitPass(self, node): return []
2.246 +
2.247 + def visitPower(self, node): return []
2.248 +
2.249 + def visitPrint(self, node): return []
2.250 +
2.251 + def visitPrintnl(self, node): return []
2.252 +
2.253 + def visitRaise(self, node): return []
2.254 +
2.255 + def visitReturn(self, node): return []
2.256 +
2.257 + def visitRightShift(self, node): return []
2.258 +
2.259 + def visitSlice(self, node): return []
2.260 +
2.261 + def visitStmt(self, node):
2.262 + result = []
2.263 + for n in node.nodes:
2.264 + result += self.dispatch(n)
2.265 + return result
2.266 +
2.267 + def visitSub(self, node): return []
2.268 +
2.269 + def visitSubscript(self, node): return []
2.270 +
2.271 + def visitTryExcept(self, node): return []
2.272 +
2.273 + def visitTryFinally(self, node): return []
2.274 +
2.275 + def visitTuple(self, node): return []
2.276 +
2.277 + def visitUnaryAdd(self, node): return []
2.278 +
2.279 + def visitUnarySub(self, node): return []
2.280 +
2.281 + def visitWhile(self, node): return []
2.282 +
2.283 + def visitWith(self, node): return []
2.284 +
2.285 + def visitYield(self, node): return []
2.286 +
2.287 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/micropython/inspect.py Sun Nov 04 18:27:20 2007 +0100
3.2 +++ b/micropython/inspect.py Fri Nov 09 00:19:03 2007 +0100
3.3 @@ -101,10 +101,11 @@
3.4
3.5 "An inspected class."
3.6
3.7 - def __init__(self, name, parent_name):
3.8 + def __init__(self, name, parent_name, node=None):
3.9 NamespaceDict.__init__(self)
3.10 self.name = name
3.11 self.parent_name = parent_name
3.12 + self.node = node
3.13
3.14 self.bases = []
3.15 self.instattr = set() # instance attributes
3.16 @@ -241,17 +242,23 @@
3.17
3.18 "An inspected function."
3.19
3.20 - def __init__(self, name, parent_name, argnames, has_star, has_dstar):
3.21 + def __init__(self, name, parent_name, argnames, has_star, has_dstar, node=None):
3.22 NamespaceDict.__init__(self)
3.23 self.name = name
3.24 self.parent_name = parent_name
3.25 self.argnames = argnames
3.26 self.has_star = has_star
3.27 self.has_dstar = has_dstar
3.28 + self.node = node
3.29
3.30 self.localnames = None # cache for locals
3.31 self.alllocalnames = None # cache for all_locals
3.32
3.33 + # Add parameters to the namespace.
3.34 +
3.35 + for name in argnames:
3.36 + self[name] = None
3.37 +
3.38 # Image generation details.
3.39
3.40 self.location = None
3.41 @@ -511,7 +518,7 @@
3.42 if self.namespaces:
3.43 print "Class %r in %r is not global: ignored." % (node.name, self)
3.44 else:
3.45 - cls = Class(node.name, self.get_parent().full_name())
3.46 + cls = Class(node.name, self.get_parent().full_name(), node)
3.47 for base in node.bases:
3.48 base_ref = self.dispatch(base)
3.49 if base_ref is None:
3.50 @@ -583,8 +590,9 @@
3.51 node.name,
3.52 self.get_parent().full_name(),
3.53 node.argnames,
3.54 - has_star=(node.flags & 4 != 0),
3.55 - has_dstar=(node.flags & 8 != 0)
3.56 + (node.flags & 4 != 0),
3.57 + (node.flags & 8 != 0),
3.58 + node
3.59 )
3.60
3.61 self.namespaces.append(function)