[pypy-svn] r66267 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools
benjamin at codespeak.net
benjamin at codespeak.net
Thu Jul 16 02:00:26 CEST 2009
Author: benjamin
Date: Thu Jul 16 02:00:23 2009
New Revision: 66267
Modified:
pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py
Log:
add mutation support to AST visitors
Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py (original)
+++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/tools/asdl_py.py Thu Jul 16 02:00:23 2009
@@ -49,10 +49,18 @@
class ASTNodeVisitor(ASDLVisitor):
- def visitType(self, tp):
- self.visit(tp.value, tp.name)
+ def visitModule(self, mod):
+ dont_touch = set()
+ for type in mod.dfns:
+ if isinstance(type.value, asdl.Product) or \
+ self.is_simple_sum(type.value):
+ dont_touch.add(type.name.value)
+ super(ASTNodeVisitor, self).visitModule(mod, dont_touch)
+
+ def visitType(self, tp, simple):
+ self.visit(tp.value, tp.name, simple)
- def visitSum(self, sum, base):
+ def visitSum(self, sum, base, simple):
if self.is_simple_sum(sum):
for i, cons in enumerate(sum.types):
self.emit("%s = %i" % (cons.name, i + 1))
@@ -62,10 +70,10 @@
self.emit("pass", 1)
self.emit("")
for cons in sum.types:
- self.visit(cons, base, sum.attributes)
+ self.visit(cons, base, sum.attributes, simple)
self.emit("")
- def visitProduct(self, product, name):
+ def visitProduct(self, product, name, simple):
self.emit("class %s(AST):" % (name,))
self.emit("")
self.make_constructor(product.fields)
@@ -84,13 +92,31 @@
self.emit("def __init__(self):", 1)
self.emit("pass", 2)
- def visitConstructor(self, cons, base, extra_attributes):
+ def visitConstructor(self, cons, base, extra_attributes, simple):
self.emit("class %s(%s):" % (cons.name, base))
self.emit("")
self.make_constructor(cons.fields + extra_attributes)
self.emit("")
self.emit("def walkabout(self, visitor):", 1)
self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
+ self.emit("")
+ self.emit("def mutate_over(self, visitor):", 1)
+ for field in cons.fields:
+ if field.type.value not in asdl.builtin_types and \
+ field.type.value not in simple:
+ if field.opt or field.seq:
+ level = 3
+ self.emit("if self.%s:" % (field.name,), 2)
+ else:
+ level = 2
+ if field.seq:
+ sub = (field.name,)
+ self.emit("visitor._mutate_sequence(self.%s)" % sub, level)
+ else:
+ sub = (field.name, field.name)
+ self.emit("self.%s = self.%s.mutate_over(visitor)" % sub,
+ level)
+ self.emit("return visitor.visit_%s(self)" % (cons.name,), 2)
def visitField(self, field):
self.emit("self.%s = %s" % (field.name, field.name), 2)
@@ -109,6 +135,10 @@
self.emit("def default_visitor(self, node):", 1)
self.emit("raise NodeVisitorNotImplemented", 2)
self.emit("")
+ self.emit("def _mutate_sequence(self, seq):", 1)
+ self.emit("for i in range(len(seq)):", 2)
+ self.emit("seq[i] = seq[i].mutate_over(self)", 3)
+ self.emit("")
super(ASTVisitorVisitor, self).visitModule(mod)
self.emit("")
@@ -185,6 +215,9 @@
def walkabout(self, visitor):
raise AssertionError("walkabout() implementation not provided")
+ def mutate_over(self, visitor):
+ raise AssertionError("mutate_over() implementation not provided")
+
class NodeVisitorNotImplemented(Exception):
pass
More information about the Pypy-commit
mailing list