def create_properties(self): """ Turn the various abstract expression attributes for this env spec into internal properties. :rtype: list[PropertyDef] """ result = [] def create_internal_property(name, expr, type): if expr is None: return None # Set has_implicit_env for these internal properties so that they # can use a default environment that the context gives. This # default will be the Self_Env of the parent node, which is always # the same, regardless of being run in the populate lexical env # pass or later on. See Initial_Env_Getter_Fn functions for the # code that fetches this default environment. p = PropertyDef(expr, AbstractNodeData.PREFIX_INTERNAL, name=names.Name('_{}_{}'.format( name, next(self.PROPERTY_COUNT))), private=True, type=type, has_implicit_env=True) result.append(p) return p self.initial_env = create_internal_property( 'Initial_Env', self._unresolved_initial_env, LexicalEnvType) self.envs_expressions = [ add_to_env( create_internal_property('Env_Key', exprs.key, None), create_internal_property('Env_Value', exprs.val, None), create_internal_property('Env_Dest', exprs.dest_env, LexicalEnvType), create_internal_property('MD', exprs.metadata, T.env_md), exprs.is_post) for exprs in self._unresolved_envs_expressions ] self.has_post_actions = any([e.is_post for e in self.envs_expressions]) self.ref_envs = create_internal_property('Ref_Envs', self._unresolved_ref_envs, LexicalEnvType.array_type()) self.env_hook_arg = create_internal_property( 'Env_Hook_Arg', self._unresolved_env_hook_arg, T.root_node) return result
def env_group(env_array_expr): """ Expression that will return a lexical environment that logically groups together multiple lexical environments from an array of lexical environments. :param AbstractExpression env_array_expr: Expression that will return an array of lexical environments. If this array is empty, the empty environment is returned. """ return BuiltinCallExpr( 'Group', LexicalEnvType, [construct(env_array_expr, LexicalEnvType.array_type())], 'Group_Env')
def env_group(env_array_expr): """ Expression that will return a lexical environment that logically groups together multiple lexical environments from an array of lexical environments. :param AbstractExpression env_array_expr: Expression that will return an array of lexical environments. If this array is empty, the empty environment is returned. """ return BuiltinCallExpr( 'Group', LexicalEnvType, [construct(env_array_expr, LexicalEnvType.array_type())], 'Group_Env' )
def create_properties(self): """ Turn the various abstract expression attributes for this env spec into internal properties. :rtype: list[PropertyDef] """ result = [] def create_internal_property(name, expr, type): if expr is None: return None p = PropertyDef( expr, AbstractNodeData.PREFIX_INTERNAL, name=names.Name('_{}_{}'.format(name, next(self.PROPERTY_COUNT))), private=True, type=type ) result.append(p) return p self.initial_env = create_internal_property( 'Initial_Env', self._unresolved_initial_env, LexicalEnvType ) self.envs_expressions = [ add_to_env( create_internal_property('Env_Key', exprs.key, None), create_internal_property('Env_Value', exprs.val, None), create_internal_property('Env_Dest', exprs.dest_env, LexicalEnvType), create_internal_property('MD', exprs.metadata, T.env_md), exprs.is_post ) for exprs in self._unresolved_envs_expressions ] self.has_post_actions = any([e.is_post for e in self.envs_expressions]) self.ref_envs = create_internal_property( 'Ref_Envs', self._unresolved_ref_envs, LexicalEnvType.array_type() ) self.env_hook_arg = create_internal_property( 'Env_Hook_Arg', self._unresolved_env_hook_arg, T.root_node ) return result
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 LexicalEnvType, StructMetaclass env_element = StructMetaclass.root_grammar_class.env_el() self.astnode_types = list(StructMetaclass.astnode_types) self.root_grammar_class = StructMetaclass.root_grammar_class self.generic_list_type = self.root_grammar_class.generic_list_type self.env_metadata = StructMetaclass.env_metadata # 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 env_element array type: LexicalEnv.get returns it. self.array_types.add(env_element.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')
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' )