SPL (State Programming Language)
I developed this (with help from others) while at
ObjectEngineeringInc.
The language was implemented as a seamless front-end to C - that is, statements and expressions of the new language (which we called
SPL - State Programming Language) had a syntax that was recognizable to C programmers. The state hierarchy was represented by literal nesting of "state" blocks. The language was implemented by a complete ANSI C preprocessor, plus a YACC grammar that included the entire C language plus the new state chart constructs. Here's how SPL code looked:
state ( ... state name and optional attributes ...)
{
oninit { ... code when state machine is initialized ... }
ondeinit { ... code when state machine is terminated ... }
onentry { ... code when state is entered ... }
onexit { ... code when state is exited ... }
state ( ... sub-state name and optional attributes )
{
...
}
}
We needed a way to trigger state transitions. Since at that tme there was no generally available
EventMechanism we had to invent one. The approach I took was to say that an event would be represented as a structured ASCII string. The structure consisted of an initial keyword (or actually, a key 'path' as in "Category/SubCategory/EventName") followed by any number of keyword/value pairs. I also defined representations for arrays. We developed a simple library for creating and 'broadcasting' such events.
In addition we wanted to be able to force state transitions based on timer expiration.
Both the event- and timer- triggers were built into the SPL syntax. For example,
OnEvent( ... syntax for event pattern matching ...)
{
... code for the event handler
}
OnTimer( ... syntax for setting a timer ...)
{
... code for the timer handler
}
By building these constructs into the language I was able to ensure that the generated code would automatically clear timers and event subscriptions on leaving the state where they were defined.
SPL was designed so that an application could contain any number of distinct state machines and there could be any number of
instances of a single state machine. I accomplished this by designing the event- and timer- mechanisms so that when an event was reported (via a callback), one of the parameters contained a tag that associated the event report with the original subscription request. When the event and timer mechanisms were used from with
SPL this tag mechanism was largely transparent. Each state machine instance was assigned a unique ID at the time it was initialized, and that ID was used as the tag.
The first implementation of SPL was on QNX 2 - a nice little real-time OS that could fit on a floppy disk. There was really no support for threads, so our basic rule was:
Never Block (
NonBlockingPattern?). That is, if a state machine made a blocking function call, the entire application would be blocked and so none of the state machines would be able to operate. It was actually quite easy to implement this rule - QNX recognized the need for non-blocking calls, and the external libraries that we used or developed also provided non-blocking / callback versions of all the functions that we required.
As a result we were able to get nearly all of the benefits of thread-based programming with none of the synchronization headaches. Each instance of each state machine
appeared to operate independently of the rest, as if it were running in its own thread. But in fact every state machine was running in the same thread. This was a great benefit - debugging was not difficult and there were few timing-related problems.
It took about 12 weeks to get SPL into its final form. We then began development of a lot of station controllers (about 40, if memory serves). We developed a set of SPL templates that captured the common elements across multiple station controllers. In some cases we were able to use the template without change in every station controller; in other cases we were able to define templates that applied to a 'class' of station controllers and that could be used without change for all station controllers of that class; and in other cases the template had to be modified somewhat in a case-by-case way. Anyway - the state chart model and the SPL implementation served us well.
--
DaleBrayden - 23 Jul 2002