""" 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)