|
Win32Forth
命名的输入参数和局部变量
W32F 的实现是从 Macintosh Forth 系统 Yerkes ( 原来称为 Neon) 移植过来的。 ANSI 标准中“ Local ”局部变量与本文的“ args ”参数非常相似。
语法
: 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
... ;
您可以定义 0 或者多达 12 个的参数。 -- 和 } 都是语法要求的部分。任何位于 -- 和 } 之间内容都被作为注释,不做任何事情。下面是合法的参数声明:
{ -- } \ does nothing
{ arg -- } \ one input argument
{ \ local -- } \ one local (not initialized!)
{ arg \ local -- } \ one arg and one local
{ arg1 arg2 -- result } \ two args
参数和局部变量都与“ values ”值非常相似,也就是说当执行一个定义而遇到参数或者局部变量名字的时候,它们的值将被推入堆栈。它们的内容可以使用 TO 或者 +TO 进行修改。
限制
如果在 :M 方法定义中使用,则左大括号 ' { ' 必须是第一个字;
全部的参数和局部变量的数目限制到最多 12 个;
只能支持普通的(单个单元 ) 的数,不支持双精度和浮点数,可以使用 LOCALALLOC: 定义双精度数、浮点数和串;
局部变量不能被初始化;
名称不能以 '\' '-' 或者 '}' 开始;
一个定义或者使用 { 或者使用 LOCALS| 。如果定义中使用了一种方式,就不能再使用另外一种!
局部变量不能在控制结构中声明;
当声明了局部变量后,匹配的 >R 和 R> 或者 DO 循环先于局部变量的使用(除了在方法中,见 1 )。
实现
在一个字的开始,局部变量被分配,参数从数据堆栈中弹出并压入返回栈。它们相对于用户变量 'LP' 引用。当您使用 exit 或者 ; 分号时,参数区被释放。对于 DO ... LOOP 和 >R R> 也是一样的。
由于有一些运行时间开销,您应该在能够使代码更清晰的情况下、或者在做许多堆栈捣弄的情况才使用参数或者局部变量,不要滥用这个特性!

其它说明 :
现在也实现了字 LOCALS| ,这个字在 ANS 标准的 LOCAL-EXT 扩展中定义,下面是一个例子:
: FOO
LOCALS| A1 A2 |
2 +TO A2
A1 A2 ;
序列 7 8 FOO 将在堆栈上返回 8 和 9 , 9 在栈顶。
使用 LOCALALLOC:
LOCALALLOC: 可以用来引用任意大小的数据,比如串、双精度数和数组。
: 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
.... ;
使用栈帧
另一个局部结构方法是把值保存在连续的局部区域中,这在与操作系统接口时特别有用,因为 C 语言的 C struct 比如:
typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;
可以简单地映射为参数列表,如下例子:
: 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 ;
这里结构的地址通过其第一个成员的地址确定。 如果需要, POINT 结构 ( pt.x 和 pt.y ) 可以通过
&OF pt.x
全部引用。
注意: Win32F 的早期版本中, &OF 只能在值上工作,而另一个字 &LOCAL 可以提供局部变量的地址。
|