Diff for /gforth/glocals.fs between versions 1.4 and 1.21

version 1.4, 1994/07/08 15:00:43 version 1.21, 1996/05/09 18:12:59
Line 1 Line 1
   \ A powerful locals implementation
   
   \ Copyright (C) 1995 Free Software Foundation, Inc.
   
   \ This file is part of Gforth.
   
   \ Gforth is free software; you can redistribute it and/or
   \ modify it under the terms of the GNU General Public License
   \ as published by the Free Software Foundation; either version 2
   \ of the License, or (at your option) any later version.
   
   \ This program is distributed in the hope that it will be useful,
   \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   \ GNU General Public License for more details.
   
   \ You should have received a copy of the GNU General Public License
   \ along with this program; if not, write to the Free Software
   \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   
   
   \ More documentation can be found in the manual and in
   \ http://www.complang.tuwien.ac.at/papers/ertl94l.ps.gz
   
 \ Local variables are quite important for writing readable programs, but  \ Local variables are quite important for writing readable programs, but
 \ IMO (anton) they are the worst part of the standard. There they are very  \ IMO (anton) they are the worst part of the standard. There they are very
 \ restricted and have an ugly interface.  \ restricted and have an ugly interface.
Line 61 Line 85
 \ Currently locals may only be  \ Currently locals may only be
 \ defined at the outer level and TO is not supported.  \ defined at the outer level and TO is not supported.
   
 include float.fs  require search-order.fs
 include search-order.fs  require float.fs
   
 : compile-@local ( n -- )  : compile-@local ( n -- ) \ gforth compile-fetch-local
  case   case
     0 of postpone @local0 endof      0       of postpone @local0 endof
     4 of postpone @local4 endof      1 cells of postpone @local1 endof
     8 of postpone @local8 endof      2 cells of postpone @local2 endof
    12 of postpone @local12 endof      3 cells of postpone @local3 endof
    ( otherwise ) dup postpone @local# ,     ( otherwise ) dup postpone @local# ,
  endcase ;   endcase ;
   
 : compile-f@local ( n -- )  : compile-f@local ( n -- ) \ gforth compile-f-fetch-local
  case   case
     0 of postpone f@local0 endof      0        of postpone f@local0 endof
     8 of postpone f@local8 endof      1 floats of postpone f@local1 endof
    ( otherwise ) dup postpone f@local# ,     ( otherwise ) dup postpone f@local# ,
  endcase ;   endcase ;
   
Line 87  include search-order.fs Line 111  include search-order.fs
 \ lp must have the strictest alignment (usually float) across calls;  \ lp must have the strictest alignment (usually float) across calls;
 \ for simplicity we align it strictly for every group.  \ for simplicity we align it strictly for every group.
   
   slowvoc @
   slowvoc on \ we want a linked list for the vocabulary locals
 vocabulary locals \ this contains the local variables  vocabulary locals \ this contains the local variables
 ' locals >body ' locals-list >body !  ' locals >body ' locals-list >body !
   slowvoc !
   
 create locals-buffer 1000 allot \ !! limited and unsafe  create locals-buffer 1000 allot \ !! limited and unsafe
     \ here the names of the local variables are stored      \ here the names of the local variables are stored
Line 131  variable locals-dp \ so here's the speci Line 158  variable locals-dp \ so here's the speci
     postpone lp@ postpone c! ;      postpone lp@ postpone c! ;
   
 : create-local ( " name" -- a-addr )  : create-local ( " name" -- a-addr )
         \ defines the local "name"; the offset of the local shall be stored in a-addr      \ defines the local "name"; the offset of the local shall be
       \ stored in a-addr
     create      create
         immediate          immediate restrict
         here 0 , ( place for the offset ) ;          here 0 , ( place for the offset ) ;
   
 : lp-offset ( n1 -- n2 )  : lp-offset ( n1 -- n2 )
