Esempio n. 1
0
class Example(FooNode):
    name = Field(type=T.Id)
    dest_scope = Field(type=T.Id)
    content = Field(type=T.Id.list)

    @langkit_property()
    def has_kw(kw=T.Symbol):
        """
        Return whether "content" contains the ``kw`` keyword.
        """
        return Self.content.map(lambda c: c.symbol).contains(kw)

    env_spec = EnvSpec(
        add_env(names=[Self.name.symbol]),
        add_to_env_kv(
            key=Self.name.symbol,
            value=Self,

            # Check correct behavior when the env argument is null or not (when
            # it's not, add to the parents' env), and when or_current=True is
            # passed or not (current = Self's env).
            dest_env=Let(lambda name=If(
                Self.has_kw("null_name"),
                No(T.Symbol),
                Self.dest_scope.symbol,
            ): If(
                Self.has_kw("or_current"),
                named_env(name, or_current=True),
                named_env(name),
            ))),
    )
Esempio n. 2
0
    def test_if():
        # define x
        x = Var(
            # let's see... maybe 24?
            24
        )

        # call foo
        return If(
            # no way!
            True,

            # haha
            If(
                # second
                False,
                # nope
                12,
                # finally!
                Self.test_cond(
                    # arg
                    x
                )
            ),

            # hoho
            24
        )
Esempio n. 3
0
    def name_parent():
        """
        Assuming this node can define a named environment, return the syntactic
        parent node that defines the parent scope for Self. If there is no such
        node (because Self is in the root list), return null.
        """
        return If(
            Self.parent.is_null
            | Not(Self.parent.is_a(T.FooNode.list))
            | Self.parent.parent.is_null
            | Not(Self.parent.parent.is_a(T.DeclarativePart))
            | Self.parent.parent.parent.is_null,
            No(T.FooNode),

            # All nodes that can define a named environment are supposed to
            # live in lists (Self.parent is a list), so Self.parent.parent is
            # supposed to be a declarative part, and finally Self.parent.parent
            # gets the node that owns that declarative part.
            Let(
                lambda owner=Self.parent.parent.parent:
                If(
                    owner.is_a(
                        T.PackageDecl, T.PackageBody, T.SubpDecl, T.SubpBody,
                        T.SubpBodyDecls, T.PublicPart, T.PrivatePart
                    ),
                    owner.match(
                        lambda pp=T.PublicPart: pp.parent,
                        lambda pp=T.PrivatePart: pp.parent,
                        lambda n: n,
                    ),
                    No(T.FooNode),
                )
            )
        )
Esempio n. 4
0
 def get_rebindings(inverse=T.Bool):
     example_nodes = Var(Self.parent.cast(T.Example.list).as_array)
     n1 = Var(example_nodes.at(If(inverse, 1, 2)))
     n2 = Var(example_nodes.at(If(inverse, 2, 1)))
     return No(T.EnvRebindings).append_rebinding(
         n1.children_env,
         n2.children_env,
     )
Esempio n. 5
0
 def binding_name():
     """
     Return the binding name associated with this selector call, if any.
     """
     return If(Self.binding.is_null,
               String(""),
               Self.binding.text)
Esempio n. 6
0
class FooNode(ASTNode):
    pred = Property(True)

    foo_1 = Property(
        If(Self.pred, No(T.BarNode), No(T.Literal)).as_bare_entity,
        public=True
    )
 def quantifier_name():
     """
     Return the selector's quantifier name.
     If the name hasn't been explicitly specified, the default quantifier
     name is 'all'.
     """
     return If(Self.quantifier.is_null, String("all"), Self.quantifier.text)
Esempio n. 8
0
 def contains_chained():
     """
     Return whether this pattern contains a value part
     that is a chained pattern.
     """
     return If(Self.value_part.is_null, False,
               Self.value_part.is_a(ChainedNodePattern))
