跳过循环主体时,BASIC如何查找无序的NEXT语句


9

设置WABAC机器 Sherman。这个问题通常与BASIC有关,尤其与Microsoft的BASIC-80有关。老派基本。带行号。

当循环主体未执行且NEXT语句出现故障时,老式的BASIC解释器如何(或更确切地说,是)如何处理FOR ... NEXT循环?

与之前时间无序的NEXT语句:

这是David H. Ahl的“ 101基本计算机游戏”Awari游戏的子例程:

200 K=M:GOSUB 600
205 E=0:IF K>6 THEN K=K-7
210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K
215 FOR I=0 TO 5:IF B(I)<>0 THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN
235 GOTO 220

这就是除流量控制之外的所有内容:

200 GOSUB 600
215 FOR I=0 TO 5:IF ... THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF ... THEN RETURN
235 GOTO 220

那会带回不太喜欢的回忆吗?你能听到迪克斯特拉 在坟墓里翻滚吗?

以下是此片段中发生的有趣的部分:

  • 由于第二个FOR循环使用相同的循环变量,因此它将替换第一个FOR循环
  • 两个FOR循环共享相同的NEXT语句
  • 第二个FOR循环的NEXT语句按源顺序在它之前,但按执行顺序在它之后

然后,您可能会认为,解释器已经开始执行FOR循环,只运行语句,直到它在NEXT循环中发生为止。在这种情况下,源中语句的顺序无关紧要。但是,让我们看看basic80手册对FOR循环必须说些什么:

基本80手册上写着“ moo ...”

如果循环的初始值乘以步长的符号超过最终值乘以步长的符号,则跳过循环的主体。

因此,循环体可以完全跳过。

我们以公开程序的形式证明,至少某些BASIC版本正在动态查找其NEXT语句。这在执行循环主体时很容易做到。但是,在应跳过FOR语句的主体的情况下(如BASIC-80所允许的那样),考虑到源代码可能位于FOR语句之前,BASIC如何定位NEXT语句?

  • “ 101基本计算机游戏”中使用的BASIC版本是否总是至少执行一次循环主体?
  • BASIC-80是否要求FOR循环的NEXT语句按源顺序出现在FOR语句之后?

PS:是的,我正在为老式BASIC编写BASIC解释器。这是一种疾病。


Ahl书最初由DEC于1973年出版,比Microsoft BASIC早两年。这些程序可能已经在RT-11 BASIC或BASIC-PLUS中完成。除了特定于系统的扩展名之外,大多数方言都是兼容的,并且我从本书的DEC版本中运行的程序在几个系统上运行起来几乎没有困难。您可能会发现Applesoft BASIC ROM 的反汇编,已记录文档的来源很有启发性。实现该NEXT语句的代码从$ DCF9开始。
Blrfl 2014年

不了解BASIC-80,但我100%确信Commodore Basic(Microsoft BASIC V2)总是执行一次循环,并且源代码中的语句顺序无关紧要-就像您怀疑的那样。
Doc Brown

Answers:


7

这带回了过去...

我有这本书的副本,印刷于1​​975年,第三版。我检查了您的清单,但它不是原始的。在原始源代码中,语句无空格,赋值使用关键字LET。例如

200 LETK=M:GOSUB600

该方言是DIGITAL PDP-11 BASIC(不是Basic-plus或BASIC-80)。从经验来看,并不是所有这些游戏都适用于BASIC的所有方言。我有一种模糊的回忆,那就是必须重新编码其中的一些游戏才能使它们在其他方言中起作用。这种可怕的循环结构绝对是一个问题。

我有20多种不同的BASIC方言经验,我可以告诉你,这在当时是一个烦人的问题。有两个主要营地。

在一个营地中,有完整的口译员,每次翻译时都会重新解析每一行。他们通过将FOR循环压入堆栈(由其变量标识),然后扫描堆栈以查找与每个NEXT匹配的内容来处理FOR循环。如果跳过循环,则必须扫描源以查找NEXT。有的有,有的没有。

另一个阵营是令牌生成器或半编译器。他们将在执行之前扫描所有行并将其转换为某种内部格式。他们还匹配了FOR / NEXT循环,并检查了缺少的GOTO和GOSUB目标。我记得,DEC和BASIC-80曾在这个阵营中,但是很久以前。

