Sunday, February 14, 2010

Meta Programming System: editor for Miss Grant's controller

I’ve been playing with MPS over the last couple months so I felt like I have to write something about it. Here is Martin Fowler’s introductory example from his upcoming book about DSLs.

If you haven’t read introductory example, it might be a good idea to take a look now because without it the following example won’t make much sense. I will also assume that you know basics of MPS and at least have read MPS tutorial.

What it’s going to be like in the end?

There will be nice editor for state machine language with text completion and syntax highlighting. The syntax will be close to Miss Grant’s Controller. Something like this:

(To be fair, there is already secretCompartmentLanguage bundled with MPS which is kind of the same thing. There are some differences between Martin Fowler’s example and secretCompartmentLanguage, though. In secretCompartmentLanguage there are no commands and states don’t have actions.)


Editors for StateMachine, Event and Command

First off, let’s create concepts for AST which will be used in editors. We have state machine which receives events, changes its state and sends commands. Here is the first version of StateMachine, Event, Command and State:








Note that all concepts implement INamedConcept interface and both Event and Command implement IHaveCode:


Now when we have concept let’s create editor for StateMachine:










After all the changes editor for StateMachine will look like this (note that cell collections for %event%, %command% and %state% are vertical):

Let’s create simple editors for Event and Command concepts…



… and this is it. On the whole editors will work like this:

After generating language …

… we’ll be able to create instance of StateMachine concept and actually use state machine editor:





Reset events for state machine

In his state machine Martin Fowler has notion of reset events. Events which return machine to its initial state. In terms of our language AST, reset events are just links (or references) to already defined events. Let’s add resetEvent reference to StateMachine concept:

Turns out that unlike child nodes, there can’t be references to multiple nodes (this is not conceptual problem, ”it’s just not implemented”). As a workaround let’s create EventRef concept which will hold one reference to Event. Then, we’ll be able to add several EventRefs as StateMachine children.



Because EventRef concept is different from Event, we’ll need new editor for EventRef which will show name of Event it references to:



After language generation …

… editor for state machine will look like this:

Editor for State concept

At the moment State concept is pretty much empty and doesn’t have editor:

In Martin Fowler’s example State have actions (commands which are send on state entry) and transitions (rules which say when state machine will change its state). Let’s add actions to the State concept. There are multiple actions and they reference to already defined commands so there is the same problem as with resetEvents. We have to create CommandRef concept:





Creating concept and editor for transition is pretty much straightforward:





Now we can create editor for the State and see how it works:





“Add Action” intention

When all the states from Miss Grant’s controller example are added, states declaration will look like this:

Unfortunately, some of the states don’t have any actions and empty actions statements add noise. Let’s add condition to hide actions statement if there are no actions to show.



After language generation all empty actions are gone:

This creates another problem. When new state is added, it doesn’t have any actions. Because of that actions statement is not shown and there is no way to add new actions. This is one of the downsides of editing AST directly. There is a good solution, though. We can use intention which will add empty actions.











Syntax highlighting

The last thing that’s left is syntax highlighting. It can be easily done with stylesheets. (Note that stylesheets are created in editor module.)



Now we can use this stylesheet in editors to attach different styles to different parts of state machine language.

After applying styles to all editors, the final result will look like this:

0 comments: