Hey,
I asked myself this question a couple of times and came up with a solution for that feels very dirty. Maybe you can give me any advice since I think this is a basic problem for every DSL written in Scala.
I want to have a hierarchical structure of nested objects without adding any extra syntax. Specs is a good example for this:
MySpec extends Specification {
"system" should {
"example0" in { ... }
"example1" in { ... }
"example2" in { ... }
}
"system" can {
"example0" in { ... }
}
}
For instance I do not have to write "example0" in { ... } :: "example1" in { ... } :: "example2" in { ... } :: Nil
.
This is exactly the same behaviour I would like to have. I think this is achieved by an implicit definition in the Specification class in Specs like (please do not be offended if you are the Specs author and I missunderstood something :))
implicit def sus2spec(sus: Sus): Specification = {
suslist += sus
this
}
My main problem arises now when I want to nest such objects. Imagine I have this grammar:
root: statement*;
statement:
IDENT '{' statement* '}'
| declaration*
;
declaration: IDENT ':=' INT+;
I would like to translate this into a DSL that looks like this:
MyRoot extends Root {
"statement0" is {
"nested_statement0" is {
"nested_nested_statement0" is {
"declaration0" := 0
}
"declaration1" := 1
"declaration2" := 2
}
"declaration3" := 3
}
"statement1" is {
"declaration4" := 4
}
}
The problem that arises here is for me that the implicit solution does not work. The implicit definition would be executed in the scope of the root object which means I would add all objects to the root and the hierarchy is lost.
Then I thought I can use something like a Stack[Statement]. I could push an object to it for every call to is
but that feels very dirty.
To put the question in one sentence: How do I create a recursive DSL wich respect to its hierarchy without adding any extra syntax and is there a solution to do this with immutable objects only?