使用 Gforth 的解释器指令在单词定义中添加新行

New lines in word definition using interpreter directives of Gforth

我正在使用 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

这正是我想要的。

有没有办法在单词定义中换行?我想写的词要复杂得多,为了演示我需要更好地格式化它们。

最好直接使用直接词。例如,

: 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. 时,停止逐行阅读并循环
  5. 注意在[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 行放在它上面。