~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/interpreter/pyparser/test/test_astcompiler.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import sys
 
2
import os
 
3
 
 
4
from pypy.interpreter.pyparser import pythonparse
 
5
from pypy.interpreter.pyparser.astbuilder import AstBuilder
 
6
from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder
 
7
from pypy.interpreter.pycode import PyCode
 
8
import py.test
 
9
 
 
10
def setup_module(mod):
 
11
    import pypy.conftest
 
12
    mod.std_space = pypy.conftest.gettestobjspace('std')
 
13
 
 
14
from pypy.interpreter.astcompiler import ast, misc, pycodegen
 
15
 
 
16
from test_astbuilder import SNIPPETS, LIBSTUFF, FakeSpace, source2ast
 
17
from expressions import PY23_TESTS, EXEC_INPUTS, SINGLE_INPUTS, OPTIONAL_TESTS
 
18
 
 
19
TESTS = PY23_TESTS + EXEC_INPUTS
 
20
 
 
21
 
 
22
if sys.version_info[0]==2 and sys.version_info[1]>=4:
 
23
    # genexps and new style import don't work on python2.3
 
24
    # TESTS.append(genexps) XXX: 2.4 optimizes bytecode so our comparison doesn't work
 
25
    TESTS += OPTIONAL_TESTS
 
26
 
 
27
 
 
28
def compile_with_astcompiler(expr, mode='exec', space=FakeSpace()):
 
29
    ast = source2ast(expr, mode, space) # xxx exec: single not really tested, mumble
 
30
    misc.set_filename('<?>', ast)
 
31
    if mode == 'exec':
 
32
        Generator = pycodegen.ModuleCodeGenerator
 
33
    elif mode == 'single':
 
34
        Generator = pycodegen.InteractiveCodeGenerator
 
35
    elif mode == 'eval':
 
36
        Generator = pycodegen.ExpressionCodeGenerator
 
37
    codegen = Generator(space, ast)
 
38
    rcode = codegen.getCode()
 
39
    return rcode
 
40
 
 
41
# Create parser from Grammar_stable, not current grammar.
 
42
stable_parser = pythonparse.make_pyparser('stable')
 
43
 
 
44
def compile_with_testcompiler(expr, mode='exec', space=FakeSpace()):
 
45
    mode2 = 'exec' # xxx exec: single not really tested
 
46
    builder = TupleBuilder(stable_parser)
 
47
    stable_parser.parse_source(expr, mode2, builder)
 
48
    tuples =  builder.stack[-1].as_tuple(True)
 
49
    from pypy.interpreter.stablecompiler import transformer, pycodegen, misc
 
50
    ast = transformer.Transformer('<?>').compile_node(tuples)
 
51
    misc.set_filename('<?>', ast)
 
52
    if mode == 'exec':
 
53
        Generator = pycodegen.ModuleCodeGenerator
 
54
    elif mode == 'single':
 
55
        Generator = pycodegen.InteractiveCodeGenerator
 
56
    elif mode == 'eval':
 
57
        Generator = pycodegen.ExpressionCodeGenerator
 
58
    codegen = Generator(ast)
 
59
    rcode = codegen.getCode()
 
60
    return rcode
 
61
 
 
62
 
 
63
def compare_code(ac_code, sc_code, space=FakeSpace()):
 
64
    #print "Filename", ac_code.co_filename, sc_code.co_filename
 
65
    ac_code = to_code(ac_code, space)
 
66
    assert ac_code.co_filename == sc_code.co_filename
 
67
    #print repr(ac_code.co_code)
 
68
    #print repr(sc_code.co_code)
 
69
    if ac_code.co_code != sc_code.co_code:
 
70
        import dis
 
71
        print "Code from pypy:"
 
72
        dis.dis(ac_code)
 
73
        print "Code from python", sys.version
 
74
        dis.dis(sc_code)
 
75
        assert ac_code.co_code == sc_code.co_code
 
76
    assert ac_code.co_varnames == sc_code.co_varnames
 
77
    assert ac_code.co_flags == sc_code.co_flags
 
