예제 #1
0
class FooNode(ASTNode):
    pred = Property(True)

    foo_1 = Property(
        If(Self.pred, No(T.BarNode), No(T.Literal)).as_bare_entity,
        public=True
    )
예제 #2
0
파일: test.py 프로젝트: leogermond/langkit
    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),
                )
            )
        )
예제 #3
0
    def rebind(from_node=T.FooNode.entity, to_node=T.FooNode.entity):

        # Build non-null rebindings
        rbdng = Var(No(T.EnvRebindings).append_rebinding(
            from_node.children_env,
            to_node.children_env
        ))

        # Call rebind_env on them (this is the important part, the rest is
        # cosmetic).
        return No(T.LexicalEnv).rebind_env(rbdng).get("foo")
예제 #4
0
파일: test.py 프로젝트: leogermond/langkit
class FunDecl(FooNode):
    name = Field(type=T.Identifier)
    args = Field(type=T.ArgSpec.list)

    env_spec = EnvSpec(
        add_to_env(
            T.env_assoc.new(
                key=Self.name.symbol,
                val=Self,
                dest_env=No(T.LexicalEnv),
                metadata=No(T.Metadata),
            )))
예제 #5
0
파일: test.py 프로젝트: leogermond/langkit
class ConsDecl(FooNode):
    name = Field(type=T.Identifier)
    cons_expr = Field(type=T.Expr)

    env_spec = EnvSpec(
        add_to_env(
            T.env_assoc.new(
                key=Self.name.symbol,
                val=Self,
                dest_env=No(T.LexicalEnv),
                metadata=No(T.Metadata),
            )))
예제 #6
0
class FooNode(ASTNode):
    null_unit = Property(No(AnalysisUnit), public=True)
    null_node = Property(No(T.Expression.entity), public=True)

    deref_null_unit = Property(Self.null_unit.root.as_bare_entity, public=True)
    deref_null_node = Property(Self.null_node.null_node, public=True)
    null_node_unit = Property(Self.null_node.unit, public=True)

    cast_null_node = Property(Self.null_node.cast(T.Name), public=True)

    match_null_node = Property(
        Self.null_node.node.match(lambda l=T.Literal: l,
                                  lambda n=T.Name: n,
                                  lambda others: others).as_bare_entity,
        public=True)
예제 #7
0
 def arg_exprs_assocs_getter():
     """
     For each argument, associate its name to its default expression.
     """
     decl = Var(Self.node_env.get_first(Self.name).cast(T.FunDecl))
     return decl.args.map(lambda a: T.inner_env_assoc.new(
         key=a.name.symbol, value=a.arg_expr.node, metadata=No(T.env_md)))
예제 #8
0
파일: test.py 프로젝트: pmderodat/langkit
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),
            ))),
    )
예제 #9
0
    def test_arrays():
        empty = Var(No(T.Example.array))
        single = Var(ArrayLiteral([Self.cast(Example)]))
        complete = Var(Self.parent.cast(T.Example.list).as_array)

        arr = Var(empty.concat(single).concat(complete))
        return arr.length  # BREAK:test_arrays
예제 #10
0
파일: test.py 프로젝트: shintakezou/langkit
 def get_entity(md=Metadata):
     return New(Couple.entity,
                node=Self,
                info=New(T.entity_info,
                         md=md,
                         rebindings=No(EnvRebindings),
                         from_rebound=False))
예제 #11
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,
     )
예제 #12
0
    def find_atoms():
        return Entity.match(
            # This should match Lit .. Ref
            lambda a=T.Atom: a.singleton,

            # This should match Def | Plus .. FooNode.list
            lambda _: No(T.Atom.entity.array),
        ).concat(Entity.children.mapcat(lambda c: c.find_atoms))
예제 #13
0
 def args_assocs_getter():
     """
     For each argument, associate its name to the expression passed in this
     call.
     """
     decl = Var(Self.node_env.get_first(Self.name).cast(T.FunDecl))
     return decl.args.map(lambda i, a: T.inner_env_assoc.new(
         key=a.name.symbol, value=Self.args.at(i), metadata=No(T.env_md)))
