# HG changeset patch # User paulb@jeremy # Date 1161478642 -7200 # Node ID 896b313225a44f9b71ba728259170323173e2d43 # Parent 747eeb273b45114abe0f61e0b1238744fa3f34e5 Added a special AST node annotation for convenient comparison operator access. Expanded node coverage in the viewer, adding operator target display. diff -r 747eeb273b45 -r 896b313225a4 simplify.py --- a/simplify.py Sun Oct 22 01:43:53 2006 +0200 +++ b/simplify.py Sun Oct 22 02:57:22 2006 +0200 @@ -393,9 +393,9 @@ ...to: - Subprogram -> Conditional (test) -> (body) - (else) -> Conditional (test) -> (body) - (else) -> ... + InvokeBlock -> Subprogram -> Conditional (test) -> (body) + (else) -> Conditional (test) -> (body) + (else) -> ... """ subprogram = Subprogram(name=None, acquire_locals=1, returns_value=1, params=[], star=None, dstar=None) @@ -409,6 +409,10 @@ previous = self.dispatch(compare.expr) results = nodes = [] + # For viewing purposes, record invocations on the AST node. + + compare._ops = [] + for op in compare.ops: op_name, node = op expr = self.dispatch(node) @@ -444,6 +448,7 @@ raise NotImplementedError, op_name nodes.append(StoreTemp(expr=invocation)) + compare._ops.append(invocation) # Return from the subprogram where the test is not satisfied. @@ -456,7 +461,8 @@ # Put subsequent operations in the else section of this conditional. - nodes = test.else_ = [ReleaseTemp()] + nodes[-1].else_ = [ReleaseTemp()] + nodes = nodes[-1].else_ # For the last operation, return the result. diff -r 747eeb273b45 -r 896b313225a4 viewer.py --- a/viewer.py Sun Oct 22 01:43:53 2006 +0200 +++ b/viewer.py Sun Oct 22 02:57:22 2006 +0200 @@ -123,6 +123,11 @@ padding: 0.2em; background-color: #000000; } + .invocations { + padding: 0.5em; background-color: #770000; + clear: all; + } + .types { padding: 0.5em; background-color: #0000FF; float: right; @@ -133,12 +138,14 @@ float: left; } + .op, .name, .attr { position: relative; } + .op:hover > .popup, .name:hover > .popup, .attr:hover > .popup { @@ -160,6 +167,16 @@ """ A browsing visitor for AST nodes. + + Covered: AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break, + CallFunc, Class, Compare, Const, Continue, Dict, Discard, For, + Function, Getattr, If, Keyword, Lambda, List, Module, Name, Pass, Raise, Return, Slice, + Stmt, Subscript, Tuple, While. + + Missing: And, Add, 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. """ def __init__(self, stream): @@ -201,6 +218,11 @@ self.dispatch(node.expr) self.stream.write("\n") + def visitBreak(self, node): + self.stream.write("
\n") + self._keyword("break") + self.stream.write("
\n") + def visitClass(self, node): definition = node._node structure = definition.expr.ref @@ -237,6 +259,11 @@ self.stream.write("\n") self.stream.write("\n") + def visitContinue(self, node): + self.stream.write("
\n") + self._keyword("continue") + self.stream.write("
\n") + def visitFor(self, node): self.stream.write("
\n") self.stream.write("
\n") @@ -271,24 +298,7 @@ self._popup_end() self._name_end() self.stream.write("(") - first = 1 - for param, default in subprogram.params: - if not first: - self.stream.write(",\n") - self._parameter(subprogram, param, default) - first = 0 - if subprogram.star is not None: - if not first: - self.stream.write(", *\n") - param, default = subprogram.star - self._parameter(subprogram, param, default) - first = 0 - if subprogram.dstar is not None: - if not first: - self.stream.write(", **\n") - param, default = subprogram.dstar - self._parameter(subprogram, param, default) - first = 0 + self._parameters(subprogram) self.stream.write(")") self.stream.write(":\n") self._comment(self._text(subprogram.full_name())) @@ -354,6 +364,26 @@ self.default(node) self.stream.write("
\n") + def visitWhile(self, node): + self.stream.write("
\n") + self.stream.write("
\n") + self._keyword("while") + self.dispatch(node.test) + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(node.body) + self.stream.write("
\n") + if node.else_ is not None: + self.stream.write("
\n") + self._keyword("else") + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(node.else_) + self.stream.write("
\n") + self.stream.write("
\n") + # Expressions. def visitAssAttr(self, node): @@ -423,9 +453,14 @@ def visitCompare(self, node): self.stream.write("\n") self.dispatch(node.expr) - for name, op in node.ops: - self.stream.write("%s\n" % name) - self.dispatch(op) + for (op_name, expr), _op in map(None, node.ops, node._ops): + self.stream.write("\n") + self.stream.write(op_name) + self._popup_start() + self._op(op_name, _op) + self._popup_end() + self.stream.write("\n") + self.dispatch(expr) self.stream.write("\n") def visitConst(self, node): @@ -453,6 +488,15 @@ self.dispatch(node.expr) self.stream.write("\n") + def visitLambda(self, node): + definition = node._node + subprogram = definition.expr.ref + self.stream.write("\n") + self._keyword("lambda") + self._parameters(subprogram) + self.dispatch(node.code) + self.stream.write("\n") + visitList = visitAssList def visitName(self, node): @@ -529,6 +573,26 @@ self.dispatch(n) first = 0 + def _parameters(self, subprogram): + first = 1 + for param, default in subprogram.params: + if not first: + self.stream.write(",\n") + self._parameter(subprogram, param, default) + first = 0 + if subprogram.star is not None: + if not first: + self.stream.write(", *\n") + param, default = subprogram.star + self._parameter(subprogram, param, default) + first = 0 + if subprogram.dstar is not None: + if not first: + self.stream.write(", **\n") + param, default = subprogram.dstar + self._parameter(subprogram, param, default) + first = 0 + def _parameter(self, subprogram, param, default): self._name_start(param) if hasattr(subprogram, "paramtypes"): @@ -555,6 +619,23 @@ def _popup_end(self): self.stream.write("\n") + def _op(self, op_name, op): + if op is not None: + self._invocations(op) + + def _invocations(self, node): + if hasattr(node, "invocations"): + self._invocations_list(node.invocations) + + def _invocations_list(self, invocations): + self.stream.write("
\n") + for invocation in invocations: + fn = invocation.full_name() + self.stream.write("
") + self.stream.write(self._text(fn)) + self.stream.write("
\n") + self.stream.write("
\n") + def _types(self, node): if hasattr(node, "types"): self._types_list(node.types)