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


9

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

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

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

これは、David H. Ahlの「101 Basic Computer Games」からのゲーム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

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

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

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

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

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

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

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

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

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

PS:はい、私はオールドスクールBASICのBASIC通訳を書いています。それは病気です。


Ahlの本は、1973年にDECによって最初に発行され、Microsoft BASICより2年前に出版されました。プログラムはおそらくRT-11 BASICまたはBASIC-PLUSで行われたでしょう。システム固有の拡張機能を除いて、ほとんどの方言は互換性があり、私は本のDECバージョンのプログラムをいくつかのシステムでほとんどまたはまったく問題なく実行しました。Applesoft BASIC ROM の逆アセンブルされ、文書化されたソースが啓発的である場合があります。NEXTステートメントを実装するコードは、$ DCF9から始まります。
Blrfl 2014

BASIC-80についてはわかりませんが、Commodore Basic(Microsoft BASIC V2)は常にループを1回実行し、ソース内のステートメントの順序は問題ではないことを100%確信しています。
Doc Brown

回答:


7

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

私は本のコピーを持っています。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のシーケンスは文書化された要件ではありませんでしたが、動作は未定義でした。プロとして、私は明らかにそれをやったことはありません。:)

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


これはとても役に立ちます、ありがとう。この本には、DECバージョン、TRS-80バージョン、およびマイクロコンピュータバージョンがあります。マイコン版のプログラムは、Microsoft 8080 basic(MITS Altair Basic Rev 4.0)です。それが私の通訳のターゲットです。
ウェインコンラッド

私は1980年頃にCP / MでMBASICを使用しましたが、それ以前の趣味のマシンはどれも使用していませんでした。ファイルシステムが必要です。多くの点で、DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basicの生まれ変わりはもっと面白いと思いますが、なぜそうでないのか理解できます。がんばって!私が助けてくれるなら私に連絡してください。
david.pfx 2014

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ループではなく、最上位のFORループをNEXTします。

これは、「NEXT FOR 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インタープリターのファミリーが少なくとも1つわかっています。これを「すべての古代BASICインタープリター」に一般化することはできません。
Doc Brown、

仕様は存在します。PDP-11 BASICを検索します。
david.pfx 14

1
この奇妙な質問を試していただきありがとうございます。この本で使用されているBASICが、同じカウンター変数を持つ2番目のFORステートメントに遭遇すると、最初のFORステートメントを忘れ、2番目のFORステートメントからループを再開することを確認しました。これは暗闇での刺しと矛盾します。ループを書くのはおかしな方法ですが、BASICはとにかく臭いものです。
ウェインコンラッド

2

「101 Computer Games」BASICの機能

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

から。i12、「通常の」BASICの例外をリストします。

FOR ... TO ... STEP

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

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

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

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

BASIC-80が順不同のNEXTを処理することは可能ですか?

BASIC-80 v.5では、FORステートメントがループ本体をスキップし、ほとんどの場合、順不同のNEXTステートメントを許可する可能性があります。方法は次のとおりです。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.