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