Esempio n. 9
0
def get_value(self, logic_var):
    """
    Extract the value out of a logic variable. The returned type is always the
    root entity type. If the variable is not defined, return a null entity.

    :param AbstractExpression logic_var: The logic var from which we want to
        extract the value.
    """
    from langkit.expressions import If

    PropertyDef.get()._gets_logic_var_value = True

    rtype = T.root_node.entity

    logic_var_expr = construct(logic_var, T.LogicVarType)
    logic_var_ref = logic_var_expr.create_result_var('Logic_Var_Value')

    return If.Expr(cond=CallExpr('Is_Logic_Var_Defined',
                                 'Eq_Node.Refs.Is_Defined', T.BoolType,
                                 [logic_var_expr]),
                   then=CallExpr('Eq_Solution', 'Eq_Node.Refs.Get_Value',
                                 rtype, [logic_var_ref]),
                   else_then=NullExpr(T.root_node.entity),
                   rtype=rtype,
                   abstract_expr=self)
Esempio n. 10
0
 def body_decl_scope():
     """
     Assuming this PackageBody is not in the top-level list, return the
     environment of its PackageDecl that it should reference.
     """
     pkg_decl = Var(Self.lookup_decl_part)
     return If(pkg_decl.private_part.is_null, pkg_decl.children_env,
               pkg_decl.private_part.children_env)
Esempio n. 11
0
    def new_env_names():
        """
        Return the names for the environment that this package creates.
        """
        # Always register the "regular" name for this package
        result = Self.full_name

        # If there is a private part, that's all we need. Otherwise, register
        # this environment with the name of the private part as well, so that
        # package bodies can assume there is always a private part.
        return If(
            result.length == 0, No(T.Symbol.array),
            If(
                Self.private_part.is_null,
                [result, result.concat(String('.__privatepart'))],
                [result],
            ).map(lambda s: s.to_symbol))
Esempio n. 12
0
 def min_depth_expr():
     """
     If the 'min_depth' arg is set and 'depth" is not set, return the
     expression for 'min_depth'. If 'depth' is set return its expression.
     If neither 'depth' or 'min_depth' is set, return a null expression.
     """
     return If(Self.depth_expr.is_null,
               Self.expr_for_arg(String('min_depth')), Self.depth_expr)
Esempio n. 13
0
 def resolve(lhs=T.FooNode.entity, rhs=T.FooNode.entity):
     eq = Var(
         All([
             NPropagate(Self.v, T.Literal.combiner, Self.lhs.v, Self.rhs.v),
             Bind(Self.lhs.v, lhs),
             Bind(Self.rhs.v, rhs),
         ]))
     return If(eq.solve, Self.v.get_value,
               PropertyError(T.FooNode.entity, "unreachable"))
Esempio n. 14
0
class Scope(Def):
    error = Field()
    name = Field()
    defs = Field()

    env_spec = EnvSpec(
        add_to_env(New(T.env_assoc, key=Self.name.symbol, val=Self)),
        add_env(),
        do(If(Self.error.as_bool, PropertyError(T.FooNode), No(T.FooNode))),
    )
Esempio n. 15
0
 def construct(self):
     from langkit.expressions import If, IsNull, EmptyArray
     expr = construct(self.expr)
     ret = CollectionSingleton.Expr(expr)
     if self.coerce_null:
         return If.Expr(IsNull.construct_static(expr),
                        EmptyArray.construct_static(expr.type.array_type()),
                        ret, ret.type)
     else:
         return ret
Esempio n. 16
0
 def get_initial_env():
     """
     Assuming this PackageBody cannot define a named environment, return the
     environment in which this declaration should be registered.
     """
     pkg_decl = Var(
         Self.parent.children_env.get_first(
             Self.name.base_name.to_symbol).cast(T.PackageDecl))
     return If(pkg_decl.private_part.is_null, pkg_decl.children_env,
               pkg_decl.private_part.children_env)
Esempio n. 17
0
 def decl_parent_scope_name():
     """
     If this node can define a named environment (see ``can_have_name``),
     return the name of its parent scope. Return a null symbol otherwise.
     """
     return If(
         Self.can_have_name,
         Self.name_parent.then(
             lambda np: np.full_name,
             default_val=Self.self_name.parent_scope_name,
         ).to_symbol, No(T.Symbol))
