Difference between revisions of "Technical topic: OpenGEODE - SDL Operators: How to work with data"
Line 96: | Line 96: | ||
dcl bar MyInt; | dcl bar MyInt; | ||
− | bar := length (foo) -- 3 | + | bar := fix (length (foo)) -- 3 |
for each in foo: | for each in foo: |
Revision as of 12:11, 6 March 2019
Contents
Introduction
The SDL language primarily targets the description of a system's behaviour. It is however also possible to manipulate data using a collection of built-in operators. This can be convenient to avoid depending on external, manually-written code to process the parameters of messages during the execution of a state machine transition.
Variables are defined in the ASN.1 language and can express simple types (boolean, numbers and enumerated values) as well as complex data structures (records, arrays, and choices). Each type comes with some dedicated operators which are described in this page.
INTEGER types
MyInt ::= INTEGER (-10 .. 255)
dcl foo MyInt := 42;
The following can be done (in addition to the +, -, / and * operators):
foo := -5 -- assign a value foo := abs (foo) -- return 5 foo := fix (5.7) -- convert float to integer foo := power (10, 2) -- 100 foo := (foo + 1) mod 10 -- modulo write (foo) writeln (foo) -- display the value (procedure call)
REAL types
MyReal ::= REAL (0.0 .. 10.0) dcl foo MyReal := 42.0; dcl bar MyInt := 5;
The following can be done:
foo := 0.0 -- assign a value foo := ceil (1.618) -- ceiling foo := floor (1.618) -- ceiling foo := float (bar) -- convert integer to real foo := round (3.14159) -- round foo := sin (3.14) foo := cos (3.14) foo := sqrt (2) foo := trunc (7.77) -- truncation write (foo) writeln (foo)
ENUMERATED types
MyEnum ::= ENUMERATED { foo, bar }
dcl var MyEnum := foo; dcl pos INTEGER (0..1);
Keep in mind that an enumerated in a _state_ and not a number. You can get the _position_ (as a number) of an enumerant like this:
pos := num (var);
And in the reverse you could set the value from a position:
var := val (1, MyEnum) -- sets to bar
You can also print the enumerant name on the screen with the write or writeln operators.
CHOICE types
MyChoice ::= CHOICE { foo BOOLEAN, bar INTEGER (0 .. 255) } dcl a MyChoice := foo : FALSE; -- ASN.1 Value Notation to set the value
You can evaluate the current choice using the *present* operator in a decision:
DECISION present (a) -- test against foo and bar
writeln (if present (a) = foo then a.foo else a.bar fi)
You can also use an implicit type to store the choice determinant:
dcl current_choice MyChoice_selection := present (a);
And if you happen to have an ENUMERATED type with the extact same enumerants as the CHOICE options, you can convert from an to:
MyDeterminants ::= ENUMERATED { foo, bar } dcl det MyDeterminants := to_enum (a, MyDeterminants); current_choice := to_selector (det, MyChoice);
SEQUENCE OF types (arrays)
MySeqOf ::= SEQUENCE (SIZE (0..10)) OF BOOLEAN dcl foo MySeqOf := { true, false, false }; -- ASN.1 Value Notation dcl bar MyInt;
bar := fix (length (foo)) -- 3
for each in foo: call writeln (each); endfor
SEQUENCE types (records)
MySeq ::= SEQUENCE { a BOOLEAN OPTIONAL, b INTEGER (0 .. 255) }
dcl seq MySeq := { a FALSE, b 10 }; -- ASN.1 Value Notation
DECISION exist (seq.a) -- test presence of optional field
TIMER types =
timer mytimer;
The SET and RESET operators from SDL are indirectly supported via procedure calls:
set_timer (1000, mytimer); reset_timer (mytimer);