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

时间:2015-01-12 11:33:30

标签: forth 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

这正是我想要的。

有没有办法在单词定义中添加新行?我想写的字更复杂,对于演示,我需要更好地格式化。

1 个答案:

答案 0 :(得分: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. 请注意在[NEXT]之后立即离开> IN,以便正常继续进行解释。

  5. 您可能仍会遇到一些代码问题,例如代码检查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行。