Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

vocabulary with VFX forth

65 views
Skip to first unread message

emmanuel

unread,
Sep 2, 2021, 7:47:25 AM9/2/21
to
Dear all ,

I would like to play with the vocabulary under VFX forth (windows version).

I do the same under gforth and it's ok why ?

cheers
Emmanuel


In fact, I have an error like this :


vocs
WINCONSTANTS BNF-VOC EXTERN.VOC TYPES DISASSEMBLER H-C ASM-ACCESS ASM-CORE LOCALGEN LOCALARGS
COMPILATION? LOCALVARS LICENSED EXTERNALS SUBSTITUTIONS SOURCEFILES ENVIRONMENT SYSTEM ROOT
FORTH
ok
vocabulary myvocabulary ok
myvocabulary definitions ok
: hello ." hello from my myvocabulary" ;
Err# -13 ERR: Undefined word.
-> : hello ." hello from my myvocabulary" ;
^

Ruvim

unread,
Sep 2, 2021, 8:42:54 AM9/2/21
to
On 2021-09-02 14:47, emmanuel wrote:
> Dear all ,
>
> I would like to play with the vocabulary under VFX forth (windows version).
>
> I do the same under gforth and it's ok why ?
>

>
> In fact, I have an error like this :
>
>
> vocs
> WINCONSTANTS BNF-VOC EXTERN.VOC TYPES DISASSEMBLER H-C ASM-ACCESS ASM-CORE LOCALGEN LOCALARGS
> COMPILATION? LOCALVARS LICENSED EXTERNALS SUBSTITUTIONS SOURCEFILES ENVIRONMENT SYSTEM ROOT
> FORTH
> ok
> vocabulary myvocabulary ok
> myvocabulary definitions ok
> : hello ." hello from my myvocabulary" ;
> Err# -13 ERR: Undefined word.
> -> : hello ." hello from my myvocabulary" ;
> ^
>

"myvocabulary" is a vocabulary. When a vocabulary is performed, it
*replaces* the top word list in the search order.
See also:
<https://forth-standard.org/proposals/vocabulary?hideDiff#reply-453>

So, the "myvocabulary" word has the following effects:

myvocabulary ( -- ) ( O: i*wid wid0 -- i*wid wid-myvocabulary )

Where "O:" identifies the search order stack.

If the search order is ( O: wid-forth ), then after "myvocabulary" is
performed the search order is ( O: wid-myvocablulary ).
And nothing can be found anymore.

It's your case in VFX.

In Gforth the initial search order is:

( O: wid-root wid-forth wid-forth )

and after "myvocabulary" it is:

( O: wid-root wid-forth wid-myvocabulary )

So your code works in Gforth.

But in the general case you cannot assume that the initial search order
contains anything except FORTH-WORDLIST


So, your code should be:

vocabulary myvocabulary
also myvocabulary definitions

where
also ( O: wid -- wid wid )



--
Ruvim

emmanuel

unread,
Sep 2, 2021, 8:54:47 AM9/2/21
to
Great ! :)

thank's a lot

Emmanuel





dxforth

unread,
Sep 2, 2021, 7:04:34 PM9/2/21
to
On 2/09/2021 22:42, Ruvim wrote:
>
> But in the general case you cannot assume that the initial search order
> contains anything except FORTH-WORDLIST

Alas, how complicated we humans have made Forth (and everything else).

Hugh Aguilar

unread,
Sep 2, 2021, 9:23:54 PM9/2/21
to
> > Ruvim
> Great ! :)
>
> thank's a lot

Here is code that brings ANS-Forth up to the level of Forth-83 (see the
SET-CONTEXT word that does what storing a vocno into CONTEXT did
in Forth-83). There are other features provided. This is from my novice package.
----------------------------------------------------------------------------------------------------------------
\ ******
\ ****** Some word-list stuff.
\ ******

: set-forth ( -- ) \ sets default configuration
only forth definitions ;

: <get-context> ( -- wid ) \ like CONTEXT @ in Forth-83 (ANS-Forth already provides GET-CURRENT)
get-order dup 1 < abort" *** GET-CONTEXT given empty search-order ***"
over >r \ r: -- top-wid
0 do drop loop \ --
r> ;

: <push-context> { wid -- }
get-order
wid swap 1+ \ put WID on top of whatever is there
set-order ;

