If you want to do something that allocates memory from the dictionary or compiles code in the middle of a contiguous region of another dictionary allocation, or in the middle of a colon definition, that’s not possible with a single dictionary pointer, leading to complicated workarounds.
Gforth provides dictionary sections to address this problem. Each section has its own dictionary pointer, and allocating or compiling something in one section does not interrupt the contiguity of allocations in other sections. In this respect Gforth’s sections are similar to sections and segments in assembly languages.
One difference is that the most common usage of sections is as a stack
of sections, which is useful for building nested definitions or
dictionary-allocated data structures: Use next-section
for the
inner definition or data structure, switch back with
previous-section
.
Words like latest
(see Name token) and latestxt
(see Anonymous Definitions) refer to the most recent definition in
the current section. Quotations (see Quotations) and the implicit
quotation of does>
(see User-defined defining words using create) are in a different section than the containing definition, so
after the quotation ends (and the section is switched back), words
like latest
report the outer definition rather than the
quotation.
An example of such a usage of the section stack is:
create my2x2matrix next-section here 1 , 2 , previous-section , next-section here 3 , 4 , previous-section , \ now print my2x2matrix[0,1], i.e., "2": my2x2matrix 0 cells + @ 1 cells + @ .
This works also for allocating section memory while compiling a definition, or defining a definition during a contiguous region, e.g.:
create mydispatchtable next-section :noname ." foo" ; previous-section , next-section :noname ." bar" ; previous-section , \ now dispatch mydispatchtable[1] mydispatchtable 1 cells + @ execute
Note that the interpretation semantics of [:
(see Quotations) switches to the next section internally, so you
can write mydispatchtable
also as follows:
create mydispatchtable [: ." foo" ;] , [: ." bar" ;] ,
The interpretation semantics of does>
uses a separate section,
so the does>
does not end the contiguous region, and you can
define a word mydispatch
that includes the dispatch code, as
follows:
create mydispatch does> ( u -- ) ( u addr ) swap cells + @ execute ; [: ." foo" ;] , [: ." bar" ;] , 1 mydispatch \ prints "bar"
next-section
( – ) gforth-1.0 “next-section”
Switch to the next section in the section stack. If there is no such section yet, create it (with the size being a quarter of the size of the current section).
previous-section
( – ) gforth-1.0 “previous-section”
Switch to the previous section in the section stack; the now-next section continues to exist with everything that was put there. Throw an exception if there is no previous section.
The bottom section in the section stack has the size given with the
--dictionary-size
command-line parameter (see Invoking Gforth).
In addition to the stack of anonymous sections you can also have named sections that you define with:
extra-section
( usize "name" – ) gforth-1.0 “extra-section”
Define a new word name and create a section s with at
least usize unused bytes.
Name execution (
... xt -- ... )
: When calling name, the current section is
c. Switch the current section to be s, execute xt,
then switch the current section back to c.
As an example, here’s a variant of the my2x2matrix
definition:
4 cells extra-section myvec create my2x2matrix ' here myvec 1 ' , myvec 2 ' , myvec , ' here myvec 3 ' , myvec 4 ' , myvec ,
Currently a named section does not start a dictionary stack, and using
next-section
inside a named section throws an error.
You can show the existing sections with:
.sections
( – ) gforth-1.0 “.sections”
Show all the sections and their status.
At the time of this writing this outputs:
start size used name $7F9A5A516000 32768 96 noname $7F9A5A1A1000 131072 208 noname $7F9A5A1C2000 524288 2128 noname $7F9A4BDFD000 2097152 32680 noname > $7F9A4BFFE040 8388608 659272 Forth $7F9A5A51F000 20480 1448 locals-headers
The lines describe the different sections: First the section stack,
with sections called noname
and (the bottom) Forth
, then
the extra-sections. The columns are the start address of the section,
the gross size (including section management overhead), how much of
the section is already used, and the name. The size and used columns
are in decimal base.
In the section Forth
, not all of the remaining size can be used
for allot
ting memory, because room must be left for pad
(memory blocks
). The current section is marked with the
>
. Also, if you use word
(see The Input Stream),
you must leave room in the current section for the parsed string and
its length byte.