存在しないラインへのGOTO(など)?

Dec 07 2020

書き込みBASICインタプリタは、ドキュメントに記載されない傾向にある情報の興味深いビット数を明らかにしました。例えば:

10 PRINT"ONE";:IF 1=2 THEN PRINT"TWO":PRINT"THREE"

ONEDartmouthが作成する間、Microsoftから派生したBASICで印刷しますONETHREE。つまり、MSは残りの行全体をの一部として扱いTHENます。これは...奇妙な(そして間違ったIMHO)です。私がこれに気付いたの、最後のステートメントを実行したサンプルコードが原因で、スーパースタートレックが失敗したためです。

私はホイポロイに投げかけたい別の例に出くわしました。このプログラムを検討してください:

10 PRINT"HELLO"
20 GOTO 25
30 PRINT"WORLD"

私が持っているサンプルコードは 25行目以降のステートメントを検索します。したがって、そのコードでは、30行目が実行されます。これは、「UNDEFN'DSTATEMENT」を返すCommodoreBASICには絶対に当てはまりません。

だから...誰かがこのように動作するBASICのバージョンを知っていますか、それともこれは(私が強く疑うように)サンプルコードの単なるバグですか?

回答

5 Brian Dec 09 2020 at 22:36

ZXSpectrumのSinclairBASICは、次に利用可能な行番号にジャンプします。マニュアルは言います

GO TOコマンドの行番号が存在しない行を参照している場合、指定された番号の次の行にジャンプします。同じことがRUNにも当てはまります。実際、RUN自体は、実際にはRUN0を意味します。

13 Chromatix Dec 07 2020 at 21:04

BASIC方言は、細部がかなり異なることが知られています。より決定的なバージョンの1つはBBCBASICであり、これは次のことを行います。

IF-THEN-ELSE構造に注意してください。これは、マルチステートメントのIF-THEN本体の使用を正当化します。これは実際には実際に役立ちます。

BBC BASIC Vは、ENDIFキーワードと複数行のIF-THEN-ELSE-ENDIFブロックの機能を追加しました。一般に、BBC BASICは、構造化プログラミングを以前のほとんどのマイクロコンピューターBASICよりも簡単にすることを目的としています。

13 snips-n-snails Dec 08 2020 at 01:54

例はバグではなく、他の言語でも一般的な未定義の動作です。クロスプラットフォームの互換性が期待される場合は、未定義の動作を引き起こすようなことをしないでください。

さらに、最初の例でのプログラマーの意図は不明確であり、修正が難しいバグにつながる可能性があります。繰り返しますが、そうしないでください。2番目の例は、プログラマーが意図したとおりに機能するか、パーサーが文句を言うため、バグをすばやく見つけて修正するのが簡単になるため、より優れています。

10 Raffzahn Dec 07 2020 at 22:18

10 PRINT"ONE";:IF 1=2 THEN PRINT"TWO":PRINT"THREE"

DartmouthがONETHREEを作成する間、Microsoftから派生したBASICでONEを印刷します。つまり、MSは残りの行全体をTHENの一部として扱いますが、これは...奇妙な(そして間違ったIMHO)です。

まあ、正しいことも悪いこともないと思いますが、それぞれのBASIC独自の方法です。MSの方法では、基本的に、GOTOを必要とせずにTHEN句内にコードブロックを作成できます。以前のFORTRANのようにその時点で機能するダートマスでは、THENはコードブロックにジャンプし、続いてGOTOにジャンプして回避する必要があります。

10 PRINT"ONE";
20 IF 1=2 THEN GOTO 40
30 GOTO 50
40 PRINT"TWO"
50 PRINT"THREE"
60 REM

または、逆句を使用してコードブロックをジャンプします。どちらも本当に素晴らしい構成ではありません。

THENの後に任意のステートメントを許可することは後のアドオンであり、ダートマスBASICには存在しないことに注意する必要があります。同じことが、コロンで区切られた複数のステートメントにも当てはまります。

行全体(残りの部分)をthenブロックの一部として扱うMSの方法により、脳のジョギングやゴトをあまり使わずにこの構成を行うことができます。

しかし、それはMSによって発明されたのではなく、マニュアルのp.3-12で説明されているように、1972年のDEC BASIC-PLUS(結局、MSBASICはDECBASICのクローンです)から取ったものです。

