anderson@uwvax.ARPA (05/03/84)
<> Single-stepping in Forth is not hard if you understand how the virtual machine works and how it is implemented. The key is to modify only the "inner interpreter", the piece of code that transfers control from one word to the next. All it does is, roughly speaking, MOV (IP)+,W JMP @(W) where IP and W are Forth virtual registers (IP is like a program counter). How this is implemented depends on your machine, but it is not complicated. You can implement single stepping by inserting a call to your debugging routine before or after the MOV. This assumes the routine is assembler, not Forth. If it's Forth things are messier because you don't want debugging routine single-stepping through itself. There is probably some way to do it involving a flag. The only other way of doing single stepping I can think of is to modify "docol" (the code pointed to by the CFA of colon definitions). However, this would not really be single stepping because it would not "break" at the start of "code" words. I used single-stepping while I was bringing up Forth on my 6809 system; the inner interpreter contained a couple of NOPs for this very purpose, and I replace them with a jump to the monitor. One thing, though, is that you have to do an awful lot of single stepping to get anywhere. Hope this helps -- David Anderson (anderson@uwvax (or wisc-rsch, as they call it now))
liberte@uiucdcs.UUCP (05/08/84)
#R:uwvax:-24100:uiucdcs:30900008:000:2039 uiucdcs!liberte May 8 15:05:00 1984 Although the single stepping methods suggested by Dave Anderson may be helpful, particularly in bringing up a new system, neither of them do what I had in mind, as stated. They are both "global" stepping, in that they would step through everything (except code words). What I wanted was "local" stepping that would step through just the words I choose. To do this by changing (modifying the compiled code of) either the inner interpreter (;S, I believe) or the docol word, one would also have to have a table of words that are being stepped through and the stepper would have to continuously determine whether it is supposed to step through the current word. Blechkt! The alternative is, as I suggested, to change just the CFA of those words which you wish to step through and have the stepper control the interpreting of those words. Then the inner interpreter would always return to the stepper as each subword finished. A schematic of the stepper follows. : step ( instead of docol for stepped words ) magic words to initialize begin load next subword address display name of subword prompt for command if step then execute subword ( return here ) more magic words again ; Another approach is to have the stepper change the subword address following the next subword to reference the stepper again so that after the next subword returns, the stepper is activated again. This would act like a series of breakpoints. The problem here, as with breakpoints, is that the address replaced by the stepper address must be saved and restored, probably on the return stack. Another more serious problem is that finding that address depends on what the next subword does. Literals stored in the code would have to be jumped over correctly. This is an argument for keeping literals in a separate place, as in Smalltalk, another threaded interpreted language of more appropriate design. Daniel LaLiberte, U of Illinois, Urbana-Champaign, Computer Science {moderation in all things - including moderation}