1: \ assertions
2:
3: \ This file is in the public domain. NO WARRANTY.
4:
5: \ It is a good idea to make your programs self-checking, in
6: \ particular, if you use an assumption (e.g., that a certain field of a
7: \ data structure is never zero) that may become wrong during maintenance.
8: \ Gforth supports assertions for this purpose. They are used like this:
9:
10: \ assert( FLAG )
11:
12: \ The code between `assert(' and `)' should compute a flag, that
13: \ should be true if everything is alright and false otherwise. It should
14: \ not change anything else on the stack. The overall stack effect of the
15: \ assertion is `( -- )'. E.g.
16:
17: \ assert( 1 1 + 2 = ) \ what we learn in school
18: \ assert( dup 0<> ) \ assert that the top of stack is not zero
19: \ assert( false ) \ this code should not be reached
20:
21: \ The need for assertions is different at different times. During
22: \ debugging, we want more checking, in production we sometimes care more
23: \ for speed. Therefore, assertions can be turned off, i.e., the assertion
24: \ becomes a comment. Depending on the importance of an assertion and the
25: \ time it takes to check it, you may want to turn off some assertions and
26: \ keep others turned on. Gforth provides several levels of assertions for
27: \ this purpose:
28:
29: \ `assert0(' -- gforth ``assert-zero''
30: \ important assertions that should always be turned on
31:
32: \ `assert1(' -- gforth ``assert-one''
33: \ normal assertions; turned on by default
34:
35: \ `assert2(' -- gforth ``assert-two''
36: \ debugging assertions
37:
38: \ `assert3(' -- gforth ``assert-three''
39: \ slow assertions that you may not want to turn on in normal debugging;
40: \ you would turn them on mainly for thorough checking
41:
42: \ `assert(' -- gforth ``assert(''
43: \ equivalent to assert1(
44:
45: \ `)' -- gforth ``close-paren''
46: \ end an assertion
47:
48: \ `Assert(' is the same as `assert1('. The variable `assert-level'
49: \ specifies the highest assertions that are turned on. I.e., at the
50: \ default `assert-level' of one, `assert0(' and `assert1(' assertions
51: \ perform checking, while `assert2(' and `assert3(' assertions are
52: \ treated as comments.
53:
54: \ Note that the `assert-level' is evaluated at compile-time, not at
55: \ run-time. I.e., you cannot turn assertions on or off at run-time, you
56: \ have to set the `assert-level' appropriately before compiling a piece
57: \ of code. You can compile several pieces of code at several
58: \ `assert-level's (e.g., a trusted library at level 1 and newly written
59: \ code at level 3).
60:
61: \ `assert-level' -- a-addr gforth ``assert-level''
62: \ all assertions above this level are turned off
63:
64: \ The program uses the following words
65: \ from CORE :
66: \ Variable ! : @ > IF POSTPONE THEN ; immediate 0=
67: \ from BLOCK-EXT :
68: \ \
69: \ from EXCEPTION-EXT :
70: \ abort"
71: \ from FILE :
72: \ (
73:
74: variable assert-level ( -- a-addr ) \ gforth
75: \ all assertions above this level are turned off
76: 1 assert-level !
77:
78: : assertn ( n -- ) \ gforth assert-n
79: \ this is internal (it is not immediate)
80: assert-level @ >
81: if
82: POSTPONE (
83: then ;
84:
85: : assert0( ( -- ) \ gforth assert-zero
86: \ important assertions that should always be turned on
87: 0 assertn ; immediate
88: : assert1( ( -- ) \ gforth assert-one
89: \ normal assertions; turned on by default
90: 1 assertn ; immediate
91: : assert2( ( -- ) \ gforth assert-two
92: \ debugging assertions
93: 2 assertn ; immediate
94: : assert3( ( -- ) \ gforth assert-three
95: \ slow assertions that you may not want to turn on in normal debugging;
96: \ you would turn them on mainly for thorough checking
97: 3 assertn ; immediate
98: : assert( ( -- ) \ gforth
99: \ equivalent to assert1(
100: POSTPONE assert1( ; immediate
101:
102: : (endassert) ( flag -- ) \ gforth-internal
103: \ inline argument sourcepos
104: 0= abort" assertion failed" ;
105:
106: : ) ( -- ) \ gforth close-paren
107: \ end an assertion
108: POSTPONE (endassert) ; immediate
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>