[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler __init__.py,1.4,1.5 pycodegen.py,1.54,1.55 transformer.py,1.27,1.28
Jeremy Hylton
jhylton@users.sourceforge.net
Mon, 17 Sep 2001 14:02:53 -0700
Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv16466
Modified Files:
__init__.py pycodegen.py transformer.py
Log Message:
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.
Index: __init__.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/__init__.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** __init__.py 2001/04/09 04:23:55 1.4
--- __init__.py 2001/09/17 21:02:51 1.5
***************
*** 4,8 ****
from modules contained in the package.
! parse(buf) -> AST
Converts a string containing Python source code to an abstract
syntax tree (AST). The AST is defined in compiler.ast.
--- 4,8 ----
from modules contained in the package.
! parse(buf, mode="exec") -> AST
Converts a string containing Python source code to an abstract
syntax tree (AST). The AST is defined in compiler.ast.
***************
*** 15,19 ****
See compiler.visitor for details.
! compile(filename)
Generates a .pyc file by compilining filename.
"""
--- 15,22 ----
See compiler.visitor for details.
! compile(source, filename, mode, flags=None, dont_inherit=None)
! Returns a code object. A replacement for the builtin compile() function.
!
! compileFile(filename)
Generates a .pyc file by compilining filename.
"""
***************
*** 21,24 ****
from transformer import parse, parseFile
from visitor import walk
! from pycodegen import compile
--- 24,27 ----
from transformer import parse, parseFile
from visitor import walk
! from pycodegen import compile, compileFile
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.54
retrieving revision 1.55
diff -C2 -d -r1.54 -r1.55
*** pycodegen.py 2001/09/17 19:33:48 1.54
--- pycodegen.py 2001/09/17 21:02:51 1.55
***************
*** 42,46 ****
self.loop = None
! def compile(filename, display=0):
f = open(filename)
buf = f.read()
--- 42,46 ----
self.loop = None
! def compileFile(filename, display=0):
f = open(filename)
buf = f.read()
***************
*** 56,69 ****
f.close()
! class Module:
def __init__(self, source, filename):
- self.filename = os.path.abspath(filename)
self.source = source
self.code = None
! def compile(self, display=0):
! tree = parse(self.source)
misc.set_filename(self.filename, tree)
syntax.check(tree)
gen = ModuleCodeGenerator(tree)
if display:
--- 56,121 ----
f.close()
! 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.source = source
+ self.filename = filename
self.code = None
! 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:
***************
*** 1097,1100 ****
--- 1149,1190 ----
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:
Index: transformer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/transformer.py,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** transformer.py 2001/09/17 19:33:48 1.27
--- transformer.py 2001/09/17 21:02:51 1.28
***************
*** 43,48 ****
return parse(src)
! def parse(buf):
! return Transformer().parsesuite(buf)
def asList(nodes):
--- 43,54 ----
return parse(src)
! def parse(buf, mode="exec"):
! if mode == "exec" or mode == "single":
! return Transformer().parsesuite(buf)
! elif mode == "eval":
! return Transformer().parseexpr(buf)
! else:
! raise ValueError("compile() arg 3 must be"
! " 'exec' or 'eval' or 'single'")
def asList(nodes):