예제 #14
0
class RegularBlock(FooNode):
    id = Field(type=T.Identifier)

    env_spec = EnvSpec(
        set_initial_env_by_name(Self.id.symbol, No(T.LexicalEnv)))

    @lazy_field(public=True)
    def synth():
        return T.SynthNode.new(id=Self.id)
예제 #15
0
 def test_struct_iterator():
     val = Var(TestStruct.new(
         count=2,
         nodes=[No(Example.entity), Entity],
     ))
     itr = Var(
         ArrayLiteral([val, val], element_type=TestStruct).to_iterator)
     return ArrayLiteral([itr, itr],
                         element_type=T.TestStruct.iterator).to_iterator
예제 #16
0
파일: test.py 프로젝트: leogermond/langkit
 def parent_scope_name():
     """
     Absolute name of the scope that defines this name, assuming that
     ``prefix`` is the implicit prefix for that name.
     """
     return Self.match(
         lambda _=Identifier: No(T.String),
         lambda dn=DottedName: dn.prefix.scope_name,
     )
예제 #17
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))),
    )
예제 #18
0
파일: test.py 프로젝트: pmderodat/langkit
    def rebind():
        left_env = Var(Self.left.children_env)
        right_env = Var(Self.right.children_env)

        # Depending on whether "left_env" is rebindable, the following will
        # succeed or raise a PropertyError. The status of "right_env" does not
        # matter.
        r = Var(No(T.EnvRebindings).append_rebinding(left_env, right_env))

        return Self.children_env.rebind_env(r).env_node
예제 #19
0
class Def(FooNode):
    name = Field(type=T.Name)
    ref = Field(type=T.Name)

    env_spec = EnvSpec(
        add_to_env(mappings=New(T.env_assoc, key=Self.name.sym, val=Self),
                   metadata=New(Metadata,
                                node=Self.ref.then(lambda r: r.resolve.node,
                                                   default_val=No(
                                                       T.FooNode)))))
예제 #20
0
파일: test.py 프로젝트: shintakezou/langkit
class Literal(Expression):
    token_node = True

    # This one is private, but it is called by "evaluate" so it's not usused
    result = ExternalProperty(uses_entity_info=False, uses_envs=False)

    # See Expression.name
    names = Property(No(T.Name.array))

    evaluate = Property(Self.result, public=True)
예제 #21
0
파일: test.py 프로젝트: Tubbz-alt/langkit
 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))
예제 #22
0
    def find_atoms_or_exprs():
        return Entity.match(
            # This should match Lit .. Ref
            lambda a=T.Atom: a.cast(T.Expr).singleton,

            # This should match the only remaining expression: Plus
            lambda e=T.Expr: e.singleton,

            # This should match Def | FooNode.list
            lambda _: No(T.Expr.entity.array),
        ).concat(Entity.children.mapcat(lambda c: c.find_atoms_or_exprs))
예제 #23
0
파일: test.py 프로젝트: leogermond/langkit
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)
예제 #24
0
    def find_exprs():
        return Entity.match(
            # This should match Lit .. Plus
            lambda e=T.Expr: e.singleton,

            # This should match nothing (Atom is an Expr subclass), so emit a
            # warning.
            lambda a=T.Atom: a.cast(T.Expr).singleton,

            # This should match Def | FooNode.list
            lambda _: No(T.Expr.entity.array),
        ).concat(Entity.children.mapcat(lambda c: c.find_exprs))
