GOTO (dll) ke baris yang tidak ada?

Dec 07 2020

Menulis juru bahasa BASIC telah mengungkapkan sejumlah informasi menarik yang cenderung tidak disebutkan dalam dokumentasi. Contohnya:

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

Akan mencetak ONEpada BASIC turunan Microsoft, sementara Dartmouth akan memproduksi ONETHREE. Artinya, MS memperlakukan seluruh baris lainnya sebagai bagian dari THEN, yang ... aneh (dan IMHO salah). Saya hanya memperhatikan ini karena kode contoh yang saya lakukan menjalankan pernyataan terakhir, yang menyebabkan Super Star Trek gagal.

Saya telah menemukan contoh lain yang ingin saya sampaikan pada hoi polloi. Pertimbangkan program ini:

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

Kode contoh yang saya miliki akan mencari baris 25 atau pernyataan berikutnya yang lebih tinggi . Jadi dalam kode itu, baris 30 akan dijalankan. Ini jelas tidak terjadi untuk Commodore BASIC, yang mengembalikan "UNDEFN'D STATEMENT".

Jadi ... apakah ada yang tahu versi BASIC yang berfungsi dengan cara ini, atau apakah ini (seperti yang sangat saya duga) hanyalah bug dalam kode contoh?

Jawaban

5 Brian Dec 09 2020 at 22:36

Sinclair BASIC pada ZX Spectrum akan melompat ke nomor baris berikutnya yang tersedia. The pengguna mengatakan

Jika nomor baris dalam perintah GO TO mengacu pada baris yang tidak ada, maka lompatannya adalah ke baris berikutnya setelah nomor yang diberikan. Hal yang sama berlaku untuk RUN; sebenarnya RUN sendiri sebenarnya berarti RUN 0.

13 Chromatix Dec 07 2020 at 21:04

Dialek BASIC dikenal memiliki detail yang cukup banyak. Salah satu versi yang lebih pasti adalah BBC BASIC, yang melakukan hal berikut:

Perhatikan konstruksi IF-THEN-ELSE, yang membenarkan penggunaan badan IF-THEN multi pernyataan - yang pada kenyataannya berguna dalam praktik.

BBC BASIC V menambahkan kata kunci ENDIF dan fasilitas untuk blok multi-baris IF-THEN-ELSE-ENDIF. Secara umum BBC BASIC diarahkan untuk membuat pemrograman terstruktur lebih mudah daripada kebanyakan BASIC komputer mikro sebelumnya.

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

Contohnya bukanlah bug tetapi perilaku tidak terdefinisi, yang juga umum dalam bahasa lain. Jika Anda mengharapkan kompatibilitas lintas platform, cukup jangan lakukan hal-hal yang mengakibatkan perilaku tidak terdefinisi.

Selain itu, niat programmer pada contoh pertama tidak jelas, yang dapat menyebabkan bug yang sulit diperbaiki. Sekali lagi, jangan lakukan itu. Contoh kedua lebih baik karena berfungsi seperti yang diinginkan pemrogram atau pengurai mengeluh, sehingga memudahkan untuk menemukan dan memperbaiki bug dengan cepat.

10 Raffzahn Dec 07 2020 at 22:18

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

Akan mencetak SATU di BASIC turunan Microsoft, sementara Dartmouth akan menghasilkan ONETHREE. Artinya, MS memperlakukan seluruh sisa baris sebagai bagian dari KEMUDIAN, yang ... aneh (dan IMHO salah).

Yah, saya kira tidak ada yang benar atau salah, tetapi setiap BASIC memiliki caranya sendiri-sendiri. Cara MS pada dasarnya memungkinkan pembuatan blok kode dalam klausa THEN tanpa perlu GOTO. Dengan Dartmouth, yang bekerja pada titik itu seperti FORTRAN sebelumnya, MAKA perlu melompat ke blok kode, diikuti oleh GOTO untuk berkeliling:

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

Nah, atau gunakan klausa terbalik untuk melompati blok kode. Bukan konstruksi yang benar-benar hebat.

Harus dicatat bahwa mengizinkan pernyataan arbitrer setelah THEN adalah add-on yang lebih baru, tidak ada di Dartmouth BASIC. Hal yang sama berlaku untuk beberapa pernyataan yang dipisahkan oleh titik dua.

Dengan cara MS memperlakukan seluruh (sisa) baris sebagai bagian dari blok kemudian memungkinkan konstruksi ini tanpa banyak jogging dan gotos otak.

Tapi itu tidak ditemukan oleh MS, mereka hanya mengambilnya dari DEC BASIC-PLUS tahun 1972 (Bagaimanapun, MS BASIC adalah tiruan dari DEC BASIC) seperti yang dijelaskan pada halaman 3-12 dari manual:

Jadi di sini setelah THEN beberapa pernyataan diizinkan, tetapi dieksekusi secara keseluruhan (jika kondisinya benar) atau tidak sama sekali.