78
 
 
79
    assert len(ac_code.co_consts) == len(sc_code.co_consts)
 
80
    for c1, c2 in zip( ac_code.co_consts, sc_code.co_consts ):
 
81
        if isinstance(c1, PyCode):
 
82
            return compare_code( c1, c2, space )
 
83
        else:
 
84
            assert c1 == c2
 
85
 
 
86
def to_code( rcode, space ):
 
87
    import new
 
88
    consts = []
 
89
    for w in rcode.co_consts_w:
 
90
        if type(w)==PyCode:
 
91
            consts.append(w)
 
92
        else:
 
93
            consts.append(space.unwrap(w))
 
94
    code = new.code( rcode.co_argcount,
 
95
                     rcode.co_nlocals,
 
96
                     rcode.co_stacksize,
 
97
                     rcode.co_flags,
 
98
                     rcode.co_code,
 
99
                     tuple(consts),
 
100
                     tuple(rcode.co_names),
 
101
                     tuple(rcode.co_varnames),
 
102
                     rcode.co_filename,
 
103
                     rcode.co_name,
 
104
                     rcode.co_firstlineno,
 
105
                     rcode.co_lnotab,
 
106
                     tuple(rcode.co_freevars),
 
107
                     tuple(rcode.co_cellvars) )
 
108
    return code
 
109
 
 
110
def check_compile(expr, mode='exec', quiet=False, space=None):
 
111
    if not quiet:
 
112
        print "Compiling:", expr
 
113
 
 
114
    if space is None:
 
115
        space = std_space
 
116
 
 
117
    ac_code = compile_with_astcompiler(expr, mode=mode, space=space)
 
118
    if expr == "k[v,]" or expr.startswith('"'):  # module-level docstring
 
119
        py.test.skip('comparison skipped, bug in "reference stable compiler"')
 
120
    sc_code = compile_with_testcompiler(expr, mode=mode)
 
121
    compare_code(ac_code, sc_code, space=space)
 
122
 
 
123
 
 
124
def test_compile_argtuple_1():
 
125
    code = """def f( x, (y,z) ):
 
126
    print x,y,z
 
127
"""
 
128
    check_compile( code )
 
129
 
 
130
def test_compile_argtuple_2():
 
131
    code = """def f( x, (y,(z,t)) ):
 
132
    print x,y,z,t
 
133
"""
 
134
    check_compile( code )
 
135
 
 
136
 
 
137
def test_compile_argtuple_3():
 
138
    code = """def f( x, (y,(z,(t,u))) ):
 
139
    print x,y,z,t,u
 
140
"""
 
141
    check_compile( code )
 
142
 
 
143
 
 
144
def test_basic_astgen():
 
145
    for family in TESTS:
 
146
        for expr in family:
 
147
            yield check_compile, expr
 
148
 
 
149
def test_snippets():
 
150
    for snippet_name in SNIPPETS:
 
151
        filepath = os.path.join(os.path.dirname(__file__), 'samples', snippet_name)
 
152
        source = file(filepath).read()
 
153
        yield check_compile, source, 'exec'
 
154
 
 
155
STDLIB_PATH = os.path.dirname(os.__file__)
 
156
def test_on_stdlib():
 
157
    py.test.skip('too ambitious for now (and time consuming)')
 
158
    for basename in os.listdir(STDLIB_PATH):
 
159
        if not basename.endswith('.py'):
 
160
            continue
 
161
        filepath = os.path.join(STDLIB_PATH, basename)
 
162
        # size = os.stat(filepath)[6]
 
163
        # filter on size
 
164
        # if size <= 10000:
 
165
        source = file(filepath).read()
 
166
        yield check_compile, source, 'exec'
 
167
 
 
168
def test_libstuff():
 
169
    for snippet_name in LIBSTUFF:
 
170
        filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name)
 
171
        source = file(filepath).read()
 
172
        yield check_compile, source, 'exec'
 
173
 
 
174
 
 
175
def test_single_inputs():
 
176
    for family in SINGLE_INPUTS:
 
177
        for expr in family:
 
178
            yield check_compile, expr, 'single'