Diff for /gforth/see.fs between versions 1.9 and 1.64

version 1.9, 1995/11/07 18:06:59 version 1.64, 2008/02/12 16:44:58
Line 1 Line 1
 \ SEE.FS       highend SEE for ANSforth                16may93jaw  \ SEE.FS       highend SEE for ANSforth                16may93jaw
   
 \ Copyright (C) 1995 Free Software Foundation, Inc.  \ Copyright (C) 1995,2000,2003,2004,2006,2007 Free Software Foundation, Inc.
   
 \ This file is part of Gforth.  \ This file is part of Gforth.
   
 \ Gforth is free software; you can redistribute it and/or  \ Gforth is free software; you can redistribute it and/or
 \ modify it under the terms of the GNU General Public License  \ modify it under the terms of the GNU General Public License
 \ as published by the Free Software Foundation; either version 2  \ as published by the Free Software Foundation, either version 3
 \ of the License, or (at your option) any later version.  \ of the License, or (at your option) any later version.
   
 \ This program is distributed in the hope that it will be useful,  \ This program is distributed in the hope that it will be useful,
Line 15 Line 15
 \ GNU General Public License for more details.  \ GNU General Public License for more details.
   
 \ You should have received a copy of the GNU General Public License  \ You should have received a copy of the GNU General Public License
 \ along with this program; if not, write to the Free Software  \ along with this program. If not, see http://www.gnu.org/licenses/.
 \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
   
   
 \ May be cross-compiled  \ May be cross-compiled
Line 25 Line 24
   
 \ Ideas:        Level should be a stack  \ Ideas:        Level should be a stack
   
   require look.fs
   require termsize.fs
   require wordinfo.fs
   
 decimal  decimal
   
 \ Screen format words                                   16may93jaw  \ Screen format words                                   16may93jaw
Line 48  VARIABLE Level Line 51  VARIABLE Level
 : level-        -7 Level +! ;  : level-        -7 Level +! ;
   
 VARIABLE nlflag  VARIABLE nlflag
   VARIABLE uppercase      \ structure words are in uppercase
   
 DEFER nlcount ' noop IS nlcount  DEFER nlcount ' noop IS nlcount
   
 : nl            nlflag on ;  : nl            nlflag on ;
 : (nl)          nlcount  : (nl)          nlcount
                 XPos @ Level @ = ?Exit                  XPos @ Level @ = IF EXIT THEN \ ?Exit
                 C-Formated @ IF                  C-Formated @ IF
                 C-Output @                  C-Output @
                 IF C-Clearline @ IF 80 XPos @ - spaces                  IF C-Clearline @ IF cols XPos @ - spaces
                                  ELSE cr THEN                                   ELSE cr THEN
                 1 YPos +! 0 XPos !                  1 YPos +! 0 XPos !
                 Level @ spaces                  Level @ spaces
Line 64  DEFER nlcount ' noop IS nlcount Line 68  DEFER nlcount ' noop IS nlcount
   
 : warp?         ( len -- len )  : warp?         ( len -- len )
                 nlflag @ IF (nl) nlflag off THEN                  nlflag @ IF (nl) nlflag off THEN
                 XPos @ over + 79 u> IF (nl) THEN ;                  XPos @ over + cols u>= IF (nl) THEN ;
   
 : ctype         ( adr len -- )  : ctype         ( adr len -- )
                 warp? dup XPos +! C-Output @ IF type ELSE 2drop THEN ;                  warp? dup XPos +! C-Output @ 
                   IF uppercase @ IF bounds ?DO i c@ toupper emit LOOP
                                     uppercase off ELSE type THEN
                   ELSE 2drop THEN ;
   
 : cemit         1 warp?  : cemit         1 warp?
                 over bl = Level @ XPos @ = and                  over bl = Level @ XPos @ = and
                 IF 2drop ELSE XPos +! C-Output @ IF emit ELSE drop THEN                  IF 2drop ELSE XPos +! C-Output @ IF emit ELSE drop THEN
                 THEN ;                  THEN ;
   
 DEFER .string  DEFER .string ( c-addr u n -- )
   
 [IFDEF] Green  [IFDEF] Green
 VARIABLE Colors Colors on  VARIABLE Colors Colors on