예제 #25
0
파일: test.py 프로젝트: pmderodat/langkit
class Example(BaseExample):

    fld_2 = NullField()
    fld_1 = Field()

    @langkit_property()
    def to_public(p=T.PrivatePoint):
        return Point.new(label=String("from private"), x=p.x, y=p.y)

    @langkit_property(public=True)
    def prop(p=T.Point):
        return Self.to_public(PrivatePoint.new(x=p.x, y=p.y))

    @langkit_property(public=True)
    def result():
        return T.NodeResult.new(n=Self, e=Entity)

    # Test for primitive types
    id_bool = Property(lambda id=T.Bool: id, public=True)
    id_int = Property(lambda id=T.Int: id, public=True)
    id_bigint = Property(lambda id=T.BigInt: id, public=True)
    id_char = Property(lambda id=T.Character: id, public=True)
    id_token = Property(lambda id=T.Token: id, public=True)
    id_sym = Property(lambda id=T.Symbol: id, public=True)
    id_unit = Property(lambda id=T.AnalysisUnit: id, public=True)
    id_root_node = Property(lambda id=T.FooNode: id, public=True)
    id_name = Property(lambda id=T.Name: id, public=True)

    # Test for enums
    id_unit_kind = Property(lambda id=T.AnalysisUnitKind: id, public=True)

    # Test for arrays
    id_node_array = Property(lambda id=T.FooNode.entity.array: id, public=True)
    id_expr_array = Property(lambda id=T.Expr.entity.array: id, public=True)
    id_bigint_array = Property(lambda id=T.BigInt.array: id, public=True)
    id_unit_array = Property(lambda id=T.AnalysisUnit.array: id, public=True)

    # Test for iterators
    create_bigint_iterator = Property(
        ArrayLiteral([BigIntLiteral(1), BigIntLiteral(2), BigIntLiteral(3)])
        .to_iterator,
        public=True
    )
    id_bigint_iterator = Property(lambda id=T.BigInt.iterator: id, public=True)

    # Test for default values
    id_dflt_bool = Property(lambda id=(T.Bool, True): id, public=True)
    id_dflt_int = Property(lambda id=(T.Int, 42): id, public=True)
    id_dflt_char = Property(
        lambda id=(T.Character, CharacterLiteral('\x00')): id,
        public=True)
    id_dflt_root_node = Property(lambda id=(T.FooNode, No(T.FooNode)): id,
                                 public=True)
예제 #26
0
    def find_refs():
        return Entity.match(
            # This should match Ref
            lambda r=T.Ref: r.singleton,

            # This should match Lit
            lambda _: No(T.Ref.entity.array),

            # ... and we should not get CASE coverage errors in generated code,
            # even though we did not cover all possible FooNode kinds.
        ).concat(
            Entity.children.mapcat(
                lambda c: c.cast_or_raise(T.Expr).find_refs))
예제 #27
0
    def test_rebindings():
        null = Var(No(T.EnvRebindings))
        r1 = Var(Self.get_rebindings(False))
        r2 = Var(Self.get_rebindings(True))
        concat = Var(r1.concat_rebindings(r2))

        arr = Var(ArrayLiteral([
            null,
            r1,
            r2,
            concat,
        ]))
        return arr.length  # BREAK:test_rebindings
예제 #28
0
class SingleParam(PythonNode):
    is_varargs = Field(type=T.VarArgsFlag)
    is_kwargs = Field(type=T.KwArgsFlag)
    name = Field(type=T.PythonNode)
    default_value = Field(type=T.Expr)

    env_spec = EnvSpec(
        add_to_env(
            Self.name.match(
                lambda i=T.Id: new_env_assoc(key=i.sym, val=Self).singleton,
                lambda l=T.Id.list: l.map(lambda i: new_env_assoc(key=i.sym,
                                                                  val=Self)),
                lambda _: No(T.env_assoc.array))))
예제 #29
0
파일: test.py 프로젝트: pmderodat/langkit
class Number(Expr):
    token_node = True

    @langkit_property(external=True, uses_entity_info=False, uses_envs=False)
    def eval():
        pass

    # Test for default values
    id_dflt_bool = Property(lambda id=(T.Bool, True): id, public=True)
    id_dflt_int = Property(lambda id=(T.Int, 42): id, public=True)
    id_dflt_char = Property(
        lambda id=(T.Character, CharacterLiteral('\x00')): id, public=True)
    id_dflt_root_node = Property(lambda id=(T.FooNode, No(T.FooNode)): id,
                                 public=True)
예제 #30
0
파일: test.py 프로젝트: Tubbz-alt/langkit
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),
        )))