# Dictionary handling

The unit [mem/dict.fs] contains a few words that are useful to play around with
dictionary structures.

By "entry", we mean the address of the LL "next" field for the dictionary entry.
By "word", we mean the executable address of the entry. Remember: w>e translates
a word to an entry, e>w translates an entry into a word.

## API

Constants:

ENTRYSZ
  The maximum length of a dictionary entry, excluding the name. We say "maximum"
  because the actual number of bytes depends on alignment constraints.

Words related to dictionary:

.word ( word -- )
  Print "word"'s name.

words ( -- )
  Print all word name of the dictionary.

delete ( "name" -- )
  Find "name" and makes the entry unfindeable by setting its length to 0.

forget ( "name" -- )
  Find "name" in the dictionary and bring back the sysdict to the word that
  precedes it.

  This is different from the traditional Forth's "forget", which also rewinds
  "here". In Dusk, rewinding "here" is too tricky, tons of things can go wrong.
  Therefore, "forget" reclaims no memory. It merely tidies up the sysdict.

dictlink ( "name" -- )
  Create a new "Dictionary link", as described in doc/arch, named "name".
  Whenever you want to hold an entry reference without having to dereference
  held value before passing it to "find", you should use a dictlink rather than
  a simple "create" to avoid the possibility of a false match.

unitofentry ( e -- unit-or-0 )
  Look in all loaded units to see if entry "e" is part of one. If yes, yield
  it. That "unit" is a dict entry (for example, you can call "entryname[]" on
  it).

?w>e ( a -- e-or-0 )
  Checks whether address "a" is the payload of a word, that is:

  1. Whether it's in "here" space or kernel space (memory can be read without
     breaking the system).
  2. Whether length byte is nonzero.
  3. Whether all characters in the name are in the range $21-7e.

  If all conditions are met, yield the associated entry. Otherwise, yield 0.