Line 95  VARIABLE Colors Colors on Line 102  VARIABLE Colors Colors on
   
 ' (.string) IS .string  ' (.string) IS .string
   
   : c-\type ( c-addr u -- )
       \ type string in \-escaped form
       begin
           dup while
               2dup newline string-prefix? if
                   '\ cemit 'n cemit
                   newline nip /string
               else
                   over c@
                   dup '" = over '\ = or if
                       '\ cemit cemit
                   else
                       dup bl 127 within if
                           cemit
                       else
                           base @ >r try
                               8 base ! 0 <<# # # # '\ hold #> ctype #>> 0
                           restore
                               r@ base !
                           endtry
                           rdrop throw
                       endif
                   endif
                   1 /string
               endif
       repeat
       2drop ;
   
 : .struc        Str# .string ;  : .struc        
           uppercase on Str# .string ;
   
 \ CODES                                                 15may93jaw  \ CODES (Branchtypes)                                    15may93jaw
   
 21 CONSTANT RepeatCode  21 CONSTANT RepeatCode
 22 CONSTANT AgainCode  22 CONSTANT AgainCode
Line 108  VARIABLE Colors Colors on Line 143  VARIABLE Colors Colors on
 11 CONSTANT AheadCode  11 CONSTANT AheadCode
 13 CONSTANT WhileCode2  13 CONSTANT WhileCode2
 14 CONSTANT Disable  14 CONSTANT Disable
   15 CONSTANT LeaveCode
   
   
 \ FORMAT WORDS                                          13jun93jaw  \ FORMAT WORDS                                          13jun93jaw
   
 VARIABLE C-Stop  VARIABLE C-Stop
 VARIABLE Branches  VARIABLE Branches
   
 VARIABLE BranchPointer  VARIABLE BranchPointer  \ point to the end of branch table
 VARIABLE SearchPointer  VARIABLE SearchPointer
 CREATE BranchTable 500 allot  
   \ The branchtable consists of three entrys:
   \ address of branch , branch destination , branch type
   
   CREATE BranchTable 128 cells allot
 here 3 cells -  here 3 cells -
 ACONSTANT MaxTable  ACONSTANT MaxTable
   
 : FirstBranch BranchTable cell+ SearchPointer ! ;  : FirstBranch BranchTable cell+ SearchPointer ! ;
   
 : (BranchAddr?) ( a-addr -- a-addr true | false )  : (BranchAddr?) ( a-addr1 -- a-addr2 true | false )
   \ searches a branch with destination a-addr1
   \ a-addr1: branch destination
   \ a-addr2: pointer in branch table
         SearchPointer @          SearchPointer @
         BEGIN   dup BranchPointer @ u<          BEGIN   dup BranchPointer @ u<
         WHILE          WHILE
Line 151  ACONSTANT MaxTable Line 195  ACONSTANT MaxTable
         2drop true          2drop true
         THEN ;          THEN ;
   
   : MyBranch      ( a-addr -- a-addr a-addr2 )
   \ finds branch table entry for branch at a-addr
                   dup @
                   BranchAddr?
                   BEGIN
                   WHILE 1 cells - @
                         over <>
                   WHILE dup @
                         MoreBranchAddr?
                   REPEAT
                   SearchPointer @ 3 cells -
                   ELSE    true ABORT" SEE: Table failure"
                   THEN ;
   
 \  \
 \                 addrw               addrt  \                 addrw               addrt
 \       BEGIN ... WHILE ... AGAIN ... THEN  \       BEGIN ... WHILE ... AGAIN ... THEN
Line 182  ACONSTANT MaxTable Line 240  ACONSTANT MaxTable
         BranchPointer @ 1 cells - ! ;          BranchPointer @ 1 cells - ! ;
   
 : Branch! ( a-addr rel -- a-addr )  : Branch! ( a-addr rel -- a-addr )
         over + over ,Branch ,Branch 0 ,Branch ;      over ,Branch ,Branch 0 ,Branch ;
   \        over + over ,Branch ,Branch 0 ,Branch ;
   
 \ DEFER CheckUntil  \ DEFER CheckUntil
 VARIABLE NoOutput  VARIABLE NoOutput
