Gforth has had structs before the standard had them; they are a little
different, and you can still use them. One benefit of the Gforth
structs is that they propagate knowledge of alignment requirements, so
if you build the nested
structure (see Standard Structures), you do not need to look inside intlist
to find
out the proper alignment, and you also do not need to mention
alignment at all. Instead, this example would look like:
struct cell% field intlist-next cell% field intlist-val end-struct intlist% struct char% field nested-foo intlist% field nested-bar end-struct nested%
The fields are variable-flavoured, i.e., they work in the same way as
those defined with field:
, +field
etc.
A disadvantage of the Gforth structs is that, with the standard going for something else, you need to learn additional material to write and understand code that uses them. Another disadvantage of the Gforth structs is that they do not support value-flavoured or defer-flavoured fields. On the balance, in our opinion the disadvantages now outweigh the advantages, so we recommend using the standard structure words (see Standard Structures). Nevertheless, here is the documentation for Gforth’s structs.
The list
and intlist
example looks like this with Gforth
structs:
struct cell% field list-next end-struct list% list% cell% field intlist-val end-struct intlist%
Intlist%
contains information about size and alignment, and you
use %size
to get the size, e.g., for allocation:
intlist% %size allocate throw constant my-intlist1
A shorthand for that is
intlist% %alloc constant my-intlist1
The fields behave the same way, so the rest of the example works as with standard structures.
In addition to specifying single cells with cell%
, you can also
specify an array of, e.g., 10 cells like this:
cell% 10 * field bla-blub \ equivalent to the standard: \ aligned 10 cells +field bla-blub
You can use cell% 10 *
not just with field
, but also in
other places where an alignment and size is expected, e.g., with
%alloc
.
%align
( align size – ) gforth-0.4 “%align”
Align the data space pointer to the alignment align.
%alignment
( align size – align ) gforth-0.4 “%alignment”
The alignment of the structure.
%alloc
( align size – addr ) gforth-0.4 “%alloc”
Allocate size address units with alignment align,
giving a data block at addr; throw
an ior code
if not successful.
%allocate
( align size – addr ior ) gforth-0.4 “%allocate”
Allocate size address units with alignment align,
similar to allocate
.
%allot
( align size – addr ) gforth-0.4 “%allot”
Allot size address units of data space with alignment align; the resulting block of data is found at addr.
cell%
( – align size ) gforth-0.4 “cell%”
char%
( – align size ) gforth-0.4 “char%”
dfloat%
( – align size ) gforth-0.4 “dfloat%”
double%
( – align size ) gforth-0.4 “double%”
end-struct
( align size "name" – ) gforth-0.2 “end-struct”
Define a structure/type descriptor name with alignment
align and size size1 (size rounded up to be a
multiple of align).
name
execution: – align size1
field
( align1 offset1 align size "name" – align2 offset2 ) gforth-0.2 “field”
Create a field name with offset offset1, and the type
given by align size. offset2 is the offset of the
next field, and align2 is the alignment of all fields.
name
execution: addr1 – addr2.
addr2=addr1+offset1
float%
( – align size ) gforth-0.4 “float%”
sfloat%
( – align size ) gforth-0.4 “sfloat%”
%size
( align size – size ) gforth-0.4 “%size”
The size of the structure.
struct
( – align size ) gforth-0.2 “struct”
An empty structure, used to start a structure definition.