Line 149  variable locals-dp \ so here's the speci Line 177  variable locals-dp \ so here's the speci
 vocabulary locals-types \ this contains all the type specifyers, -- and }  vocabulary locals-types \ this contains all the type specifyers, -- and }
 locals-types definitions  locals-types definitions
   
 : W:  : W: ( "name" -- a-addr xt ) \ gforth w-colon
     create-local ( "name" -- a-addr xt )      create-local
         \ xt produces the appropriate locals pushing code when executed          \ xt produces the appropriate locals pushing code when executed
         ['] compile-pushlocal-w          ['] compile-pushlocal-w
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         \ compiles a local variable access          \ compiles a local variable access
         @ lp-offset compile-@local ;          @ lp-offset compile-@local ;
   
 : W^  : W^ ( "name" -- a-addr xt ) \ gforth w-caret
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-w          ['] compile-pushlocal-w
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, ;          postpone laddr# @ lp-offset, ;
   
 : F:  : F: ( "name" -- a-addr xt ) \ gforth f-colon
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-f          ['] compile-pushlocal-f
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         @ lp-offset compile-f@local ;          @ lp-offset compile-f@local ;
   
 : F^  : F^ ( "name" -- a-addr xt ) \ gforth f-caret
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-f          ['] compile-pushlocal-f
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, ;          postpone laddr# @ lp-offset, ;
   
 : D:  : D: ( "name" -- a-addr xt ) \ gforth d-colon
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-d          ['] compile-pushlocal-d
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, postpone 2@ ;          postpone laddr# @ lp-offset, postpone 2@ ;
   
 : D^  : D^ ( "name" -- a-addr xt ) \ gforth d-caret
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-d          ['] compile-pushlocal-d
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, ;          postpone laddr# @ lp-offset, ;
   
 : C:  : C: ( "name" -- a-addr xt ) \ gforth c-colon
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-c          ['] compile-pushlocal-c
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, postpone c@ ;          postpone laddr# @ lp-offset, postpone c@ ;
   
 : C^  : C^ ( "name" -- a-addr xt ) \ gforth c-caret
     create-local ( "name" -- a-addr xt )      create-local
         ['] compile-pushlocal-c          ['] compile-pushlocal-c
     does> ( Compilation: -- ) ( Run-time: -- w )      does> ( Compilation: -- ) ( Run-time: -- w )
         postpone laddr# @ lp-offset, ;          postpone laddr# @ lp-offset, ;
Line 234  new-locals-map ' new-locals >body cell+ Line 262  new-locals-map ' new-locals >body cell+
 variable old-dpp  variable old-dpp
   
 \ and now, finally, the user interface words  \ and now, finally, the user interface words
 : { ( -- addr wid 0 )  : { ( -- addr wid 0 ) \ gforth open-brace
     dp old-dpp !      dp old-dpp !
     locals-dp dpp !      locals-dp dpp !
     also new-locals      also new-locals
Line 244  variable old-dpp Line 272  variable old-dpp
   
 locals-types definitions  locals-types definitions
   
 : } ( addr wid 0 a-addr1 xt1 ... -- )  : } ( addr wid 0 a-addr1 xt1 ... -- ) \ gforth close-brace
     \ ends locals definitions      \ ends locals definitions
     ] old-dpp @ dpp !      ] old-dpp @ dpp !
     begin      begin
Line 258  locals-types definitions Line 286  locals-types definitions
     previous previous      previous previous
     locals-list TO locals-wordlist ;      locals-list TO locals-wordlist ;
   
 : -- ( addr wid 0 ... -- )  : -- ( addr wid 0 ... -- ) \ gforth dash-dash
     }      }
     [char] } word drop ;      [char] } parse 2drop ;
   
 forth definitions  forth definitions
   
Line 369  forth definitions Line 397  forth definitions
   
 \ explicit scoping  \ explicit scoping
   
 : scope ( -- scope )  : scope ( compilation  -- scope ; run-time  -- ) \ gforth
  cs-push-part scopestart ; immediate   cs-push-part scopestart ; immediate
   
 : endscope ( scope -- )  : endscope ( compilation scope -- ; run-time  -- ) \ gforth
  scope?   scope?
  drop   drop
  locals-list @ common-list   locals-list @ common-list
