An IDL for SCXML interpreters

Stefan Radomski <[email protected]> Fri, 3 Jul 2015 14:01:27 +0000
Newsgroups gmane.comp.web.voice
Message-ID <4C224481-448E-4EFA-A407-6E33F0CE59EF@tk.informatik.tu-darmstadt.de>
--_000_4C224481448E4EFAA4076E33F0CE59EFtkinformatiktudarmstadt_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hey there,

[explicitly bcc'ing David, Jacob and Zjnue for I know that they maintain SC=
XML implementations] - this post is pertaining to action point 1 from my pr=
evious mail:

1. An Interface Description Language (IDL) for SCXML interpreters.
1.1 For simple life-cycle and interpretation of state-charts.
1.2 A set of hooks for (on-line) visualisation.
1.3 A set of hooks for (on-line) modelling / debugging.

For now, I'd like to focus on point 1.1, but we ought to keep the others in=
 mind and maybe eventually extend our ambitions. At least 1.2 is very usefu=
l as it would allow or a common visualisation. I hereby propose a first ske=
tch for an Interface Description Language (IDL) for SCXML (see below). It w=
ill only allow to instantiate interpreters, run them and deliver events. A =
typical session would look like this:

import namespace scxml;
try {
Interpreter session =3D Implementation.fromURI("http://www.example.com/foo.=
scxml");
for(;;) {
int state =3D session.step();
if (state =3D=3D FINISHED)
break;
if (state =3D=3D AFTER_MACROSTEP && session.configuration.in('foo'))
session.receive('bar.baz');
}
} catch (Exception e) {
print e;
}

A couple of notes and possible variations:

=3D=3D 1. Threads
I want to avoid any assumptions about the availability of threads in the em=
bedding platform. As such, there is e.g. no non-blocking interpret(). It wo=
uld be the responsibility of the target platform to emulate something like =
this by embedding the block above in a thread.

=3D=3D 2. Exceptions
Similarly I want to avoid any assumption about the availability of exceptio=
ns, therefore step() might return FAULT and set the lastError attribute:

int state;
for(;;) {
state - session.step();
switch(state) {
case FAULT:
print session.lastError;
break;
case FINISHED:
return;
}
}

=3D=3D 3. Data
0. If nothing in a Data object is set, its value is undefined
1. If an atom is given, the respective field is to be interpreted as the ev=
aluation of that atom, e.g. "3" is a string, 3 is an integer.
2. If a node is given and 1. is not the case, the field is to be represente=
d as a DOM Node
3. If a key in a compound is set and 1. and 2. are not the case, the respec=
tive field is a map
4. If an index is set and none of the above applies, the respective field i=
s an array. Setting a an item at an index N will cause the array to behave =
as if it has N fields for the largest N. With all unset fields undefined.

=3D=3D 4. Event
Having most fields visible will allow for interpreters where all i/o proces=
sors are external by simply delivering respective Event entities via receiv=
e. The distinction between internal and external events ought to happen in =
receive(Event) itself depending on the event's type field. I am not sure if=
 we need the PLATFORM class though.

=3D=3D 5. Hibernating
We might want to include a way to serialise a complete interpreter and inst=
antiate it again from its serialised representation. I do know that Jacob w=
as working on a respective feature. We dropped our ambitions for now as mos=
t of the datamodels we employed via 3rd party libraries would not support s=
omething like that.

=3D=3D 6. Naming
AFTER_MACROSTEP might just as well be called STABLE. I choose the former fo=
r its more explicit reference to the runtime semantics of SCXML, which migh=
t play a role if we were to specify a bunch of hooks for 1.2 and 1.3 (see d=
ebugger paper[1], table 1)

=3D=3D 7. Events *from* the interpreter
While point 4 allows an embedding platform to send arbitrary events *into* =
the interpreter, maybe we ought to have something similar for everything <s=
end> from the interpreter?


Maybe anyone who is interested in pursuing the idea of this basic IDL could=
 speak up and comment about the proposal? What is missing, what is superflu=
ous for a basic IDL?

Regards
Stefan

[1] http://scxmlworkshop.de/eics2014/submissions/A%20Debugger%20for%20SCXML=
%20Documents.pdf



=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

module scxml {

exception Exception {
const unsigned short PARSE_ERR =3D 1; // Given string could not be parsed a=
s an xml document
const unsigned short SCHEMA_ERR =3D 2; // XML DOM not a valid SCXML documen=
t
const unsigned short IMPL_ERR =3D 4; // Unknown datamodel, ioproc, executab=
le content or invoker used

unsigned short code;
String cause;
};


// central place to get interpreter instances
interface Implementation {
Interpreter fromURI(in String uri) raises(Exception);
Interpreter fromXML(in String xmlString) raises(Exception);
Interpreter fromDOM(in Node scxmlRoot) raises(Exception);
}

interface Event {
const unsigned short PLATFORM_EVENT  =3D 1;
const unsigned short INTERNAL_EVENT  =3D 2;
const unsigned short EXTERNAL_EVENT  =3D 3;

String name;
unsigned short type;
String origin;
String originType;
String sendid;
Data data;
};

interface Data {
set(in String value); // atom
String get();

setNode(in Node node); // XML node
Node getNode();

setKey(in String key, in Data value); // compound
Data getKey(in String key);

setItemAt(in String index, in Data value); // array
Data getItemAt(in String index);
};

interface Configuration {
boolean in(in String state);
String item(in unsigned long index);
readonly attribute unsigned long length;
};

interface Interpreter {
const unsigned int FAULT =3D 0; // something bad happened, look into lastEr=
ror
const unsigned int AFTER_MICROSTEP =3D 1; // step finished with a single mi=
crostep
const unsigned int AFTER_MACROSTEP =3D 2; // step finished with a single ma=
crostep and interpreter is stable
const unsigned int SCXML_IDLE =3D 3; // interpreter is stable with no pendi=
ng events on queues
const unsigned int SCXML_FINISHED =3D 4; // interpreter reached top-level f=
inal state

const unsigned int step() raises(Exception) raises(Exception); // blocking =
per default
const unsigned int step(in int timeOutMs) raises(Exception); // block at mo=
st for given duration, 0 for non-blocking

receive(in Event event);
receive(in String event); // convenience

readonly attribute Exception lastError;
readonly attribute Configuration configuration;
readonly attribute Configuration basicConfiguration;
}
}

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

--_000_4C224481448E4EFAA4076E33F0CE59EFtkinformatiktudarmstadt_
Content-Type: text/html; charset="us-ascii"
Content-ID: <[email protected]>
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
</head>
<body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-lin=
e-break: after-white-space;" class=3D"">
Hey there,<br class=3D"">
<br class=3D"">
[explicitly bcc'ing David, Jacob and Zjnue for I know that they maintain SC=
XML implementations] - this post is pertaining to action point 1 from my pr=
evious mail:<br class=3D"">
<br class=3D"">
1. An Interface Description Language (IDL) for SCXML interpreters.<br class=
=3D"">
1.1 For simple life-cycle and interpretation of state-charts.<br class=3D""=
>
1.2 A set of hooks for (on-line) visualisation.<br class=3D"">
1.3 A set of hooks for (on-line) modelling / debugging.<br class=3D"">
<br class=3D"">
For now, I'd like to focus on point 1.1, but we ought to keep the others in=
 mind and maybe eventually extend our ambitions. At least 1.2 is very usefu=
l as it would allow or a common visualisation. I hereby propose a first ske=
tch for an Interface Description
 Language&nbsp;(IDL) for SCXML (see below). It will only allow to instantia=
te interpreters, run them and deliver events. A typical session would look =
like this:<br class=3D"">
<br class=3D"">
import namespace scxml;<br class=3D"">
try {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Interpreter=
 session =3D Implementation.fromURI(&quot;<a href=3D"http://www" class=3D""=
>http://www</a>.example.com/foo.scxml&quot;);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>for(;;) {<b=
r class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>int state =
=3D session.step();<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if (state =
=3D=3D FINISHED)<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br c=
lass=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if (state =
=3D=3D AFTER_MACROSTEP &amp;&amp; session.configuration.in('foo'))<br class=
=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>session.rec=
eive('bar.baz');<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br class=
=3D"">
} catch (Exception e) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print e;<br=
 class=3D"">
}<br class=3D"">
<br class=3D"">
A couple of notes and possible variations:<br class=3D"">
<br class=3D"">
=3D=3D 1. Threads<br class=3D"">
I want to avoid any assumptions about the availability of threads in the em=
bedding platform. As such, there is e.g. no non-blocking interpret(). It wo=
uld be the responsibility of the target platform to emulate something like =
this by embedding the block above&nbsp;in
 a thread.<br class=3D"">
<br class=3D"">
=3D=3D 2. Exceptions<br class=3D"">
Similarly I want to avoid any assumption about the availability of exceptio=
ns, therefore step() might return FAULT and set the lastError attribute:<br=
 class=3D"">
<br class=3D"">
int state;<br class=3D"">
for(;;) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>state - ses=
sion.step();<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>switch(stat=
e) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case FAULT:=
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print sessi=
on.lastError;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br c=
lass=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case FINISH=
ED:<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>return;<br =
class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br class=
=3D"">
}<br class=3D"">
<br class=3D"">
=3D=3D 3. Data<br class=3D"">
0. If nothing in a Data object is set, its value is undefined<br class=3D""=
>
1. If an atom is given, the respective field is to be interpreted as the ev=
aluation of that atom, e.g. &quot;3&quot; is a string, 3 is an integer.<br =
class=3D"">
2. If a node is given and 1. is not the case, the field is to be represente=
d as a DOM Node<br class=3D"">
3. If a key in a compound is set and 1. and 2. are not the case, the respec=
tive field is a map<br class=3D"">
4. If an index is set and none of the above applies, the respective field i=
s an array. Setting a an item at an index N will cause the array to behave =
as if it has N fields for the largest N. With all unset fields undefined.<b=
r class=3D"">
<br class=3D"">
=3D=3D 4. Event<br class=3D"">
Having most fields visible will allow for interpreters where all i/o proces=
sors are external by simply delivering respective Event entities via receiv=
e. The distinction between internal and external events ought to happen in =
receive(Event) itself depending
 on&nbsp;the event's type field. I am not sure if we need the PLATFORM clas=
