On Tuesday, September 3, 2019 at 11:15:11 AM UTC-7, Anton Ertl wrote:
> Ruvim <
ruvim...@gmail.com> writes:
> >I saw the following definitions:
> >
> > HIDE ( -- )
> > Make the last defined entry invisible, if it is possible.
> >
> > REVEAL ( -- )
> > Make the last defined entry visible, does nothing if HIDE does so.
> >
> >See also the reference implementation for SYNONYM in Forth-2012 [1]
> >It uses REVEAL in this sense too.
>
> This implementation is specific to VFX (as mentioned in the text). It
> uses CREATE, which REVEALs the new word, and then HIDEs it again to
> find the old word, and finally REVEALs the new word again.
>
> Gforth's SYNONYM implementation currently looks as follows:
>
> : Synonym ( "name" "oldname" -- ) \ Forth200x
> header dodefer,
> ?parse-name find-name dup 0= #-13 and throw
> dup compile-only? IF compile-only THEN
> ['] s>int ['] s>comp synonym, reveal ;
>
> This creates the word with HEADER (which does not REVEAL it), then
> FIND-NAMEs the old word, and eventually REVEALs the new word. Gforth
> does not have HIDE, and we have not missed it yet.
SYNONYM SYNONYM-FAST and ALIAS are trivial to implement in ANS-Forth
given that the disambiguifiers are already provided:
-----------------------------------------------------------------------
\ ******
\ ****** Our SYNONYM SYNONYM-FAST and ALIAS words --- these depend upon having the disambiguifiers available.
\ ******
: :synonym { xt flg str wid -- } \ FLG is 1 for immediate and -1 for non-immediate
str wid :name
flg 1 = if xt lit, execute, ;, immediate exit then
flg -1 = if xt compile, ;, exit then
true abort" *** :SYNONYM given an invalid xt ***" ;
: :synonym-fast-check ( -- )
state @ 0= abort" *** a word created by :SYNONYM-FAST can't be used in interpretive mode ***" ;
: :synonym-fast { xt flg str wid -- } \ FLG is 1 for immediate and -1 for non-immediate
str wid :name
flg 1 = if xt lit, execute, ;, immediate exit then
flg -1 = if postpone :synonym-fast-check
xt lit, postpone compile, ;, immediate exit then
true abort" *** :SYNONYM-FAST given an invalid xt ***" ;
: 'find ( -- xt flg ) \ stream: name \ FLG is 1 for immediate and -1 for non-immediate
bl word find dup 0= abort" *** 'FIND couldn't find the word ***" ;
: synonym { wid | new -- } \ stream: new-name old-name \ the new word is compiled into the WID word-list
bl word hstr to new
'find new wid :synonym
new dealloc ;
: synonym-fast { wid | new -- } \ stream: new-name old-name \ the new word is compiled into the WID word-list
bl parse <hstr> to new
'find new wid :synonym-fast
new dealloc ;
\ :SYNONYM-FAST generates faster executing code than :SYNONYM but the words can't be used in interpretive mode.
\ This may not be necessary with a good optimizing compiler, but I'm not aware of any at this time.
1234512345 constant alias-id \ an arbitrary number used to identify alias'd definitions
0
w field alias.xt \ this should be the first field so the DOES> portion of ALIAS will be fast (no addition needed)
w field alias.adr \ the address of the body, used to identify alias'd definitions
w field
alias.id \ the constant ALIAS-ID, used to identify alias'd definitions
constant alias-struct
: alias ( wid -- ) \ stream: new-name old-name \ the new word is compiled into the WID word-list
get-current swap set-current create set-current
here >r alias-struct allot
'find 1 = if immediate then r@ alias.xt !
r@ r@ alias.adr !
alias-id r@
alias.id !
rdrop
does>
alias.xt @ execute ;
\ ALIAS does the same thing as SYNONYM but has the advantage that ' ['] and >BODY will work on it.
\ It is slower executing though (especially under SwiftForth in which CREATE DOES> words are very inefficient).
: ' ( -- xt ) \ stream: name
' \ -- xt
dup >body >r
r@ alias.adr @ r@ = if r@
alias.id @ alias-id = if \ is this an alias'd word?
drop r> alias.xt @ exit then then \ return the xt of the original word
rdrop ;
: ['] ( -- ) \ stream: name \ runtime: -- xt
' postpone literal ; immediate
: >body ( xt -- adr )
>body >r
r@ alias.adr @ r@ = if r@
alias.id @ alias-id = if \ is this an alias'd word?
r> alias.xt @ >body exit then then \ return the body of the original word
r> ; \ return the body of this word
\ Note that >BODY still has an undefined result if used on a word that wasn't defined with CREATE or isn't an alias of such a word.
-----------------------------------------------------------------------