import lexer_example
@with_lexer(foo_lexer)
grammar foo_grammar {
    @main_rule main_rule <- list+(block)
    name <- Name(@identifier)
    block <- Block(
        name decl_list "{" using_list ref_list "}"
    )
    decl_list <- pick("(" list*(decl) ")")
    using_list <- pick("(" list*(using) ")")
    ref_list <- list*(ref)
    decl <- Decl(name)
    using <- Using(name)
    ref <- Ref(name)

}

@abstract class FooNode : Node {
}

class Block : FooNode {
    @parse_field name : Name
    @parse_field decls : ASTList[Decl]
    @parse_field usings : ASTList[Using]
    @parse_field refs : ASTList[Ref]
}

class Decl : FooNode {
    @parse_field name : Name
}

class Name : FooNode implements TokenNode {

    fun ambiant_entity (): FooNode = env.get(node)?(0)

    fun designated_env (): LexicalEnv =
    node.unit().root.node_env().get(node)?(0).children_env()

    @export fun entity (): FooNode = {
        bind env = node.node_env();

        node.ambiant_entity()
    }
}

class Ref : FooNode {
    @parse_field name : Name

    @export fun entity (): FooNode = node.as_entity.name.entity()
}

class Using : FooNode {
    @parse_field name : Name
}
