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.processdef A_Proc() { /* pre-state common code executed first whatever the current state */ common { IO.println("pre-state common code"); } state First { /* state-specific code goes here */ IO.println("state code"); } /* post-state common code executed last whatever the current state */ finally { IO.println("post-state common code"); } } process A_Proc: p1[1s]();
- 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
:processdef Simple() { state First { IO.println("Time %t - executing state First", time64.time()); self.continue = true; } on (true) to Second; state Second { IO.println("Time %t - Executing state Second", time64.time()); } on (true) to Third; state Third { IO.println("Time %t - Executing state Third", time64.time()); } on (true) to First; } process Simple: p1[1s]();
- ADDED: possibility to affect the result of a function through a mechanism called “currying”:
double( in uint8: x, out uint8: y) { y = 2 * x; } init() { var uint8: result = double(5); IO.println("result = %u", result); }
- ADDED: possibility to test the result of a function (currying again):
add_1ms( in time64: a, out time64: res) { res = a + 1ms; } init() { var time64: t1 = 999ms; var time64: expected = 1s; assert(expected == add_1ms(t1)); }
- 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:processdef Simple() { static var bool: change_state = false; common { change_state = bool.rand_uniform(); } state First { } on (change_state) to Second; state Second { } on (change_state) to First; } process Simple: p1[1s](); processdef Observer() { static var Process_State: previous; state Single { IO.print("Current state of p1: "); if (p1.process_state == Process_State.First) { IO.println("First"); } else { IO.println("Second"); } } } process Observer: p2[1s]();
What has been fixed or changed
- FIXED: Named blocks can be declared anywhere, e.g. inside
if
statement (#318):processdef Proc() { state Main { var bool: b; valid1: { } if (b) { valid2: { } } } }
- 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.init(){ var queue<uint8>: my_data[4] = {1, 5, 7, 9 }; loop over my_data with it { IO.println("%u", it.current); if (it.current == 1) { it.remove_current(); /* it points now to the next element of the collection */ } if (it.current == 5) { it.remove_current(); } if (it.current == 7) { it.remove_current(); } IO.println("size of the collection: %u", my_data.count()); } }
- 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