6.25.1 Gforth locals

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:

value-flavoured

(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?).

variable-flavoured

(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 ;
defer-flavoured

(see Deferred Words) A defer-flavoured local (defined with XT:) executes 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: