"Locals + extensions"

locals
The Portable Forth Environment does implement locals
in such an extended form as that additional variable
names can be declared anywhere in the compiled word.

Locals are names for values that live in a locals-frame
on the return-stack - on entry to the procedure that
locals-frame is carved from the return-stack and a
frame-pointer is setup. Locals are in two forms, one
is inialized by a chunk from the parameter-stack as
it is with LOCALS| while the others are local variables
declared later. The latter are left unitialized on
setup of the locals-frame.

For unnamed returnstack locals, see words like
R@ R! R'@ R'! R"@ R"! 2R@ 2R!
but here the setup and cleanup of the return-stack frame
is left to the user, possibly using some words like
>R R> 2>R 2R> R>DROP while the locals-ext
will take care to provide a frame-creation token and
some cleanup-code for each EXIT or ;
Tektronix CTE %version: bln_mpt1!5.16 % GNU LGPL
[ANS]
* (LOCAL) ( strptr strcnt -- )

this word is used to create compiling words that can
declare LOCALS| - it shall not be used directly
to declare a local, the pfe provides LVALUE for
that a purpose beyond LOCALS|

locals compiling primitive

* LOCALS| ( xN ... x2 x1 [name1 .. nameN <|>] -- )

create local identifiers to be used in the current definition.
At runtime, each identifier will be assigned a value from
the parameter stack.

The identifiers may be treated as if being a VALUE , it does
also implement the ansi TO extensions for locals. Note that
the identifiers are only valid inside the currently compiled
word, the SEE decompiled word will show them as
<A> <B> ... <N> a.s.o.

see also LVALUE

locals compiling primitive

EXTENSIONS
* LVALUE ( value [name] -- )

declares a single local VALUE using (LOCAL) - a
sequence of LVALUE declarations can replace a
LOCALS| argument, ie. LOCALS| a b c |
is the same as LVALUE a LVALUE b LVALUE c .
This should also clarify the runtime stack behaviour of
LOCALS| where the stack parameters seem to be
assigned in reverse order as opposed to their textual
identifier declarations.

compare with VALUE and the pfe's convenience word
VAR.
 : LVALUE 
   STATE @ IF 
     VALUE 
   ELSE 
     BL WORD COUNT DUP (LOCAL) (TO)
   THEN
 ; IMMEDIATE

locals compiling primitive

* LBUFFER: ( size [name] -- )

declares a single local VALUE using (LOCAL) - which
will hold the address of an area like BUFFER: but carved
from the return-stack (as in C with alloca). This local buffer
will be automatically given up at the end of the word. The
return-stack-pointer will be increased only at the time of
this function (and the address assigned to the LVALUE)
so that the provided size gets determined at runtime. Note
that in some configurations the forth-return-stack area is
quite small - for large string operations you should consider
to use a POCKET-PAD in pfe.
 : LBUFFER:
   STATE @ IF 
     BUFFER:
   ELSE 
     :NONAME ( size -- rp* ) R> RP@ - DUP RP! SWAP >R ;NONAME
     COMPILE, POSTPONE LVALUE
   THEN
 ; IMMEDIATE

locals compiling primitive

ENVIRONMENT
enviroment hints (testing for -EXT will mark this wordset as present)
ENVIRONMENT LOCALS-EXT

no special info, see general notes

locals ordinary constant

* ENVIRONMENT #LOCALS ( -- number )

the number of local names allowed during compilation.
portable programs can check this with ENVIRONMENT?

locals ordinary constant

ENVIRONMENT LOCALS-LOADED

no special info, see general notes

locals constructor primitive