Dictionary Organisation/Manipulation

The heart of any Forth system is the dictionary. There are two types of word which act on the dictionary. The first are those words which act on definition headers, whilst the second set act on dictionary "data-space."

Definition Header Structure

Definitions created with any standard defining word except :NONAME have a header within the dictionary. The header format is:


Link | Ctrl | Count | <name> | Term | Line# | Info | XRef | Len/xt | Cgen
-------------------------------------------------------------------------
Cell | Byte |  Byte | n Bytes| Byte |  Word | Word | Cell |  Cell  | Cell
-------------------------------------------------------------------------

Link

Also called LFA. This field contains the address of the "Ctrl Byte" of the previous word in the same wordlist.

Ctrl

The Control Byte: The top two bits are set. The lower six bits are:


           Bit5    NDCS bit
           Bit4    SYNONYM bit
           Bit3    Smudge bit
           Bit2    Immediate bit
           Bit1    ** bit
           Bit0    *** bit

Count

Also called the Count Byte. This field contains a byte which is the length of the name. The address of the byte is often called the "Name Field Address"

<name>

A string of ASCII characters which make up the definition name.

Term

All definition names are terminated with a 0 ASCII byte.

Line#

This field holds the line number of the first line of source which built the definition. The actual source file reponsible can be found from the SOURCES structure described in the FILE section of this manual.

Info

MPE/CCS Reserved field.

XRef

Pointer to XREF Information

Len/xt

Binary length of the word, or the xt of the code generator for this word.

Cgen

Holds the address of additional code generator information.

64bit? [if] #29 [else] #17 [then] equ /AfterName
The number of bytes that follow the name of a word.

Header Manipulation Words

These words allow the manipulation and navigation of dictionary headers.

cell 2+ /AfterName + constant HEADSIZE  \ -- n
Return the size of a standard dictionary header minus the name text.

: .NAME         \ nfa --
Display a definition's name given an NFA.

: name>         \ nfa -- xt
Move a pointer from an NFA to the XT.

: name>         \ nfa -- xt
Move a pointer from an NFA to the XT.

: ctrl>nfa      \ ^ctrl -- nfa
Move a pointer from the control byte to the name field.

: nfa>ctrl      \ nfa -- ^ctrl
Move a pointer from the NFA to the control byte field.

: >name         \ xt -- nfa|xt
Move a pointer from an XT back to the NFA or name-pointer. If the original pointer was not an XT or if the definition in question has no name header in the dictionary the returned pointer will be useless. Care should be taken when manipulating or scanning the Forth dictionary in this way. If xt is outside the dictionary, a dummy for "???" is returned.

: >BODY         \ xt -- a-addr                                   6.1.0550
Move a pointer from an xt to the body of a definition. This should only be used with children of CREATE. For example, if FOOBAR is defined by CREATE FOOBAR, then the phrase ' FOOBAR >BODY would yield the same result as executing FOOBAR.

: BODY>         \ a-addr -- xt
The inverse of >BODY. Note that this word is only valid for children of CREATE for which the data area follows the code portion. For words created by VARIABLE, VALUE, and BUFFER: amongst others, the result may/will be invalid, especially if the +IDATA switch is in use.

: >line#        \ xt -- addr
Move a pointer from an XT to the Line# field.

: >info         \ xt -- addr
Move a pointer from an XT to the header INFO field.

: >line#        \ xt -- addr
Move a pointer from an XT to the Line# field.

: >info         \ xt -- addr
Move a pointer from an XT to the header INFO field.

: >xref         \ xt -- xref
Move a pointer from a supplied XT to the XREF field in the header.

: >code-len     \ xt -- addr
Move a pointer from an XT to the length/xt field.

: >code-gen     \ xt -- addr
Move a pointer from an XT to the optimiser token stream field.

: ZeroOptData   \ cl --
Zero the optimiser fields at code-len.

: N>LINK        \ addr -- a-addr'
Move a pointer from a NFA field to the Link Field.

: LINK>N        \ a-addr -- addr'
The inverse of N>LINK.

: >LINK         \ xt -- a-addr'
Move a pointer from an XT to the link field address.

: LINK>         \ a-addr -- xt
The inverse of >LINK.

: name?         \ addr -- flag
Check to see if the supplied address is a valid NFA. A valid NFA satisfies the following:

: InOvl?      \ addr1 -- addr2|0
Returns the overlay address (addr2) if the given address (addr1) is within an overlay, otherwise returns 0.

: InForth?      \ addr -- flag
Returns true if the given address is within the Forth dictionary or an overlay.

: IP>NFA        \ addr -- nfa
Attempt to move backwards from an address within a definition to the relevant NFA.

: xtoptimised?  \ xt -- flag
Is the definition with the given XT optimised?

: patched?      \ xt -- flag
Is the definition with the given XT patched/plugged?

: patchxt       \ xtnew xtold -- ud patchflag
Patch the code for xtold to jump to xtnew. Return the first 8 bytes of xtold as ud. *i{Patchflag} is non-zero if xtold had already been patched. All optimisation for xtold is disabled.

: unpatch       \ ud patchflag xt --
Reverse the effect of PATCHXT.

Definition and Data space access.

These words act upon definition information or dictionary data space.

: LATEST        \ -- c-addr
Return pointer past the Link of the last definition. Note that this is NOT the name field, but the control field of the dictionary header. Use CTRL>NFA to move to the name field.

: latest-xt     \ -- xt
Returns the xt of the last definition to have a dictionary header.

: SMUDGE        \ --
Toggle the SMUDGE bit of the latest definition.

: HideName      \ nfa --
Hide (make unFINDable) the word whose NFA is given.

: RevealName    \ nfa --
Reveal (make FINDable) the word whose NFA is given.

: HIDE          \ --
Make the last word defined invisible to SEARCH-WORDLIST, FIND and friends.

: REVEAL        \ --
Make the last word defined visible to SEARCH-WORDLIST, FIND and friends.

: >#THREADS     \ wid -- a-addr
Converts a wid wordlist identifier to address of the cell holding the number of threads in the wordlist.

: >THREADS      \ wid -- a-addr
Converts a wid wordlist identifier to address of the first thread in the wordlist.

: WID-THREADS   \ wid -- addr len
Given a wid, return the address and length of its table of threads.

TRUE value warnings?    \ -- flag
Returns true if redefinition warnings are enabled.

: +warnings     \ --
Enable redefined warnings.

: -warnings     \ --
Disable redefined warnings.

0 value LastNameFound   \ -- nfa|0
Set by SEARCH-WORDLIST to contain the NFA of the last word found, or zero if no word was found. Use of LASTNAMEFOUND avoids having to use >NAME later.

Defer RedefHook \ --
A hook available for handling redefinitions. The NFA of the previous word is given by LastNameFound, and its xt by Original-Xt.

: (RedefHook)   \ --
The default action of RedefHook, which is to display the name of the word being redefined.

: ($CREATE)     \ caddr u --
Create a new definition in the dictionary with the name described by caddr/u. The phrase S" foobar" ($CREATE) has the same effect as typing CREATE foobar at the console.

: $create-in    \ caddr len wid --
Create a new definition in the dictionary with the name described by caddr/u in the wordlist given by wid.

: $CREATE       \ c-addr --
As with ($CREATE) but takes a counted string.

: CREATE        \ -- ; CREATE <name>
Create a new definition in the dictionary. When the new definition is executed it will return the address of the definition's data area.

: ndcs          \ --
Mark the last defined word as NDCS, i.e having "non-default compilation semantics". NDCS words will execute special behaviour during compilation.

: ndcs:         \ --
Defines the compilation actions of an NDCS word after the interpretation action has been defined. NDCS: sets flags, starts compilation of a :NONAME definition and sets the compilation action of the last word defined. Use this for code generators for words that have different interpretation and compilation actions, e.g. IF or S". Such words may parse or produce or consume items from the stack. NOTE that the *\fo{NDCS: word must not contain the word it is applied to because the word would be compiled before its compilation word has been completed.


: ."    \ "ccc<quote>"  --
\ Output the text up to the closing double-quotes character.
  [char] " word $.  ;
ndcs: ( -- )  compile (.")  ",  discard-sinline  ;

: ndcs?    \ xt -- flag
Return true if the word at xt is an NDCS word. Immediate words are also NDCS words.

: IMMEDIATE     \ --                                            6.1.1710
Mark the last defined word as immediate. Immediate words will execute whenever encountered regardless of STATE. IMMEDIATE words are marked as NDCS.

: Immediate?    \ xt -- flag
Return true if the word at xt is immediate.