\ <PUSH-CONTEXT> always pushes WID, even if WID is already the 1st. It has to be consistent in always pushing, so <POP-CONTEXT> can pop what was pushed.

: <pop-context> ( -- wid ) \ undo PUSH-CONTEXT and return the wid
get-order dup 1 < abort" *** POP-CONTEXT given empty search-order ***"
swap >r 1-
set-order
r> ;

: <drop-context> ( -- )
<pop-context> drop ;

\ <GET-CONTEXT> <PUSH-CONTEXT> <POP-CONTEXT> and <DROP-CONTEXT> don't take into consideration LOCALVARS# being in the way.

\ VFX pushes a wid called LOCALVARS onto the search order in colon words that have locals, then pops it off again at the semicolon.
\ It is in the way. If you set the 1st value to a replacement wid, you will replace LOCALVARS rather than the wid you thought you were replacing (which is now 2nd).
\ This is a gross violation of the ANS-Forth standard (13.3.3-1):
\ "...if the Search-Order word set is present, local identifiers shall always be searched before any of the word lists in any definable search order,
\ and none of the Search-Order words shall change the locals’ privileged position in the search order."

\ Note: Stephan Pelc fixed the bug mentioned above in version 4.71.3523 of Oct.8,2014.

\ The following definition of SET-CONTEXT works around the bug in VFX, and will also work in Forths that don't have the bug.

false value localvars# \ this is the wid that is 1st in the search-order inside of colon words that have local variables
marker temporary
false value expected# \ this is the wid that we are expecting to be 1st

