Version 1.18 – release date: April 26, 2017
We are pleased to announce the release of CPAL V1.18 which is a drop in replacement for v1.17, with several important new constructs in the language to improve its expressiveness and clarity. This release also irons out a few issues. Under the hood, the toolset evolves to prepare for C code generation that will be available in a coming release.
What is new
- ADDED:
finally
block of code which is executed after any state of the process. This “post-state common code” block is the counterpart of thecommon
block executed before any state.common
andfinally
blocks are perfect locations to check resp. pre- and post-conditions.x1
2processdef A_Proc()
3{
4/* pre-state common code executed first whatever the current state */
5common {
6IO.println("pre-state common code");
7}
89state First {
10/* state-specific code goes here */
11IO.println("state code");
12}
1314/* post-state common code executed last whatever the current state */
15finally {
16IO.println("post-state common code");
17}
18}
19
20process A_Proc: p1[1s]();
21
- ADDED:
self.continue
allows to execute several states of a FSM in a row before relinquishing the CPU (similar in the spirit to “forced states” in Opnet). In the example below, the execution of stateFirst
will always be followed by the execution of stateSecond
:251
2processdef Simple()
3{
4state First {
5IO.println("Time %t - executing state First", time64.time());
6self.continue = true;
7}
8on (true)
9to Second;
10
11state Second {
12IO.println("Time %t - Executing state Second", time64.time());
13}
14on (true)
15to Third;
16
17state Third {
18IO.println("Time %t - Executing state Third", time64.time());
19}
20on (true)
21to First;
22}
23
24process Simple: p1[1s]();
25
- ADDED: possibility to affect the result of a function through a mechanism called “currying”:141
2double(
3in uint8: x,
4out uint8: y)
5{
6y = 2 * x;
7}
8
9init()
10{
11var uint8: result = double(5);
12IO.println("result = %u", result);
13}
14
- ADDED: possibility to test the result of a function (currying again):151
2add_1ms(
3in time64: a,
4out time64: res)
5{
6res = a + 1ms;
7}
8
9init()
10{
11var time64: t1 = 999ms;
12var time64: expected = 1s;
13assert(expected == add_1ms(t1));
14}
15
- ADDED: possibility to test and store the state of a process, from within the process through
self.current_state
and from another process through aProcess_State
variable. The latter case is illustrated below:361
2processdef Simple()
3{
4static var bool: change_state = false;
5common {
6change_state = bool.rand_uniform();
7}
8
9state First {
10}
11on (change_state)
12to Second;
13
14state Second {
15}
16on (change_state)
17to First;
18}
19
20process Simple: p1[1s]();
21
22processdef Observer()
23{
24static var Process_State: previous;
25state Single {
26IO.print("Current state of p1: ");
27if (p1.process_state == Process_State.First) {
28IO.println("First");
29} else {
30IO.println("Second");
31}
32}
33}
34
35process Observer: p2[1s]();
36
What has been fixed or changed
- FIXED: Named blocks can be declared anywhere, e.g. inside
if
statement (#318):141
2processdef Proc()
3{
4state Main {
5var bool: b;
6valid1: {
7}
8if (b) {
9valid2: {
10}
11}
12}
13}
14
- CHANGED:
break
statement now forbidden in states, reserved for loops (#343). - CHANGED:
@cpal:unknown
annotations are rejected by the parser, user-defined annotations must be prefixed by anything other than@cpal
) (#354). - CHANGED: Queue iteration: no more implicit
continue
statement after a call toremove_current()
(#49).remove_current()
does not support anymore the optionsrestart
andbreak
(#49,#269) whose behavior can be achieved programmatically.1912init(){
3var queue<uint8>: my_data[4] = {1, 5, 7, 9 };
4loop over my_data with it {
5IO.println("%u", it.current);
6if (it.current == 1) {
7it.remove_current();
8/* it points now to the next element of the collection */
9}
10if (it.current == 5) {
11it.remove_current();
12}
13if (it.current == 7) {
14it.remove_current();
15}
16IO.println("size of the collection: %u", my_data.count());
17}
18}
19
- CHANGED:
{ }
required afterif
statement (#352). - FIXED: correct parser issues with sub-processes (#358,#359,#360).
Test coverage metrics (figures for embedded Linux platform)
- Test code coverage for the execution engine: 85.9% (lines of code), 82.2% (functions) and 72.8% (branches)
- Tests: parser=3963, interpreter=857, cpal2x=3342