aboutsummaryrefslogblamecommitdiffstats
path: root/contrib/tools/cython/Cython/Compiler/Interpreter.py
blob: 9ec391f2a021dc75ceff0e19006f0b5866176824 (plain) (tree)






























































                                                                                 
"""
This module deals with interpreting the parse tree as Python
would have done, in the compiler.

For now this only covers parse tree to value conversion of
compile-time values.
"""

from __future__ import absolute_import

from .Nodes import *
from .ExprNodes import *
from .Errors import CompileError


class EmptyScope(object):
    def lookup(self, name):
        return None

empty_scope = EmptyScope()

def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=()):
    """
    Tries to interpret a list of compile time option nodes.
    The result will be a tuple (optlist, optdict) but where
    all expression nodes have been interpreted. The result is
    in the form of tuples (value, pos).

    optlist is a list of nodes, while optdict is a DictNode (the
    result optdict is a dict)

    If type_env is set, all type nodes will be analysed and the resulting
    type set. Otherwise only interpretateable ExprNodes
    are allowed, other nodes raises errors.

    A CompileError will be raised if there are problems.
    """

    def interpret(node, ix):
        if ix in type_args:
            if type_env:
                type = node.analyse_as_type(type_env)
                if not type:
                    raise CompileError(node.pos, "Invalid type.")
                return (type, node.pos)
            else:
                raise CompileError(node.pos, "Type not allowed here.")
        else:
            if (sys.version_info[0] >=3 and
                isinstance(node, StringNode) and
                node.unicode_value is not None):
                return (node.unicode_value, node.pos)
            return (node.compile_time_value(empty_scope), node.pos)

    if optlist:
        optlist = [interpret(x, ix) for ix, x in enumerate(optlist)]
    if optdict:
        assert isinstance(optdict, DictNode)
        new_optdict = {}
        for item in optdict.key_value_pairs:
            new_key, dummy = interpret(item.key, None)
            new_optdict[new_key] = interpret(item.value, item.key.value)
        optdict = new_optdict
    return (optlist, new_optdict)