[pypy-svn] r14122 - in pypy/dist/pypy: interpreter interpreter/test tool

adim at codespeak.net adim at codespeak.net
Sun Jul 3 12:24:39 CEST 2005


Author: adim
Date: Sun Jul  3 12:24:37 2005
New Revision: 14122

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/executioncontext.py
   pypy/dist/pypy/interpreter/pycompiler.py
   pypy/dist/pypy/interpreter/pyopcode.py
   pypy/dist/pypy/interpreter/test/test_compiler.py
   pypy/dist/pypy/tool/option.py
Log:
added options fields to choose which compiler / parser should be 
used.
(For now, only the cpython parser/compiler can be run)



Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Sun Jul  3 12:24:37 2005
@@ -1,9 +1,12 @@
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.argument import Arguments
+from pypy.interpreter.pycompiler import CPythonCompiler
+from pypy.interpreter.pycompiler import PythonCompiler, PyPyCompiler
 from pypy.interpreter.miscutils import ThreadLocals
 from pypy.tool.cache import Cache 
 from pypy.rpython.rarithmetic import r_uint
+import pypy.tool.option
 
 __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable',
            'W_Root']
@@ -92,12 +95,17 @@
     
     full_exceptions = True  # full support for exceptions (normalization & more)
 
-    def __init__(self):
+    def __init__(self, options=None):
         "NOT_RPYTHON: Basic initialization of objects."
         self.fromcache = InternalSpaceCache(self).getorbuild
         self.threadlocals = ThreadLocals()
         # set recursion limit
         # sets all the internal descriptors
+        
+        # XXX: Options in option.py is replaced by a function so
+        # it's not really clean to do a from option import Options
+        # since changing import order can change the Options object
+        self.options = options or pypy.tool.option.Options()
         self.initialize()
 
     def __repr__(self):
@@ -134,9 +142,11 @@
         #self.setbuiltinmodule('_codecs')
         # XXX we need to resolve unwrapping issues to 
         #     make this the default _sre module
-        #self.setbuiltinmodule("_sre", "_sre_pypy") 
-
-        # XXX disabled: self.setbuiltinmodule('parser')
+        #self.setbuiltinmodule("_sre", "_sre_pypy")
+        if self.options.parser == "recparser":
+            self.setbuiltinmodule('parser', 'recparser')
+        elif self.options.parser == "parser":
+            self.setbuiltinmodule('parser')
 
         # initialize with "bootstrap types" from objspace  (e.g. w_None)
         for name, value in self.__dict__.items():
@@ -177,6 +187,20 @@
         "Factory function for execution contexts."
         return ExecutionContext(self)
 
+    def createcompiler(self):
+        "Factory function creating a compiler object."
+        if self.options.parser == 'recparser':
+            if self.options.compiler == 'cpython':
+                return PythonCompiler(self)
+            else:
+                return PyPyCompiler(self)
+        elif self.options.compiler == 'recparser':
+            # <=> options.parser == 'cpython'
+            return PythonCompiler(self)
+        else:
+            # <=> options.compiler == 'cpython' and options.parser == 'cpython'
+            return CPythonCompiler(self)
+
     # Following is a friendly interface to common object space operations
     # that can be defined in term of more primitive ones.  Subclasses
     # may also override specific functions for performance.