Esempio n. 18
0
class PackageDecl(FooNode):
    name = Field(type=T.Name)
    public_part = Field(type=T.PublicPart)
    private_part = Field(type=T.PrivatePart)

    @langkit_property(return_type=T.Name)
    def self_name():
        return Self.name

    @langkit_property(return_type=T.Symbol.array)
    def new_env_names():
        """
        Return the names for the environment that this package creates.
        """
        # Always register the "regular" name for this package
        result = Self.full_name

        # If there is a private part, that's all we need. Otherwise, register
        # this environment with the name of the private part as well, so that
        # package bodies can assume there is always a private part.
        return If(
            result.length == 0,
            No(T.Symbol.array),

            If(
                Self.private_part.is_null,
                [result, result.concat(String('.__privatepart'))],
                [result],
            ).map(lambda s: s.to_symbol)
        )

    env_spec = EnvSpec(
        set_initial_env_by_name(
            If(
                Self.is_toplevel,
                Self.decl_parent_scope_name,
                No(T.Symbol),
            ),
            Self.parent.children_env
        ),
        add_to_env_kv(Self.name.base_name.to_symbol, Self),
        add_env(names=Self.new_env_names)
    )

    @langkit_property(return_type=T.PackageBody.entity, public=True)
    def body_part():
        """
        Return the PackageBody node corresponding to this PackageDecl.
        """
        return Self.private_part.then(
            lambda pp: pp,
            default_val=Self,
        ).children_env.get_first('__nextpart').cast(T.PackageBody)
Esempio n. 19
0
class SubpBodyDecls(DeclarativePart):
    """
    Top-level list of declaration in a subprogam body.
    """
    env_spec = EnvSpec(
        # The only case where we need a declarative part to have a name is when
        # it is top-level in subprogram body (A), so that separate subprogram
        # bodies (B) can use this environment as their initial env. Note that
        # this case is legal only when that (A) is the syntactic root.
        add_env(names=If(
            Self.parent.is_a(T.SubpBody) & Self.parent.parent.is_null,
            [Self.parent.cast(T.SubpBody).name.scope_name.to_symbol],
            No(T.Symbol.array),
        )))
Esempio n. 20
0
def make_as_entity(node_expr,
                   entity_info=None,
                   null_check=True,
                   abstract_expr=None):
    """
    Helper for as_entity. Takes a resolved expression instead of an abstract
    one.

    :param ResolvedExpression node_expr: The AST node expression to wrap as an
        entity.
    :param ResolvedExpression|None entity_info: Expression to use as the entity
        information. If provided, its type must be T.entity_info. Otherwise,
        the ambient entity info is used.
    """
    from langkit.expressions import If, IsNull, New

    entity_type = node_expr.type.entity

    # If we use the ambient entity info, make the current property an entity
    # one.
    if entity_info is None:
        p = PropertyDef.get()
        p.set_uses_entity_info()
        entity_info = construct(p.entity_info_arg)

    # Expression tree sharing is forbidden, so if we need to reference the
    # result of the input node expression multiple times, create a variable to
    # hold the input node.
    node_ref = (node_expr.create_result_var('Node_For_Entity')
                if null_check else node_expr)

    entity_expr = New.StructExpr(
        entity_type,
        {
            names.Name('El'): node_ref,
            names.Name('Info'): entity_info
        },
        result_var_name=names.Name.from_lower('as_entity'),
    )

    result = If.Expr(
        IsNull.construct_static(node_expr),
        NullExpr(entity_type),
        entity_expr,
        entity_type,
        abstract_expr=abstract_expr) if null_check else entity_expr

    result.abstract_expr = abstract_expr
    return result
Esempio n. 21
0
    def can_have_name():
        """
        Return whether this node can define a named environment.
        """
        return If(
            Self.is_a(PackageDecl, PackageBody, SubpDecl, SubpBody,
                      SubpBodyDecls, PublicPart, PrivatePart),

            # All nodes that can define a named environment are supposed to
            # live in lists, so use Self.parent.parent to get the node that
            # owns that list.
            Self.parent.is_a(T.FooNode.list)
            & (Self.parent.parent.is_null | Self.parent.parent.can_have_name),
            False,
        )
