[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Aug 10 18:28:32 1993 
Subject:assert 
From:jlc (Jonathan Cunningham) 
Volume-ID:930810.01 


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