def resolved_arguments(called_fn=BaseFunction.entity):
     """
     Return the arguments of this call (default arguments included)
     as named arguments.
     """
     return Let(lambda call_args=Self.as_entity.call_args(called_fn): Let(
         lambda default_args=called_fn.default_parameters(
         ).filter(lambda p: dsl_expr.Not(
             call_args.any(lambda e: e.name().text == p.name())
         )).map(lambda param: SynthNamedArg.new(
             arg_name=param.param_identifier.node,
             value_expr=param.default_expr.node).cast(NamedArg).as_entity
                ): call_args.concat(default_args)))
Esempio n. 2
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. 3
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. 4
0
 def test_dotexpr_lhs():
     """
     Test various valid dotexpr's LHS.
     """
     a = Var(ArrayLiteral([1]).find(lambda v: v == 1))
     b = Var(Let(lambda b=[1, 2]: b).find(lambda v: v == 1))
     c = Var(String("hello").find(lambda c: c == Char('h')))
     ignore(b)
     ignore(c)
     return a
Esempio n. 5
0
class Literal(FooNode):
    token_node = True

    a = AbstractProperty(runtime_check=True, type=FooNode.entity)
    var = UserField(LogicVar, public=False)

    b = Property(Bind(Self.var, Self.a))

    public_prop = Property(Let(lambda _=Self.b: Self.as_bare_entity),
                           public=True)
Esempio n. 6
0
 def test_let():
     # let it go!!!
     return Let(
         # where is this comment?
         lambda
         # define x
         x=42,
         # define y
         y=24:
         # compute
         x + y
     )
Esempio n. 7
0
 def prop():
     return Let(lambda _=Self.foo(1): Self.foo(2))
Esempio n. 8
0
 def public_pro():
     return Let(lambda _=Self.b: Self.as_bare_entity)
Esempio n. 9
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. 10
0
class BarNode(FooNode):
    prop = Property(Let(lambda _=Self.parent: No(FooNode)))
Esempio n. 11
0
 def unused_let_var():
     return Let(lambda ex_list=Self.items: Self.items.as_bare_entity)
Esempio n. 12
0
        def __init__(self, prefix_expr, matchers, abstract_expr=None):
            """
            :param ResolvedExpression prefix_expr: The expression on which the
                dispatch occurs. It must be either an AST node or an entity.
            :param list[Match.Matcher] matchers: List of matchers for this
                node.
            """
            assert (prefix_expr.type.is_ast_node
                    or prefix_expr.type.is_entity_type)
            self.prefix_expr = NullCheckExpr(
                prefix_expr, implicit_deref=prefix_expr.type.is_entity_type)

            # Variable to hold the value of which we do dispatching
            # (prefix_expr).
            self.prefix_var = PropertyDef.get().vars.create(
                'Match_Prefix', self.prefix_expr.type)

            # Compute the return type as the unification of all branches
            rtype = matchers[-1].match_expr.type
            for m in matchers:
                rtype = m.match_expr.type.unify(
                    rtype,
                    'Mismatching types in Match expression: got {self} but'
                    ' expected {other} or sub/supertype')
            self.static_type = rtype

            # Wrap each matcher expression so that all capture variables are
            # bound and initialized.
            self.matchers = []
            for m in matchers:
                # Initialize match_var. Note that assuming the code generation
                # is bug-free, this cast cannot fail, so don't generate type
                # check boilerplate.
                let_expr = Let.Expr(
                    [m.match_var],
                    [
                        Cast.Expr(self.prefix_var.ref_expr,
                                  m.match_var.type,
                                  unsafe=True)
                    ],

                    # ... and cast this matcher's result to the Match result's
                    # type, as required by OOP with access types in Ada.
                    (m.match_expr if m.match_expr.type == rtype else Cast.Expr(
                        m.match_expr, rtype)))

                # Now do the binding for static analysis and debugging
                self.matchers.append(
                    Match.Matcher(
                        m.match_var,
                        BindingScope(let_expr, [], scope=m.inner_scope),
                        m.inner_scope))

            # Determine for each matcher the set of concrete AST nodes it can
            # actually match.
            prefix_type = self.prefix_expr.type
            if prefix_type.is_entity_type:
                prefix_type = prefix_type.element_type
            matched_types, remainder = collapse_concrete_nodes(
                (prefix_type.element_type if prefix_type.is_entity_type else
                 prefix_type), [m.match_astnode_type for m in self.matchers])
            assert not remainder
            for matcher, matched in zip(self.matchers, matched_types):
                matcher.matched_concrete_nodes = matched

            super(Match.Expr, self).__init__('Match_Result',
                                             abstract_expr=abstract_expr)
Esempio n. 13
0
from langkit.expressions import Let, Literal, Property

from utils import emit_and_print_errors


def run(name, expr):
    """
    Emit and print the errors we get for the below grammar with "expr" as
    a property in ExampleNode.
    """

    global Compound, Expression, FooNode, NullNode, Number

    print('== {} =='.format(name))

    class FooNode(ASTNode):
        pass

    class BarNode(FooNode):
        prop = Property(expr, public=True)

    emit_and_print_errors(lkt_file='foo.lkt')
    print('')


run("Correct code", lambda: Let(lambda a=Literal(1): a))
run("Missing var value", lambda: Let(lambda a: a))
run("Invalid args", lambda: Let(lambda a=Literal(1), *b, **c: a))

print('Done')
Esempio n. 14
0
 def test_control_flow(i=T.Int):
     nodes = Var(Self.parent.children)
     arr = Var(
         nodes.map(lambda n: n.parents().length + Let(
             lambda item=n.children: Self.control_flow_helper(item))))
     return i + arr.length
Esempio n. 15
0
class BarNode(FooNode):
    prop = Property(Let(lambda _=Self.parent: No(FooNode.entity)), public=True)
Esempio n. 16
0
 def unused_let_var():
     return Let(lambda ex_list=Self.items: Self.items)