1

我正在使用 Gforth 的解释器指令(非 ANS 标准)控制结构,如手册第5.13.4 节解释器指令中所述。我基本上想使用循环词来创建一个包含文字的动态大小的词。例如,我提出了这个定义:

: 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

这正是我想要的。

有没有办法在单词定义中获得新的行?我想写的单词要复杂得多,对于演示文稿,我需要更好的格式。

4

1 回答 1

2

最好用一个直接的词来代替。例如,

: ones ( n -- ) 0 ?do 1 postpone literal loop ; immediate
: foo ( -- ten ones )  [ 10 ] ones ;

结果与SEE FOO您的示例相同。使用POSTPONE,尤其是使用 Gforth 的]] .. [[语法,重复的代码可以随心所欲。

多行[FOR]需要做四件事:

  1. 用于REFILL在后续行中阅读。

  2. 保存读入的行,因为您需要一一评估它们以保留预期行的解析行为(例如来自注释:)\

  3. 当您匹配终止的[NEXT].

  4. 注意在 之后立即离开 >IN[NEXT]以便解释可以正常继续。

您可能仍然会遇到一些代码问题,例如代码检查SOURCE-ID

有关使用 REFILL 跨多行解析的示例,以下是 Gerry最近从 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>和 a之间的所有内容</text>,就像 HERE 文档一样,同时还添加了空格。为了[FOR]以简单的方式保存单独的行,我建议将 0 作为数据堆栈上的标记,然后将SAVE-MEM'd 行放在它上面。

于 2015-01-13T00:24:27.120 回答