示例#1
0
    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
示例#2
0
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')
示例#3
0
文件: envs.py 项目: AdaCore/langkit
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'
    )
示例#4
0
文件: envs.py 项目: AdaCore/langkit
    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
示例#5
0
    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')
示例#6
0
    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'
                    )