Local Variables


The ANS standard provides for simple local variable support. At the beginning of a subroutine, parameters may be moved to the return stack. Locals are variables that reside on the return stack. They act like VALUEs in that you use TO to store to them. At the end of the subroutine, the return stack is cleaned up. Locals are basically a functional replacement for return stack manipulation.

The proposed ANS syntax is LOCAL| arga argb | where arga is the value on the top of the data stack and argb is next on the stack. This is backwards from the stack picture comment ( argb arga -- ? ).

Firmware Studio (as well as many other Forths) use a modified version whose syntax is:
{ argb arga \ argc -- }

Here, { behaves like LOCAL| except that it reverses the stack order and allows comments. So, it looks like a stack picture. The example shown above is handled as follows:

  1. Uninitialized storage is allocated for argc on the return stack. Marked by \ .
  2. Arga and Argb are removed from the data stack and placed on the return stack.
  3. Everything between -- and } is treated as a comment.

It is assumed that the CPU will use stack-relative addressing to access locals. R@, R>, R> and other return stack manipulators may throw off the indexing. For example:

: bad+ { a b \ -- } a >r b r> + ;

The >R in this case throws off the indexing of b.

The compiler compensates inside of DO..LOOP structures so that locals may be used inside of DO loops.

Locals support for various CPUs are handled via four defered words:

For 8051, AVR and 68K CPUs, locals need the files LOCALS.F51, LOCALS.FAR and LOCALS.FCF, respectively. They contain run-time code for the above-named words. For the 8051 and 68K, they also contain support for locals in tokenized code.

Firmware Studio and Win32forth support both syntaxes. The { } syntax is easily implemented and fairly common, so you should be safe using it. In other words, your code won't be locked into a particular Forth.

On the 68K builder, TOF has a word to allocate an array of cells on the data stack.
n {CELLS} ( #cells -- )
This is an immediate word that compiles code to return a base address. For example:

: FOO { \ mydata -- }
  [ 16 ] {cells} to mydata
  ;