--- gforth/glocals.fs 1996/09/24 19:15:02 1.27 +++ gforth/glocals.fs 1997/03/11 16:00:39 1.31 @@ -319,7 +319,9 @@ previous true abort" this should not happen: new-locals-reveal" ; create new-locals-map ( -- wordlist-map ) -' new-locals-find A, ' new-locals-reveal A, +' new-locals-find A, +' new-locals-reveal A, +' drop A, \ rehash method slowvoc @ slowvoc on @@ -448,20 +450,7 @@ forth definitions \ If this assumption is too optimistic, the compiler will warn the user. -\ Implementation: migrated to kernel.fs - -\ THEN (another control flow from before joins the current one): -\ The new locals-list is the intersection of the current locals-list and -\ the orig-local-list. The new locals-size is the (alignment-adjusted) -\ size of the new locals-list. The following code is generated: -\ lp+!# (current-locals-size - orig-locals-size) -\ : -\ lp+!# (orig-locals-size - new-locals-size) - -\ Of course "lp+!# 0" is not generated. Still this is admittedly a bit -\ inefficient, e.g. if there is a locals declaration between IF and -\ ELSE. However, if ELSE generates an appropriate "lp+!#" before the -\ branch, there will be none after the target . +\ Implementation: \ explicit scoping @@ -495,16 +484,30 @@ forth definitions lastcfa ! last ! DEFERS ;-hook ; -: (then-like) ( orig -- addr ) - swap -rot dead-orig = +\ THEN (another control flow from before joins the current one): +\ The new locals-list is the intersection of the current locals-list and +\ the orig-local-list. The new locals-size is the (alignment-adjusted) +\ size of the new locals-list. The following code is generated: +\ lp+!# (current-locals-size - orig-locals-size) +\ : +\ lp+!# (orig-locals-size - new-locals-size) + +\ Of course "lp+!# 0" is not generated. Still this is admittedly a bit +\ inefficient, e.g. if there is a locals declaration between IF and +\ ELSE. However, if ELSE generates an appropriate "lp+!#" before the +\ branch, there will be none after the target . + +: (then-like) ( orig -- ) + dead-orig = if - drop + >resolve drop else dead-code @ if - set-locals-size-list dead-code off + >resolve set-locals-size-list dead-code off else \ both live - dup list-size adjust-locals-size + over list-size adjust-locals-size + >resolve locals-list @ common-list dup list-size adjust-locals-size locals-list ! then @@ -570,10 +573,6 @@ forth definitions \ things above are not control flow joins. Everything should be taken \ over from the live flow. No lp+!# is generated. -\ !! The lp gymnastics for UNTIL are also a real problem: locals cannot be -\ used in signal handlers (or anything else that may be called while -\ locals live beyond the lp) without changing the locals stack. - \ About warning against uses of dead locals. There are several options: \ 1) Do not complain (After all, this is Forth;-) @@ -618,10 +617,9 @@ forth definitions \ this gives a unique identifier for the way the xt was defined \ words defined with different does>-codes have different definers \ the definer can be used for comparison and in definer! - dup >code-address [ ' spaces >code-address ] Literal = - \ !! this definition will not work on some implementations for `bits' - 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 + dup >does-code + ?dup-if + nip 1 or else >code-address then ; @@ -635,7 +633,7 @@ forth definitions then ; :noname - ' dup >definer [ ' locals-wordlist >definer ] literal = + ' dup >definer [ ' locals-wordlist ] literal >definer = if >body ! else @@ -643,17 +641,17 @@ forth definitions endif ; :noname 0 0 0. 0.0e0 { c: clocal w: wlocal d: dlocal f: flocal } - ' dup >definer + comp' drop dup >definer case - [ ' locals-wordlist >definer ] literal \ value + [ ' locals-wordlist ] literal >definer \ value OF >body POSTPONE Aliteral POSTPONE ! ENDOF - [ comp' clocal drop >definer ] literal + [ comp' clocal drop ] literal >definer OF POSTPONE laddr# >body @ lp-offset, POSTPONE c! ENDOF - [ comp' wlocal drop >definer ] literal + [ comp' wlocal drop ] literal >definer OF POSTPONE laddr# >body @ lp-offset, POSTPONE ! ENDOF - [ comp' dlocal drop >definer ] literal + [ comp' dlocal drop ] literal >definer OF POSTPONE laddr# >body @ lp-offset, POSTPONE 2! ENDOF - [ comp' flocal drop >definer ] literal + [ comp' flocal drop ] literal >definer OF POSTPONE laddr# >body @ lp-offset, POSTPONE f! ENDOF -&32 throw endcase ;