5 \ We CANNOT access code!
\r
6 \ We CANNOT change the compiler!
\r
7 \ We CANNOT do anything!
\r
9 \ But we want a debugger!
\r
10 \ Ok, here it is....
\r
13 \ ********************************************************************
\r
15 \ * Debugger for ANSI Forth Programs *
\r
18 \ * Contributed to the community by *
\r
20 \ * Joerg Plewe, 1dec94 *
\r
22 \ * This code can be used and copied free of charge. *
\r
23 \ * All rights reserved. *
\r
25 \ * Comments, hints and bug reports are welcome. Please email to *
\r
27 \ * jps@Forth-eV.de *
\r
30 \ * testet with: F68KANS (>jan94), pfe0.9.7, thisForth *
\r
32 \ * Special thanks to Ulrich Hoffmann and Bernd Paysan *
\r
33 \ * for testing and commenting. *
\r
35 \ * V0.1: Added treatment of nesting levels *
\r
36 \ * V0.2: Decompiler feature *
\r
37 \ * V0.3: worked in hints from the net *
\r
38 \ ********************************************************************
\r
41 \ The following code provides a simple debugging tool for ANSI Forth
\r
42 \ programs. It may be used to debug colon- and DOES>- and :NONAME-code
\r
45 \ The debugger expects your system to be a well behaved Forth system.
\r
46 \ (Like my F68KANS :-)
\r
47 \ When you suspect that your problems arise from the compiler itself
\r
48 \ (do you use an optimizer?), please use another tool.
\r
53 \ There are two pairs of words switching the debugger on and off.
\r
56 \ These two control a global switch, which has effects both a compile-
\r
57 \ and runtime. When used at compiletime, -DEBUG will completely switch
\r
58 \ of the debugger. So no debugging code is generated. This allows you
\r
59 \ to leave your code with all debugging statements in it and test it
\r
61 \ At runtime, -DEBUG switches off the evaluation of debugging code.
\r
62 \ So your code will behave as normal, just a bit slower.
\r
65 \ You will have to use [DBG at compiletime in front of a ':' or a DOES>
\r
66 \ to tell the debugger to generate special debugging code. [DBG is
\r
67 \ valid until switched off with DBG]. DBG] may appear anywhere in the source!
\r
68 \ So it is possible to debug only the first part of a word and then to switch
\r
69 \ of the debugger causing 'original' code to be generated for the rest.
\r
70 \ It is not possible to generate normal code a the beginning of a definition
\r
71 \ and debugging code in the end!
\r
74 \ : FOO CREATE [DBG 0 , DOES> @ ; DBG]
\r
76 \ will only debug the DOES>-part of the definition. The reason is that [DBG
\r
77 \ only switches the behaviour of ':' and DOES>.
\r
80 \ Think about the difference of +-DEBUG and [DBG]!
\r
83 \ There some additional words to control the debugger a runtime. These
\r
84 \ words have short names to be typepable at debugtime. But of course
\r
85 \ you may also compile them into your code. Thsi gives you the
\r
86 \ possibility to realize breakpoints etc.
\r
89 \ Interactive. This switch controls wether you do singlestepping or a
\r
90 \ kind of code animation. When singlestepping, you can type any number
\r
91 \ of Forth statements between two steps. The next step is peformed when
\r
92 \ simply pressing <return>.
\r
95 \ Verbose. [+V] adds a stack dump to the output on each step.
\r
98 \ Silent. [+S] switches off all outputs and the program begins to run.
\r
99 \ Pressing a key switches it back to interactive mode.
\r
102 \ Goto Level of nesting. This option recieves a parameter (don't forget).
\r
103 \ It lets the debugger run in '[+S] [-I] [-V]'-mode until the given
\r
104 \ level of nesting is reached the next time. Then the previous state of
\r
105 \ the debugger is restored.
\r
106 \ Note that the given level may be lower, higher or equal to the current level.
\r
107 \ You can overwrite the settings invoked be [>L] with further debugger
\r
109 \ Suppose you are on level 1, than
\r
111 \ will give you an animation of your code until the next word on nestinglevel 1
\r
115 \ Step over. This command will avoid nesting to deeper levels. It is
\r
116 \ equivalent to a [>L] with the current level. So the example above can
\r
122 \ Default: [+I] [-V] [-S], no nestlevel targeting
\r
125 \ The debugger also supports a decompiler feature for words compiled with the
\r
126 \ debugger on. The decompiler is envoked by
\r
130 \ and decompiles the whole word at once. For this decompiler works completely
\r
131 \ different from these you maybe know, it has e.g. the possibility to
\r
132 \ decompile even things which were in you source with the compiler off.
\r
133 \ This means, sequences like '... [ 1 2 3 + + ] LITERAL ...' will
\r
134 \ reappear while decompiling.
\r
139 \ This is the debugger's reset. It sets back e.g. the level of nesting.
\r
140 \ You should use this at the beginning of a file you compile, e.g.
\r
142 \ in the first line.
\r
145 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
148 \ F68KANS (>jan94) portable 68k nativecode Forth by me
\r
149 \ pfe0.9.7 by Dirk Zoller
\r
150 \ thisForth by Wil Baden
\r
152 \ Reported to work with:
\r
154 \ gforth by Bernd Paysan (paysan@informatik.tu-muenchen.de)
\r
155 \ iForth by Marcel Hendrix (mhx@bbs.forth-ev.de)
\r
158 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
159 \ ENVIRONMENTAL DEPENDENCIES
\r
161 \ When the decompiler option is used:
\r
162 \ The Control Stack (CS) has to be the data stack.
\r
165 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
168 \ The generation of debugging code can only be invoked with the words
\r
169 \ ':', DOES> and :NONAME (or words which use them, after the debugger
\r
170 \ has been compiled).
\r
172 \ The debugger is steered by some string literals: debugging is switched
\r
173 \ off when the debugger's outer interpreter finds the words DBG] or ';'.
\r
174 \ The words a compiled as string literals into the debugger, so no
\r
175 \ definitions including them will be able to do theire job!
\r
176 \ Further, the words ';' and '[' have a special meaning for the
\r
177 \ debugger (they both switch off the Forth compiler).
\r
179 \ In the current state, the debugger cannot handle floating point
\r
180 \ literals. This will be removed in one of the next releases.
\r
184 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
187 \ A standard system does not let you examine the code. You do not know
\r
188 \ anything about it's location in memory or it's structure. You do not
\r
189 \ know wether it is direct or inderect threaded or native code.
\r
190 \ But most debuggers exactly do that: they examine the code, and sometimes
\r
191 \ even modify it at runtime (e.g. to set breakpoints in native code systems).
\r
192 \ They need detailed knowledge about the code and the CPU it runs on.
\r
193 \ In most cases, additional knowledge about the structure of the
\r
194 \ dictionary is needed, too.
\r
196 \ For all that cannot be done with an ANSI Forth system, this debugger
\r
197 \ tries a completely different way.
\r
198 \ From the things said above, it is clear that once the code is
\r
199 \ generated, there is no possibility for debugging any more. So an ANSI
\r
200 \ debugger has to generate a special debugging code. In order to do that,
\r
201 \ it must define a new compiler, because an ANSI system does not
\r
202 \ let you manipulate the outer interpreter.
\r
203 \ My debugger uses an own outer interpreter which generates, let's say,
\r
204 \ 'self debugging code'.
\r
205 \ (Thanks to the standard comittee for providing REFILL)
\r
207 \ The next serious problem is how to access the source? There are
\r
208 \ different input sources like TIB, files, blocks or strings. Perhaps for
\r
209 \ blocks it would be possible to compile the blocknumber into the code.
\r
210 \ Then the right block could be accessed at runtime.
\r
211 \ Files would be more complicated, because they are represented by a
\r
212 \ single number, which may be OS dependent. Reaccessing a file from
\r
213 \ this number later means to implement a completely new
\r
214 \ file word set. I did not want to do that!
\r
215 \ With source from TIB or a string, the source retrieval will be
\r
216 \ impossible at all.
\r
217 \ So the only way to solve the problem is to compile the source together
\r
218 \ with the generated code!
\r
219 \ (Thanks to the standard comittee for providing SLITERAL)
\r
221 \ The following code is generated (in general) for a Forth word <word>:
\r
223 \ [ S" <word>" ] SLITERAL dodebug nodecomp @ IF <word> THEN
\r
225 \ (So make sure that you have enough space in your code area!)
\r
228 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
231 \ V0.2 initially did not work with Wil Baden's thisForth.
\r
232 \ The reason seemed to be
\r
233 \ that VALUES cannot be POSTPONEd in thisForth. So I turned the VALUE
\r
234 \ 'decompile' into the VARIABLE 'nodecomp'.
\r
235 \ thisForth had (has?) some problems with it's REFILL. Wil Baden send
\r
236 \ me a valid definition:
\r
238 \ : REFILL ( -- flag ) next-char eof <> ;
\r
240 \ Don't wonder about what you see when debugging thisForth programs!
\r
241 \ The debugger also sees thisForth's macro expansions!!
\r
245 \ CR .( ANSI Forth debugger V0.3 by Joerg Plewe, 1dec94 ) CR
\r
252 \ Compile the decompiler feature?
\r
253 \ This will introduce an environmental dependency!
\r
254 \ TRUE CONSTANT withDSEE
\r
256 \ Try to find out wether the control stack is the data stack.
\r
257 \ In this case, the system fullfills the environmental dependency
\r
258 MARKER *check_for_controlstack*
\r
259 FALSE VARIABLE CSisDS CSisDS !
\r
263 [ DEPTH saveDEPTH ! ]
\r
264 IF \ IF should change the controlstack
\r
265 [ DEPTH saveDEPTH @ > CSisDS ! ] \ datastack changed?
\r
268 CSisDS @ *check_for_controlstack* CONSTANT withDSEE
\r
273 : is_defined ( <name> -- flag )
\r
277 \ is_defined ON is_defined OFF AND 0=
\r
279 : ON ( addr -- ) TRUE SWAP ! ;
\r
280 : OFF ( addr -- ) FALSE SWAP ! ;
\r
287 \ switching debugger globally
\r
289 VARIABLE use_debugger use_debugger ON
\r
290 \ use the debugger at all?
\r
291 VARIABLE nodecomp nodecomp ON
\r
292 \ controls decompiling vs. debugging at runtime
\r
293 VARIABLE creating_dbgcode creating_dbgcode OFF \ internal switch
\r
294 VARIABLE nestlevel 0 nestlevel ! \ level of nesting
\r
306 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
308 \ executing watches
\r
310 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
312 10 CONSTANT #watches
\r
313 CREATE watchlist #watches CELLS ALLOT
\r
315 : slot ( n -- addr )
\r
316 CELLS watchlist + ;
\r
318 : watch_execute ( xt -- flag )
\r
319 DEPTH >R EXECUTE DEPTH R> - \ may ONLY return a flag!
\r
320 ABORT" A watch is not legal: not returning ONLY a flag!"
\r
324 : do_watch ( n -- flag )
\r
325 DUP 0 #watches WITHIN
\r
327 slot @ DUP \ if slot @ gives 0, this is
\r
329 IF watch_execute THEN
\r
330 ELSE DROP FALSE THEN ;
\r
332 : do_watches ( -- flag )
\r
334 #watches 0 DO I do_watch 0= 0= OR LOOP ;
\r
337 : find_free_slot ( -- n | -1 )
\r
341 IF I UNLOOP EXIT THEN
\r
346 watchlist #watches CELLS ERASE ;
\r
351 : :WATCH ( -- xt ) ( C: -- colon-sys )
\r
352 use_debugger @ -DEBUG \ no debugging of the watches
\r
355 : ;WATCH ( xt -- ) ( C: colon-sys -- )
\r
357 SWAP use_debugger !
\r
358 find_free_slot DUP 0< 0=
\r
361 R> ." ( Slot #" . ." filled with watch.) "
\r
363 2DROP TRUE ABORT" Cannot add more watches!"
\r
367 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
369 \ we need some routines for service
\r
373 \ is a string a number?
\r
375 : ?negate ( n sign -- n' ) 0< IF NEGATE THEN ;
\r
376 : ?dnegate ( d sign -- d' ) 0< IF DNEGATE THEN ;
\r
378 : number? ( addr c -- FALSE | u 1 | ud -1 )
\r
379 \ Tries to find out, wether the given string can be interpreted
\r
380 \ as a numeric literal.
\r
381 \ Returns a flag and the converted number, if possible.
\r
382 0 >R \ push default sign
\r
383 OVER C@ [CHAR] - = IF R> DROP -1 >R THEN \ - sign?
\r
384 OVER C@ [CHAR] + = IF R> DROP 1 >R THEN \ + sign?
\r
386 0. 2SWAP >NUMBER ( ud2 c-addr2 u2 )
\r
387 ?DUP 0= IF DROP D>S R> ?negate 1 EXIT THEN ( exit: single )
\r
388 1 = SWAP C@ [CHAR] . = AND \ with a '.', it is double
\r
389 IF R> ?dnegate -1 EXIT THEN ( exit: double )
\r
390 R> DROP 2DROP FALSE
\r
396 \ things to be done while debugging
\r
399 CREATE debugTIB 80 CHARS ALLOT
\r
400 : eval_debug_statements ( -- )
\r
401 \ A simple outer interpreter for interactive input at
\r
404 CR ." > " debugTIB DUP 80 ACCEPT SPACE DUP
\r
406 ['] EVALUATE CATCH IF ." Oops!?" CR THEN
\r
411 : .next_statement ( addr len -- )
\r
412 \ addr len shows the name of the following statement in the
\r
413 \ source code. .next_statement formats and prints it.
\r
414 nestlevel @ 2* SPACES
\r
416 ." Nxt[" nestlevel @ S>D <# #S #> TYPE ." ]: "
\r
422 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
424 \ steering the debugger
\r
426 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
427 VARIABLE debugstate 0 debugstate !
\r
428 \ Bit 0 = Interactive
\r
432 : +debugstate: ( state <name> -- )
\r
434 DOES> @ debugstate @ OR debugstate ! ;
\r
436 : -debugstate: ( state <name> -- )
\r
438 DOES> @ debugstate @ AND debugstate ! ;
\r
440 : ?debugstate: ( state <name> -- )
\r
442 DOES> @ debugstate @ AND 0<> ;
\r
444 1 DUP +debugstate: (+I) DUP -debugstate: [-I] ?debugstate: [?I]
\r
445 2 DUP +debugstate: [+S] DUP -debugstate: [-S] ?debugstate: [?S]
\r
446 4 DUP +debugstate: [+V] DUP -debugstate: [-V] ?debugstate: [?V]
\r
449 \ define some additional rules
\r
451 : [+I] ( -- ) \ interactive can never be silent
\r
454 VARIABLE target_nestlevel -1 target_nestlevel !
\r
455 VARIABLE savedebugstate debugstate @ savedebugstate !
\r
458 : check_nesting ( -- )
\r
459 \ Checks wether the execution has reached a defined level
\r
460 \ of nexting (target_nestlevel). In this case, it switches off
\r
461 \ targetting (-1!) and restore the previously saved state
\r
463 target_nestlevel @ nestlevel @ =
\r
465 -1 target_nestlevel ! \ switch targeting off
\r
466 savedebugstate @ debugstate !
\r
470 : [>L] ( n -- ) \ goto level
\r
472 debugstate @ savedebugstate !
\r
477 : [Y] ( -- ) \ step over
\r
483 : [DEF] ( -- ) \ the default behaviour
\r
484 -1 target_nestlevel !
\r
492 \ check: what has to be displayed?
\r
495 : ?.next_statement ( addr len -- )
\r
496 \ When the debugger is not running silent, the following
\r
497 \ has to be displayed. When not beeing interactive, a CR
\r
507 : ?eval_debug_statements ( -- )
\r
508 \ When the debugger is interactive but not silent, we want
\r
509 \ to evaluate statements.
\r
511 IF eval_debug_statements THEN ;
\r
514 \ Perhaps, a stackdump is needed. This is indicated by the
\r
520 \ Oh oh. Return to interactive mode when a key is pressed
\r
521 \ or a watch is activated.
\r
524 EKEY? IF KEY DROP [+I] THEN
\r
525 do_watches IF [+I] THEN
\r
529 : dodebug ( addr len -- )
\r
530 \ This word is executed between two statements in the source.
\r
531 \ Note I had to do some stack juggling for the stack has to
\r
532 \ be 'original' when showing the stackdump!
\r
533 use_debugger @ IF \ wonna debug anyway?
\r
536 >R >R ?.s R> R> ( >R's for addr len )
\r
538 ?eval_debug_statements
\r
546 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
548 \ this section is to create debugging code
\r
550 \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\r
554 \ THIS word is the main point:
\r
555 \ It compiles code suitable for debugging.
\r
556 \ Or better: it compiles self-debugging code
\r
558 : .source, ( c-addr -- )
\r
559 STATE @ DUP >R 0= IF ] THEN \ switch compiler on for SLITERAL
\r
561 POSTPONE SLITERAL ( POSTPONE) ALIGN
\r
563 R> 0= IF POSTPONE [ THEN \ switch compiler off when it was off
\r
566 CREATE wordbuf 64 CHARS ALLOT
\r
568 : >wordbuf ( c-addr -- )
\r
569 DUP C@ CHAR+ wordbuf SWAP CHARS MOVE ;
\r
572 : C$= ( c-addr addr u -- flag )
\r
573 ROT COUNT COMPARE 0= ;
\r
575 : $;= ( c-addr -- flag ) S" ;" C$= ;
\r
576 : $DBG]= ( c-addr -- flag ) S" DBG]" C$= ;
\r
577 : $[= ( c-addr -- flag ) S" [" C$= ;
\r
580 : apply_semantic ( xt +-1 -- ? )
\r
582 IF COMPILE, ELSE EXECUTE THEN ;
\r
585 : compile_number ( u 1 | ud -1 -- )
\r
588 0< IF POSTPONE 2LITERAL ELSE POSTPONE LITERAL THEN
\r
592 : compiler_error ( c-addr -- )
\r
593 ." Not found in dictionary: " wordbuf COUNT TYPE
\r
598 \ handling the nesting level
\r
607 : endof_dbgd_def? ( -- flag ) \ end of debugged definition?
\r
612 : compiler_off? ( -- flag ) \ a word, which switches the compiler off?
\r
620 \ compile conditinal branches to skip 'real' code for decompiling
\r
624 CREATE CSbuffer 20 CELLS ALLOT
\r
625 VARIABLE decompilerIF decompilerIF OFF
\r
626 VARIABLE saveDEPTH 0 saveDEPTH !
\r
627 VARIABLE CSsaved 0 CSsaved !
\r
630 \ Save control structure information from the data stack
\r
631 \ to a special buffer.
\r
632 \ The variable saveDEPTH has to be set!!
\r
635 DEPTH saveDEPTH @ <>
\r
637 CSbuffer CSsaved @ CELLS + !
\r
641 : restoreCS ( -- ? )
\r
642 \ restore control structure information from the buffer to stack
\r
647 CSbuffer CSsaved @ CELLS + @
\r
651 : decompiler_jump ( -- )
\r
652 \ Under right conditions, compile a 'nodecomp @ IF'
\r
653 \ The possible change on data stack (IF) is cleared, so that
\r
654 \ words like LITERAL do not come into trouble.
\r
655 \ The Control Stack CS defined in the ANSI document may consist
\r
656 \ of some entries on the common data stack (which, indeed, is implemented
\r
657 \ in most Forth systems). But the data stack has to be unchanged by the
\r
658 \ debugger when compiling a word: ' ... [ 1 2 3 + + ] LITERAL ...'
\r
659 \ In this example, 'LITERAL' wants to compile the number 6, and not some
\r
660 \ token left on the stack by the decompiler's IF. For it is unknown,
\r
661 \ what IF will place in an arbitary Forth system, this complicated
\r
662 \ construction has to be made.
\r
663 STATE @ compiler_off? 0= AND
\r
665 DEPTH saveDEPTH ! \ DEPTH of stack 'before'
\r
666 POSTPONE nodecomp POSTPONE @
\r
667 POSTPONE IF \ now compile IF. It may change stack!
\r
668 saveCS \ stackeffect of IF removed
\r
669 decompilerIF ON \ ok, there is an IF
\r
673 : decompiler_target ( -- )
\r
674 \ Resolve the decompiler IF compiled
\r
677 restoreCS \ prepare stack with IF-values
\r
678 POSTPONE THEN \ and resolve the jump.
\r
679 decompilerIF OFF \ done!
\r
683 [ELSE] ( withDSEE )
\r
684 : decompiler_jump ; IMMEDIATE
\r
685 : decompiler_target ; IMMEDIATE
\r
686 [THEN] ( withDSEE )
\r
691 \ now construct a complete outer interpreter
\r
694 \ a special hack to allow F68KANS to handle files with tabs etc.
\r
696 [IF] blankbits [ELSE] BL [THEN]
\r
697 CONSTANT whitespace
\r
700 : create_debugging_code ( -- )
\r
702 creating_dbgcode @ >R creating_dbgcode ON
\r
703 BEGIN \ loop to EOF
\r
704 BEGIN \ loop to EOL
\r
705 whitespace WORD DUP C@
\r
709 endof_dbgd_def? IF POSTPONE -nest THEN
\r
711 wordbuf FIND ( c-addr 0 | xt +1 | xt -1 ) ?DUP
\r
715 IF compile_number ELSE compiler_error THEN
\r
718 endof_dbgd_def? IF R> creating_dbgcode ! EXIT ( **) THEN
\r
721 R> creating_dbgcode !
\r
730 \ Define the decompiler
\r
733 : DSEE ( <name> -- )
\r
734 \ Show a decompiler listing of a word compiled with the debugger.
\r
735 \ A non-debugger word will be executed instead.
\r
737 nodecomp @ >R FALSE nodecomp !
\r
738 debugstate @ >R [-I] [-V] [-S]
\r
744 : DSEE ( <name> -- )
\r
746 ." Debugger compiled without decompiler option! "
\r
752 \ Now the replacements for the code-beginning words.
\r
755 : debug: ( <name> -- )
\r
756 : create_debugging_code ;
\r
758 : debug:NONAME ( -- xt )
\r
759 :NONAME create_debugging_code ;
\r
763 creating_dbgcode @ IF POSTPONE -nest THEN
\r
764 \ when the decompiler is invoked between ':' and 'DOES>',
\r
765 \ there has to be a '-nest' compiled before 'DOES>'.
\r
766 POSTPONE DOES> create_debugging_code ;
\r
770 \ switching the debugger on and off
\r
772 VARIABLE debugging debugging OFF
\r
775 debugging ON ; IMMEDIATE
\r
778 debugging OFF ; IMMEDIATE
\r
782 \ reset the debugger
\r
787 creating_dbgcode OFF
\r
793 \ redefinition of the code generating defining words
\r
796 use_debugger @ debugging @ AND
\r
797 IF debug: ELSE : THEN ;
\r
799 : DOES> ( <name> -- )
\r
800 use_debugger @ debugging @ AND
\r
801 IF debugDOES> ELSE POSTPONE DOES> THEN ; IMMEDIATE
\r
803 : :NONAME ( <name> -- )
\r
804 use_debugger @ debugging @ AND
\r
805 IF debug:NONAME ELSE :NONAME THEN ;
\r
812 .( The words for you are: ) CR
\r
813 .( +DEBUG -DEBUG to switch debugging on/off globally ) CR
\r
814 .( [DBG DBG] to envoke and terminate generation ) CR
\r
815 .( of debugging code at compiletime ) CR
\r
816 .( :WATCH ;WATCH Define a watch function returning a flag ) CR
\r
817 .( 0!WATCHES to remove all watch functions ) CR
\r
818 .( [+I] [-I] Interactive mode on/off ) CR
\r
819 .( [+S] [-S] Silent mode on/off ) CR
\r
820 .( [+V] [-V] Verbose mode on/off ) CR
\r
821 .( [>L] [Y] level targeting control ) CR
\r
822 .( [DEF] DEFault settings ) CR
\r
824 .( DSEE Decompile words compiled with debugger ) CR
\r
826 .( 0!DBG Reset the debugger when something goes wrong ) CR
\r