def env_get(env_expr, token_expr, resolve_unique=False, sequential=False): """ Expression for lexical environment get operation. :param AbstractExpression env_expr: Expression that will yield the env to get the element from. :param AbstractExpression token_expr: Expression that will yield the token to use as a key on the env. :param bool resolve_unique: Wether we want an unique result or not. NOTE: For the moment, nothing will be done to ensure that only one result is available. The implementation will just take the first result. :param bool sequential: Whether resolution needs to be sequential or not. """ sub_exprs = [construct(env_expr, LexicalEnvType), construct(token_expr, Token)] if sequential: # Pass the From parameter if the user wants sequential semantics array_expr = 'AST_Envs.Get ({}, Get_Symbol ({}), {})' sub_exprs.append(construct(Self, T.root_node)) else: array_expr = 'AST_Envs.Get ({}, Get_Symbol ({}))' make_expr = partial(BasicExpr, result_var_name="Env_Get_Result", sub_exprs=sub_exprs) if resolve_unique: return make_expr("Get ({}, 0)".format(array_expr), EnvElement) else: EnvElement.array_type().add_to_context() return make_expr("Create ({})".format(array_expr), EnvElement.array_type())
def compute_types(self): """ Compute various information related to compiled types, that needs to be available for code generation. """ # Get the list of ASTNode types from the Struct metaclass from langkit.compiled_types import ( EnvElement, LexicalEnvType, StructMetaclass ) self.astnode_types = list(StructMetaclass.astnode_types) # Here we're skipping Struct because it's not a real type in # generated code. We're also putting env_metadata and EnvElement in # the beginning and in the right dependency order (the metadata # type before the env element type). # TODO: Using a dependency order topological sort wouldn't hurt at # some point. self.struct_types = [ t for t in StructMetaclass.struct_types if t not in [EnvElement, StructMetaclass.env_metadata] ] self.struct_types.insert(0, EnvElement) if StructMetaclass.env_metadata: self.struct_types = ( [StructMetaclass.env_metadata] + self.struct_types ) self.root_grammar_class = StructMetaclass.root_grammar_class self.env_metadata = StructMetaclass.env_metadata self.env_element = EnvElement # The Group lexical environment operation takes an array of lexical # envs, so we always need to generate the corresponding array type. self.array_types.add(LexicalEnvType.array_type()) # Likewise for the EnvElement array type: LexicalEnv.get returns it. # No need to bind anything if the language specification did not # specify any EnvElement, though. if self.env_element: self.array_types.add(EnvElement.array_type()) # Sort them in dependency order as required but also then in # alphabetical order so that generated declarations are kept in a # relatively stable order. This is really useful for debugging # purposes. keys = { cls: cls.hierarchical_name() for cls in self.astnode_types } self.astnode_types.sort(key=lambda cls: keys[cls]) # Check that the environment hook is bound if the language spec uses # it. if self.env_hook_subprogram is None: for t in self.astnode_types: with t.diagnostic_context(): check_source_language( t.env_spec is None or not t.env_spec.env_hook_enabled, 'Cannot invoke the environment hook if' ' CompileContext.bind_env_hook has not been called' )