第四:具有多个出口点的便携式无限循环

wza*_*zab 5 loops forth

我需要实现一个具有多个退出点的不确定循环。不幸的是,最明显的解决方案 - REPEAT - UNTIL with multiple WHILE 在 Gforth 和 swapforth 中都不起作用(当然,下面示例中的循环可以用 DO - LOOP 实现。但是,该代码只是一个演示。真正的问题与嵌入式系统中的硬件控制有关,因此循环确实必须是不确定的)

: test1 ( step -- step count )
    0
    begin
      over +
      dup .
      dup 20 < while
      dup 13 = while
    repeat
;

3 test1 
Run Code Online (Sandbox Code Playgroud)

在“Thinking Forth”中引用了摩尔的声明:

很多时候条件语句被用来跳出循环。可以通过具有多个退出点的循环来避免这种特殊用途。这是一个实时主题,因为在 poly-Forth 中存在多个 WHILE 结构,但还没有渗透到 Forth '83。这是在同一个 REPEAT 中定义多个 WHILE 的简单方法。此外,[Forth, Inc.] 的 Dean Sanderson 发明了一种新结构,该结构将两个出口点引入 DO LOOP。鉴于这种结构,您将进行更少的测试。

不幸的是我没有找到院长的解决方案。是否有任何可移植的方式在 Forth 的无限循环中实现多个退出点?

wza*_*zab 2

经过一些实验,我创建了一个基于 DO +LOOP 的解决方案。不知道和Dean Sanderson提出的是否一样。

我已经在 Gforth 和 swapforth 中成功测试了它。似乎可以创建任意数量的退出点。不定循环是通过以下方式创建的: 0 1 DO 循环内容此处 0 +LOOP。退出点由放置在 IF THEN 中的 LEAVE 创建。

示例代码:

: test1 ( start step -- count step )
    swap
    1 0 do
      over +
      dup .
      dup 20 > if 
        ." >20 "
        leave
      then
      dup 13 = if
        ." =13 "
        leave
      then
      dup 17 = if
        ." =17 "
        leave
      then
    0 +loop
;
Run Code Online (Sandbox Code Playgroud)

检测结果:

> 1 3 test1
 4 7 10 13 =13  ok
> 2 3 test1
 5 8 11 14 17 =17  ok
> 0 3 test1
 3 6 9 12 15 18 21 >20  ok
Run Code Online (Sandbox Code Playgroud)