summaryrefslogtreecommitdiff
path: root/Lib/compiler/pycodegen.py
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-09-17 21:02:51 +0000
committerJeremy Hylton <jeremy@alum.mit.edu>2001-09-17 21:02:51 +0000
commit29f233d651ba3ebc40eed3bb4114160b88ffc9a7 (patch)
treed87314a07f964972deb0777eaf22c40dc21a2e93 /Lib/compiler/pycodegen.py
parent50f0c155c5f53f1afba3ee089a87c7526b0cee8b (diff)
downloadcpython-29f233d651ba3ebc40eed3bb4114160b88ffc9a7.tar.gz
API change:
compile() becomes replacement for builtin compile() compileFile() generates a .pyc from a .py both are exported in __init__ compiler.parse() gets optional second argument to specify compilation mode, e.g. single, eval, exec Add AbstractCompileMode as parent class and Module, Expression, and Interactive as concrete subclasses. Each corresponds to a compilation mode. THe AbstractCompileMode instances in turn delegate to CodeGeneration subclasses specialized for their particular functions -- ModuleCodeGenerator, ExpressionCodeGeneration, InteractiveCodeGenerator.
Diffstat (limited to 'Lib/compiler/pycodegen.py')
-rw-r--r--Lib/compiler/pycodegen.py100
1 files changed, 95 insertions, 5 deletions
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index 7bc17958cf..3cdf108bad 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -41,7 +41,7 @@ class BlockStack(misc.Stack):
self.__super_init(self)
self.loop = None
-def compile(filename, display=0):
+def compileFile(filename, display=0):
f = open(filename)
buf = f.read()
f.close()
@@ -55,16 +55,68 @@ def compile(filename, display=0):
mod.dump(f)
f.close()
-class Module:
+def compile(source, filename, mode, flags=None, dont_inherit=None):
+ """Replacement for builtin compile() function"""
+ if flags is not None or dont_inherit is not None:
+ raise RuntimeError, "not implemented yet"
+
+ if mode == "single":
+ gen = Interactive(source, filename)
+ elif mode == "exec":
+ gen = Module(source, filename)
+ elif mode == "eval":
+ gen = Expression(source, filename)
+ else:
+ raise ValueError("compile() 3rd arg must be 'exec' or "
+ "'eval' or 'single'")
+ gen.compile()
+ return gen.code
+
+class AbstractCompileMode:
+
+ mode = None # defined by subclass
+
def __init__(self, source, filename):
- self.filename = os.path.abspath(filename)
self.source = source
+ self.filename = filename
self.code = None
- def compile(self, display=0):
- tree = parse(self.source)
+ def _get_tree(self):
+ tree = parse(self.source, self.mode)
misc.set_filename(self.filename, tree)
syntax.check(tree)
+ return tree
+
+ def compile(self):
+ pass # implemented by subclass
+
+ def getCode(self):
+ return self.code
+
+class Expression(AbstractCompileMode):
+
+ mode = "eval"
+
+ def compile(self):
+ tree = self._get_tree()
+ gen = ExpressionCodeGenerator(tree)
+ self.code = gen.getCode()
+
+class Interactive(AbstractCompileMode):
+
+ mode = "single"
+
+ def compile(self):
+ tree = self._get_tree()
+ gen = InteractiveCodeGenerator(tree)
+ self.code = gen.getCode()
+
+class Module(AbstractCompileMode):
+
+ mode = "exec"
+
+ def compile(self, display=0):
+ tree = self._get_tree()
gen = ModuleCodeGenerator(tree)
if display:
import pprint
@@ -1097,6 +1149,44 @@ class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
def get_module(self):
return self
+class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
+ __super_init = CodeGenerator.__init__
+
+ scopes = None
+ futures = ()
+
+ def __init__(self, tree):
+ self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
+ self.__super_init()
+ self.set_lineno(tree)
+ walk(tree, self)
+ self.emit('RETURN_VALUE')
+
+ def get_module(self):
+ return self
+
+class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
+
+ __super_init = CodeGenerator.__init__
+
+ scopes = None
+ futures = ()
+
+ def __init__(self, tree):
+ self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
+ self.__super_init()
+ self.set_lineno(tree)
+ walk(tree, self)
+ self.emit('RETURN_VALUE')
+
+ def get_module(self):
+ return self
+ def visitDiscard(self, node):
+ # XXX Discard means it's an expression. Perhaps this is a bad
+ # name.
+ self.visit(node.expr)
+ self.emit('PRINT_EXPR')
+
class AbstractFunctionCode:
optimized = 1
lambdaCount = 0