File:  [gforth] / gforth / see.fs
Revision 1.20: download - view: text, annotated - select for diffs
Fri Nov 27 21:13:43 1998 UTC (25 years, 3 months ago) by pazsan
Branches: MAIN
CVS tags: v0-4-0, HEAD
Fixed DOES> see bug

    1: \ SEE.FS       highend SEE for ANSforth                16may93jaw
    2: 
    3: \ Copyright (C) 1995 Free Software Foundation, Inc.
    4: 
    5: \ This file is part of Gforth.
    6: 
    7: \ Gforth is free software; you can redistribute it and/or
    8: \ modify it under the terms of the GNU General Public License
    9: \ as published by the Free Software Foundation; either version 2
   10: \ of the License, or (at your option) any later version.
   11: 
   12: \ This program is distributed in the hope that it will be useful,
   13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: \ GNU General Public License for more details.
   16: 
   17: \ You should have received a copy of the GNU General Public License
   18: \ along with this program; if not, write to the Free Software
   19: \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20: 
   21: 
   22: \ May be cross-compiled
   23: 
   24: \ I'm sorry. This is really not "forthy" enough.
   25: 
   26: \ Ideas:        Level should be a stack
   27: 
   28: require look.fs
   29: require termsize.fs
   30: require wordinfo.fs
   31: [IFUNDEF] .name : .name name>string type space ; [THEN]
   32: 
   33: decimal
   34: 
   35: \ Screen format words                                   16may93jaw
   36: 
   37: VARIABLE C-Output   1 C-Output  !
   38: VARIABLE C-Formated 1 C-Formated !
   39: VARIABLE C-Highlight 0 C-Highlight !
   40: VARIABLE C-Clearline 0 C-Clearline !
   41: 
   42: VARIABLE XPos
   43: VARIABLE YPos
   44: VARIABLE Level
   45: 
   46: : Format        C-Formated @ C-Output @ and
   47:                 IF dup spaces XPos +! ELSE drop THEN ;
   48: 
   49: : level+        7 Level +!
   50:                 Level @ XPos @ -
   51:                 dup 0> IF Format ELSE drop THEN ;
   52: 
   53: : level-        -7 Level +! ;
   54: 
   55: VARIABLE nlflag
   56: VARIABLE uppercase	\ structure words are in uppercase
   57: 
   58: DEFER nlcount ' noop IS nlcount
   59: 
   60: : nl            nlflag on ;
   61: : (nl)          nlcount
   62:                 XPos @ Level @ = IF EXIT THEN \ ?Exit
   63:                 C-Formated @ IF
   64:                 C-Output @
   65:                 IF C-Clearline @ IF cols XPos @ - spaces
   66:                                  ELSE cr THEN
   67:                 1 YPos +! 0 XPos !
   68:                 Level @ spaces
   69:                 THEN Level @ XPos ! THEN ;
   70: 
   71: : warp?         ( len -- len )
   72:                 nlflag @ IF (nl) nlflag off THEN
   73:                 XPos @ over + cols u>= IF (nl) THEN ;
   74: 
   75: : c-to-upper
   76:   dup [char] a >= over [char] z <= and if  bl -  then ;
   77: 
   78: : ctype         ( adr len -- )
   79:                 warp? dup XPos +! C-Output @ 
   80: 		IF uppercase @ IF bounds ?DO i c@ c-to-upper emit LOOP
   81: 				  uppercase off ELSE type THEN
   82: 		ELSE 2drop THEN ;
   83: 
   84: : cemit         1 warp?
   85:                 over bl = Level @ XPos @ = and
   86:                 IF 2drop ELSE XPos +! C-Output @ IF emit ELSE drop THEN
   87:                 THEN ;
   88: 
   89: DEFER .string
   90: 
   91: [IFDEF] Green
   92: VARIABLE Colors Colors on
   93: 
   94: : (.string)     ( c-addr u n -- )
   95:                 over warp? drop
   96:                 Colors @
   97:                 IF C-Highlight @ ?dup
   98:                    IF   CT@ swap CT@ or
   99:                    ELSE CT@
  100:                    THEN
  101:                 attr! ELSE drop THEN
  102:                 ctype  ct @ attr! ;
  103: [ELSE]
  104: : (.string)     ( c-addr u n -- )
  105:                 drop ctype ;
  106: [THEN]
  107: 
  108: ' (.string) IS .string
  109: 
  110: 
  111: : .struc        
  112: 	uppercase on Str# .string ;
  113: 
  114: \ CODES (Branchtypes)                                    15may93jaw
  115: 
  116: 21 CONSTANT RepeatCode
  117: 22 CONSTANT AgainCode
  118: 23 CONSTANT UntilCode
  119: \ 09 CONSTANT WhileCode
  120: 10 CONSTANT ElseCode
  121: 11 CONSTANT AheadCode
  122: 13 CONSTANT WhileCode2
  123: 14 CONSTANT Disable
  124: 15 CONSTANT LeaveCode
  125: 
  126: 
  127: \ FORMAT WORDS                                          13jun93jaw
  128: 
  129: VARIABLE C-Stop
  130: VARIABLE Branches
  131: 
  132: VARIABLE BranchPointer	\ point to the end of branch table
  133: VARIABLE SearchPointer
  134: 
  135: \ The branchtable consists of three entrys:
  136: \ address of branch , branch destination , branch type
  137: 
  138: CREATE BranchTable 500 allot
  139: here 3 cells -
  140: ACONSTANT MaxTable
  141: 
  142: : FirstBranch BranchTable cell+ SearchPointer ! ;
  143: 
  144: : (BranchAddr?) ( a-addr1 -- a-addr2 true | false )
  145: \ searches a branch with destination a-addr1
  146: \ a-addr1: branch destination
  147: \ a-addr2: pointer in branch table
  148:         SearchPointer @
  149:         BEGIN   dup BranchPointer @ u<
  150:         WHILE
  151:                 dup @ 2 pick <>
  152:         WHILE   3 cells +
  153:         REPEAT
  154:         nip dup  3 cells + SearchPointer ! true
  155:         ELSE
  156:         2drop false
  157:         THEN ;
  158: 
  159: : BranchAddr?
  160:         FirstBranch (BranchAddr?) ;
  161: 
  162: ' (BranchAddr?) ALIAS MoreBranchAddr?
  163: 
  164: : CheckEnd ( a-addr -- true | false )
  165:         BranchTable cell+
  166:         BEGIN   dup BranchPointer @ u<
  167:         WHILE
  168:                 dup @ 2 pick u<=
  169:         WHILE   3 cells +
  170:         REPEAT
  171:         2drop false
  172:         ELSE
  173:         2drop true
  174:         THEN ;
  175: 
  176: : MyBranch      ( a-addr -- a-addr a-addr2 )
  177: \ finds branch table entry for branch at a-addr
  178:                 dup @ over +
  179:                 BranchAddr?
  180:                 BEGIN
  181:                 WHILE 1 cells - @
  182:                       over <>
  183:                 WHILE dup @ over +
  184:                       MoreBranchAddr?
  185:                 REPEAT
  186:                 SearchPointer @ 3 cells -
  187:                 ELSE    true ABORT" SEE: Table failure"
  188:                 THEN ;
  189: 
  190: \
  191: \                 addrw               addrt
  192: \       BEGIN ... WHILE ... AGAIN ... THEN
  193: \         ^         !        !          ^
  194: \         ----------+--------+          !
  195: \                   !                   !
  196: \                   +-------------------+
  197: \
  198: \
  199: 
  200: : CheckWhile ( a-addrw a-addrt -- true | false )
  201:         BranchTable
  202:         BEGIN   dup BranchPointer @ u<
  203:         WHILE   dup @ 3 pick u>
  204:                 over @ 3 pick u< and
  205:                 IF dup cell+ @ 3 pick u<
  206:                         IF 2drop drop true EXIT THEN
  207:                 THEN
  208:                 3 cells +
  209:         REPEAT
  210:         2drop drop false ;
  211: 
  212: : ,Branch ( a-addr -- )
  213:         BranchPointer @ dup MaxTable u> ABORT" SEE: Table overflow"
  214:         !
  215:         1 cells BranchPointer +! ;
  216: 
  217: : Type!   ( u -- )
  218:         BranchPointer @ 1 cells - ! ;
  219: 
  220: : Branch! ( a-addr rel -- a-addr )
  221:         over + over ,Branch ,Branch 0 ,Branch ;
  222: 
  223: \ DEFER CheckUntil
  224: VARIABLE NoOutput
  225: VARIABLE C-Pass
  226: 
  227: 0 CONSTANT ScanMode
  228: 1 CONSTANT DisplayMode
  229: 2 CONSTANT DebugMode
  230: 
  231: : Scan? ( -- flag ) C-Pass @ 0= ;
  232: : Display? ( -- flag ) C-Pass @ 1 = ;
  233: : Debug? ( -- flag ) C-Pass @ 2 = ;
  234: 
  235: : back? ( n -- flag ) 0< ;
  236: : ahead? ( n -- flag ) 0> ;
  237: 
  238: : c-(compile)
  239:     Display?
  240:     IF
  241: 	s" POSTPONE " Com# .string
  242: 	dup @ look 0= ABORT" SEE: No valid XT"
  243: 	name>string 0 .string bl cemit
  244:     THEN
  245:     cell+ ;
  246: 
  247: : c-lit
  248:     Display? IF
  249: 	dup @ dup abs 0 <# #S rot sign #> 0 .string bl cemit
  250:     THEN
  251:     cell+ ;
  252: 
  253: : .name-without ( addr -- addr )
  254: \ prints a name without () e.g. (+LOOP) or (s")
  255:   dup 1 cells - @ look 
  256:   IF   name>string over c@ '( = IF 1 /string THEN
  257:        2dup + 1- c@ ') = IF 1- THEN .struc ELSE drop 
  258:   THEN ;
  259: 
  260: : c-c"
  261: 	Display? IF nl .name-without THEN
  262:         count 2dup + aligned -rot
  263:         Display?
  264:         IF      bl cemit 0 .string
  265:                 [char] " cemit bl cemit
  266:         ELSE    2drop
  267:         THEN ;
  268: 
  269: 
  270: : Forward? ( a-addr true | false -- a-addr true | false )
  271: \ a-addr1 is pointer into branch table
  272: \ returns true when jump is a forward jump
  273:         IF      dup dup @ swap 1 cells - @ -
  274:                 Ahead? IF true ELSE drop false THEN
  275:                 \ only if forward jump
  276:         ELSE    false THEN ;
  277: 
  278: : RepeatCheck ( a-addr1 a-addr2 true | false -- false )
  279:         IF  BEGIN  2dup
  280:                    1 cells - @ swap dup @ +
  281:                    u<=
  282:             WHILE  drop dup cell+
  283:                    MoreBranchAddr? 0=
  284:             UNTIL  false
  285:             ELSE   true
  286:             THEN
  287:         ELSE false
  288:         THEN ;
  289: 
  290: : c-branch
  291:         Scan?
  292:         IF      dup @ Branch!
  293:                 dup @ back?
  294:                 IF                      \ might be: AGAIN, REPEAT
  295:                         dup cell+ BranchAddr? Forward?
  296:                         RepeatCheck
  297:                         IF      RepeatCode Type!
  298:                                 cell+ Disable swap !
  299:                         ELSE    AgainCode Type!
  300:                         THEN
  301:                 ELSE    dup cell+ BranchAddr? Forward?
  302:                         IF      ElseCode Type! drop
  303:                         ELSE    AheadCode Type!
  304:                         THEN
  305:                 THEN
  306:         THEN
  307:         Display?
  308:         IF
  309:                 dup @ back?
  310:                 IF                      \ might be: AGAIN, REPEAT
  311:                         level- nl
  312:                         dup cell+ BranchAddr? Forward?
  313:                         RepeatCheck
  314:                         IF      drop S" REPEAT " .struc nl
  315:                         ELSE    S" AGAIN " .struc nl
  316:                         THEN
  317:                 ELSE    MyBranch cell+ @ LeaveCode =
  318: 			IF 	S" LEAVE " .struc
  319: 			ELSE
  320: 				dup cell+ BranchAddr? Forward?
  321:        	                 	IF      dup cell+ @ WhileCode2 =
  322:        	                         	IF nl S" ELSE" .struc level+
  323:                                 	ELSE level- nl S" ELSE" .struc level+ THEN
  324:                                 	cell+ Disable swap !
  325:                         	ELSE    S" AHEAD" .struc level+
  326:                         	THEN
  327: 			THEN
  328:                 THEN
  329:         THEN
  330:         Debug?
  331:         IF      dup @ +
  332:         ELSE    cell+
  333:         THEN ;
  334: 
  335: : DebugBranch
  336:         Debug?
  337:         IF      dup @ over + swap THEN ; \ return 2 different addresses
  338: 
  339: : c-?branch
  340:         Scan?
  341:         IF      dup @ Branch!
  342:                 dup @ Back?
  343:                 IF      UntilCode Type! THEN
  344:         THEN
  345:         Display?
  346:         IF      dup @ Back?
  347:                 IF      level- nl S" UNTIL " .struc nl
  348:                 ELSE    dup    dup @ over +
  349:                         CheckWhile
  350:                         IF      MyBranch
  351:                                 cell+ dup @ 0=
  352:                                          IF WhileCode2 swap !
  353:                                          ELSE drop THEN
  354:                                 level- nl
  355:                                 S" WHILE " .struc
  356:                                 level+
  357:                         ELSE    MyBranch cell+ @ LeaveCode =
  358: 				IF   s" 0= ?LEAVE " .struc
  359: 				ELSE nl S" IF " .struc level+
  360: 				THEN
  361:                         THEN
  362:                 THEN
  363:         THEN
  364:         DebugBranch
  365:         cell+ ;
  366: 
  367: : c-for
  368:         Display? IF nl S" FOR" .struc level+ THEN ;
  369: 
  370: : c-loop
  371:         Display? IF level- nl .name-without bl cemit nl THEN
  372:         DebugBranch cell+ 
  373: 	Scan? 
  374: 	IF 	dup BranchAddr? 
  375: 		BEGIN   WHILE cell+ LeaveCode swap !
  376: 			dup MoreBranchAddr?
  377: 		REPEAT
  378: 	THEN
  379: 	cell+ ;
  380: 
  381: : c-do
  382:         Display? IF nl .name-without level+ THEN ;
  383: 
  384: : c-?do
  385:         Display? IF nl S" ?DO" .struc level+ THEN
  386:         DebugBranch cell+ ;
  387: 
  388: : c-exit  dup 1 cells -
  389:         CheckEnd
  390:         IF      Display? IF nlflag off S" ;" Com# .string THEN
  391:                 C-Stop on
  392:         ELSE    Display? IF S" EXIT " .struc THEN
  393:         THEN
  394:         Debug? IF drop THEN ;
  395: 
  396: : c-does>               \ end of create part
  397:         Display? IF S" DOES> " Com# .string THEN
  398: 	maxaligned /does-handler + ;
  399: 
  400: : c-abort"
  401:         count 2dup + aligned -rot
  402:         Display?
  403:         IF      S" ABORT" .struc
  404:                 [char] " cemit bl cemit 0 .string
  405:                 [char] " cemit bl cemit
  406:         ELSE    2drop
  407:         THEN ;
  408: 
  409: 
  410: CREATE C-Table
  411: 	        ' lit A,            ' c-lit A,
  412: 		' (s") A,	    ' c-c" A,
  413:        		 ' (.") A,	    ' c-c" A,
  414:         	' "lit A,           ' c-c" A,
  415: [IFDEF] (c")	' (c") A,	    ' c-c" A, [THEN]
  416:         	' (do) A,           ' c-do A,
  417: [IFDEF] (+do)	' (+do) A,	    ' c-do A, [THEN]
  418: [IFDEF] (u+do)	' (u+do) A,	    ' c-do A, [THEN]
  419: [IFDEF] (-do)	' (-do) A,	    ' c-do A, [THEN]
  420: [IFDEF] (u-do)	' (u-do) A,	    ' c-do A, [THEN]
  421:         	' (?do) A,          ' c-?do A,
  422:         	' (for) A,          ' c-for A,
  423:         	' ?branch A,        ' c-?branch A,
  424:         	' branch A,         ' c-branch A,
  425:         	' (loop) A,         ' c-loop A,
  426:         	' (+loop) A,        ' c-loop A,
  427: [IFDEF] (s+loop) ' (s+loop) A,       ' c-loop A, [THEN]
  428: [IFDEF] (-loop) ' (-loop) A,        ' c-loop A, [THEN]
  429:         	' (next) A,         ' c-loop A,
  430:         	' ;s A,             ' c-exit A,
  431:         	' (does>) A,        ' c-does> A,
  432:         	' (abort") A,       ' c-abort" A,
  433:         	' (compile) A,      ' c-(compile) A,
  434:         	0 ,		here 0 ,
  435: 
  436: avariable c-extender
  437: c-extender !
  438: 
  439: \ DOTABLE                                               15may93jaw
  440: 
  441: : DoTable ( cfa -- flag )
  442:         C-Table
  443:         BEGIN   dup @ dup 0= 
  444: 		IF drop cell+ @ dup 
  445: 		  IF ( next table!) dup @ ELSE 
  446: 			( end!) 2drop false EXIT THEN 
  447: 		THEN
  448: 		\ jump over to extender, if any 26jan97jaw
  449:        		2 pick <>
  450:         WHILE   2 cells +
  451:         REPEAT
  452:         nip cell+ perform
  453:         true
  454: 	;
  455: 
  456: : BranchTo? ( a-addr -- a-addr )
  457:         Display?  IF    dup BranchAddr?
  458:                         IF
  459: 				BEGIN cell+ @ dup 20 u>
  460:                                 IF drop nl S" BEGIN " .struc level+
  461:                                 ELSE
  462:                                   dup Disable <> over LeaveCode <> and
  463:                                   IF   WhileCode2 =
  464:                                        IF nl S" THEN " .struc nl ELSE
  465:                                        level- nl S" THEN " .struc nl THEN
  466:                                   ELSE drop THEN
  467:                                 THEN
  468:                                   dup MoreBranchAddr? 0=
  469:                            UNTIL
  470:                         THEN
  471:                   THEN ;
  472: 
  473: : analyse ( a-addr1 -- a-addr2 )
  474:         Branches @ IF BranchTo? THEN
  475:         dup cell+ swap @
  476:         dup >r DoTable r> swap IF drop EXIT THEN
  477:         Display?
  478:         IF look 0= IF  drop dup 1 cells - @ .  \ ABORT" SEE: Bua!"
  479: 	ELSE
  480: 	    dup cell+ count dup immediate-mask and
  481: 	    IF  bl cemit  ." POSTPONE " THEN
  482: 	    31 and rot wordinfo .string  THEN  bl cemit
  483:         ELSE drop
  484:         THEN ;
  485: 
  486: : c-init
  487:         0 YPos ! 0 XPos !
  488:         0 Level ! nlflag off
  489:         BranchTable BranchPointer !
  490:         c-stop off
  491:         Branches on ;
  492: 
  493: : makepass ( a-addr -- )
  494:     c-stop off
  495:     BEGIN
  496: 	analyse
  497: 	c-stop @
  498:     UNTIL drop ;
  499: 
  500: Defer xt-see-xt ( xt -- )
  501: \ this one is just a forward declaration for indirect recursion
  502: 
  503: : .defname ( xt c-addr u -- )
  504:     rot look
  505:     if ( c-addr u nfa )
  506: 	-rot type space .name
  507:     else
  508: 	drop ." noname " type
  509:     then
  510:     space ;
  511: 
  512: Defer discode ( addr -- )
  513: \  hook for the disassembler: disassemble code at addr (as far as the
  514: \  disassembler thinks is sensible)
  515: :noname ( addr -- )
  516:     drop ." ..." ;
  517: IS discode
  518: 
  519: : seecode ( xt -- )
  520:     dup s" Code" .defname
  521:     threading-method
  522:     if
  523: 	>code-address
  524:     then
  525:     discode
  526:     ."  end-code" cr ;
  527: : seevar ( xt -- )
  528:     s" Variable" .defname cr ;
  529: : seeuser ( xt -- )
  530:     s" User" .defname cr ;
  531: : seecon ( xt -- )
  532:     dup >body ?
  533:     s" Constant" .defname cr ;
  534: : seevalue ( xt -- )
  535:     dup >body ?
  536:     s" Value" .defname cr ;
  537: : seedefer ( xt -- )
  538:     dup >body @ xt-see-xt cr
  539:     dup s" Defer" .defname cr
  540:     >name dup ??? = if
  541: 	drop ." lastxt >body !"
  542:     else
  543: 	." IS " .name cr
  544:     then ;
  545: : see-threaded ( addr -- )
  546:     C-Pass @ DebugMode = IF
  547: 	ScanMode c-pass !
  548: 	EXIT
  549:     THEN
  550:     ScanMode c-pass ! dup makepass
  551:     DisplayMode c-pass ! makepass ;
  552: : seedoes ( xt -- )
  553:     dup s" create" .defname cr
  554:     S" DOES> " Com# .string XPos @ Level !
  555:     >does-code see-threaded ;
  556: : seecol ( xt -- )
  557:     dup s" :" .defname nl
  558:     2 Level !
  559:     >body see-threaded ;
  560: : seefield ( xt -- )
  561:     dup >body ." 0 " ? ." 0 0 "
  562:     s" Field" .defname cr ;
  563: 
  564: : xt-see ( xt -- )
  565:     cr c-init
  566:     dup >does-code
  567:     if
  568: 	seedoes EXIT
  569:     then
  570:     dup xtprim?
  571:     if
  572: 	seecode EXIT
  573:     then
  574:     dup >code-address
  575:     CASE
  576: 	docon: of seecon endof
  577: 	docol: of seecol endof
  578: 	dovar: of seevar endof
  579: [ [IFDEF] douser: ]
  580: 	douser: of seeuser endof
  581: [ [THEN] ]
  582: [ [IFDEF] dodefer: ]
  583: 	dodefer: of seedefer endof
  584: [ [THEN] ]
  585: [ [IFDEF] dofield: ]
  586: 	dofield: of seefield endof
  587: [ [THEN] ]
  588: 	over >body of seecode endof
  589: 	2drop abort" unknown word type"
  590:     ENDCASE ;
  591: 
  592: : (xt-see-xt) ( xt -- )
  593:     xt-see cr ." lastxt" ;
  594: ' (xt-see-xt) is xt-see-xt
  595: 
  596: : (.immediate) ( xt -- )
  597:     ['] execute = if
  598: 	."  immediate"
  599:     then ;
  600: 
  601: : name-see ( nfa -- )
  602:     dup name>int >r
  603:     dup name>comp 
  604:     over r@ =
  605:     if \ normal or immediate word
  606: 	swap xt-see (.immediate)
  607:     else
  608: 	r@ ['] compile-only-error =
  609: 	if \ compile-only word
  610: 	    swap xt-see (.immediate) ."  compile-only"
  611: 	else \ interpret/compile word
  612: 	    r@ xt-see-xt cr
  613: 	    swap xt-see-xt cr
  614: 	    ." interpret/compile " over .name (.immediate)
  615: 	then
  616:     then
  617:     rdrop drop ;
  618: 
  619: : see ( "name" -- ) \ tools
  620:     name find-name dup 0=
  621:     IF
  622: 	drop -&13 bounce
  623:     THEN
  624:     name-see ;
  625: 
  626: 

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