Multi file DSLs
While a DSL can really cut down the amount of code that you need to write, putting everything in one file is not a good idea. But I like my DSLs to be script like, without the need for an explicit compilation step. I have thought about it for a while now, and yesterday ago Craig Neuwirt* asked how it can be done using Binsor.
My default language is Boo, obviously, which is a static, compiled language that pretends that it is dynamic and scriptish, giving the best of all worlds. One of the cool things about Boo is that you can reference an assembly by just doing this:
import System.Data.SqlClient from System.Data
This make it very easy to write scripts, because you just declare things and they will be automatically referenced, without needing to pass parameters to the script runner.
Now, I wanted to have some way to handle file inclusion as well. But Boo doesn't support this. This is not something that you can do in a method, or dynamic loading, you have to do this as part of the compilation process.
In a normal language, I would be left with building pre-processors, or doing heuristics to find all the relevant files that I want, or write an XML file that would detail which file I want to include. But Boo is not a normal language, it is a Super Language. It let me do what I want. And I wanted to have file references.
So I did.
I love Boo, I really do. The initial sample I started with was this. This is actually on the examples, what do you know. Then I thought about how I wanted to it, and I figured out that I can do this:
import file from anotherFile.boo
Boo allows me to modify the compiler object model (AST) at compilation, so I just detect all the imports for the namespace "file", and then I compile and reference that file. I can even do this:
import file from "~/config/anotherFile.boo"
Where ~ is translated to the AppDomain BaseDirectory.
You can find the code here, about 100 lines of code, out of which around 30 could be YAGNIed away. Wasn't very hard, and make me love Boo all over again, for what it allows me to do.
* Who doesn't blog, and a search for "Craig Neuwirt blog" brings back my blog :-) (hint)