Most of you will be familiar with the "assert" construct available in
some languages. I can't remember if one has been posted to popforum
recently: if so, here is another (simple) one; if not, I hope you
will find this one useful.
I haven't used this extensively (see creation date!), but am posting
it now in case someone else posts a better version with a different
syntax before I've embedded too many -assert-s in my code!
--Jonathan
-----------------------CUT HERE-----------------------------------------
;;; 10th Aug 1993
;;; JL Cunningham
/* Provides some 'assert' syntax:
assert <expr> [else <stmt-seq>] endassert
This generates a mishap if <expr> evaluates to false, in which case
a mishap message is generated. The optional <stmt-seq> is evaluated
to provide the culprits (the 'INVOLVING' line).
No code will be planted (and therefore no assertion checking done)
if the variable -asserting- is false when an assertion is compiled.
Examples:
assert true endassert; ;;; nothing happens
assert false endassert; ;;; assertion fails, generating a mishap
assert x < 3 else 'Bad News' endassert;
assert x < 3 else 'x out of bounds', [x = ^x] endassert;
Try this example:
;;; prints all the decimal digits
vars i;
for i from 0 to 10 do
assert i < 10 else 'i too large', [i = ^i] endassert;
i =>
endfor;
Try it after doing
false -> asserting;
Assertions are used during development as a sanity check, and
are particularly useful if Bad Things don't happen immediately
a calculation gets the wrong result. A final example:
define risky_procedure(i, j);
lvars i, j;
assert i.isinteger and j.isinteger endassert;
(i fi_+ j) fi_* (i fi_- j)
enddefine;
risky_procedure(5, 3)=>
risky_procedure(7, '')=> ;;;generates rubbish if -asserting- was false
See also lib slowprocs
*/
global vars asserting = true;
lconstant assert_proc = /* I hate lconstants */
procedure culprits;
lvars culprits;
mishap('Assertion failed', culprits);
endprocedure;
global vars syntax endassert;
define global syntax assert;
lvars lab = sysNEW_LABEL(), word;
dlocal pop_syntax_only = pop_syntax_only or not(asserting);
pop11_comp_expr_to([endassert else])->word;
sysIFSO(lab);
if word == "else" then
sysPUSHQ(popstackmark);
pop11_comp_stmnt_seq_to("endassert")->;
sysCALLQ(sysconslist);
else
sysPUSHQ([]);
endif;
sysCALLQ(assert_proc);
sysLABEL(lab);
enddefine;
;;;eof
|