# HG changeset patch # User paulb@localhost.localdomain # Date 1164585998 -3600 # Node ID 6f50625c615f88df3ebbcaa7f1c911fc8b18fa8b # Parent 5b213d091b9f05370ff4f9cc8bca40388c0d87ce Fixed namespace merging for return values (upon finishing a shared locals block invocation) and temporary variables. Improved Add node support. diff -r 5b213d091b9f -r 6f50625c615f annotate.py --- a/annotate.py Sun Nov 26 21:28:11 2006 +0100 +++ b/annotate.py Mon Nov 27 01:06:38 2006 +0100 @@ -361,7 +361,6 @@ choice_types += self.namespace.types for expr_type in expr_types: if expr_type.type.get_class() not in choice_types: - print "CheckExc", expr_type, "should be revoked!" self._prune_non_accesses(checkexc.expr, expr_type) return checkexc @@ -686,7 +685,7 @@ if getattr(invoke, "share_locals", 0): namespace = Namespace() - namespace.merge_namespace(self.namespace, no_return_locals=1) + namespace.merge_namespace(self.namespace, everything=0) using_module_namespace = self.namespace is self.module.namespace elif getattr(target, "structure", None): namespace = Namespace() @@ -720,7 +719,7 @@ if getattr(invoke, "share_locals", 0): self.namespace.reset() for locals in self.returned_locals: - self.namespace.merge_namespace(locals, no_return_locals=1) + self.namespace.merge_namespace(locals, everything=0) # Incorporate any raised exceptions. @@ -970,14 +969,17 @@ def revoke_exception_type(self, type): self.raises.remove(type) - def merge_namespace(self, namespace, no_return_locals=0): + def merge_namespace(self, namespace, everything=1): self.merge_items(namespace.names.items()) - combine(self.returns, namespace.returns) - if not no_return_locals: + if everything: + combine(self.returns, namespace.returns) combine(self.return_locals, namespace.return_locals) combine(self.raises, namespace.raises) - self.temp = {} - self.temp.update(namespace.temp) + for name, values in namespace.temp.items(): + if values: + if not self.temp.has_key(name) or not self.temp[name]: + self.temp[name] = [[]] + combine(self.temp[name][-1], values[-1]) def merge_items(self, items): for name, types in items: diff -r 5b213d091b9f -r 6f50625c615f simplify.py --- a/simplify.py Sun Nov 26 21:28:11 2006 +0100 +++ b/simplify.py Mon Nov 27 01:06:38 2006 +0100 @@ -47,14 +47,14 @@ """ A simplifying visitor for AST nodes. - Covered: And, AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break, - CallFunc, Class, Compare, Const, Continue, Dict, Discard, For, - From, Function, Getattr, Global, If, Import, Invert, Keyword, + Covered: Add, And, AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, + Break, CallFunc, Class, Compare, Const, Continue, Dict, Discard, + For, From, Function, Getattr, Global, If, Import, Invert, Keyword, Lambda, List, Module, Name, Not, Or, Pass, Raise, Return, Slice, Stmt, Subscript, TryExcept, TryFinally, Tuple, While, UnaryAdd, UnarySub. - Missing: Add, Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div, + Missing: Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div, Ellipsis, Exec, FloorDiv, LeftShift, ListComp, ListCompFor, ListCompIf, Mod, Mul, Power, Print, Printnl, RightShift, Sliceobj, Sub, Yield. @@ -348,8 +348,7 @@ nodes += self.dispatch(stmt) catch_all = 1 - # Produce something like... - # isinstance(, ) + # Produce an exception value check. else: test = Conditional( @@ -689,42 +688,50 @@ """ Emulate the current mechanisms by producing nodes as follows: - Try (body) -> x.__add__(y) - (else) - (handler) -> Conditional (test) -> isinstance(exc, TypeError) - (body) -> y.__radd__(x) - (else) + InvokeBlock -> Subprogram -> Try (body) -> Return (expr) -> x.__add__(y) + (else) + (handler) -> Conditional (test) -> CheckExc (expr) -> LoadExc + (choices) -> LoadName TypeError + (body) -> Return (expr) -> y.__radd__(x) + (else) """ - result = Try(add, 1, - body=[ - InvokeFunction( - expr=LoadAttr(expr=self.dispatch(add.left), name="__add__"), - args=[self.dispatch(add.right)], - star=None, - dstar=None) - ], - else_=[], - finally_=[], - handler=[ - Conditional( - test=InvokeFunction( - expr=LoadName(name="isinstance"), - args=[LoadExc(), LoadName(name="TypeError")], - star=None, - dstar=None), - body=[ - InvokeFunction( - expr=LoadAttr(expr=self.dispatch(add.right), name="__radd__"), - args=[self.dispatch(add.left)], + subprogram = Subprogram(name=None, module=self.module, internal=1, returns_value=1, params=[], star=None, dstar=None) + self.current_subprograms.append(subprogram) + + subprogram.code = [ + Try(add, 1, + body=[ + Return( + expr=InvokeFunction( + expr=LoadAttr(expr=self.dispatch(add.left), name="__add__"), + args=[self.dispatch(add.right)], star=None, dstar=None) - ], - else_=[] - ) - ] - ) + ) + ], + else_=[], + finally_=[], + handler=[ + Conditional( + test=CheckExc(expr=LoadExc(), choices=[LoadName(name="TypeError")]), + body=[ + Return( + expr=InvokeFunction( + expr=LoadAttr(expr=self.dispatch(add.right), name="__radd__"), + args=[self.dispatch(add.left)], + star=None, + dstar=None) + ) + ], + else_=[] + ) + ] + ) + ] + result = InvokeBlock(produces_result=1) + result.expr = LoadRef(ref=subprogram) return result # Assignments. diff -r 5b213d091b9f -r 6f50625c615f viewer.py --- a/viewer.py Sun Nov 26 21:28:11 2006 +0100 +++ b/viewer.py Mon Nov 27 01:06:38 2006 +0100 @@ -151,7 +151,8 @@ .op, .name, .attr, - .conditional + .conditional, + .operator { position: relative; } @@ -159,7 +160,8 @@ .op:hover > .popup, .name:hover > .popup, .attr:hover > .popup, - .conditional:hover > .popup + .conditional:hover > .popup, + .operator:hover > .popup { display: block; } @@ -180,16 +182,16 @@ """ A browsing visitor for AST nodes. - Covered: And, AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break, - CallFunc, Class, Compare, Const, Continue, Dict, Discard, For, - Function, Getattr, If, Keyword, Lambda, List, Module, Name, Not, - Or, Pass, Raise, Return, Slice, Stmt, Subscript, Tuple, While. + Covered: Add, And, AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, + Break, CallFunc, Class, Compare, Const, Continue, Dict, Discard, + For, Function, Getattr, If, Keyword, Lambda, List, Module, Name, + Not, Or, Pass, Raise, Return, Slice, Stmt, Subscript, TryExcept, + TryFinally, Tuple, While. - Missing: Add, Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div, + Missing: Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div, Ellipsis, Exec, FloorDiv, From, Global, Import, Invert, LeftShift, ListComp, ListCompFor, ListCompIf, Mod, Mul, Not, Or, Power, Print, - Printnl, RightShift, Sliceobj, Sub, TryExcept, TryFinally, - UnaryAdd, UnarySub, Yield. + Printnl, RightShift, Sliceobj, Sub, UnaryAdd, UnarySub, Yield. """ def __init__(self, stream): @@ -474,6 +476,21 @@ # Expressions. + def visitAdd(self, node): + self.stream.write("\n") + self.dispatch(node.left) + self.stream.write("\n") + self.stream.write("+") + self._popup_start() + self.stream.write("
\n") + self._invocations_list(node._node.body[0].expr) # NOTE: See visitAdd in simplify. + self._invocations_list(node._node.handler[0].body[0].expr) # NOTE: See visitAdd in simplify. + self.stream.write("
\n") + self._popup_end() + self.stream.write("
\n") + self.dispatch(node.right) + self.stream.write("
") + def visitAnd(self, node): self.stream.write("\n") first = 1 @@ -738,22 +755,22 @@ self._invocations(op) def _invocations(self, node): - if hasattr(node, "invocations"): - self._invocations_list(node.invocations) + self.stream.write("
\n") + self._invocations_list(node) + self.stream.write("
\n") - def _invocations_list(self, invocations): - self.stream.write("
\n") - for invocation in invocations: - fn = invocation.full_name() - module = invocation.module.name - name = invocation.name - structures = [x.name for x in invocation.structures] - self.stream.write("\n") - self.stream.write("
\n") + def _invocations_list(self, node): + if hasattr(node, "invocations"): + for invocation in node.invocations: + fn = invocation.full_name() + module = invocation.module.name + name = invocation.name + structures = [x.name for x in invocation.structures] + self.stream.write("\n") def _types(self, node): if hasattr(node, "types"):