The W32F implementation was ported from the Macintosh Forth system Yerkes (formerly Neon). The ANSI Standard "Local" is similar to what are called "args" in this documentation, except for reversed order.
: wordname { arg1 arg2 \ loc1 loc2 loc3$ -- result } arg1 \ returns value of 1st argument 0 TO loc1 \ stores a value to local 1 35 TO arg1 \ ok to change value of an arg 1 +TO loc2 \ increment local 2 &OF loc1 \ address of the local following ... ;
You can have 0 or more args or locals up to a total of 12. The -- and } are required parts of the syntax. Anything between -- and } is treated as a comment and does not do anything. The following are all valid argument declarations:
{ -- } \ does nothing{ arg -- } \ one input argument{ \ local -- } \ one local (not initialized!){ arg \ local -- } \ one arg and one local{ arg1 arg2 -- result } \ two args
The args and locals are similar to "values", in the sense that the value of the current arg or local is pushed on the stack during execution of a definition when the name is encountered. The content of an arg or local may be changed by using TO or +TO .
At the start of the word, locals are allocated and arguments are popped from the data stack and pushed onto the return stack. They are referenced relative to the user variable 'LP'. When you use exit or ; the arguments are deallocated. It is ok to use DO ... LOOP and >R R> at the same time as locals.
Since there is some runtime overhead, you should only use args and locals when it would clear up the code or when you find yourself doing a lot of stack juggling. Do not abuse this feature!
The LOCALS| word, as specified in the LOCAL-EXT extension in the ANS Standard has now been implemented. The following is an example:
: FOO LOCALS| A1 A2 | 2 +TO A2 A1 A2 ;
The sequence 7 8 FOO will return 8 and 9 on the stack, with the 9 on top.
LOCALALLOC: can be used to reference arbitary sized data such as strings, floats, doubles, and arrays. A local is used to hold the address and the space reserved as follows
: wordname { \ 2var -- } 2 cells localalloc: 2var \ reserve 2 cells and store base address in 2var 0. 2var 2! \ store double number 0 in 2 var .... ;
An alternative way of having local structures is to use consecutive locals to hold the values. This is especially useful for interfacing to the OS API functions since C structures like:
typedef struct tagMSG { // msg HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG;
can be easily mirrored in the argument list as in the following example:
: MESSAGE-LOOP ( -- ) \ Do all messages until WM_QUIT { \ hwnd mess wparm lparm time pt.x pt.y -- } Begin 0 0 0 &of hwnd call GetMessage While &of hwnd handlemessages drop Repeat ;
where the structure is referenced by the address of the first member. The POINT structure ( pt.x and pt.y ) can be referenced as a whole by
&OF pt.x
if required.
Note in early versions of Win32F the word &OF only worked on Values and a seperate word &LOCAL was provided for the address of a Local.
Document $Id: p-locals.htm,v 1.1 2004/12/21 00:18:56 alex_mcdonald Exp $