Sinelabore Homepage

Update for SysML v2. The same model now generates Python as well as C++, and the generator can draw a model instead of generating from it. A part also drives itself: process() steps the state machines it owns, so a test driver calls one method on the top part and nothing else. Highlights since 7.2.9:

  • A Python back end. -l python generates a Python module from the same model that -l cppx turns into C++. Parts become classes, machines are stepped by process(), and the runtime environment — framework.py, the counterpart of framework.h — is delivered with the product rather than generated.

  • Diagrams from the generator. -l svg draws a model: the state machine of a part as a state chart, the flow of an action as an activity diagram, or the structure of a part with the parts it contains, their ports and what connects them. -t names what to draw, -pc and -pcd say how much detail a part box carries. No other tool is needed — see Tooling and Validation.

  • process() steps the state machines. A part’s process() now steps every machine it drives and then the parts it contains. A machine initializes itself on its first step. A driver that used to name each machine can call tls.process() instead.

    If you override process() or init() in a subclass, call the base-class method as well — otherwise the parts below are no longer stepped.

  • More of the language is generated: collections and multiplicities, exhibited state machines (exhibit state s references SharedSM;), specialization and redefinition of features, and values derived from an expression over other features — sum, product, size, max and min over a collection, computed in init().

  • Non-executable constructs are reported, not refused. requirement, constraint, use case, view, analysis and allocation are parsed, named on the console as W3170, and skipped. A model can keep them beside the parts they constrain and still generate everything else.

  • Clearer diagnostics. A message says which line of the model it is about — including the connect ends and assignments that previously reported without a position. A wrong command line flag now prints the usage text, and -h asks for it.

  • Portability. The generated code and its runtime compile with g++, clang++ and the Microsoft compiler alike.

New diagnostic: W3210 reports a model that assigns a Real to an Integer feature, which silently discards the fraction. It is reported against the model line rather than left to a C++ compiler, which mentions it only on some toolchains.

One call drives the system#

TrafficLightSystem tls;
tls.init();                       // creates the parts, wires the connections

for (int i = 0; i < 80; i++) {
    tls.process();                // every machine in the system, top part downwards
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

The same model, in Python#

java -cp "path/to/codegen/*" codegen.Main -p sysml2text -l python -o system oven.sysml
oven = Oven()
oven.init()
while True:
    oven.process()
    time.sleep(0.2)

Drawing a model#

java -cp "path/to/codegen/*" codegen.Main -p sysml2text -l svg \
     -t MicrowaveOfen::TimerDisplay -o TimerDisplayStateMachine oven.sysml

State machine of the TimerDisplay part

The drawing is made from the same parsed model the generator works on, so it doubles as a check: if the picture does not show what you expect, the generated code will not either.