1.1 --- a/micropython/inspect.py Mon Jul 04 23:50:02 2011 +0200
1.2 +++ b/micropython/inspect.py Tue Jul 05 00:36:54 2011 +0200
1.3 @@ -171,7 +171,7 @@
1.4 if isinstance(n, compiler.ast.Global):
1.5 for name in n.names:
1.6 if not self.has_key(name):
1.7 - self[name] = None
1.8 + self[name] = Instance()
1.9 else:
1.10 self.process_globals(n)
1.11
1.12 @@ -419,7 +419,6 @@
1.13 def NOP(self, node):
1.14 for n in node.getChildNodes():
1.15 self.dispatch(n)
1.16 - return None
1.17
1.18 def NOP_ABANDON(self, node):
1.19 self.NOP(node)
1.20 @@ -469,21 +468,21 @@
1.21 if attrname == "__class__" and isinstance(value, Class):
1.22 attr = type_class
1.23 else:
1.24 - attr = value.get(attrname)
1.25 + attr = value.get(attrname) or Instance()
1.26 self.use_specific_attribute(value.full_name(), attrname)
1.27
1.28 elif isinstance(value, UnresolvedName):
1.29 attr = UnresolvedName(attrname, value.full_name(), self)
1.30
1.31 else:
1.32 - attr = None
1.33 + attr = Instance()
1.34
1.35 # Note usage of the attribute where a local is involved.
1.36
1.37 self._visitAttrUser(expr, attrname, node)
1.38
1.39 else:
1.40 - attr = None
1.41 + attr = Instance()
1.42 self.use_name(attrname, node)
1.43
1.44 return attr
1.45 @@ -613,7 +612,6 @@
1.46 for n in node.nodes:
1.47 self.dispatch(n)
1.48 self.in_assignment = 0
1.49 - return None
1.50
1.51 def visitAssAttr(self, node):
1.52 expr = self.dispatch(node.expr)
1.53 @@ -642,8 +640,6 @@
1.54 else:
1.55 self.use_name(attrname, node)
1.56
1.57 - return None
1.58 -
1.59 def visitAssList(self, node):
1.60
1.61 # Declare names which will be used by generated code.
1.62 @@ -655,7 +651,6 @@
1.63 for i, n in enumerate(node.nodes):
1.64 self.dispatch(n)
1.65 self._visitConst(i) # for __getitem__(i) at run-time
1.66 - return None
1.67
1.68 def visitAssName(self, node):
1.69 if hasattr(node, "flags") and node.flags == "OP_DELETE":
1.70 @@ -677,8 +672,6 @@
1.71 ns = self.get_namespace().full_name()
1.72 self.use_specific_attribute(fn.parent.full_name(), fn.name, "%s.%s" % (ns, node.name))
1.73
1.74 - return None
1.75 -
1.76 visitAssTuple = visitAssList
1.77
1.78 def visitAugAssign(self, node):
1.79 @@ -705,8 +698,6 @@
1.80 self.use_specific_attribute("__builtins__", "slice")
1.81 self.use_name("__setitem__", node)
1.82
1.83 - return None
1.84 -
1.85 visitBackquote = OP
1.86
1.87 visitBitand = _visitBinary
1.88 @@ -730,7 +721,7 @@
1.89
1.90 if self.namespaces:
1.91 print "Warning: class %r in %r is not global: ignored." % (node.name, self.namespaces[-1].full_name())
1.92 - return None
1.93 + return
1.94 else:
1.95 if self.in_loop:
1.96 print "Warning: class %r in %r defined in a loop." % (node.name, self.full_name())
1.97 @@ -757,7 +748,7 @@
1.98
1.99 if isinstance(expr, Attr):
1.100 if expr.assignments != 1:
1.101 - raise InspectError("Base class %r for %r is not constant." % (base, cls.full_name()))
1.102 + raise InspectError("Base class %r for %r is not constant: %r" % (base, cls.full_name(), expr))
1.103 else:
1.104 cls.add_base(expr.get_value())
1.105
1.106 @@ -856,6 +847,11 @@
1.107 in_loop = self.in_loop
1.108 self.in_loop = 1
1.109 self.dispatch(node.list)
1.110 +
1.111 + # NOTE: Could generate AST nodes for the actual operations instead of
1.112 + # NOTE: manually generating code in micropython.ast.
1.113 +
1.114 + self.expr = Instance() # each element is a result of a function call
1.115 self.dispatch(node.assign)
1.116
1.117 # Enter the loop.
1.118 @@ -886,8 +882,6 @@
1.119
1.120 self.resume_broken_branches()
1.121
1.122 - return None
1.123 -
1.124 def visitFrom(self, node):
1.125 module = self.importer.load(node.modname, 1)
1.126
1.127 @@ -916,8 +910,6 @@
1.128 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
1.129 self.importer.load(attr.get_value().name)
1.130
1.131 - return None
1.132 -
1.133 def visitFunction(self, node):
1.134 return self._visitFunction(node, node.name)
1.135
1.136 @@ -963,9 +955,24 @@
1.137 self.shelve_branch()
1.138
1.139 self.merge_branches()
1.140 - return None
1.141 +
1.142 + def visitIfExp(self, node):
1.143 + self.new_branchpoint()
1.144 +
1.145 + # Propagate attribute usage to branches.
1.146 +
1.147 + self.dispatch(node.test)
1.148
1.149 - visitIfExp = NOP
1.150 + self.new_branch(node.then)
1.151 + self.dispatch(node.then)
1.152 + self.shelve_branch()
1.153 +
1.154 + self.new_branch(node.else_)
1.155 + self.dispatch(node.else_)
1.156 + self.shelve_branch()
1.157 +
1.158 + self.merge_branches()
1.159 + return Instance() # either outcome is possible
1.160
1.161 def visitImport(self, node):
1.162 for name, alias in node.names:
1.163 @@ -976,15 +983,12 @@
1.164 module = self.importer.load(name) or UnresolvedName(None, name.split(".")[0], self)
1.165 self.store(name.split(".")[0], module)
1.166
1.167 - return None
1.168 -
1.169 visitInvert = _visitUnary
1.170
1.171 def visitKeyword(self, node):
1.172 self.dispatch(node.expr)
1.173 self._visitConst(node.name)
1.174 self.keyword_names.add(node.name)
1.175 - return None
1.176
1.177 def visitLambda(self, node):
1.178 fn = self._visitFunction(node, None)
1.179 @@ -995,12 +999,13 @@
1.180
1.181 def visitList(self, node):
1.182 self.use_specific_attribute("__builtins__", "list")
1.183 - self.OP(node)
1.184 + return self.OP(node)
1.185
1.186 def visitListComp(self, node):
1.187 for qual in node.quals:
1.188 self.dispatch(qual)
1.189 self.dispatch(node.expr)
1.190 + return Instance()
1.191
1.192 def visitListCompFor(self, node):
1.193 self.new_branchpoint()
1.194 @@ -1013,6 +1018,11 @@
1.195 in_loop = self.in_loop
1.196 self.in_loop = 1
1.197 self.dispatch(node.list)
1.198 +
1.199 + # NOTE: Could generate AST nodes for the actual operations instead of
1.200 + # NOTE: manually generating code in micropython.ast.
1.201 +
1.202 + self.expr = Instance() # each element is a result of a function call
1.203 self.dispatch(node.assign)
1.204
1.205 # Enter the loop.
1.206 @@ -1027,7 +1037,6 @@
1.207 self.in_loop = in_loop
1.208
1.209 self.merge_branches()
1.210 - return None
1.211
1.212 visitListCompIf = NOP
1.213
1.214 @@ -1043,7 +1052,7 @@
1.215 visitMul = _visitBinary
1.216
1.217 def visitName(self, node):
1.218 - return self.get_namespace().get_using_node(node.name, node)
1.219 + return self.get_namespace().get_using_node(node.name, node) or Instance()
1.220
1.221 visitNot = OP
1.222
1.223 @@ -1070,19 +1079,18 @@
1.224 visitRightShift = _visitBinary
1.225
1.226 def visitSlice(self, node):
1.227 - self._visitOperator(node, self.in_assignment and "AssSlice" or "Slice")
1.228 + return self._visitOperator(node, self.in_assignment and "AssSlice" or "Slice")
1.229
1.230 visitSliceobj = OP
1.231
1.232 def visitStmt(self, node):
1.233 for n in node.nodes:
1.234 self.dispatch(n)
1.235 - return None
1.236
1.237 visitSub = _visitBinary
1.238
1.239 def visitSubscript(self, node):
1.240 - self._visitOperator(node, self.in_assignment and "AssSubscript" or "Subscript")
1.241 + return self._visitOperator(node, self.in_assignment and "AssSubscript" or "Subscript")
1.242
1.243 def visitTryExcept(self, node):
1.244 self.dispatch(node.body)
1.245 @@ -1107,7 +1115,6 @@
1.246 self.shelve_branch()
1.247
1.248 self.merge_branches()
1.249 - return None
1.250
1.251 visitTryFinally = NOP
1.252
1.253 @@ -1155,8 +1162,6 @@
1.254
1.255 self.resume_broken_branches()
1.256
1.257 - return None
1.258 -
1.259 visitWith = NOP
1.260
1.261 visitYield = NOP