Line 196  VARIABLE C-Pass Line 255  VARIABLE C-Pass
 : Display? ( -- flag ) C-Pass @ 1 = ;  : Display? ( -- flag ) C-Pass @ 1 = ;
 : Debug? ( -- flag ) C-Pass @ 2 = ;  : Debug? ( -- flag ) C-Pass @ 2 = ;
   
 : back? ( n -- flag ) 0< ;  : back? ( addr target -- addr flag )
 : ahead? ( n -- flag ) 0> ;      over u< ;
   
 : c-(compile)  
         Display? IF s" POSTPONE " Com# .string  
                     dup @ look 0= ABORT" SEE: No valid XT"  
                     cell+ count $1F and 0 .string bl cemit  
                  THEN  
         cell+ ;  
   
 : c-lit  : .word ( addr x -- addr )
     Display? IF      \ print x as a word if possible
         dup @ dup abs 0 <# #S rot sign #> 0 .string bl cemit      dup look 0= IF
           drop dup threaded>name dup 0= if
               drop over 1 cells - @ dup body> look
               IF
                   nip nip dup ." <" name>string rot wordinfo .string ." > "
               ELSE
                   2drop ." <" 0 .r ." > "
               THEN
               EXIT
           then
     THEN      THEN
     cell+ ;      nip dup cell+ @ immediate-mask and
       IF
           bl cemit  ." POSTPONE "
       THEN
       dup name>string rot wordinfo .string
       ;
   
 : c-@local#  : c-call ( addr1 -- addr2 )
     Display? IF      Display? IF
         S" @local" 0 .string          dup @ body> .word bl cemit
         dup @ dup 1 cells / abs 0 <# #S rot sign #> 0 .string bl cemit  
     THEN      THEN
     cell+ ;      cell+ ;
   
 : c-flit  : c-callxt ( addr1 -- addr2 )
     Display? IF  
         dup f@ scratch represent 0=  
         IF    2drop  scratch 3 min 0 .string  
         ELSE  
             IF  '- cemit  THEN  1-  
             scratch over c@ cemit '. cemit 1 /string 0 .string  
             'E cemit  
             dup abs 0 <# #S rot sign #> 0 .string bl cemit  
         THEN THEN  
     float+ ;  
   
 : c-f@local#  
     Display? IF      Display? IF
         S" f@local" 0 .string          dup @ .word bl cemit
         dup @ dup 1 floats / abs 0 <# #S rot sign #> 0 .string bl cemit  
     THEN      THEN
     cell+ ;      cell+ ;
   
 : c-laddr#  \ here docon: , docol: , dovar: , douser: , dodefer: , dofield: ,
   \ here over - 2constant doers
   
   : c-lit ( addr1 -- addr2 )
     Display? IF      Display? IF
         S" laddr# " 0 .string          dup @ dup body> dup cfaligned over = swap in-dictionary? and if
         dup @ dup abs 0 <# #S rot sign #> 0 .string bl cemit              ( addr1 addr1@ )
     THEN              dup body> @ dovar: = if
                   drop c-call EXIT
               endif
           endif
           \ !! test for cfa here, and print "['] ..."
           dup abs 0 <# #S rot sign #> 0 .string bl cemit
       endif
     cell+ ;      cell+ ;
   
 : c-lp+!#  : c-lit+ ( addr1 -- addr2 )
     Display? IF      Display? if
         S" lp+!# " 0 .string  
         dup @ dup abs 0 <# #S rot sign #> 0 .string bl cemit          dup @ dup abs 0 <# #S rot sign #> 0 .string bl cemit
     THEN          s" + " 0 .string
       endif
     cell+ ;      cell+ ;
   
 : c-s"  : .name-without ( addr -- addr )
         count 2dup + aligned -rot      \ !! the stack effect cannot be correct
         Display?      \ prints a name without a() e.g. a(+LOOP) or (s")
         IF      [char] S cemit [char] " cemit bl cemit 0 .string      dup 1 cells - @ threaded>name dup IF
                 [char] " cemit bl cemit          name>string over c@ 'a = IF
         ELSE    2drop              1 /string
         THEN ;          THEN
            over c@ '( = IF
 : c-."              1 /string
         count 2dup + aligned -rot          THEN
         Display?          2dup + 1- c@ ') = IF 1- THEN .struc ELSE drop 
         IF      [char] . cemit      THEN ;
                 [char] " cemit bl cemit 0 .string  
                 [char] " cemit bl cemit  
         ELSE    2drop  
         THEN ;  
   
   [ifdef] (s")
 : c-c"  : c-c"
           Display? IF nl .name-without THEN
         count 2dup + aligned -rot          count 2dup + aligned -rot
         Display?          Display?
         IF      [char] C cemit [char] " cemit bl cemit 0 .string          IF      bl cemit 0 .string
                 [char] " cemit bl cemit                  [char] " cemit bl cemit
         ELSE    2drop          ELSE    2drop
         THEN ;          THEN ;
   [endif]
   
   : c-string? ( addr1 -- addr2 f )
       \ f is true if a string was found and decompiled.
       \ if f is false, addr2=addr1
       \ recognizes the following patterns:
       \ c":     ahead X: len string then lit X
       \ flit:   ahead X: float      then lit X f@
       \ s\":    ahead X: string     then lit X lit len
       \ .\":    ahead X: string     then lit X lit len type
       \ !! not recognized anywhere:
       \ abort": if ahead X: len string then lit X c(abort") then
       dup @ back? if false exit endif
       dup @ >r
       r@ @ decompile-prim ['] lit xt>threaded <> if rdrop false exit endif
       r@ cell+ @ over cell+ <> if rdrop false exit endif
       \ we have at least C"
       r@ 2 cells + @ decompile-prim dup ['] lit xt>threaded = if
           drop r@ 3 cells + @ over cell+ + aligned r@ = if
               \ we have at least s"
               r@ 4 cells + @ decompile-prim ['] lit-perform xt>threaded =
               r@ 5 cells + @ ['] type >body = and if
                   6 s\" .\\\" "
               else
                   4 s\" s\\\" "
               endif
               \ !! make newline if string too long?
               display? if
                   0 .string r@ cell+ @ r@ 3 cells + @ c-\type '" cemit bl cemit
               else
                   2drop
               endif
               nip cells r> + true exit
           endif
       endif
       ['] f@ xt>threaded = if
           display? if
               r@ cell+ @ f@ 10 8 16 f>str-rdp 0 .string bl cemit
           endif
           drop r> 3 cells + true exit
       endif
       \ !! check if count matches space?
       display? if
           s\" c\" " 0 .string r@ cell+ @ count 0 .string '" cemit bl cemit
       endif
       drop r> 2 cells + true ;
   
   : Forward? ( a-addr true | false -- a-addr true | false )
       \ a-addr is pointer into branch table
       \ returns true when jump is a forward jump
       IF
           dup dup @ swap 1 cells - @ u> IF
               true
           ELSE
               drop false
           THEN
           \ only if forward jump
       ELSE
           false
       THEN ;
   
 : Forward? ( a-addr true | false -- )  : RepeatCheck ( a-addr1 a-addr2 true | false -- false )
         IF      dup dup @ swap 1 cells - @ -  
                 Ahead? IF true ELSE drop false THEN  
                 \ only if forward jump  
         ELSE    false THEN ;  
   
 : RepeatCheck  
         IF  BEGIN  2dup          IF  BEGIN  2dup
                    1 cells - @ swap dup @ +                     1 cells - @ swap @
                    u<=                     u<=
             WHILE  drop dup cell+              WHILE  drop dup cell+
                    MoreBranchAddr? 0=                     MoreBranchAddr? 0=
Line 296  VARIABLE C-Pass Line 408  VARIABLE C-Pass
         ELSE false          ELSE false
         THEN ;          THEN ;
   
 : c-branch  : c-branch ( addr1 -- addr2 )
       c-string? ?exit
         Scan?          Scan?
         IF      dup @ Branch!          IF      dup @ Branch!
                 dup @ back?                  dup @ back?
Line 323  VARIABLE C-Pass Line 436  VARIABLE C-Pass
                         IF      drop S" REPEAT " .struc nl                          IF      drop S" REPEAT " .struc nl
                         ELSE    S" AGAIN " .struc nl                          ELSE    S" AGAIN " .struc nl
                         THEN                          THEN
                 ELSE    dup cell+ BranchAddr? Forward?                  ELSE    MyBranch cell+ @ LeaveCode =
                         IF      dup cell+ @ WhileCode2 =                          IF      S" LEAVE " .struc
                                 IF nl S" ELSE" .struc level+                          ELSE
                                 ELSE level- nl S" ELSE" .struc level+ THEN                                  dup cell+ BranchAddr? Forward?
                                 cell+ Disable swap !                                  IF      dup cell+ @ WhileCode2 =
                         ELSE    S" AHEAD" .struc level+                                          IF nl S" ELSE" .struc level+
                         THEN                                          ELSE level- nl S" ELSE" .struc level+ THEN
                                           cell+ Disable swap !
                                   ELSE    S" AHEAD" .struc level+
                                   THEN
                           THEN
                 THEN                  THEN
         THEN          THEN
         Debug?          Debug?
         IF      dup @ +          IF      @ \ !!! cross-interacts with debugger !!!
         ELSE    cell+          ELSE    cell+
         THEN ;          THEN ;
   
 : MyBranch      ( a-addr -- a-addr a-addr2 )  
                 dup @ over +  
                 BranchAddr?  
                 BEGIN  
                 WHILE 1 cells - @  
                       over <>  
                 WHILE dup @ over +  
                       MoreBranchAddr?  
                 REPEAT  
                 SearchPointer @ 3 cells -  
                 ELSE    true ABORT" SEE: Table failure"  
                 THEN ;  
   
 : DebugBranch  : DebugBranch
         Debug?          Debug?
         IF      dup @ over + swap THEN ; \ return 2 different addresses          IF      dup @ swap THEN ; \ return 2 different addresses
   
 : c-?branch  : c-?branch
         Scan?          Scan?
Line 372  VARIABLE C-Pass Line 476  VARIABLE C-Pass
                                 level- nl                                  level- nl
                                 S" WHILE " .struc                                  S" WHILE " .struc
                                 level+                                  level+
                         ELSE    nl S" IF " .struc level+                          ELSE    MyBranch cell+ @ LeaveCode =
                                   IF   s" 0= ?LEAVE " .struc
                                   ELSE nl S" IF " .struc level+
                                   THEN
                         THEN                          THEN
                 THEN                  THEN
         THEN          THEN
         DebugBranch          DebugBranch
         cell+ ;          cell+ ;
   
 : c-?branch-lp+!#  c-?branch cell+ ;  
 : c-branch-lp+!#   c-branch  cell+ ;  
   
 : c-do  
         Display? IF nl S" DO" .struc level+ THEN ;  
   
 : c-?do  
         Display? IF nl S" ?DO" .struc level+ THEN  
         DebugBranch cell+ ;  
   
 : c-for  : c-for
         Display? IF nl S" FOR" .struc level+ THEN ;          Display? IF nl S" FOR" .struc level+ THEN ;
   
 : c-next  
         Display? IF level- nl S" NEXT " .struc nl THEN  
         DebugBranch cell+ cell+ ;  
   
 : c-loop  : c-loop
         Display? IF level- nl S" LOOP " .struc nl THEN          Display? IF level- nl .name-without nl bl cemit THEN
         DebugBranch cell+ cell+ ;          DebugBranch cell+ 
           Scan? 
           IF      dup BranchAddr? 
                   BEGIN   WHILE cell+ LeaveCode swap !
                           dup MoreBranchAddr?
                   REPEAT
           THEN
           cell+ ;
   
 : c-+loop  : c-do
         Display? IF level- nl S" +LOOP " .struc nl THEN          Display? IF nl .name-without level+ THEN ;
         DebugBranch cell+ cell+ ;  
   
 : c-s+loop  
         Display? IF level- nl S" S+LOOP " .struc nl THEN  
         DebugBranch cell+ cell+ ;  
   
 : c--loop  
         Display? IF level- nl S" -LOOP " .struc nl THEN  
         DebugBranch cell+ cell+ ;  
   
 : c-next-lp+!#  c-next cell+ ;  
 : c-loop-lp+!#  c-loop cell+ ;  
 : c-+loop-lp+!#  c-+loop cell+ ;  
 : c-s+loop-lp+!#  c-s+loop cell+ ;  
 : c--loop-lp+!#  c--loop cell+ ;  
   
 : c-leave  
         Display? IF S" LEAVE " .struc THEN  
         Debug? IF dup @ + THEN cell+ ;  
   
 : c-?leave  
         Display? IF S" ?LEAVE " .struc THEN  
         cell+ DebugBranch swap cell+ swap cell+ ;  
   
 : c-exit  dup 1 cells -  
         CheckEnd  
         IF      Display? IF nlflag off S" ;" Com# .string THEN  
                 C-Stop on  
         ELSE    Display? IF S" EXIT " .struc THEN  
         THEN  
         Debug? IF drop THEN ;  
   
 : c-does>               \ end of create part  : c-?do ( addr1 -- addr2 )
         Display? IF S" DOES> " Com# .string THEN      Display? IF
         Cell+ cell+ ;          nl .name-without level+
       THEN
       DebugBranch cell+ ;
   
   : c-exit ( addr1 -- addr2 )
       dup 1 cells -
       CheckEnd
       IF
           Display? IF nlflag off S" ;" Com# .string THEN
           C-Stop on
       ELSE
           Display? IF S" EXIT " .struc THEN
       THEN
       Debug? IF drop THEN ; \ !!! cross-interacts with debugger !!!
   
 : c-abort"  : c-abort"
         count 2dup + aligned -rot          count 2dup + aligned -rot
Line 447  VARIABLE C-Pass Line 529  VARIABLE C-Pass
         ELSE    2drop          ELSE    2drop
         THEN ;          THEN ;
   
   [IFDEF] (does>)
   : c-does>               \ end of create part
           Display? IF S" DOES> " Com# .string THEN
           maxaligned /does-handler + ;
   [THEN]
   
   [IFDEF] (compile)
   : c-(compile)
       Display?
       IF
           s" POSTPONE " Com# .string
           dup @ look 0= ABORT" SEE: No valid XT"
           name>string 0 .string bl cemit
       THEN
       cell+ ;
   [THEN]
   
 CREATE C-Table  CREATE C-Table
         ' lit A,            ' c-lit A,                  ' lit A,            ' c-lit A,
         ' @local# A,        ' c-@local# A,                  ' does-exec A,      ' c-callxt A,
         ' flit A,           ' c-flit A,                  ' lit@ A,           ' c-call A,
         ' f@local# A,       ' c-f@local# A,  [IFDEF] call    ' call A,           ' c-call A, [THEN]
         ' laddr# A,         ' c-laddr# A,  \               ' useraddr A,       ....
         ' lp+!# A,          ' c-lp+!# A,                  ' lit-perform A,    ' c-call A,
         ' (s") A,           ' c-s" A,                  ' lit+ A,           ' c-lit+ A,
         ' (.") A,           ' c-." A,  [IFDEF] (s")    ' (s") A,           ' c-c" A, [THEN]
         ' "lit A,           ' c-c" A,  [IFDEF] (.")    ' (.") A,           ' c-c" A, [THEN]
         ' leave A,          ' c-leave A,  [IFDEF] "lit    ' "lit A,           ' c-c" A, [THEN]
         ' ?leave A,         ' c-?leave A,  [IFDEF] (c")    ' (c") A,           ' c-c" A, [THEN]
         ' (do) A,           ' c-do A,                  ' (do) A,           ' c-do A,
         ' (?do) A,          ' c-?do A,  [IFDEF] (+do)   ' (+do) A,          ' c-?do A, [THEN]
         ' (for) A,          ' c-for A,  [IFDEF] (u+do)  ' (u+do) A,         ' c-?do A, [THEN]
         ' ?branch A,        ' c-?branch A,  [IFDEF] (-do)   ' (-do) A,          ' c-?do A, [THEN]
         ' branch A,         ' c-branch A,  [IFDEF] (u-do)  ' (u-do) A,         ' c-?do A, [THEN]
         ' (loop) A,         ' c-loop A,                  ' (?do) A,          ' c-?do A,
         ' (+loop) A,        ' c-+loop A,                  ' (for) A,          ' c-for A,
         ' (s+loop) A,       ' c-s+loop A,                  ' ?branch A,        ' c-?branch A,
         ' (-loop) A,        ' c--loop A,                  ' branch A,         ' c-branch A,
         ' (next) A,         ' c-next A,                  ' (loop) A,         ' c-loop A,
         ' ?branch-lp+!# A,  ' c-?branch-lp+!# A,                  ' (+loop) A,        ' c-loop A,
         ' branch-lp+!# A,   ' c-branch-lp+!# A,  [IFDEF] (s+loop) ' (s+loop) A,      ' c-loop A, [THEN]
         ' (loop)-lp+!# A,   ' c-loop-lp+!# A,  [IFDEF] (-loop) ' (-loop) A,        ' c-loop A, [THEN]
         ' (+loop)-lp+!# A,  ' c-+loop-lp+!# A,                  ' (next) A,         ' c-loop A,
         ' (s+loop)-lp+!# A, ' c-s+loop-lp+!# A,                  ' ;s A,             ' c-exit A,
         ' (-loop)-lp+!# A,  ' c--loop-lp+!# A,  [IFDEF] (abort") ' (abort") A,      ' c-abort" A, [THEN]
         ' (next)-lp+!# A,   ' c-next-lp+!# A,  \ only defined if compiler is loaded
         ' ;s A,             ' c-exit A,  [IFDEF] (compile) ' (compile) A,      ' c-(compile) A, [THEN]
         ' (does>) A,        ' c-does> A,  [IFDEF] (does>) ' (does>) A,        ' c-does> A, [THEN]
         ' (abort") A,       ' c-abort" A,                  0 ,             here 0 ,
         ' (compile) A,      ' c-(compile) A,  
         0 ,  avariable c-extender
   c-extender !
   
 \ DOTABLE                                               15may93jaw  \ DOTABLE                                               15may93jaw
   
 : DoTable ( cfa -- flag )  : DoTable ( ca/cfa -- flag )
         C-Table      decompile-prim C-Table BEGIN ( cfa table-entry )
         BEGIN   dup @ dup          dup @ dup 0=  IF
         WHILE   2 pick <>              drop cell+ @ dup IF ( next table!)
         WHILE   2 cells +                  dup @
         REPEAT              ELSE ( end!)
         nip cell+ @ EXECUTE                  2drop false EXIT
         true              THEN 
         ELSE          THEN
         2drop drop false          \ jump over to extender, if any 26jan97jaw
         THEN ;          xt>threaded 2 pick <>
       WHILE
               2 cells +
       REPEAT
       nip cell+ perform
       true
   ;
   
 : BranchTo? ( a-addr -- a-addr )  : BranchTo? ( a-addr -- a-addr )
         Display?  IF     dup BranchAddr?          Display?  IF    dup BranchAddr?
                         IF BEGIN cell+ @ dup 20 u>                          IF
                                   BEGIN cell+ @ dup 20 u>
                                 IF drop nl S" BEGIN " .struc level+                                  IF drop nl S" BEGIN " .struc level+
                                 ELSE                                  ELSE
                                   dup Disable <>                                    dup Disable <> over LeaveCode <> and
                                   IF   WhileCode2 =                                    IF   WhileCode2 =
                                        IF nl S" THEN " .struc nl ELSE                                         IF nl S" THEN " .struc nl ELSE
                                        level- nl S" THEN " .struc nl THEN                                         level- nl S" THEN " .struc nl THEN
Line 514  CREATE C-Table Line 620  CREATE C-Table
                   THEN ;                    THEN ;
   
 : analyse ( a-addr1 -- a-addr2 )  : analyse ( a-addr1 -- a-addr2 )
         Branches @ IF BranchTo? THEN      Branches @ IF BranchTo? THEN
         dup cell+ swap @      dup cell+ swap @
         dup >r DoTable r> swap IF drop EXIT THEN      dup >r DoTable r> swap IF drop EXIT THEN
         Display?      Display?
         IF look 0= IF  drop dup 1 cells - @ .  \ ABORT" SEE: Bua!"      IF
            ELSE  dup cell+ count 31 and rot wordinfo .string  THEN  bl cemit          .word bl cemit
         ELSE drop      ELSE
         THEN ;          drop
       THEN ;
   
 : c-init  : c-init
         0 YPos ! 0 XPos !          0 YPos ! 0 XPos !
Line 531  CREATE C-Table Line 638  CREATE C-Table
         Branches on ;          Branches on ;
   
 : makepass ( a-addr -- )  : makepass ( a-addr -- )
         c-stop off      c-stop off
         BEGIN      BEGIN
                 analyse          analyse
                 c-stop @          c-stop @
         UNTIL drop ;      UNTIL drop ;
   
 DEFER dosee  Defer xt-see-xt ( xt -- )
   \ this one is just a forward declaration for indirect recursion
 : dopri .name ." is primitive" cr ;  
 : dovar ." Variable " .name cr ;  : .defname ( xt c-addr u -- )
 : douse ." User " .name cr ;      rot look
 : docon  dup cell+ (name>) >body @ . ." Constant " .name cr ;      if ( c-addr u nfa )
 : doval  dup cell+ (name>) >body @ . ." Value " .name cr ;          -rot type space .name
 : dodef ." Defer " dup >r .name cr      else
     r@ cell+ (name>) >body @ look          drop ." noname " type
     0= ABORT" SEE: No valid xt in deferred word"      then
     dup dosee cr      space ;
     ." ' " .name r> ." IS " .name cr ;  
 : dodoe ." Create " dup .name cr  Defer discode ( addr u -- ) \ gforth
         S" DOES> " Com# .string XPos @ Level ! name>  \G hook for the disassembler: disassemble code at addr of length u
         >does-code dup C-Pass @ DebugMode = IF ScanMode c-pass ! EXIT THEN  ' dump IS discode
         ScanMode c-pass ! dup makepass  
         DisplayMode c-pass ! makepass ;  : next-head ( addr1 -- addr2 ) \ gforth
 : doali here @ .name ." Alias " .name cr      \G find the next header starting after addr1, up to here (unreliable).
         here @ dosee ;      here swap u+do
 : docol S" : " Com# .string          i head? -2 and if
         dup cell+ count $1F and 2 pick wordinfo .string bl cemit bl cemit              i unloop exit
         ( XPos @ ) 2 Level !          then
         name> >body      cell +loop
         C-Pass @ DebugMode = IF ScanMode c-pass ! EXIT THEN      here ;
         ScanMode c-pass ! dup makepass  
         DisplayMode c-pass ! makepass ;  [ifundef] umin \ !! bootstrapping help
   : umin ( u1 u2 -- u )
 create wordtypes      2dup u>
         Pri# ,   ' dopri A,      if
         Var# ,   ' dovar A,          swap
         Con# ,   ' docon A,      then
         Val# ,   ' doval A,      drop ;
         Def# ,   ' dodef A,  [then]
         Doe# ,   ' dodoe A,  
         Ali# ,   ' doali A,  : next-prim ( addr1 -- addr2 ) \ gforth
         Col# ,   ' docol A,      \G find the next primitive after addr1 (unreliable)
         Use# ,   ' douse A,      1+ >r -1 primstart
         0 ,      begin ( umin head R: boundary )
           @ dup
 : (dosee) ( lfa -- )      while
         dup dup cell+ c@ >r          tuck name>int >code-address ( head1 umin ca R: boundary )
         wordinfo          r@ - umin
         wordtypes          swap
         BEGIN dup @ dup      repeat
         WHILE 2 pick = IF cell+ @ nip EXECUTE      drop dup r@ negate u>=
                           r> dup 32 and IF ."  immediate" THEN      \ "umin+boundary within [0,boundary)" = "umin within [-boundary,0)"
                                  64 and IF ."  restrict" THEN EXIT THEN      if ( umin R: boundary ) \ no primitive found behind -> use a default length
               2 cells +          drop 31
         REPEAT      then
         2drop rdrop      r> + ;
         .name ." Don't know how to handle" cr ;  
   : seecode ( xt -- )
 ' (dosee) IS dosee      dup s" Code" .defname
       >code-address
 : xtc ( xt -- )       \ do see at xt      dup in-dictionary? \ user-defined code word?
         Look 0= ABORT" SEE: No valid XT"      if
         cr c-init          dup next-head
         dosee ;      else
           dup next-prim
 : see   name sfind 0= IF ." Word unknown" cr exit THEN      then
         xtc ;      over - discode
       ." end-code" cr ;
 : lfc   cr c-init cell+ dosee ;  : seevar ( xt -- )
 : nfc   cr c-init dosee ;      s" Variable" .defname cr ;
   : seeuser ( xt -- )
       s" User" .defname cr ;
   : seecon ( xt -- )
       dup >body ?
       s" Constant" .defname cr ;
   : seevalue ( xt -- )
       dup >body ?
       s" Value" .defname cr ;
   : seedefer ( xt -- )
       dup >body @ xt-see-xt cr
       dup s" Defer" .defname cr
       >name ?dup-if
           ." IS " .name cr
       else
           ." latestxt >body !"
       then ;
   : see-threaded ( addr -- )
       C-Pass @ DebugMode = IF
           ScanMode c-pass !
           EXIT
       THEN
       ScanMode c-pass ! dup makepass
       DisplayMode c-pass ! makepass ;
   : seedoes ( xt -- )
       dup s" create" .defname cr
       S" DOES> " Com# .string XPos @ Level !
       >does-code see-threaded ;
   : seecol ( xt -- )
       dup s" :" .defname nl
       2 Level !
       >body see-threaded ;
   : seefield ( xt -- )
       dup >body ." 0 " ? ." 0 0 "
       s" Field" .defname cr ;
   
   : xt-see ( xt -- ) \ gforth
       \G Decompile the definition represented by @i{xt}.
       cr c-init
       dup >does-code
       if
           seedoes EXIT
       then
       dup xtprim?
       if
           seecode EXIT
       then
       dup >code-address
       CASE
           docon: of seecon endof
   [IFDEF] dovalue:
           dovalue: of seevalue endof
   [THEN]
           docol: of seecol endof
           dovar: of seevar endof
   [IFDEF] douser:
           douser: of seeuser endof
   [THEN]
   [IFDEF] dodefer:
           dodefer: of seedefer endof
   [THEN]
   [IFDEF] dofield:
           dofield: of seefield endof
   [THEN]
           over       of seecode endof \ direct threaded code words
           over >body of seecode endof \ indirect threaded code words
           2drop abort" unknown word type"
       ENDCASE ;
   
   : (xt-see-xt) ( xt -- )
       xt-see cr ." latestxt" ;
   ' (xt-see-xt) is xt-see-xt
   
   : (.immediate) ( xt -- )
       ['] execute = if
           ."  immediate"
       then ;
   
   : name-see ( nfa -- )
       dup name>int >r
       dup name>comp 
       over r@ =
       if \ normal or immediate word
           swap xt-see (.immediate)
       else
           r@ ['] ticking-compile-only-error =
           if \ compile-only word
               swap xt-see (.immediate) ."  compile-only"
           else \ interpret/compile word
               r@ xt-see-xt cr
               swap xt-see-xt cr
               ." interpret/compile: " over .name drop
           then
       then
       rdrop drop ;
   
   : see ( "<spaces>name" -- ) \ tools
       \G Locate @var{name} using the current search order. Display the
       \G definition of @var{name}. Since this is achieved by decompiling
       \G the definition, the formatting is mechanised and some source
       \G information (comments, interpreted sequences within definitions
       \G etc.) is lost.
       name find-name dup 0=
       IF
           drop -&13 throw
       THEN
       name-see ;
   
   

Removed from v.1.9  
changed lines
  Added in v.1.64


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>