Sometimes parameterized components are only valid for certain parameter ranges. ACT includes assertions that are checked at expansion time that can be used to validate the assumptions made.
As a simple example, suppose we want to define an N-place buffer.
template<pint N> defproc buffer(chan?(int) L; chan!(int) R) { onebuf b[N]; // create one-place buffer elements (i:N-1: b[i+1].L = b[i].R;) // connect internal channels b[0].L = L; // connect external input b[N-1].R = R; // connect external output }
Passing in parameter 0 to this buffer would yield:
buffer<0> x;
--[ERROR]-> In expanding buffer<0> (filename.act:XXXX) In expanding ::<Global> Error on or near line number XXXX. id: b[0].L FATAL: Identifer conditionally created, but used when it does not exist
The definition, as written, does not support zero-length buffers. Rather than getting a message at expansion time that may not be as understandable to a user (especially of a pre-defined library), we can add an assertion to provide a more meaningful error message to a user of the templated buffer.
template<pint N> defproc buffer(chan?(int) L; chan!(int) R) { { N > 0 : "buffer size has to be at least 1" }; onebuf b[N]; // create one-place buffer elements (i:N-1: b[i+1].L = b[i].R;) // connect internal channels b[0].L = L; // connect external input b[N-1].R = R; // connect external output }
With this change, the error now looks like the following:
--[ERROR]-> In expanding buffer<0> (filename.act:XXXX) In expanding ::<Global> Error on or near line number XXXX. *** Assertion failed *** assertion: N>0 message: buffer size has to be at least 1