web-dev-qa-db-ja.com

ループ本体がスキップされたときに、BASICはどのようにして順序が狂ったNEXTステートメントを見つけるのですか?

WABAC machine 、シャーマンを設定します。この質問は、BASIC全般、特にMicrosoftの BASIC-8 に関するものです。オールドスクールベーシック。行番号付き。

ループ本体が実行されておらず、NEXTステートメントが順不同である場合、旧式のBASICインタープリターはFOR ... NEXTループをどのように処理しますか(または、むしろ実行しましたか)?

以前からの順不同のNEXTステートメント:

これがゲームのサブルーチンです Awari out of David H.Ahlの "101 Basic Computer Games"

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

それはあまり好きではない思い出を呼び戻しますか?聞こえますか ダイクストラ 彼の墓に転がっていますか?

このフラグメントで起こっていることの興味深い部分は次のとおりです。

  • 2番目のFORループは同じループ変数を使用するため、最初のFORループを置き換えます
  • 2つのFORループは同じNEXTステートメントを共有します
  • 2番目のFORループのNEXTステートメントは、その前にソース順で、その後に実行順で表示されます

したがって、FORループを開始したインタープリターは、NEXTループ全体で発生するまでステートメントを実行するだけであると考えるかもしれません。この場合、ソース内のステートメントの順序は重要ではありません。しかし、basic80マニュアルがFORループについて何と言っているか見てみましょう。

Basic-80のマニュアルには "moo ..."と書かれています

ループの初期値にステップの符号を掛けたものが、最終値にステップの符号を掛けたものを超える場合、ループの本体はスキップされます。

したがって、ループ本体は完全にスキップできます。

公開されたプログラムの形で、BASICの少なくともいくつかのバージョンがそれらのNEXTステートメントを動的に見つけていたという証拠があります。これはループ本体が実行されているときに簡単に実行できます。ただし、BASIC-80で許可されているように、FORステートメントの本体をスキップする必要がある場合、FORがbeforeである可能性があるため、BASICはどのようにしてNEXTステートメントを見つけましたか。ソース順のステートメント?

  • 「101 Basic Computer Games」で使用されているBASICのバージョンは、ループ本体を少なくとも1回は常に実行しましたか?
  • BASIC-80では、FORステートメントの後にソース順にFORループのNEXTステートメントを配置する必要がありましたか?

PS:はい、私は古い学校のBASIC用のBASICインタープリターを書いています。それは病気です。

9
Wayne Conrad

「101コンピュータゲーム」BASICの機能

「101ComputerGames」のマイクロコンピューター版で使用されているBASICの方言は、FOR ... NEXTループの本体を少なくとも1回実行します。これは BASIC-80v。5 とは異なります。

p。i12から 、「通常の」BASICの例外を一覧表示します。

FOR ... TO ... STEP

ループを終了するためのテストが実行された後に行われることを除いて、標準のBASICと同じです。つまり、このプログラムを実行すると、次のようになります。

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

「HI」が印刷されます...

そのため、このBASICの方言は、NEXTステートメントを見つけたり、同じnextステートメントを複数のFORステートメントと共有したりするのに問題はありません。静的解析は必要ありません。すべてのステートメントを発生時に実行するだけで、どこにいても最終的にNEXTステートメントに到達します。

BASIC-80が異常なNEXTを処理することは可能ですか?

BASIC-80 v.5で許可されているように、FORステートメントでループ本体をスキップしても、ほとんどの場合、順不同のNEXTステートメントを許可することができます。方法は次のとおりです。

  • インタプリタは「実行中」と「次へスキップ」の2つの状態を取得します
  • 「実行中」状態の場合、インタープリターはすべてのステートメントを正常に実行します。
  • FORステートメントを評価するときに、ループ本体をスキップする場合、状態は「次へスキップ」に変更されます。
  • 「次へスキップ」状態の場合、インタプリタはexceptNEXTおよび無条件GOTOを除くすべてのステートメントをスキップします。
    • 無条件のGOTOステートメントに従います
    • NEXTステートメントは、その変数がFORステートメントの変数と一致する場合(または変数が指定されていない場合)、「実行中」の状態に戻ります。変数が一致しない場合、インタープリターは「次へスキップ」状態のままになります。

これは、問題のような単純な病理学的シーケンスを処理します。 IF ... GOTOステートメントまたはGOSUBによってNEXTに到達した場合は処理されません。これを行うコードは、問題のすでに悪いコードよりもはるかに悪いため、インタプリタがそのようなケースをサポートしないことを単純に宣言するのは不合理ではありません。通訳者がそのようなコードに火をつけることさえ許されるかもしれません。

2
Wayne Conrad

これは昔を取り戻します...

1975年の第3版の本のコピーを持っています。あなたのリストを確認しましたが、オリジナルではありません。元のソースコードでは、ステートメントにはスペースがなく、割り当てにはキーワードLETが含まれています。例えば

200 LETK=M:GOSUB600

方言はDIGITAL PDP-11 BASICです(Basic-plusやBASIC-80ではありません)。経験上、これらのゲームのすべてがBASICのすべての方言で機能するわけではありません。他の方言で動作させるには、これらのゲームのいくつかを書き直さなければならないという漠然とした記憶があります。この種の恐ろしいループ構造は間違いなく問題でした。

私は20を超えるBASICの方言を使った経験があり、これは当時、厄介な問題だったと言えます。 2つのメインキャンプがありました。

1つの収容所には、通訳者全員がいて、見られるたびに各行を新たに解析しました。彼らは、変数で識別されるスタックにFORループをプッシュし、スタックをスキャンして各NEXTと一致するかどうかを処理しました。ループをスキップした場合、ソースのNEXTをスキャンする必要があります。一部はしました、一部はしませんでした。

もう1つの陣営は、トークナイザーまたはセミコンパイラーでした。実行前にすべての行をスキャンして、何らかの内部形式に変換します。また、FOR/NEXTループを照合し、欠落しているGOTOおよびGOSUBターゲットをチェックしました。私が覚えているように、DECとBASIC-80はこのキャンプにいましたが、それはずっと前のことです。

あなたの質問に答えて、

  1. はい、BASICの方言は、最初に満たされた場合、ループをスキップします
  2. いいえ、FOR NEXTのシーケンスは文書化された要件ではありませんでしたが、動作は定義されていませんでした。プロとして、私は明らかにそれをやったことはありません。 :)

お役に立てれば。これらは恐ろしい言語ですが、やらなければならない場合は...

7
david.pfx

私の目の前にあるこれらの古代の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
Robert Harvey