version 1.7, 1994/09/12 19:00:30
|
version 1.25, 1996/08/26 10:07:18
|
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 search-order.fs |
require search-order.fs |
include float.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 |
1 cells of postpone @local1 endof |
1 cells of postpone @local1 endof |
Line 73 include float.fs
|
Line 97 include float.fs
|
( 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 |
1 floats of postpone f@local1 endof |
1 floats of postpone f@local1 endof |
Line 134 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 152 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 229 previous
|
Line 254 previous
|
: new-locals-reveal ( -- ) |
: new-locals-reveal ( -- ) |
true abort" this should not happen: new-locals-reveal" ; |
true abort" this should not happen: new-locals-reveal" ; |
|
|
create new-locals-map ' new-locals-find A, ' new-locals-reveal A, |
create new-locals-map ( -- wordlist-map ) |
|
' new-locals-find A, ' new-locals-reveal A, |
|
|
vocabulary new-locals |
vocabulary new-locals |
new-locals-map ' new-locals >body cell+ A! \ !! use special access words |
new-locals-map ' new-locals >body cell+ A! \ !! use special access words |
Line 237 new-locals-map ' new-locals >body cell+
|
Line 263 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 247 variable old-dpp
|
Line 273 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 261 locals-types definitions
|
Line 287 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 372 forth definitions
|
Line 398 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 448 forth definitions
|
Line 474 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 463 forth definitions
|
Line 489 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 474 forth definitions
|
Line 500 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 |
:noname |
: TO ( c|w|d|r "name" -- ) |
' dup >definer [ ' locals-wordlist >definer ] literal = |
\ !! state smart |
if |
0 0 0. 0.0e0 { c: clocal w: wlocal d: dlocal f: flocal } |
>body ! |
' dup >definer |
else |
state @ |
-&32 throw |
if |
endif ; |
case |
:noname |
[ ' locals-wordlist >definer ] literal \ value |
0 0 0. 0.0e0 { c: clocal w: wlocal d: dlocal f: flocal } |
OF >body POSTPONE Aliteral POSTPONE ! ENDOF |
' dup >definer |
[ ' 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 |
[ comp' clocal drop >definer ] literal |
[ ' dlocal >definer ] literal |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE c! ENDOF |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE d! ENDOF |
[ comp' wlocal drop >definer ] literal |
[ ' flocal >definer ] literal |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE ! ENDOF |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE f! ENDOF |
[ comp' dlocal drop >definer ] literal |
abort" can only store TO value or local value" |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE 2! ENDOF |
endcase |
[ comp' flocal drop >definer ] literal |
else |
OF POSTPONE laddr# >body @ lp-offset, POSTPONE f! ENDOF |
[ ' locals-wordlist >definer ] literal = |
-&32 throw |
if |
endcase ; |
>body ! |
interpret/compile: TO ( c|w|d|r "name" -- ) \ core-ext,local |
else |
|
abort" can only store TO value" |
|
endif |
|
endif ; immediate |
|
|
|
: locals| |
: locals| |
BEGIN name 2dup s" |" compare 0= WHILE |
\ don't use 'locals|'! use '{'! A portable and free '{' |
(local) REPEAT drop 0 (local) ; immediate restrict |
\ implementation is compat/anslocals.fs |
|
BEGIN |
|
name 2dup s" |" compare 0<> |
|
WHILE |
|
(local) |
|
REPEAT |
|
drop 0 (local) ; immediate restrict |