Sekarang, ketika mencari cara yang 'tepat', biasanya yang terbaik adalah terlebih dahulu melihat standar DASAR. Mungkin yang pertama di sini

  • ECMA 55 Minimal DASAR 1978

    Ini menjelaskan minimum yang harus dipenuhi setiap BASIC untuk menjadi portabel. Pada dasarnya ini mengkodifikasi Dartmouth BASIC (Thomas Kurtz adalah salah satu editor) dalam inkarnasinya kemudian dengan cara yang jelas dan dapat direproduksi. Di sini pernyataan THEN hanya memungkinkan nomor baris untuk melompat.

  • ANSI Minimal DASAR 1979

    Pada dasarnya versi ANSI dari ECMA-55.

Ini BTW, titik waktu MS-BASIC mulai menjadi kekuatan normatif

  • ECMA 116 BASIC tahun 1986 , juga disebut 'Full BASIC'

    Di sini pernyataan multi dan multi baris MAKA konstruksi dan campurannya dimungkinkan. Pernyataan multi bekerja seperti 'MS way', sedangkan multi baris membutuhkan pernyataan ENDIF (atau ELSE / ELSEIF) untuk menutup blok. (Itu juga mendapat banyak fitur lain yang dikenal dari BASIC modern, hanya dengan nomor baris)

  • ANSI / ISO / IEC Full BASIC tahun 1987

    Pada dasarnya ECMA-116 dengan beberapa klarifikasi / ekstensi.

Jadi MS mengikuti apa yang ECMA-116 katakan ... yah, atau lebih baik mungkin standar mengkodifikasi apa yang MS lakukan sebelumnya dan dengan demikian menjadi standar defacto. Banyak pekerjaan telah dimasukkan ke dalam standar ini untuk menangkap tempat umum yang bisa diterapkan untuk BASIC. Ini termasuk kasus-kasus tepi dari masalah yang tampaknya jelas. Saya akan mempertimbangkan praktik terbaik untuk memeriksanya setiap kali ada sesuatu yang terbuka untuk diskusi. Apalagi karena mereka juga menunjukkan masalah yang belum diputuskan / masih terbuka untuk ditafsirkan.

Kode contoh yang saya miliki akan mencari baris 25 atau pernyataan berikutnya yang lebih tinggi [...]

Jadi ... apakah ada yang tahu versi BASIC yang berfungsi dengan cara ini, atau apakah ini (seperti yang sangat saya duga) hanyalah bug dalam kode contoh?

Saya ingat TINY BASIC yang memungkinkan untuk melompat 'di antara' garis untuk memudahkan GOTO yang dihitung, tetapi melihat sumber aslinya, jahitannya seperti ini adalah modifikasi.

Sebaliknya ECMA-55 menyatakan pada target yang digunakan sebagai target di THEN / GOTO / GOSUB:

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

Dalam istilah pragmatis,

  1. Tentukan kode lama yang Anda inginkan agar dapat dijalankan oleh penerjemah Anda

  2. Tentukan dialek mana yang tidak kompatibel, jika ada, yang ingin Anda dukung sebagai opsi

  3. Lakukan hal yang sama seperti yang mereka lakukan.

Seperti yang diungkapkan Raffzahn, perilaku Microsoft lebih praktis daripada perilaku Dartmouth, karena Microsoft BASIC memungkinkan Anda menulis blok bersyarat dengan banyak pernyataan. Anda juga mengatakan ingin menjalankan program yang mengharapkan perilaku Microsoft.

Demikian pula, sangat tidak mungkin bahwa kode warisan apa pun dengan sengaja GOTOmerupakan baris yang tidak ada, tetapi ada kemungkinan bahwa beberapa program yang ada mungkin berjalan dengan benar meskipun ada kesalahan ketik, GOTO 24bukan GOTO 25.

Jika Anda juga perlu menjalankan kode yang bergantung pada perilaku yang tidak kompatibel, Anda mungkin menyediakannya sebagai opsi.

1 h22 Dec 09 2020 at 21:57

Dialek yang saya gunakan adalah meneruskan kontrol ke jalur yang ada dengan angka terdekat yang lebih besar, jika ada. Jika tidak, ini adalah cara yang sah untuk menghentikan program tanpa pesan kesalahan.

Melewati kontrol ke tengah jangkauan memungkinkan penambahan garis ke kedua sisi titik masuk. Hal ini sangat membantu karena pemfaktoran ulang juga sangat membosankan: tidak ada pencarian dan satu-satunya cara untuk mengubah garis adalah dengan mengetik ulang garis tersebut secara lengkap. Versi itu tidak memiliki penggantian nomor baris otomatis.

Mesin itu semacam "Elektronika" Soviet tapi saya tidak ingat persisnya. Itu lebih terlihat seperti kalkulator kelas atas dengan tampilan LED dua baris sendiri di konsol, tetapi sudah mendukung monitor eksternal dan keyboard.