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

« back to all changes in this revision

Viewing changes to pypy/module/__builtin__/compiling.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
"""
 
2
Implementation of the interpreter-level compile/eval builtins.
 
3
"""
 
4
 
 
5
from pypy.interpreter.pycode import PyCode
 
6
from pypy.interpreter.baseobjspace import W_Root, ObjSpace
 
7
from pypy.interpreter.error import OperationError 
 
8
from pypy.interpreter.gateway import NoneNotWrapped
 
9
 
 
10
def compile(space, w_source, filename, mode, flags=0, dont_inherit=0):
 
11
    """Compile the source string (a Python module, statement or expression)
 
12
into a code object that can be executed by the exec statement or eval().
 
13
The filename will be used for run-time error messages.
 
14
The mode must be 'exec' to compile a module, 'single' to compile a
 
15
single (interactive) statement, or 'eval' to compile an expression.
 
16
The flags argument, if present, controls which future statements influence
 
17
the compilation of the code.
 
18
The dont_inherit argument, if non-zero, stops the compilation inheriting
 
19
the effects of any future statements in effect in the code calling
 
20
compile; if absent or zero these statements do influence the compilation,
 
21
in addition to any features explicitly specified.
 
22
"""
 
23
    if space.is_true(space.isinstance(w_source, space.w_unicode)):
 
24
        # hack: encode the unicode string as UTF-8 and attach
 
25
        # a BOM at the start
 
26
        w_source = space.call_method(w_source, 'encode', space.wrap('utf-8'))
 
27
        str_ = space.str_w(w_source)
 
28
        str_ = '\xEF\xBB\xBF' + str_
 
29
    else:
 
30
        str_ = space.str_w(w_source)
 
31
 
 
32
    ec = space.getexecutioncontext()
 
33
    if not dont_inherit:
 
34
        try:
 
35
            caller = ec.framestack.top()
 
36
        except IndexError:
 
37
            pass
 
38
        else:
 
39
            flags |= ec.compiler.getcodeflags(caller.getcode())
 
40
 
 
41
    if mode not in ('exec', 'eval', 'single'):
 
42
        raise OperationError(space.w_ValueError,
 
43
                             space.wrap("compile() arg 3 must be 'exec' "
 
44
                                        "or 'eval' or 'single'"))
 
45
 
 
46
    code = ec.compiler.compile(str_, filename, mode, flags)
 
47
    return space.wrap(code)
 
48
#
 
49
compile.unwrap_spec = [ObjSpace,W_Root,str,str,int,int]
 
50
 
 
51
 
 
52
def eval(space, w_code, w_globals=NoneNotWrapped, w_locals=NoneNotWrapped):
 
53
    """Evaluate the source in the context of globals and locals.
 
54
The source may be a string representing a Python expression
 
55
or a code object as returned by compile().  The globals and locals
 
56
are dictionaries, defaulting to the current current globals and locals.
 
57
If only globals is given, locals defaults to it.
 
58
"""
 
59
    w = space.wrap
 
60
 
 
61
    if (space.is_true(space.isinstance(w_code, space.w_str)) or
 
62
        space.is_true(space.isinstance(w_code, space.w_unicode))):
 
63
        try:
 
64
            w_code = compile(space,
 
65
                             space.call_method(w_code, 'lstrip',
 
66
                                               space.wrap(' \t')),
 
67
                             "<string>", "eval")
 
68
        except OperationError, e:
 
69
            if e.match(space, space.w_SyntaxError):
 
70
                e_value_w = space.unpacktuple(e.w_value)
 
71
                if len(e_value_w) == 2:
 
72
                    e_loc_w = space.unpacktuple(e_value_w[1])
 
73
                    e.w_value = space.newtuple([e_value_w[0],
 
74
                                                space.newtuple([space.w_None]+
 
75
                                                               e_loc_w[1:])])
 
76
                raise e
 
77
            else:
 
78
                raise
 
79
 
 
80
    codeobj = space.interpclass_w(w_code)
 
81
    if not isinstance(codeobj, PyCode):
 
82
        raise OperationError(space.w_TypeError,
 
83
              w('eval() arg 1 must be a string or code object'))
 
84
 
 
85
    try:
 
86
        caller = space.getexecutioncontext().framestack.top()
 
87
    except IndexError:
 
88
        caller = None
 
89
 
 
90
    if w_globals is None or space.is_w(w_globals, space.w_None): 
 
91
        if caller is None:
 
92
            w_globals = w_locals = space.newdict()
 
93
        else:
 
94
            w_globals = caller.w_globals
 
95
            w_locals = caller.getdictscope()
 
96
    elif w_locals is None:
 
97
        w_locals = w_globals
 
98
 
 
99
    try:
 
100
        space.getitem(w_globals, space.wrap('__builtins__'))
 
101
    except OperationError, e:
 
102
        if not e.match(space, space.w_KeyError):
 
103
            raise
 
104
        if caller is not None:
 
105
            w_builtin = space.builtin.pick_builtin(caller.w_globals)
 
106
            space.setitem(w_globals, space.wrap('__builtins__'), w_builtin)
 
107
 
 
108
    return codeobj.exec_code(space, w_globals, w_locals)