State Machine Compilation
I've mentioned a few times before that I'm always a little surprised that I don't see more developers writing code as state machines. A lot of embedded systems really lend themselves to state machine descriptions and, as I've demonstrated before (click here and here), it is easy to write some simple tools to handle state machines.
This week I ran into a SourceForge project called SMC or the State Machine Compiler. It allows you to describe your state machine more in a simple language (it reminds me a little of writing yacc grammars) and then compile it into code suitable for different target languages. Although the compiler itself uses Java, it can emit code for C++, C#, Objective C, and even C. It also can handle Python, Ruby, Lua, and a handful of other languages including, of course, Java and JavaScript.
I haven't tried the program on a real project yet, but it seems pretty easy to use. Here's an example from one of the getting started tutorials:
%class Turnstile
%package turnstile
%start MainMap::Locked
%map MainMap
%%
Locked
{
coin Unlocked { unlock(); }
pass nil { alarm(); }
}
Unlocked
{
Pass Locked { lock(); }
coin nil { thankyou(); }
}
%%
You can probably puzzle this out. It represents a simple state machine for a turnstile. The %class statement tells the compiler what the name of the class is that you will provide (it creates some classes based on this name, too).
The turnstile starts in the locked state. If a coin appears, it unlocks the gate (the unlock() action) and moves to the Unlocked state. If someone passes through while it is locked, no state change occurs (nil), but an alarm sounds.
When the turnstile is unlocked, someone passing will cause the turnstile to lock again. A new coin calls thankyou().
You specify the target language when you compile. Here's a line I used to compile the above source:
java –jar bin/Smc.jar –java –d ddj ddj/turn.sm
The –java argument would change, of course, if I were using a different language. I won't reproduce the compiler output here (you can download it online) but it created a class named turnContext. There is also an abstract class called TurnstileState. The context object accepts calls that indicate events (like the coin and pass events). It, in turn, calls back to its owner to implement any actions.
That means in your code, you have to instantiate a context and call the event functions as needed. You also implement the actions, usually in the same class.
The documentation touts that you can write one state machine and compile it for many different languages. I'm sure that is somewhat true, but I did notice that a C++ compile needed a statement (%header) that the Java code didn't require. Of course, the output code for each language is different. I compiled for C and — naturally — there are no classes in C, so you wind up with lots of global functions and #defines (along with a header).
Are you using state machines in your designs? Do you use a tool and if not, would you use something like SMC? I haven't answered that last question myself yet, but I'll let you know.