したがって、ここではTHENの後に複数のステートメントが許可されますが、全体として実行されるか(条件が真の場合)、まったく実行されません。

さて、「正しい」方法を探すときは、通常、最初にBASIC標準を調べるのが最善です。ここの最初はかもしれません

  • 1978年のECMA55 Minimal BASIC

    これは、すべてのBASICが移植可能であるために準拠する必要がある最低限のことを説明しています。本質的には、ダートマスBASIC(Thomas Kurtzは編集者の1人でした)を、後の化身で明確かつ再現可能な方法で成文化しています。ここで、THENステートメントでは、行番号のみにジャンプできます。

  • 1979年のANSI最小基本

    基本的に、ECMA-55のANSIバージョン。

これはところで、MS-BASICが規範的な力になり始めた時点です

  • 1986年のECMA116 BASIC、「FullBASIC」とも呼ばれます

    ここでは、複数のステートメントと複数行のTHEN構造およびそれらの混合が可能です。複数ステートメントは「MSウェイ」のように機能しますが、複数行はブロックを閉じるためにENDIF(またはELSE / ELSEIF)ステートメントを必要とします。(また、行番号だけで、最新のBASICから知られている他の多くのnie機能もあります)

  • 1987年のANSI / ISO / IECフルベーシック

    基本的にECMA-116で、いくつかの説明/拡張があります。

したがって、MSはECMA-116の言うことに従います...まあ、あるいはもっと良いのは、標準がMSが以前に行ったことを成文化し、したがって事実上の標準になったということです。BASICの実行可能な共通の場所をキャプチャするために、これらの標準に多くの作業が投入されました。これには、特に一見明らかな問題のエッジケースが含まれます。議論の余地があるときはいつでも、それらをチェックすることがベストプラクティスだと思います。特に、彼らはまだ決定されていない/まだ解釈の余地がある問題を指摘しているからです。

私が持っているサンプルコードは、25行目以降のステートメントを検索します[...]

だから...誰かがこのように動作するBASICのバージョンを知っていますか、それともこれは(私が強く疑うように)サンプルコードの単なるバグですか?

計算されたGOTOを簡単にするために「行間」をジャンプできるTINYBASICを覚えていますが、元のソースを見ると、このように継ぎ目があります。

対照的に、ECMA-55は、THEN / GOTO / GOSUBでターゲットとして使用されるターゲットについて次のように述べています。

All line-numbers in control-statements shall refer to lines in the program.
1 Davislor Dec 08 2020 at 07:35

実用的な言葉で言えば、

  1. インタプリタに実行させたいレガシーコードを決定します

  2. オプションとしてサポートする互換性のない方言がある場合は、それを決定します

  3. 彼らがするのと同じことをしなさい。

Raffzahnが提起するように、Microsoft BASICでは複数のステートメントを含む条件付きブロックを記述できるため、Microsoftの動作はDartmouthの動作よりも便利です。また、Microsoftの動作を期待するプログラムを実行したいと言います。

同様に、レガシーコードが意図的にGOTO存在しない行になる可能性はほとんどありませんが、のGOTO 24代わりにのようなタイプミスがあるにもかかわらず、既存のプログラムが正しく実行される可能性がありますGOTO 25

互換性のない動作に依存するコードも実行する必要がある場合は、オプションとしてそれを提供できます。

1 h22 Dec 09 2020 at 21:57

私が使用した方言は、存在する場合、最も近い大きな番号を持つ既存の回線に制御を渡すことでした。そうでない場合、これはエラーメッセージなしでプログラムを終了するための正当な方法でした。

範囲の中央に制御を渡すと、エントリポイントのいずれかの側に行を追加できました。リファクタリングも非常に面倒だったため、これは大いに役立ちました。検索がなく、行を変更する唯一の方法は、完全に完全な長さで再入力することでした。そのバージョンには、自動化された行の再番号付けがありませんでした。

機械はソビエトの「エレクトロニカ」のようなものでしたが、正確には覚えていません。それは、コンソールに独自の2列LEDディスプレイを備えた非常にハイエンドの計算機のように見えましたが、すでに外部モニターとキーボードをサポートしています。