6.7.3 Sections

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.

A Gforth-specific property of sections is that 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. 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 usable size usize.
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
     7F884CE34000      4000       5D8 locals-headers 
>    7F883ECBF040    800000     A09A0 Forth 
     7F883EABE000    200000      7FE8 noname 
     7F883EA3D000     80000       7F0 noname 
     7F883EA1C000     20000        C8 noname 
     7F883EA13000      8000        58 noname

The lines are the different sections: First the named sections, then the section stack, with the bottom of the stack (Forth) shown topmost with the name Forth. 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. All numbers are in hexadecimal base. Note that not all of the remaining size can be used for allotting memory, because room must be left for the hold buffer (see Formatted numeric output) and for pad (memory blocks). The current section is marked with the >.