1"""
2This module deals with interpreting the parse tree as Python
3would have done, in the compiler.
4
5For now this only covers parse tree to value conversion of
6compile-time values.
7"""
8
9from __future__ import absolute_import
10
11from .Nodes import *
12from .ExprNodes import *
13from .Errors import CompileError
14
15
16class EmptyScope(object):
17    def lookup(self, name):
18        return None
19
20empty_scope = EmptyScope()
21
22def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=()):
23    """
24    Tries to interpret a list of compile time option nodes.
25    The result will be a tuple (optlist, optdict) but where
26    all expression nodes have been interpreted. The result is
27    in the form of tuples (value, pos).
28
29    optlist is a list of nodes, while optdict is a DictNode (the
30    result optdict is a dict)
31
32    If type_env is set, all type nodes will be analysed and the resulting
33    type set. Otherwise only interpretateable ExprNodes
34    are allowed, other nodes raises errors.
35
36    A CompileError will be raised if there are problems.
37    """
38
39    def interpret(node, ix):
40        if ix in type_args:
41            if type_env:
42                type = node.analyse_as_type(type_env)
43                if not type:
44                    raise CompileError(node.pos, "Invalid type.")
45                return (type, node.pos)
46            else:
47                raise CompileError(node.pos, "Type not allowed here.")
48        else:
49            if (sys.version_info[0] >=3 and
50                isinstance(node, StringNode) and
51                node.unicode_value is not None):
52                return (node.unicode_value, node.pos)
53            return (node.compile_time_value(empty_scope), node.pos)
54
55    if optlist:
56        optlist = [interpret(x, ix) for ix, x in enumerate(optlist)]
57    if optdict:
58        assert isinstance(optdict, DictNode)
59        new_optdict = {}
60        for item in optdict.key_value_pairs:
61            new_key, dummy = interpret(item.key, None)
62            new_optdict[new_key] = interpret(item.value, item.key.value)
63        optdict = new_optdict
64    return (optlist, new_optdict)
65