我正在使用Gforth的解释器指令(非ANS标准)控制结构,如手册部分5.13.4 Interpreter Directives中所述。我基本上想要使用循环词来创建一个包含文字的动态大小的单词。我想出了这个定义,例如:
: foo
[ 10 ] [FOR]
1
[NEXT]
;
然而,这会在[FOR]
之后产生地址对齐异常(是的,我知道你不应该在Forth中使用for循环。这只是一个简单的例子)。
最后,事实证明您必须将循环写为单行,以确保正确执行。这样做
: foo [ 10 [FOR] ] 1 [ [NEXT] ] ;
反而按预期工作。运行see foo
会产生:
: foo
1 1 1 1 1 1 1 1 1 1 1 ; ok
这正是我想要的。
有没有办法在单词定义中添加新行?我想写的字更复杂,对于演示,我需要更好地格式化。
答案 0 :(得分:2)
最好使用直接的单词代替。例如,
: ones ( n -- ) 0 ?do 1 postpone literal loop ; immediate
: foo ( -- ten ones ) [ 10 ] ones ;
SEE FOO
导致与您的示例相同。使用POSTPONE
,特别是使用Gforth的]] .. [[
语法,重复的代码可以随心所欲。
多行[FOR]
需要做四件事:
使用REFILL
读取后续行。
保存读入行,因为您需要逐个评估它们以保留行期望的解析行为(例如来自评论:\
)。
当您与终结[NEXT]
匹配时,停止阅读并循环播放。
请注意在[NEXT]
之后立即离开> IN,以便正常继续进行解释。
您可能仍会遇到一些代码问题,例如代码检查SOURCE-ID
。
有关使用REFILL解析多行的示例,请参阅Gerry的a recent posting from CLF代码:
: line, ( u1 caddr2 u2 -- u3 )
tuck here swap chars dup allot move +
;
: <text> ( "text" -- caddr u )
here 0
begin
refill
while
bl word count s" </text>" compare
while
0 >in ! source line, bl c, 1+
repeat then
;
这会收集<text>
和</text>
之间的所有内容,就像HERE文档一样,同时还会添加空格。要以简单的方式保存[FOR]
的各个行,我建议将0作为标记留在数据堆栈上,然后在其上放置SAVE-MEM
'd行。