Permalink
Browse files

pycodegen: Refactor to use Use module-level context for filenames.

The previous was a hack: adding an undeclared 'filename' attribute to
every AST node.

Also, update OPy golden checksums.  These were from prior changes.
  • Loading branch information...
Andy Chu
Andy Chu committed Mar 20, 2018
1 parent 4c9c89e commit 6a2864e8595aec455edaeee532994a234427b937
Showing with 35 additions and 40 deletions.
  1. +4 −4 opy/_regtest/dis-md5.golden.txt
  2. +31 −36 opy/compiler2/pycodegen.py
@@ -78,8 +78,8 @@
2640 31e838293b2caf82fdafabbd3c9c64f4 _tmp/regtest/core/libstr.pyc
2640 d98186573237c6762f571c45816a2459 _tmp/regtest/native/fastlex_test.pyc
2666 f743f2da8f9330956a0d0e4ece52a0f0 _tmp/regtest/native/libc_test.pyc
2733 a5abe69ff71d12e9375e6bfffd025f3b _tmp/regtest/atexit.pyc
2746 9942a106fc298536b214f611fc2f49d0 _tmp/regtest/opy/pgen2/token.pyc
2747 63323ced2f8efc7fd175c0d4e326a0eb _tmp/regtest/atexit.pyc
2769 e5153445e33077d2995ddceae21140ad _tmp/regtest/build/runpy_deps.pyc
2819 3913c2dac884ee9d0a7697b4cf8d844e _tmp/regtest/bin/opy_.pyc
2855 554887965c5d231df3d319796db90bcd _tmp/regtest/benchmarks/virtual_memory.pyc
@@ -100,7 +100,7 @@
4157 08e3878abd23a8093d252c7044df727b _tmp/regtest/core/braces_test.pyc
4194 f9d417154a0bf0da679fb957bc3eeadc _tmp/regtest/core/reader.pyc
4238 09a4df5015792a7770ee7eace0145892 _tmp/regtest/osh/arith_parse_test.pyc
4273 200f27a5d3bfb96400806da917025a37 _tmp/regtest/opy/compiler2/misc.pyc
4261 acbdc931c4df3ada5597720b5d5b8eed _tmp/regtest/opy/compiler2/misc.pyc
4276 75a15eecc1e82fb6ac0e52c14e62744d _tmp/regtest/osh/meta.pyc
4330 0b4f35f0d70efef473f2e0d80b1adf48 _tmp/regtest/build/app_deps.pyc
4371 9a488d36ee8a24b3bd483831ad8c2db0 _tmp/regtest/__future__.pyc
@@ -206,7 +206,7 @@
30811 02d4a38a06b87bc1875e62ffe18bb88a _tmp/regtest/core/builtin.pyc
32295 29b6c155971a78b46cae1c83500f7efb _tmp/regtest/osh/word_parse.pyc
32295 3f24a5980d6761b920977cfa7856a65d _tmp/regtest/opy/pytree.pyc
38761 2d30da7e24ca6a1d0f7ca547f308ce92 _tmp/regtest/core/cmd_exec.pyc
38756 66112f1a992091ab7e8a769803470e48 _tmp/regtest/core/cmd_exec.pyc
39060 b56c485f31eaedc39637a7e5dccc1a8d _tmp/regtest/opy/byterun/pyvm2.pyc
40804 4ed3a455de33717be93b724aced8c489 _tmp/regtest/platform.pyc
40808 32563c5dd8f47f81e23745fcd3e3d82a _tmp/regtest/codecs.pyc
@@ -218,5 +218,5 @@
57165 2c07e6823dbcee196553599c9d6ea8d4 _tmp/regtest/locale.pyc
59976 7ea8b29a98a017ee6aba911d78c3d599 _tmp/regtest/optparse.pyc
64817 1b56dfdd2dd91031be7e312bc8d3d7a7 _tmp/regtest/opy/compiler2/pycodegen.pyc
65309 f51234057020da7d30eafc509482a21a _tmp/regtest/logging/__init__.pyc
65169 17e417185a586f2c50aa8753b34f7e4d _tmp/regtest/logging/__init__.pyc
81561 fc68aabb67bc1ca842d3bd2fff1c746d _tmp/regtest/opy/compiler2/ast.pyc
View
@@ -27,22 +27,16 @@
gLambdaCounter = 0
def _SetFilenameOnAllNodes(filename, tree):
"""Set the filename attribute to filename on every node in tree.
class _ModuleContext(object):
"""Module-level data for the CodeGenerator tree."""
It's used a lot in the codegen below. There is probably a better way to do
this. Maybe self.ctx.{futures,filename,lambda_counter}.
"""
worklist = [tree]
while worklist:
node = worklist.pop(0)
node.filename = filename
worklist.extend(node.getChildNodes())
def __init__(self, filename, futures=()):
self.filename = filename
self.futures = futures
def compile(as_tree, filename, mode):
"""Replacement for builtin compile() function"""
_SetFilenameOnAllNodes(filename, as_tree)
# NOTE: This currently does nothing!
v = syntax.SyntaxErrorChecker()
@@ -51,7 +45,8 @@ def compile(as_tree, filename, mode):
# NOTE: the name of the flow graph is a comment, not exposed to users.
if mode == "single":
graph = pyassem.PyFlowGraph("<interactive>", filename)
gen = InteractiveCodeGenerator(graph, ())
ctx = _ModuleContext(filename)
gen = InteractiveCodeGenerator(graph, ctx)
gen.set_lineno(as_tree)
elif mode == "exec":
@@ -63,19 +58,19 @@ def compile(as_tree, filename, mode):
p1.Dispatch(as_tree)
p2.Dispatch(as_tree)
gen = TopLevelCodeGenerator(graph, p1.get_features())
ctx = _ModuleContext(filename, futures=p1.get_features())
gen = TopLevelCodeGenerator(graph, ctx)
elif mode == "eval":
graph = pyassem.PyFlowGraph("<expression>", filename)
gen = TopLevelCodeGenerator(graph, ())
ctx = _ModuleContext(filename)
gen = TopLevelCodeGenerator(graph, ctx)
else:
raise ValueError("compile() 3rd arg must be 'exec' or "
"'eval' or 'single'")
# This has a side effect of populating the gen.graph data structure?
# The multiple inheritance implements some weird double-Dispatch.
# NOTE: There is no Start() or FindLocals() at the top level.
gen.Dispatch(as_tree)
gen.Finish()
@@ -152,10 +147,10 @@ class CodeGenerator(ASTVisitor):
optimized = 0 # is namespace access optimized?
class_name = None # provide default for instance variable
def __init__(self, graph, futures):
def __init__(self, graph, ctx):
ASTVisitor.__init__(self)
self.graph = graph
self.futures = futures # passed down to child CodeGenerator instances
self.ctx = ctx # passed down to child CodeGenerator instances
self.locals = Stack()
self.setups = Stack()
@@ -170,7 +165,7 @@ def __init__(self, graph, futures):
self.setDocstring = self.graph.setDocstring
# Set flags based on future features
for feature in futures:
for feature in ctx.futures:
if feature == "division":
self.graph.setFlag(CO_FUTURE_DIVISION)
self._div_op = "BINARY_TRUE_DIVIDE"
@@ -312,10 +307,10 @@ def visitFunction(self, node):
ndecorators = 0
_CheckNoTupleArgs(node)
graph = pyassem.PyFlowGraph(node.name, node.filename, optimized=1)
graph = pyassem.PyFlowGraph(node.name, self.ctx.filename, optimized=1)
graph.setArgs(node.argnames)
gen = FunctionCodeGenerator(graph, self.futures, node, self.scopes,
gen = FunctionCodeGenerator(graph, self.ctx, node, self.scopes,
self.class_name)
self._funcOrLambda(node, gen, ndecorators)
@@ -334,10 +329,10 @@ def visitLambda(self, node):
gLambdaCounter += 1
_CheckNoTupleArgs(node)
graph = pyassem.PyFlowGraph(obj_name, node.filename, optimized=1)
graph = pyassem.PyFlowGraph(obj_name, self.ctx.filename, optimized=1)
graph.setArgs(node.argnames)
gen = LambdaCodeGenerator(graph, self.futures, node, self.scopes,
gen = LambdaCodeGenerator(graph, self.ctx, node, self.scopes,
self.class_name)
self._funcOrLambda(node, gen, 0)
@@ -356,9 +351,9 @@ def _funcOrLambda(self, node, gen, ndecorators):
self.emit('CALL_FUNCTION', 1)
def visitClass(self, node):
graph = pyassem.PyFlowGraph(node.name, node.filename,
graph = pyassem.PyFlowGraph(node.name, self.ctx.filename,
optimized=0, klass=1)
gen = ClassCodeGenerator(graph, self.futures, node, self.scopes)
gen = ClassCodeGenerator(graph, self.ctx, node, self.scopes)
gen.Start()
gen.FindLocals()
@@ -449,14 +444,14 @@ def visitFor(self, node):
def visitBreak(self, node):
if not self.setups:
raise SyntaxError, "'break' outside loop (%s, %d)" % \
(node.filename, node.lineno)
(self.ctx.filename, node.lineno)
self.set_lineno(node)
self.emit('BREAK_LOOP')
def visitContinue(self, node):
if not self.setups:
raise SyntaxError, "'continue' outside loop (%s, %d)" % \
(node.filename, node.lineno)
(self.ctx.filename, node.lineno)
kind, block = self.setups.top()
if kind == LOOP:
self.set_lineno(node)
@@ -473,12 +468,12 @@ def visitContinue(self, node):
break
if kind != LOOP:
raise SyntaxError, "'continue' outside loop (%s, %d)" % \
(node.filename, node.lineno)
(self.ctx.filename, node.lineno)
self.emit('CONTINUE_LOOP', loop_block)
self.nextBlock()
elif kind == END_FINALLY:
msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
raise SyntaxError, msg % (node.filename, node.lineno)
raise SyntaxError, msg % (self.ctx.filename, node.lineno)
def visitTest(self, node, jump):
end = self.newBlock()
@@ -647,9 +642,9 @@ def visitGenExpr(self, node):
# That workaround may no longer be necessary if we switch.
obj_name = '<genexpr>'
graph = pyassem.PyFlowGraph(obj_name, node.filename, optimized=1)
graph = pyassem.PyFlowGraph(obj_name, self.ctx.filename, optimized=1)
graph.setArgs(node.argnames)
gen = GenExprCodeGenerator(graph, self.futures, node, self.scopes,
gen = GenExprCodeGenerator(graph, self.ctx, node, self.scopes,
self.class_name)
gen.Start()
@@ -1293,8 +1288,8 @@ class _FunctionCodeGenerator(CodeGenerator):
"""Abstract class."""
optimized = 1
def __init__(self, graph, futures, func, scopes, class_name):
CodeGenerator.__init__(self, graph, futures)
def __init__(self, graph, ctx, func, scopes, class_name):
CodeGenerator.__init__(self, graph, ctx)
self.func = func
self.scopes = scopes
self.class_name = class_name
@@ -1352,8 +1347,8 @@ def Finish(self):
class ClassCodeGenerator(CodeGenerator):
def __init__(self, graph, futures, klass, scopes):
CodeGenerator.__init__(self, graph, futures)
def __init__(self, graph, ctx, klass, scopes):
CodeGenerator.__init__(self, graph, ctx)
self.klass = klass
self.scopes = scopes

0 comments on commit 6a2864e

Please sign in to comment.