: fill-localvars# ( -- ) \ this fills <LOCALVARS> at compile-time for use by <SET-CONTEXT> --- it doesn't do anything at run-time
true abort" *** FILL-LOCALVARS# is not to be run, it fills LOCALVARS# at compile-time ***"
[ <get-context> to expected# ]
1 2 3 locals| x y z |
[
<get-context> expected# <> [if]
<pop-context> to localvars#
<get-context> expected# <> [if] .( *** FILL-LOCALVARS# can't find EXPECTED# ***) abort [then]
localvars# <push-context> [then]
] ;

\ FILL-LOCALVARS# doesn't have to run --- it fills LOCALVARS# at compile-time.
temporary \ discard this code that fills LOCALVARS# at compile-time --- it is never needed again

: push-underneath { wid -- } \ push WID underneath whatever is 1st so WID becomes 2nd, leaving 1st as 1st
<pop-context> \ hold 1st
<get-context> wid <> if
wid <push-context> then \ don't push WID on top of itself (if WID was 2nd originally)
<push-context> ; \ push 1st back on top

: replace-1st ( wid -- )
push-underneath <drop-context> ; \ use PUSH-UNDERNEATH so WID is not duplicated if it already 2nd

: <set-context> { wid anchor -- }
<get-context> anchor = if \ if ANCHOR is 1st
wid anchor = if exit then \ WID is already 1st, so we are done
wid <push-context> \ push WID on top of ANCHOR, rather than replace ANCHOR
exit then
<get-context> localvars# = if \ if LOCALVARS# is 1st
<pop-context> \ -- localvars#
<get-context> anchor = if \ if ANCHOR is 2nd
wid <push-context> \ push WID on top of ANCHOR, rather than replace ANCHOR
else
wid replace-1st then \ else, replace 2nd with WID
<push-context> \ restore LOCALVARS# as 1st
exit then
wid replace-1st ; \ 1st was neither ANCHOR nor LOCALSVAR#, so we just replace 1st with WID (now GET-CONTEXT will give us WID)

: set-context ( wid -- )
forth-wordlist <set-context> ;

\ FORTH-WORDLIST SET-CONTEXT would do the same thing that FORTH does.

\ The following PUSH-CONTEXT POP-CONTEXT and DROP-CONTEXT take into account LOCALVARS#.
\ Use xxx PUSH-CONTEXT rather than ALSO xxx SET-CONTEXT because everything goes haywire if the ANCHOR is the 1st wid.
\ All in all, ALSO is a screw-ball idea because it involves making a duplicate on the search-order, which makes no sense.
\ Forth is supposed to be context-free, but ALSO only makes sense when it is followed by SET-CONTEXT (but not when the anchor is 1st).
\ In this 1993 comp.lang.forth thread: https://groups.google.com/forum/#!topic/comp.lang.forth/olO-VHXJa1Q
\ Ray Duncan (who sold UR/Forth back then), described ONLY/ALSO as "severely brain-damaged."
\ Apparently he had zero influence over ANS-Forth design though, because he gave up on Forth after ANS-Forth came out in 1994.

: get-context ( -- wid )
<get-context> \ -- 1st
dup localvars# = if drop \ --
<pop-context> <get-context> \ -- 1st 2nd
swap <push-context> then ; \ -- 2nd

: definitions ( -- ) \ the VFX version of DEFINITIONS has a bug in that it doesn't take LOCALVARS into consideration
get-context set-current ;

: push-context { wid -- }
<get-context> localvars# = if
<pop-context> wid <push-context> \ -- 1st
<push-context> \ --
else
wid <push-context> then ;

: pop-context ( -- wid ) \ undo PUSH-CONTEXT and return the wid
<pop-context> \ -- 1st
dup localvars# = if
<pop-context> \ -- 1st 2nd
swap <push-context> then ; \ -- 2nd

: drop-context ( -- )
pop-context drop ;

char & comment \ this is for testing the word-list stuff

wordlist constant test1# \ used only by TEST that follows
wordlist constant test2# \ used only by TEST that follows

: test ( -- ) \ this tests SET-CONTEXT
[ cr .( TEST1# = ) test1# u. ]
[ cr .( TEST2# = ) test2# u. ]
[ cr .( FORTH-WORDLIST = ) forth-wordlist u. ]
[ set-forth order ]
[ get-context cr .( context = ) u. order ]
[ forth-wordlist set-context order ]
[ test1# set-context order ]
1 2 3 locals| x y z | [ order ]
[ get-context cr .( context = ) u. order ]
[ test1# push-context order ]
[ drop-context order ]
[ test1# set-context order ]
[ test2# set-context order ]
[ test1# push-context order ]
[ drop-context order ]
;

order
set-forth

: test-forth ( -- ) \ this tests FORTH that is supposed to be the same as FORTH-WORDLIST SET-CONTEXT
[ set-forth cr .( test-forth) order ]
[ forth order ]
1 2 3 locals| x y z | [ order ]
[ forth order ] \ this fails under VFX
;

order
set-forth

&


VFX? [if] \ We have >NAME so error-checking will be done. This code may work in other ANS-Forth systems as well.

: in-wordlist? ( xt wid -- 0|1|-1 ) \ we return 0 for not-found, 1 for immediate and -1 for non-immediate
over >name count rot search-wordlist \ -- xt 0 | xt found-xt 1 | xt found-xt -1
>r
r@ 0= if drop r> exit then \ it wasn't found
= if r> exit then \ it was found and it is the same
r> drop 0 ; \ it was found but it wasn't the same (it had the same name, but was a different word)

[else] \ We can't be sure that >NAME will be available except in VFX, so error-checking won't be done.

: in-wordlist? ( xt wid -- 0|1|-1 )
true abort" *** IN-WORDLIST? is not available except in VFX" ;
immediate

[then]

\ Problems may arise when using PUSH-CONTEXT and POP-CONTEXT if two wids are supposed to have words of the same name.
\ The user does a PUSH-CONTEXT of one of the wids, but the other wid is already in the search-order.
\ The user then looks up a word name. Unfortunately, the wid on top that is supposed to have that name doesn't have it, and so the name is found in the other wid.
\ Because of this problem, it is best to check every xt with IN-WORDLIST? to make sure that it was defined in the expected word-list.
\ Unfortunately, IN-WORDLIST? doesn't always work because it depends upon >NAME that is not ANS-Forth (some ANS-Forth systems, such as VFX, have it though).

: this-before-that? { this that | this-first? that-first? -- ? }
false to this-first?
false to that-first?
get-order 0 ?dup do
dup this = if that-first? 0= if true to this-first? then then \ don't set THIS-FIRST? if we have already found THAT
that = if this-first? 0= if true to that-first? then then \ don't set THAT-FIRST? if we have already found THIS
loop
this-first? ;

\ THIS-BEFORE-THAT? may be more useful than GET-CONTEXT because it searches the entire search-order.
----------------------------------------------------------------------------------------------------------------
0 new messages