Modified: pypy/dist/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/dist/pypy/interpreter/executioncontext.py	(original)
+++ pypy/dist/pypy/interpreter/executioncontext.py	Sun Jul  3 12:24:37 2005
@@ -1,7 +1,6 @@
 import sys
 from pypy.interpreter.miscutils import Stack
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.pycompiler import CPythonCompiler
 
 class ExecutionContext:
     """An ExecutionContext holds the state of an execution thread
@@ -14,7 +13,7 @@
         self.w_tracefunc = None
         self.w_profilefunc = None
         self.is_tracing = 0
-        self.compiler = CPythonCompiler(space)
+        self.compiler = space.createcompiler()
 
     def enter(self, frame):
         if self.framestack.depth() > self.space.sys.recursionlimit:

Modified: pypy/dist/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycompiler.py	(original)
+++ pypy/dist/pypy/interpreter/pycompiler.py	Sun Jul  3 12:24:37 2005
@@ -6,7 +6,7 @@
 from pypy.interpreter.error import OperationError
 
 
-class Compiler:
+class AbstractCompiler:
     """Abstract base class for a bytecode compiler."""
 
     # The idea is to grow more methods here over the time,
@@ -80,11 +80,14 @@
 import warnings
 import __future__
 compiler_flags = 0
+compiler_features = {}
 for fname in __future__.all_feature_names:
-    compiler_flags |= getattr(__future__, fname).compiler_flag
+    flag = getattr(__future__, fname).compiler_flag
+    compiler_flags |= flag
+    compiler_features[fname] = flag
 
 
-class CPythonCompiler(Compiler):
+class CPythonCompiler(AbstractCompiler):
     """Faked implementation of a compiler, using the underlying compile()."""
 
     def compile(self, source, filename, mode, flags):
@@ -163,3 +166,75 @@
 
     def restore_warn_explicit(self, warnings, old_warn_explicit):
         warnings.warn_explicit = old_warn_explicit
+
+
+########
+import symbol
+from compiler.transformer import Transformer
+from compiler.pycodegen import ModuleCodeGenerator
+from compiler.pycodegen import InteractiveCodeGenerator
+from compiler.pycodegen import ExpressionCodeGenerator
+from pyparser.pythonparse import parse_python_source, PYTHON_PARSER
+from pyparser.tuplebuilder import TupleBuilder
+
+def pycompile(source, mode):
+    strings = [line+'\n' for line in source.split('\n')]
+    builder = TupleBuilder(PYTHON_PARSER.rules, lineno=False)
+    if mode == 'exec':
+        target = 'file_input'
+    elif mode == 'single':
+        target = 'single_input'
+    else: # target == 'eval':
+        target = 'eval_input'
+    parse_python_source(strings, PYTHON_PARSER, target, builder)
+    # Note: The annotator can't follow the as_tuple() method call
+    nested_tuples = builder.stack[-1].as_tuple()
+    if builder.source_encoding is not None:
+        return (symbol.encoding_decl, nested_tuples, builder.source_encoding)
+    else:
+        return nested_tuples
+
+class PythonCompiler(CPythonCompiler):
+    """Uses the stdlib's python implementation of compiler"""
+
+    def compile(self, source, filename, mode, flags):
+        flags |= __future__.generators.compiler_flag   # always on (2.2 compat)
+        space = self.space
+        try:
+            transformer = Transformer()
+            tuples = pycompile(source, mode)
+            tree = transformer.compile_node(tuples)
+            compiler.misc.set_filename(filename, tree)
+            if mode == 'exec':
+                codegenerator = ModuleCodeGenerator(tree)
+            elif mode == 'single':
+                codegenerator = InteractiveCodeGenerator(tree)
+            else: # mode == 'eval':
+                codegenerator = ExpressionCodeGenerator(tree)
+            c = codegenerator.getCode()
+        # It would be nice to propagate all exceptions to app level,
+        # but here we only propagate the 'usual' ones, until we figure
+        # out how to do it generically.
+        except SyntaxError, e:
+            w_synerr = space.newtuple([space.wrap(e.msg),
+                                       space.newtuple([space.wrap(e.filename),
+                                                       space.wrap(e.lineno),
+                                                       space.wrap(e.offset),
+                                                       space.wrap(e.text)])])
+            raise OperationError(space.w_SyntaxError, w_synerr)
+        except ValueError,e:
+            raise OperationError(space.w_ValueError,space.wrap(str(e)))
+        except TypeError,e:
+            raise OperationError(space.w_TypeError,space.wrap(str(e)))
+        from pypy.interpreter.pycode import PyCode
+        return space.wrap(PyCode(space)._from_code(c))
+
+# This doesn't work for now
+class PyPyCompiler(CPythonCompiler):
+    """Uses the PyPy implementation of Compiler
+
+    WRITEME
+    """
+# PyPyCompiler = PythonCompiler = CPythonCompiler
+# PyPyCompiler = CPythonCompiler
+# PythonCompiler = CPythonCompiler

Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Sun Jul  3 12:24:37 2005
@@ -53,7 +53,7 @@
             oparg = self.nextarg()
             fn(self, oparg)
         else:
-            fn = self.dispatch_table_no_arg[opcode]            
+            fn = self.dispatch_table_no_arg[opcode] 
             fn(self)
 
     def nextop(self):

Modified: pypy/dist/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_compiler.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_compiler.py	Sun Jul  3 12:24:37 2005
@@ -1,13 +1,13 @@
 import __future__
 import autopath
 import py
-from pypy.interpreter.pycompiler import CPythonCompiler, Compiler
+from pypy.interpreter.pycompiler import CPythonCompiler, PythonCompiler
 from pypy.interpreter.pycode import PyCode
 
 
-class TestCompiler:
+class BaseTestCompiler:
     def setup_method(self, method):
-        self.compiler = CPythonCompiler(self.space)
+        self.compiler = self.space.createcompiler()
 
     def test_compile(self):
         code = self.compiler.compile('6*7', '<hello>', 'eval', 0)
@@ -48,6 +48,20 @@
         assert flags == flags2
 
 
-class TestECCompiler(TestCompiler):
+class TestECCompiler(BaseTestCompiler):
     def setup_method(self, method):
         self.compiler = self.space.getexecutioncontext().compiler
+
+class TestPyCCompiler(BaseTestCompiler):
+    def setup_method(self, method):
+        self.compiler = CPythonCompiler(self.space)
+
+
+class SkippedForNowTestPurePythonCompiler(BaseTestCompiler):
+    def setup_method(self, method):
+        self.compiler = PythonCompiler(self.space)
+
+
+class SkippedForNowTestPyPyCompiler(BaseTestCompiler):
+    def setup_method(self, method):
+        self.compiler = PyPyCompiler(self.space)

Modified: pypy/dist/pypy/tool/option.py
==============================================================================
--- pypy/dist/pypy/tool/option.py	(original)
+++ pypy/dist/pypy/tool/option.py	Sun Jul  3 12:24:37 2005
@@ -10,6 +10,8 @@
     spaces = []
     oldstyle = 0
     uselibfile = 0
+    parser = "cpython"
+    compiler = "cpython"
 
 def run_tb_server(option, opt, value, parser):
     from pypy.tool import tb_server
@@ -67,7 +69,7 @@
     except KeyError:
         module = __import__("pypy.objspace.%s" % name, None, None, ["Space"])
         Space = module.Space
-        space = Space()
+        space = Space( Options() )
         if name == 'std' and Options.oldstyle:
             space.enable_old_style_classes_as_default_metaclass()
         if Options.uselibfile:



More information about the Pypy-commit mailing list