Well, I'm a little late to the party which I first proposed around 2012,
and which Alex McDonald actually made happen, but better late than never.
I finally got around to implementing TRAVERSE-WORDLIST in kforth64, and
it will soon appear in kforth32. The need for this word was made apparent
when David N. Williams and I were working on our modules framework -- the
word is mentioned in the document modular-forth.pdf (see ref. below):
<quote>
...
One area of planned development is to provide additional tools to Forth
authors, to aid with development of modules supporting name reuse.
Already, the simple tool SHOW-MODULES is very useful for a programmer to
view the available modules loaded in a Forth system. Other envisioned
tools will support the development and use of generic interfaces by
allowing the programmer to query for a list of name overlaps within
modules. Such tools include:
* display the names of all modules which provide a particular
name in their API,
s" <word_name>" MEMBER-OF
* display all API names which overlap between two given modules,
' <mod_A> ' <mod_B> NAMES-OVERLAP
* display a given module's dependencies,
' <mod_name> SHOW-DEPENDENCIES
... tools such as MEMBER-OF and NAMES-OVERLAP currently cannot be
implemented in standard Forth, due to the lack of a standard way of
traversing wordlists and obtaining word names. However, we expect such
features may be standardized in the near future since a number of Forth
systems already provide such features. A Request for Discussion (RfD) has
already been posted to the comp.lang.forth newsgroup for the
standardization of a word named TRAVERSE-WORDLIST . We are optimistic
that standardized infrastructure will be adopted in Forth systems to
support the development of such tools.
...
</quote>
I'm quite happy that it happened and TRAVERSE-WORDLIST became part of the
de-facto Forth standard. The inclusion of it in my Forth system means
that I can get on with adding planned features for our modules framework.
More generally, the Forth environment combined with the language gives us
powerful tools to query the environment and the code, and to write
utilities to give us a higher-level picture of the code (word)
dependencies, or optimization, or even system integrity checking.
TRAVERSE-WORDLIST can be a useful tool to develop such utilities. One
example that comes to mind is our recent discussion about the body
addresses for words, and how they are often invalid addresses for
parameter data associated with a word. I wrote a word called WL-INFO
using TRAVERSE-WORDLIST to display the name, precedence, xt, and body
address of all the words in a given wordlist. This type of environment
view will be useful in reimplementing >BODY to ensure that it returns
either a valid parameter address or zero. See below.
Krishna Myneni
Reference:
K. Myneni and D. N. Williams, A Forth Modules System with Name Reuse, 15
Feb. 2012,
https://github.com/mynenik/kForth-32/blob/master/doc/modular-forth.pdf
----
\ Example of using TRAVERSE-WORDLIST: WL-INFO
include ans-words
include strings
\ kForth-specific implementation of Forth-2012 NAME>STRING
\ (15.6.2.1909.40 in Tools Ext)
: name>string ( nt -- caddr u ) dup strlen ;
\ right justified output of a string in a field
: $.R ( caddr1 u1 nfield -- | assume nfield > u1)
over - spaces type ;
: word-info ( nt -- flag )
name>string
2dup cr 32 $.R \ display the word name
strpck find \ obtain the word's xt and precedence
4 spaces
1 = IF s" IMM " \ display precedence IMMEDIATE
ELSE s" "
THEN type
dup >body swap \ -- pfa xt/cfa
16 u.r \ display the xt/cfa
2 spaces
16 u.r \ display the pfa ( may not be valid )
true ;
\ Display info on each word in the specified wordlist:
\ Name, Precedence, xt/cfa, pfa
: wl-info ( wid -- )
['] word-info swap traverse-wordlist ;
hex
forth-wordlist wl-info
cr .s
----
The above should work on any Forth system which provides Forth-2012's
NAME>STRING and TRAVERSE-WORDLIST. The definition of the non-standard
word STRPCK (sometimes also called PACK) is simple. Below is the output
from "forth-wordlist wl-info", displaying information about the words in
the Forth wordlist in the traversal order, which is the same as the
search order. Notice that the body addresses at right appear to be all
over the place -- the longer ones probably correspond to EXECUTEable
bytecode sequences. A smarter >BODY should return zeros for these invalid
body addresses.
---
WL-INFO D74010 D6CF90
WORD-INFO D6CF90 D73F00
$.R D6F8F0 38000000EE74202D
NAME>STRING D73F00 D6FAE044
STRING>S D74090 0
NUMBER_VAL D73EE0 D73EC0
NUMBER_SIGN D73E50 D73DE0
S>STRING D73E70 D73CF044A2DC
STRING>D D73D70 4163A84764DC40
D>STRING D73D90 D73B404430DC
STRING>UD D73D40 4964DC4042
UD>STRING D73B40 80441B1C1864DC40
U>STRING D73CF0 4964CA40
STRPCK D73C80 FF
STRCAT D73C20 D73B8044A02BD3
STRBUFCPY D73BD0 D73B8044C9A0AA
ADJUST_STR_BUF_PTR D73B80 D6F680
STR_BUF_PTR D73B20 D6F680
STRING_BUF D6F660 D6FB10
STR_BUF_SIZE D6F7F0 D6FAC0
STRLEN D6FAE0 0
STRCPY D6F610 B8EE15CADDA0AAC9
UCASE D6FA80 6149
ISDIGIT D6FA50 30
IS_LC_ALPHA D6FA20 61
PARSE_LINE D6F9E0 0
PARSE_TOKEN D6F630 D6F98044
SKIP D6F980 4CE6F7
SCAN D6F6B0 4CE6F7
IS IMM D6F8A0 40992A47
DEFER D6F870 149
THROW D6F470 25E6
CATCH D6F830 D6F43041DC
EMPTY-HANDLER D6F450 B800000000000000
HANDLER D6F3F0 D6F430
[THEN] IMM D6F410 3800000000000000
[IF] IMM D6F5F0 12E6
[ELSE] IMM D6F720 1
$UCASE D6F500 49
F~ D6F360 46
VALUE D6AA40 149
TO IMM D6F3B0 40992A4748
PAD D6F0F0 D6F110
CHARS D6F0D0 0
SPACE D6AA20 E80000000000EE65
FTRUNC>S D46DE0 B800007FC1EEC6EE
FROUND>S D46DC0 B800007FC1EEC6EE
F>D D46DA0 B800007FC1EEC6EE
D>F D46D80 B800007FC1EEC6EE
S>F D46D60 B800007FC1EEC6EE
D>S D46D40 B800007FC1EEC6EE
S>D D46D20 B800007FC1EEC6EE
RAD>DEG D46D00 B800007FC1EEC6EE
DEG>RAD D46CE0 B800007FC1EEC6EE
FEXPM1 D46CC0 414191
FEXP D46CA0 B800007FC1EEC6EE
FLNP1 D46C80 414235
...
>FLOAT D45AC0 415F02
HOLD D45AA0 B800007FC1EEC6EE
SIGN D45A80 B800007FC1EEC6EE
#> D45A60 B800007FC1EEC6EE
#S D45A40 B800007FC1EEC6EE
# D45A20 B800007FC1EEC6EE
<# D45A00 B800007FC1EEC6EE
NUMBER? D459E0 4163A8
>NUMBER D459C0 415CA5
COUNT D459A0 B800007FC1EEC6EE
-TRAILING D45980 415744
/STRING D45960 4106A9
S" IMM D45940 B800007FC1EEC6EE
C" IMM D45920 B800007FC1EEC6EE
.( IMM D45900 B800007FC1EEC6EE
( IMM D458E0 B800007FC1EEC6EE
#! IMM D458C0 B800007FC1EEC6EE
\ IMM D458A0 B800007FC1EEC6EE
CONSOLE D45880 B800007FC1EEC6EE
>FILE D45860 B800007FC1EEC6EE
CHDIR D45840 416942
US2@ D45820 416D44
US D45800 416BC5
MS@ D457E0 B800007FC1EEC6EE
MS D457C0 B800007FC1EEC6EE
TIME&DATE D457A0 416A14
GET-ITIMER D45780 4173BC
SET-ITIMER D45760 417298
...
FIND D445C0 B800007FC1EEC6EE
WORD D445A0 B800007FC1EEC6EE
PARSE D44580 415616
ASSEMBLER D44560 40514A
VOCABULARY D44540 404E0E
PREVIOUS D44520 4050ED
ONLY D44500 404F7B
ALSO D444E0 404FAD
TRAVERSE-WORDLIST D444C0 40516B
SEARCH-WORDLIST D44280 404BC1
GET-ORDER D44260 4049E7
SET-CURRENT D44240 404992
GET-CURRENT D44220 404956
WORDLIST D44200 40488E
DEFINITIONS D441E0 404DDB
<empty>
ok