Line 445  forth definitions Line 473  forth definitions
   
 \ And here's finally the ANS standard stuff  \ And here's finally the ANS standard stuff
   
 : (local) ( addr u -- )  : (local) ( addr u -- ) \ local paren-local-paren
     \ a little space-inefficient, but well deserved ;-)      \ a little space-inefficient, but well deserved ;-)
     \ In exchange, there are no restrictions whatsoever on using (local)      \ In exchange, there are no restrictions whatsoever on using (local)
     \ as long as you use it in a definition      \ as long as you use it in a definition
Line 460  forth definitions Line 488  forth definitions
     \ this gives a unique identifier for the way the xt was defined      \ this gives a unique identifier for the way the xt was defined
     \ words defined with different does>-codes have different definers      \ words defined with different does>-codes have different definers
     \ the definer can be used for comparison and in definer!      \ the definer can be used for comparison and in definer!
     dup >code-address [ ' bits >code-address ] Literal =      dup >code-address [ ' spaces >code-address ] Literal =
     \ !! this definition will not work on some implementations for `bits'      \ !! this definition will not work on some implementations for `bits'
     if  \ if >code-address delivers the same value for all does>-def'd words      if  \ if >code-address delivers the same value for all does>-def'd words
         >does-code 1 or \ bit 0 marks special treatment for does codes          >does-code 1 or \ bit 0 marks special treatment for does codes
Line 471  forth definitions Line 499  forth definitions
 : definer! ( definer xt -- )  : definer! ( definer xt -- )
     \ gives the word represented by xt the behaviour associated with definer      \ gives the word represented by xt the behaviour associated with definer
     over 1 and if      over 1 and if
         does-code!          swap [ 1 invert ] literal and does-code!
     else      else
         code-address!          code-address!
     then ;      then ;
   
 \ !! untested  : TO ( c|w|d|r "name" -- ) \ core-ext,local
 : TO ( c|w|d|r "name" -- )      0 0 0. 0.0e0 { c: clocal w: wlocal d: dlocal f: flocal }
 \ !! state smart      ' dup >definer
  0 0 0. 0.0e0 { c: clocal w: wlocal d: dlocal f: flocal }      case
  ' dup >definer          [ ' locals-wordlist >definer ] literal \ value
  state @           OF >body POSTPONE Aliteral POSTPONE ! ENDOF
  if          [ ' clocal >definer ] literal
    case          OF POSTPONE laddr# >body @ lp-offset, POSTPONE c! ENDOF
      [ ' locals-wordlist >definer ] literal \ value          [ ' wlocal >definer ] literal
      OF >body POSTPONE Aliteral POSTPONE ! ENDOF          OF POSTPONE laddr# >body @ lp-offset, POSTPONE ! ENDOF
      [ ' clocal >definer ] literal          [ ' dlocal >definer ] literal
      OF POSTPONE laddr# >body @ lp-offset, POSTPONE c! ENDOF          OF POSTPONE laddr# >body @ lp-offset, POSTPONE 2! ENDOF
      [ ' wlocal >definer ] literal          [ ' flocal >definer ] literal
      OF POSTPONE laddr# >body @ lp-offset, POSTPONE ! ENDOF          OF POSTPONE laddr# >body @ lp-offset, POSTPONE f! ENDOF
      [ ' dlocal >definer ] literal          -&32 throw
      OF POSTPONE laddr# >body @ lp-offset, POSTPONE d! ENDOF      endcase ; immediate
      [ ' flocal >definer ] literal  interpretation:
      OF POSTPONE laddr# >body @ lp-offset, POSTPONE f! ENDOF      ' dup >definer [ ' locals-wordlist >definer ] literal =
      abort" can only store TO value or local value"      if
    endcase          >body !
  else      else
    [ ' locals-wordlist >definer ] literal =          -&32 throw
    if      endif ;
      >body !  
    else  
      abort" can only store TO value"  
    endif  
  endif ; immediate  
   
 \ : locals|  : locals|
 \ !! should lie around somewhere      \ don't use 'locals|'! use '{'! A portable and free '{'
       \ implementation is compat/anslocals.fs
       BEGIN
           name 2dup s" |" compare 0<>
       WHILE
           (local)
       REPEAT
       drop 0 (local) ; immediate restrict

Removed from v.1.4  
changed lines
  Added in v.1.21


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