在回答您的问题时,

  1. 是的,如果最初满足,BASIC的方言确实会跳过循环
  2. 不,FOR NEXT的排序不是一个记录的要求,但是行为是不确定的。作为专业人士,显然我从来没有做过。:)

希望这可以帮助。这些是可怕的语言,但是如果您要这么做的话...


这非常有帮助,谢谢。本书有DEC版本,TRS-80版本和微型计算机版本。微型计算机版本中的程序在Microsoft 8080 basic(MITS Altair Basic Rev 4.0)中;那是我翻译的目标。
韦恩·康拉德2014年

我在1980年左右在CP / M上使用了MBASIC,但是没有一个较早的业余爱好者机器。您需要一个文件系统!在许多方面,我都会觉得DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic的转世更有趣,但我可以理解为什么您不这样做。祝你好运!如果需要帮助,请与我联系。
david.pfx

2

我面前没有这些古老的BASIC解释器之一的规范副本(它甚至可能不存在),但是我要冒昧地说,BASIC解释器将不会执行即使循环变量具有相同的名称,也不属于它的FOR循环上的NEXT

因此,换句话说,在您的示例中

200 K=M:GOSUB 600
205 E=0:IF K>6 THEN K=K-7
210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K
215 FOR I=0 TO 5:IF B(I)<>0 THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN
235 GOTO 220

当第235行执行并转到第220行时,第220 行将与顶部FOR循环而不是底部NEXT相邻。

这在“没有FOR的下一个”错误消息中很明显;BASIC解释器拒绝任何找不到对应的FOR的NEXT。当您使NEXT出现故障时,通常会发生这种情况,例如

100 FOR I = 1 to 10
110 FOR J = 1 to 10
120 ...
130 NEXT I
140 NEXT J

因此,回答您的项目符号问题:

  • 是,如果循环变量在FOR范围内。
  • 是的,据我所知,就是这种情况。

2
“ BASIC解释器将不会在不属于它的FOR循环上执行NEXT”-我知道至少一个旧的BASIC解释器家族中,该语句是错误的,您不能将其概括为“所有古老的BASIC解释器”。
布朗

规格存在。搜索PDP-11 BASIC。
david.pfx

1
感谢您为这个奇怪的问题question之以鼻。我现在已经确认,本书中使用的BASIC遇到第二个具有相同计数器变量的FOR语句时,会忘记第一个FOR语句,并从第二个语句重新开始循环。这与您在黑暗中的刺伤相矛盾。这是一种编写循环的可恶方式,但是BASIC还是很臭。
韦恩·康拉德

2

“ 101电脑游戏” BASIC的作用

在“ 101计算机游戏”的微型计算机版中使用的BASIC方言将至少执行一次FOR ... NEXT循环的主体。这与BASIC-80 v。5确实有所不同。

从第。i12,列出“常规” BASIC的例外:

对于...到... STEP

与标准BASIC中一样,只是在执行完循环h之后才进行结束循环的测试。也就是说,运行该程序时:

10 FOR X=2 TO 1
20 PRINT "HI"
30 NEXT X
40 END

将打印“ HI”。

因此,这种BASIC方言可以轻松找到NEXT语句,或与多个FOR语句共享相同的next语句。无需静态分析。只要执行每条语句,无论它在哪里,都将最终到达NEXT语句。

BASIC-80是否可以处理无序的NEXT?

正如BASIC-80 v.5所允许的,FOR语句有可能跳过循环体,并且在大多数情况下仍允许无序的NEXT语句。就是这样:

  • 解释器得到两种状态,“正在运行”和“正在跳到下一步”
  • 处于“运行”状态时,解释器正常执行每个语句。
  • 在评估FOR语句时,如果要跳过循环体,则状态将更改为“正在跳至NEXT”
  • 当处于“跳到下一个”状态时,解释器将跳过 NEXT和无条件GOTO 之外的所有语句。
    • 遵循无条件的GOTO语句
    • NEXT语句(如果其变量与FOR语句的变量匹配)(或如果未指定变量),则切换回“正在运行”状态。如果变量不匹配,则解释器将保持“正在跳到下一个”状态。

这将处理简单的病理序列,例如问题中的序列。它不会处理通过IF ... GOTO语句或GOSUB到达NEXT的情况。这样做的代码比已经很糟糕的代码要糟糕得多,以至于简单地声明解释器将不支持这种情况并非没有道理。解释器甚至可以放纵此类代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.