home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / wimpforth_2 / !WimpForth / debug < prev    next >
Encoding:
Text File  |  1996-03-21  |  18.9 KB  |  562 lines

  1. \ $Id: debug.f 1.1 1994/04/01 07:52:43 andrew Exp $
  2.  
  3. cr .( Loading the Debugger...)
  4.  
  5. \ use: &8000 128 dbg dump
  6. \  or: debug ?line       see interpret
  7.  
  8. 32 value max.rstack
  9.  
  10. only forth also definitions also hidden
  11.  
  12. : key-breaker   ( -- )
  13.                 noop ;
  14.  
  15. : breaker       ( -- )
  16.                 noop ;
  17.  
  18. : L.ID  ( nfa len -- )  swap dup .id  c@ 31 and 1+ - spaces  ;
  19.  
  20. new-chain dbg-next-cell
  21. new-chain dbg-nest-chain        ( cfa flag -- cfa false | true )
  22. new-chain .word-type-chain
  23.  
  24. vocabulary bug          also bug also definitions
  25.  
  26. \ Numeric printing words that do NOT use PAD !!!
  27.  
  28. : CHR>ASC   ( n -- char )
  29.         dup 9 > 7 and + 48 + ;
  30.  
  31. : &   ( n1 -- char n2 )
  32.         0 base @ um/mod swap chr>asc swap ;
  33.  
  34. : &S   ( n1 -- c1 c2 ... 0 )
  35.     BEGIN
  36.         & dup 0=
  37.         UNTIL ;
  38.         
  39. : <&   ( n -- 0 n )
  40.         0 swap ;
  41.         
  42. : &>  drop ;
  43.  
  44. : &TYPE   ( 0 c1 c2 ... -- )
  45.         BEGIN ?dup
  46.     WHILE emit
  47.     REPEAT ;
  48.  
  49. \ externally usable number display words that don't use PAD
  50.  
  51. : U%.   ( u -- )
  52.         <& &s &> &type space ;
  53.         
  54. : %.    ( n -- )
  55.         dup 0<
  56.         IF      abs ascii - emit
  57.         THEN u%. ;
  58.  
  59. : 0%.R  ( n -- )        \ display signed right justified except in HEX,
  60.                         \ then display unsigned
  61.         base @  0x10 <>
  62.         if      dup 0<
  63.                 IF      abs ascii - emit
  64.                 THEN
  65.         then    <& &s &> &type ;
  66.  
  67. : H%.   ( n -- )
  68.         base @ swap hex u%. base ! ;
  69.         
  70. : %.S   ( ... -- ... )
  71.         ?stack depth .smax @ min dup
  72.         IF      ." [" depth 1- 0%.r ." ] "
  73.         BEGIN
  74.                 dup pick 0%.r
  75.             base @ 0x10 =
  76.             IF  ." h" THEN
  77.             space
  78.             1- dup 0=
  79.                 UNTIL
  80.         ELSE    ."  empty "
  81.         THEN
  82.         drop ;
  83.         
  84. \ -------------------- Variables --------------------
  85.  
  86. variable ip  0 ,        \ ip & contents of current breakpoint
  87. variable ip0            \ ip at start of word
  88. variable rtop           \ top of return stack
  89. variable nesting        \ nesting level
  90.  
  91. 0 value ?dbg-cont       \ are we stepping contiuously
  92.  
  93. : patch  ( cfa -- )
  94.         ip @ @ ip cell+ !       \ save old word
  95.         ip @ ! ;                \ patch in trace word
  96.  
  97.  
  98. \ -------------------- Advance IP --------------------
  99.  
  100. : colon?        ( cfa -- f ) call@ ['] patch call@ = ;
  101.  
  102. : variable?     ( cfa -- f ) call@ ['] ip    call@ = ;
  103.  
  104. \ : code?         ( cfa -- f ) dup @ swap cell+ = ;
  105.  
  106. : defer?        ( cfa -- f ) @ ['] key   @ = ;
  107.  
  108. : execute?      ( cfa -- f )   ['] execute = ;
  109.  
  110. : constant?     ( cfa -- f ) call@ ['] 1     call@ = ;
  111.  
  112. : does>?        ( cfa -- f ) dup call@ swap @ over =
  113.                              if drop false else cell+ call@ dodoes = then ;
  114.  
  115. : m1cfa?        ( cfa -- f ) call@ m1cfa = ;
  116.  
  117. : m0cfa?        ( cfa -- f ) call@ m0cfa = ;
  118.  
  119. : ?JUMP  ( ip f -- ip' )  IF  CELL+ @  ELSE  2 CELLS +  THEN ;
  120.  
  121. : <STRING>  ( ip -- ip' )   CELL+ COUNT + 1+ ALIGNED ;
  122.  
  123. : <EXIT>  ( ip -- ip' )
  124.         drop nesting @ 0>
  125.         if      rtop @                          \ unnest level
  126.                 dup ?name ?dup
  127.                 if      ." Unnesting to: " .name
  128.                 then    -1 nesting +!
  129.         else    ip0 @   ( done, reset ip for next time )
  130.                 nesting off
  131.         then ;
  132.  
  133. : <EXITP>  ( ip -- ip' )
  134.         drop nesting @ 0>
  135.         if      lp @ cell+ @            \ unnest level
  136.                 dup ?name ?dup
  137.                 if      ." Unnesting to: " .name
  138.                 then    -1 nesting +!
  139.         else    ip0 @   ( done, reset ip for next time )
  140.                 nesting off
  141.         then ;
  142.  
  143. : <EXITM>  ( ip -- ip' )
  144.         drop nesting @ 0>
  145.         if      lp @ 2 cells+ @         \ unnest level
  146.                 -1 nesting +!
  147.         else    ip0 @   ( done, reset ip for next time )
  148.                 nesting off
  149.         then ;
  150.  
  151. : dbg-next  ( -- )
  152.    IP @   DUP @ CASE
  153.      ['] LIT      OF  2 CELLS+                                  ENDOF
  154.         &flit     of  cells/float cells+ cell+                  ENDOF
  155.      ['] (IS)     OF  2 CELLS+                                  ENDOF
  156.      ['] COMPILE  OF  2 CELLS+                                  ENDOF
  157.      ['] BRANCH   OF  TRUE ?JUMP                                ENDOF
  158.      ['] _endof   OF  TRUE ?JUMP                                ENDOF
  159.      ['] _again   OF  TRUE ?JUMP                                ENDOF
  160.      ['] _repeat  OF  TRUE ?JUMP                                ENDOF
  161.      ['] leave    of  drop rp@ 5 cells+ @                       ENDOF
  162.      ['] ?leave   of  over
  163.                       if    drop rp@ 5 cells+ @
  164.                       else  cell+ then                          ENDOF
  165.      ['] ?BRANCH  OF  OVER 0= ?JUMP                             ENDOF
  166.      ['] _until   OF  OVER 0= ?JUMP                             ENDOF
  167.      ['] _while   OF  OVER 0= ?JUMP                             ENDOF
  168.      ['] (DO)     OF  2 CELLS +                                 ENDOF
  169.      ['] (?DO)    OF  OVER 3 PICK = ?JUMP                       ENDOF
  170.      ['] (LOOP)   OF  1 RTOP @ +OV? NOT ?JUMP                   ENDOF
  171.      ['] (+LOOP)  OF  OVER RTOP @ +OV? NOT ?JUMP                ENDOF
  172.      ['] _OF      OF  OVER 3 PICK <> ?JUMP                      ENDOF
  173.      ['] (S")     OF  <STRING>                                  ENDOF
  174.      ['] (C")     OF  <STRING>                                  ENDOF
  175.      ['] (Z")     OF  <STRING>                                  ENDOF
  176.      ['] (.")     OF  <STRING>                                  ENDOF
  177.      ['] (ABORT") OF  <STRING>                                  ENDOF
  178.      'EXIT        OF  <EXIT>                                    ENDOF
  179.      ['] (;CODE)  OF  <EXIT>                                    ENDOF
  180.      ['] UNNEST   OF  <EXIT>                                    ENDOF
  181.      ['] EXITP    OF  <EXITP>                                   ENDOF
  182.      ['] UNNESTP  OF  <EXITP>                                   ENDOF
  183.      ['] EXITM    OF  <EXITM>                                   ENDOF
  184.      ['] UNNESTM  OF  <EXITM>                                   ENDOF
  185.   ['] init-locals OF  2 cells+                                  ENDOF
  186.    DUP @ M1CFA =  IF  SWAP CELL+ SWAP ( skip an extra cell )    THEN
  187.                       dbg-next-cell do-chain
  188.                       SWAP CELL+ SWAP
  189.    ENDCASE   IP ! ;
  190.  
  191.  
  192. \ -------------------- Trace Commands --------------------
  193.  
  194. defer debug-entry       ' noop is debug-entry   \ application init stuff
  195. defer debug-exit        ' noop is debug-exit    \ application un-init stuff
  196.  
  197. create tib-save         260 allot
  198. create pocket-save      260 allot
  199. create here-save        260 allot
  200. create watch-buf        260 allot       watch-buf off   \ empty to start
  201.  
  202. : perform-watch ( -- )
  203.                 watch-buf count evaluate ;
  204.  
  205. : do-watch      ( -- )
  206.                 watch-buf c@ 0= ?exit
  207.                 cr ." Watch-[" watch-buf count type ." ]: "
  208.                 ['] perform-watch catch drop ;
  209.  
  210. : run-forth
  211.         here   here-save     255 move
  212.         pocket pocket-save   255 move
  213.         source tib-save swap 255 min move      \ save SOURCE buffer
  214.         (source) 2@ 2>r >in @ >r                \ save SOURCE and >IN
  215.         begin   cr ." forth>  "
  216.                 query  source nip
  217.         while   ['] interpret catch
  218.                 if      ." <- interpret error!" beep
  219.                 then
  220.         repeat
  221.         r> >in ! 2r> (source) 2!                \ restore SOURCE and >IN
  222.         tib-save source move                    \ restore SOURCE buffer
  223.         pocket-save pocket 255 move
  224.         here-save   here   255 move ;
  225.  
  226. : dbg-watch     ( -- )
  227.         cr ." Enter a line to interpret after each instruction step is performed:"
  228.         cr watch-buf 1+ 255 accept watch-buf c! ;
  229.  
  230. 0 value emit-save
  231. 0 value type-save
  232. 0 value cr-save
  233. 0 value key-save
  234. 0 value key?-save
  235. 0 value cls-save
  236. 0 value gotoxy-save
  237. 0 value getxy-save
  238. 0 value tabing?-save
  239. 0 value left-margin-save
  240. 0 value indent-save
  241. 0 value x-save
  242. 0 value y-save
  243.  
  244. : _dbg-nest  ( cfa -- )
  245.         false dbg-nest-chain do-chain ?exit
  246.         dup colon?                              \ colon definitions
  247.         if      >body ip !
  248.                 1 nesting +! else
  249.         dup does>?                              \ does> definitions
  250.         if      ." DOES> nesting "
  251.                 @ 2 cells + ip !
  252.                 1 nesting +! else
  253.         dup defer?                              \ defered words
  254.         if      ." DEFER nesting " dup
  255.                 case    ['] type of     drop   type-save  endof
  256.                         ['] emit of     drop   emit-save  endof
  257.                         ['] cr   of     drop     cr-save  endof
  258.                         ['] key  of     drop    key-save  endof
  259.                         ['] key? of     drop   key?-save  endof
  260.                         ['] cls  of     drop    cls-save  endof
  261.                       ['] gotoxy of     drop gotoxy-save  endof
  262.                        ['] getxy of     drop  getxy-save  endof
  263.                                         swap >body @ swap
  264.                 endcase dup .name
  265.                 [ reveal ] _dbg-nest else
  266.         dup execute?                            \ handle execute
  267.         if      ." EXECUTE nesting " over .name
  268.                 drop dup _dbg-nest else
  269.         dup m0cfa?                              \ methods type zero
  270.         if      3 cells+ ip !
  271.                 1 nesting +! else
  272.         dup m1cfa?                              \ methods type 1
  273.         if      2 cells+ ip !
  274.                 1 nesting +! else
  275.         drop ." Can't nest " beep
  276. \        then
  277.         then then then then then then ;
  278.  
  279. : dbg-nest      ( a1 -- )
  280.                 ip @ @ _dbg-nest ;
  281.  
  282. : dbg-unnest    ( -- )  \ not valid inside a loop or if >R has been used!
  283.                 rtop @ here u<
  284.                 if      rtop @ ip !
  285.                         -1 nesting +!
  286.                         rtop @ ?name ?dup
  287.                         if      ." Unnesting to: " .name
  288.                         then
  289.                 else    ." Can't unnest " beep
  290.                 then    ;
  291.  
  292. : #dbg-rstack   ( a1 a2 -- )
  293.                 cr ." RETURN STACK[" 2dup swap - cell / 1 .r ." ]: "
  294.                 over max.rstack cells+ umin     \ limit return stack entries
  295.                 swap over min
  296.                 ?do     i @ ?name ?dup
  297.                         if      i @ here u<
  298.                                 if      dup >name nfa-count type
  299.                                         i @
  300.                                         swap >body - cell / 1- ." +" %.
  301.                                 else    h%.
  302.                                 then
  303.                         else    i @ h%.
  304.                         then    12 ?cr
  305.           cell +loop    cr ;
  306.  
  307. : dbg-rstack    ( -- )
  308.                 rp@ 1 cells + rp0 @ #dbg-rstack ;
  309.  
  310. : dbg-help
  311.         cr ."  ENTER/SPACE-single step, ESC/Q-quit,       C-continuous step,"
  312.         cr ."  P-proceed to def again,  D-done,  N-nest,  U-unnest,  F-forth, "
  313.         cr ."  R-show Return stack,     H-Hex toggle,     W-watch commands"
  314.         cr ."  J-Jump over next Word" ;
  315.  
  316. : .wordtype     ( -- )
  317.         ip @ @ false .word-type-chain do-chain ?exit
  318.                 dup colon?
  319.         if      drop ."    :  " exit
  320.         then    dup variable?
  321.         if      drop ." var   " exit
  322.         then    dup does>?
  323.         if      drop ." does  " exit
  324.         then    dup constant?
  325.         if      drop ." const " exit
  326.         then    dup defer?
  327.         if      drop ." defer " exit
  328.         then    dup  m0cfa?
  329.                 over m1cfa? or
  330.         if      drop ." Meth: " exit
  331.         then    drop ." code  " ;
  332.  
  333. 0 value debug-base
  334.  
  335. : .s-base       ( -- )
  336.                 base @ >r debug-base base ! %.s r> base ! ;
  337.  
  338. : base-toggle   ( -- )
  339.                 debug-base 0x10 =
  340.                 if      0x0A to debug-base
  341.                 else    0x10 to debug-base
  342.                 then    ;
  343.  
  344. : restore-io    ( -- )
  345.                 emit-save 0= ?exit
  346.                 tabing?-save     to tabing?
  347.                 left-margin-save to left-margin
  348.                 indent-save      to indent
  349.                 emit-save defer@ emit = ?exit
  350.                 emit-save        is emit
  351.                 type-save        is type
  352.                   cr-save        is cr
  353.                  key-save        is key
  354.                 key?-save        is key?
  355.                  cls-save        is cls
  356.                 gotoxy-save      is gotoxy
  357.                 getxy-save       is getxy
  358. \               x-save y-save       gotoxy
  359.                 0                to emit-save   \ clear emit flag
  360.                 tabbing-off
  361.                 ;
  362.  
  363. : debug-io      ( -- )
  364.                 defer@ emit    to   emit-save   \ save current contents
  365.                 defer@ type    to   type-save
  366.                 defer@ cr      to     cr-save
  367.                 defer@ key     to    key-save
  368.                 defer@ key?    to   key?-save
  369.                 defer@ cls     to    cls-save
  370.                 defer@ gotoxy  to gotoxy-save
  371.                 defer@ getxy   to  getxy-save
  372.                 forth-io
  373. \                ['] _key       is key
  374. \                ['] _key?      is key?
  375.                 tabing?        to tabing?-save
  376.                 left-margin    to left-margin-save
  377.                 16             to left-margin
  378.                 indent         to indent-save
  379.                 -16            to indent
  380.                 tabing-off ;
  381.  
  382. \ -------------------- Trace Breakpoint --------------------
  383.  
  384. -1 value nextbreak
  385.  
  386. : trace  ( -- )
  387.         debug-entry
  388.         debug-io
  389.         r>
  390.         r@ rtop !
  391.         cell - dup >r
  392.         ip @ <>
  393.         if      true abort" trace error"
  394.         then
  395.         ip 2@ !  ( restore )
  396.         getxy drop 25 >
  397.         if      first-line
  398.                 cr 25 col
  399.         then    .s-base
  400.         first-line
  401.         do-watch
  402.         first-line
  403.         cr .wordtype
  404.         nesting @ 0max ?dup
  405.         if      ." |" spaces
  406.         then
  407.         obj-save >r
  408.         defer@ cr >r ['] noop is cr
  409.         ip @ dup @ .execution-class drop
  410.         r> is cr
  411.         r> to obj-save
  412.         20 nesting @ ?dup if 1+ - then getxy drop max col
  413.         getxy drop 20 >
  414.         if      cr 20 col
  415.         then    ."  --> "
  416.         ?dbg-cont                               \ are we doing continuous steps
  417.         if      key?                           \ did user press a key
  418.                 if      key drop               \ then discard it
  419.                         false to ?dbg-cont      \ stop continuous
  420.                         key upc                \ and wait for next command
  421.                 else    ip @ @
  422.                         dup     'EXIT   =       \ if at EXIT
  423.                         over ['] UNNEST = or    \ or at UNNEST
  424.                         over ['] EXITP  = or    \ or at EXITP
  425.                         over ['] EXITM  = or    \ or at EXITM
  426.                         nip
  427.                         if      false to ?dbg-cont \ stop continuous
  428.                                 key upc           \ and wait for next command
  429.                         else    0x0D               \ else just do an 'enter'
  430.                         then
  431.                 then
  432.         else    key upc                        \ not continuous, get a key
  433.         then
  434.         case
  435.           ascii P of  ip0 @ ip ! nesting off            endof
  436.            ctrl P of  ip @ to nextbreak nesting off
  437.                       dbg-next 0x0D pushkey             endof
  438.           ascii J of  ip @ 2 cells+ to nextbreak nesting off
  439.                       dbg-next 0x0D pushkey             endof
  440.           ascii C of  true to ?dbg-cont                 endof   \ continuous
  441.           ascii D of  ip off  restore-io debug-exit
  442.                                                 exit    endof
  443.           ascii H of  base-toggle                       endof
  444.           ascii N of  dbg-nest                          endof
  445.           ascii U of  dbg-unnest                        endof
  446.           ascii F of  run-forth                         endof
  447.           ascii R of  dbg-rstack                        endof
  448.           ascii W of  dbg-watch                         endof
  449.           ascii Q of  ip off  ." unbug" restore-io forth-io
  450.                                                 abort   endof
  451.                27 of  ip off  ." unbug" restore-io forth-io
  452.                                                 abort   endof
  453.           ascii ? of  dbg-help                          endof
  454.                       >r dbg-next ( default )
  455.                       nextbreak -1 <>
  456.                       if        nextbreak ip !
  457.                                 -1 to nextbreak
  458.                       then
  459.                       r>
  460.         endcase
  461.         restore-io
  462.         debug-exit
  463.         [ last @ name> ] literal patch ;        \ patch in trace
  464.  
  465.  
  466. \ -------------------- Initialize Debugger --------------------
  467.  
  468. forth definitions
  469.  
  470. : .rstack       ( -- )
  471.                 rp@ rp0 @ #dbg-rstack ;
  472.  
  473. : unbug  ( -- )
  474.         ip @
  475.         if      ip 2@ !  ip off
  476.         then    ;
  477.  
  478. synonym unbp unbug
  479.  
  480. : adebug        ( cfa -- )      \ set a breakpoint at cfa
  481.         begin   false to obj-save
  482.                 false to ?dbg-cont              \ turn off contuous step
  483.                 base @ to debug-base
  484.                 dup  colon?
  485.                 over does>?   or
  486.                 over defer?   or
  487.                 0=
  488.            if   cr ." Must be a :, DEFER or DOES> definition"
  489.                 drop EXIT
  490.            then dup  colon?
  491.            if   >body
  492.                 TRUE
  493.            else dup does>?
  494.                 if      ." DOES> nesting " call@ 2 cells +
  495.                         TRUE
  496.                 else
  497.                     ." DEFER nesting "
  498.                         >body @ dup .name FALSE
  499.                 then
  500.             then
  501.         until   dup ip0 ! ip !
  502.                 ['] trace patch
  503.                 nesting off ;
  504.  
  505. : auto-debug-key ( -- )
  506.                 debug-io
  507.                 unbug ['] key-breaker adebug
  508.                 restore-io ;
  509.  
  510. : auto-debug-breaker ( -- )
  511.                 debug-io
  512.                 unbug ['] breaker adebug
  513.                 restore-io ;
  514.  
  515. : debug ( -<name>- )
  516.         unbug ' adebug ;
  517.  
  518. synonym bp debug
  519.  
  520. : debug-io debug-io ;
  521. : restore-io restore-io ;
  522.  
  523. : dbg   ( -<name>- )    \ debug a word now
  524.         >in @ debug >in ! ;
  525.  
  526. : watch         ( -<watch_command_line>- )
  527.                 0 word c@
  528.                 if      pocket count watch-buf place
  529.                 else    dbg-watch
  530.                 then    ;
  531. comment ö
  532. : #patchinto    ( a1 n1 -<name1 name2>- ) \ patch a1 into name1 at name2
  533.                 >r                        \ at occurance n1
  534.                 bl word anyfind 0= abort" Couldn't find the patchinto function"
  535.                 bl word anyfind 0= abort" Replacable word isn't defined"
  536.                 swap dup 0x200 ['] unnest lscan
  537.                 0= abort" Couldn't find end of the function"
  538.                 over - rot
  539.                 r> 0
  540.                 do      dup>r lscan dup
  541.                         0= abort" Couldn't find the replacable word in function"
  542.                         1- swap cell+ swap
  543.                         r>
  544.                 loop    2drop cell - ! ;
  545.  
  546. : patchinto     ( a1 -<name1 name2>- )
  547.                 1 #patchinto ;
  548. ö
  549. only forth also definitions
  550.  
  551. \s
  552. : test1  dup dup + + ;
  553. : test2  test1 test1 ;
  554. : test3  1 test2 test2 drop ;
  555.  
  556. variable foo
  557. : test4  foo @ if  foo @ test2 .  then ;
  558.  
  559. : test5  10 0 do i foo +! loop ;
  560.  
  561. : wf  ." foo = " foo ? ;
  562.