MPS provides a set of DSLs for defining DSLs. They DSLs are all extensions of a common base language called BaseLanguage :-), which is essentially Java. So in the same sense as mbeddr modularly extends C to enable embedded development, MPS modularly extends Java for efficiently defining DSLs.
And in the same way as mbeddr can be extended by users, MPS itself can be extended by users. MPS it built with itself (bootstrapped), so extending the MPS BaseLanguage is not different from extending any other language. Recently we have exploited this to build DSLs that make the implementation of our DSLs simpler. In this post we want to show a few examples (click on the code for bigger fonts).
The first example is a new expression that forms the basis for quickly writing model interpreters. It is called the dispatch expression. It takes an expression as an argument, and each case referes to a language concept. The right side of the case is executed if the expression is an instance of the language concept referenced on the left side of the case. What makes this expression so convenient is that there are two special, additional expressions that can be used on the right side of the arrow. The it expression refers to the expression passed into dispatch, but it is already downcast to the respective language concept. The # expression recursively calls the function in which the current dispatch resides. As you can see from the example code above, this makes for very compact interpreter code.
The second example is an extension of BaseLanguage that is used in defining the debug behavior for language extensions. As you can see in the getStepOverStrategy method above, the new statements can be used inside regular concept behavior methods. In fact, these new statements are restricted to be used only inside a few methods of the ISteppableContext interface, because they only make sense there. Using these statements, the definition of debug behavior can be done much more concisely.
The last example is the well-known builder. It supports construction of MPS “model trees” with a very convenient syntax. Note that this is a real language extension, not something built with closures and other meta programming facilities. As a consequence, the builder works with arbitrary structures (as long as they are MPS languages), it understands the structure of the to-be-built tree and provides code completion and static error checking regarding the structural correctness of the created tree.
Summing up, it is extremely useful to be able to extend the infrastructure you’re working with — it makes working with your own abstraction during language definition much simper. And the fact that MPS can be extended in the same way you use for extending other languages is just plain cool 🙂