s though.<br class=3D"">
<br class=3D"">
=3D=3D 5. Hibernating<br class=3D"">
We might want to include a way to serialise a complete interpreter and inst=
antiate it again from its serialised representation. I do know that Jacob w=
as working on a respective feature. We dropped our ambitions for now as mos=
t of the datamodels we&nbsp;employed
 via 3rd party libraries would not support something like that.<br class=3D=
"">
<br class=3D"">
=3D=3D 6. Naming<br class=3D"">
AFTER_MACROSTEP might just as well be called STABLE. I choose the former fo=
r its more explicit reference to the runtime semantics of SCXML, which migh=
t play a role if we were to specify a bunch of hooks for 1.2 and 1.3 (see d=
ebugger paper[1], table&nbsp;1)<br class=3D"">
<br class=3D"">
=3D=3D 7. Events *from* the interpreter<br class=3D"">
While point 4 allows an embedding platform to send arbitrary events *into* =
the interpreter, maybe we ought to have something similar for everything &l=
t;send&gt; from the interpreter?<br class=3D"">
<br class=3D"">
<br class=3D"">
Maybe anyone who is interested in pursuing the idea of this basic IDL could=
 speak up and comment about the proposal? What is missing, what is superflu=
ous for a basic IDL?<br class=3D"">
<br class=3D"">
Regards<br class=3D"">
Stefan<br class=3D"">
<br class=3D"">
[1] http://scxmlworkshop.de/eics2014/submissions/A%20Debugger%20for%20SCXML=
%20Documents.pdf<br class=3D"">
<br class=3D"">
<br class=3D"">
<br class=3D"">
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br class=3D"">
<br class=3D"">
<font face=3D"Courier" class=3D"">module scxml {<br class=3D"">
<br class=3D"">
exception Exception {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short PARSE_ERR =3D 1; // Given string could not be parsed as an xml do=
cument<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short SCHEMA_ERR =3D 2; // XML DOM not a valid SCXML document<br class=
=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short IMPL_ERR =3D 4; // Unknown datamodel, ioproc, executable content =
or invoker used<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>unsigned sh=
ort code;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String caus=
e;<br class=3D"">
};<br class=3D"">
<br class=3D"">
<br class=3D"">
// central place to get interpreter instances<br class=3D"">
interface Implementation {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Interpreter=
 fromURI(in String uri) raises(Exception);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Interpreter=
 fromXML(in String xmlString) raises(Exception);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Interpreter=
 fromDOM(in Node scxmlRoot) raises(Exception);<br class=3D"">
}<br class=3D"">
<br class=3D"">
interface Event {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short PLATFORM_EVENT &nbsp;=3D 1;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short INTERNAL_EVENT &nbsp;=3D 2;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned short EXTERNAL_EVENT &nbsp;=3D 3;<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String name=
;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>unsigned sh=
ort type;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String orig=
in;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String orig=
inType;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String send=
id;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data data;<=
br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Data {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>set(in Stri=
ng value); // atom<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String get(=
);<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>setNode(in =
Node node); // XML node<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Node getNod=
e();<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>setKey(in S=
tring key, in Data value); // compound<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data getKey=
(in String key);<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>setItemAt(i=
n String index, in Data value); // array<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data getIte=
mAt(in String index);<br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Configuration {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>boolean in(=
in String state);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String item=
(in unsigned long index);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly at=
tribute unsigned long length;<br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Interpreter {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int FAULT =3D 0; // something bad happened, look into lastError<br clas=
s=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int AFTER_MICROSTEP =3D 1; // step finished with a single microstep<br =
class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int AFTER_MACROSTEP =3D 2; // step finished with a single macrostep and=
 interpreter is stable<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int SCXML_IDLE =3D 3; // interpreter is stable with no pending events o=
n queues<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int SCXML_FINISHED =3D 4; // interpreter reached top-level final state<=
br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int step() raises(Exception) raises(Exception); // blocking per default=
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const unsig=
ned int step(in int timeOutMs) raises(Exception); // block at most for give=
n duration, 0 for non-blocking<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>receive(in =
Event event);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>receive(in =
String event); // convenience<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly at=
tribute Exception lastError;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly at=
tribute Configuration configuration;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly at=
tribute Configuration basicConfiguration;<br class=3D"">
}<br class=3D"">
}<br class=3D"">
</font><br class=3D"">
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</body>
</html>

--_000_4C224481448E4EFAA4076E33F0CE59EFtkinformatiktudarmstadt_--