Esempio n. 22
0
    def construct(self):
        from langkit.expressions import If, IsNull, ArrayLiteral

        expr = construct(self.expr)
        expr_var = expr.create_result_var('To_Array_Prefix')

        # Use "expr" only for first evaluation, and then use expr_var to refer
        # to the result. We do this to avoid resolved expression sharing in the
        # expression tree.
        ret = CollectionSingleton.Expr(expr_var if self.coerce_null else expr)
        if self.coerce_null:
            return If.Expr(IsNull.construct_static(expr),
                           ArrayLiteral.construct_static([], expr.type.array),
                           ret, ret.type)
        else:
            return ret
Esempio n. 23
0
 def expr_for_arg(name=T.String):
     return Let(
         lambda x=Self.args.find(lambda a: a.arg_name.text == name):
         If(x.is_null, No(Expr), x.expr)
     )
Esempio n. 24
0
 def foo():
     return If(True, Self, Self).then(lambda s: s).as_bare_entity
Esempio n. 25
0
 def test_prop(numbers=T.Int.array, c=T.String):
     return If(c == String("one"), numbers.at(0), numbers.at(1))
Esempio n. 26
0
 def recurse(n=Int):
     return If(n <= 1, n, Self.recurse(n - 1))
Esempio n. 27
0
 def node_for_env():
     return If(Self.create_synthetic.as_bool, New(T.DummySyntheticNode),
               Self)
Esempio n. 28
0
 def evaluate():
     return BigIntLiteral(If(Self.left.evaluate < Self.right.evaluate, 1,
                             0))
Esempio n. 29
0
class PackageBody(FooNode):
    name = Field(type=T.Name)
    decls = Field(type=T.DeclarativePart)

    @langkit_property(return_type=T.Name)
    def self_name():
        return Self.name

    @langkit_property(return_type=T.LexicalEnv)
    def body_decl_scope():
        """
        Assuming this PackageBody is not in the top-level list, return the
        environment of its PackageDecl that it should reference.
        """
        pkg_decl = Var(Self.lookup_decl_part)
        return If(
            pkg_decl.private_part.is_null,
            pkg_decl.children_env,
            pkg_decl.private_part.children_env
        )

    @langkit_property(return_type=T.PackageDecl)
    def lookup_decl_part():
        """
        Assuming this PackageBody is not in the top-level list, return the
        the corresponding package declaration.
        """
        return (
            Self.parent.children_env.get_first(Self.name.base_name.to_symbol)
            .cast(T.PackageDecl).node
        )

    env_spec = EnvSpec(
        # The initial environment for package bodies is the private part of the
        # corresponding package specs (or the public part if there is no
        # private part).
        set_initial_env_by_name(
            If(
                Self.is_toplevel,
                Self.suffixed_full_name(String('__privatepart')).to_symbol,
                No(T.Symbol),
            ),
            Self.parent.children_env,
        ),

        add_to_env_by_name(
            '__nextpart',
            Self,
            If(Self.can_have_name,
               Self.suffixed_full_name(String('__privatepart')).to_symbol,
               No(T.Symbol)),
            Self.body_decl_scope,
        ),

        add_env(names=[Self.suffixed_full_name(String('__body')).to_symbol]),

        reference(
            Self.cast(FooNode).singleton,
            through=T.PackageBody.body_decl_scope,
            cond=Not(Self.is_toplevel),
            kind=RefKind.prioritary,
        ),
    )

    @langkit_property(return_type=T.PackageDecl.entity, public=True)
    def decl_part():
        """
        Return the PackageDecl node corresponding to this PackageBody.
        """
        env = Var(Self.parent.children_env)
        return Self.name.resolve(env).cast(T.PackageDecl)
Esempio n. 30
0
 def me(b=Bool):
     return FooNodeStruct.new(node=If(b, Entity, No(FooNode.entity)))