Locals can be defined with
{: local1 local2 ... -- comment :}
or
{: local1 local2 ... :}
or
{: local1 local2 ... | ulocal0 ulocal1 -- comment :}
E.g.,
: max {: n1 n2 -- n3 :} n1 n2 > if n1 else n2 endif ;
The similarity of locals definitions with stack comments is intended. A
locals definition often replaces the stack comment of a word. The order
of the locals corresponds to the order in a stack comment and everything
after the --
is really a comment.
The name of the local may be preceded by a type specifier, e.g.,
F:
for a floating point value:
: CX* {: F: Ar F: Ai F: Br F: Bi -- Cr Ci :} \ complex multiplication Ar Br f* Ai Bi f* f- Ar Bi f* Ai Br f* f+ ;
Gforth currently supports cells (W:
, W^
), doubles
(D:
, D^
), floats (F:
, F^
), characters
(C:
, C^
), and xts (xt:
)
in several flavours:
(see Values) A value-flavoured local (defined with W:
,
D:
etc.) produces its value and can be changed with TO
and +TO
. Also, if you put addressable:
in front of the
locals definition, you can get its address with ADDR
(see How long do locals live?).
(see Variables) A variable-flavoured local (defined with W^
etc.) produces its address (see How long do locals live?). E.g.,
the standard word emit
can be defined in terms of type
like this:
: emit {: C^ char* -- :} char* 1 type ;
(see Deferred Words) A defer-flavoured local (defined with
XT:
) execute
s the xt; you can use action-of
(see Deferred Words) to get the xt out of a defer-flavoured local.
If the local is defined with addressable: xt:
, you can use
addr
to get the address where the xt is stored (see How long do locals live?). E.g., the standard word execute
can be
defined with a defer-flavoured local like this:
: execute {: xt: x -- :} x ;
A local without type specifier is a W:
local. You can also
leave away the w:
if you use addressable:
.
All flavours of locals are initialized with values from the data or
(for FP locals) FP stack, with the exception being locals defined
behind |
: Gforth initializes them to 0; some Forth systems leave
them uninitialized.
Gforth supports the square bracket notation for local buffers and data
structures. These locals are similar to variable-flavored locals, the
size is specified as a constant expression. A declaration looks
name[ size ]
. The Forth expression size
is
evaluated during declaration, it must have the stack effect ( --
+n )
, giving the size in bytes. The square bracket [
is part
of the defined name.
Local data structures are initialized by copying size bytes from
an address passed on the stack; uninitialized local data structures
(after |
in the declaration) are not erased, they just contain
whatever data there was on the locals stack before.
Example:
begin-structure test-struct field: a1 field: a2 end-structure : test-local {: foo[ test-struct ] :} foo[ a1 ! foo[ a2 ! foo[ test-struct dump ;
Gforth allows defining locals everywhere in a colon definition. This poses the following questions: