Bagaimana BASIC menemukan pernyataan NEXT yang out-of-order ketika badan loop dilewati

9

Atur mesin WABAC , Sherman. Pertanyaan ini adalah tentang BASIC secara umum, dan Microsoft BASIC-80 pada khususnya. Dasar sekolah tua. Dengan nomor baris.

Bagaimana (atau, lebih tepatnya,) penafsir BASIC sekolah tua menangani UNTUK ... BERIKUTNYA loop ketika tubuh loop tidak dieksekusi, dan pernyataan NEXT muncul rusak?

Pernyataan NEXT yang rusak dari waktu sebelumnya:

Berikut ini subrutin dari game Awari dari "101 Basic Computer Games" karya David H. Ahl :

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

dan ini dia dengan semuanya kecuali kontrol aliran disunting:

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

Apakah itu membawa kembali kenangan yang tidak begitu disukai? Bisakah Anda mendengar Dijkstra berguling di kuburnya?

Inilah bagian yang menarik dari apa yang terjadi dalam fragmen ini:

  • FOR loop kedua, karena menggunakan variabel loop yang sama, menggantikan loop FOR pertama
  • Dua loop FOR berbagi pernyataan BERIKUTNYA yang sama
  • Pernyataan NEXT UNTUK loop kedua datang sebelum, dalam urutan sumber, tetapi setelah itu, dalam urutan eksekusi

Jadi, Anda mungkin mengira bahwa penerjemah, setelah memulai loop UNTUK, menjalankan pernyataan sampai terjadi di loop NEXT. Urutan pernyataan dalam sumber tidak masalah dalam kasus ini. Tapi mari kita lihat apa yang dikatakan manual dasar80 tentang loop FOR:

Manual dasar-80 mengatakan "moo ..."

Tubuh loop dilewati jika nilai awal loop kali tanda langkah melebihi nilai akhir kali tanda langkah.

Jadi, badan loop dapat dilewati seluruhnya.

Kami memiliki bukti, dalam bentuk program yang diterbitkan, bahwa setidaknya beberapa versi BASIC secara dinamis menemukan pernyataan NEXT mereka. Ini cukup mudah dilakukan ketika loop body dieksekusi. Namun, dalam kasus di mana badan pernyataan FOR harus dilewati, sebagaimana BASIC-80 mengizinkan, bagaimana BASIC menemukan pernyataan NEXT, mengingat bahwa itu mungkin sebelum pernyataan FOR dalam urutan sumber?

  • Apakah versi BASIC yang digunakan dalam "101 Basic Computer Games" selalu menjalankan loop body setidaknya sekali?
  • Apakah BASIC-80 memerlukan pernyataan NEXT UNTUK loop berikutnya terjadi setelah pernyataan FOR, dalam urutan sumber?

PS: Ya, saya sedang menulis penerjemah BASIC untuk sekolah dasar BASIC. Itu penyakit.

Wayne Conrad
sumber
Buku Ahl awalnya diterbitkan oleh DEC pada tahun 1973, mendahului Microsoft BASIC oleh dua tahun. Program mungkin akan dilakukan di RT-11 BASIC atau BASIC-PLUS. Selain ekstensi khusus sistem, sebagian besar dialek kompatibel, dan saya menjalankan program dari versi DEC buku pada beberapa sistem dengan sedikit atau tanpa kesulitan. Anda mungkin menemukan sumber - sumber Applesoft BASIC ROM yang dibongkar dan didokumentasikan mencerahkan. Kode yang mengimplementasikan NEXTpernyataan mulai dari $ DCF9.
Blrfl
Tidak tahu tentang BASIC-80, tapi saya 100% yakin bahwa Commodore Basic (yang merupakan Microsoft BASIC V2) selalu menjalankan loop sekali, dan urutan pernyataan dalam sumber tidak masalah - seperti yang Anda duga.
Doc Brown

Jawaban:

7

Ini membawa kembali ke masa lalu ...

Saya memiliki salinan buku itu, cetakan ke-3, 1975. Saya memeriksa daftar Anda dan itu tidak asli. Dalam kode sumber asli pernyataan tidak memiliki spasi dan tugas memiliki kata kunci LET. Sebagai contoh

200 LETK=M:GOSUB600

Dialeknya adalah DIGITAL PDP-11 BASIC (bukan Basic-plus atau BASIC-80). Dari pengalaman, tidak semua game ini bekerja pada semua dialek BASIC. Saya memiliki ingatan yang samar-samar karena harus mengode ulang beberapa game ini untuk membuatnya dapat digunakan pada dialek lain. Jenis struktur lingkaran mengerikan ini jelas merupakan masalah.

Saya memiliki pengalaman dengan lebih dari 20 dialek BASIC yang berbeda dan saya dapat memberi tahu Anda bahwa ini adalah pertanyaan yang membingungkan pada saat itu. Ada 2 kamp utama.

Di satu kamp ada penerjemah penuh, yang mengurai setiap baris lagi setiap kali terlihat. Mereka menangani loop FOR dengan mendorongnya pada stack, diidentifikasi oleh variabelnya, dan kemudian memindai stack untuk menemukan kecocokan dengan setiap NEXT. Jika mereka melewatkan satu loop, mereka harus memindai sumber untuk NEXT. Ada yang melakukannya, ada yang tidak.

Kamp lainnya adalah tokenizers atau semi-compiler. Mereka akan memindai semua baris sebelum dieksekusi dan mengubahnya menjadi semacam format internal. Mereka juga cocok dengan loop UNTUK / BERIKUTNYA dan memeriksa untuk kehilangan target GOTO dan GOSUB. DEC dan BASIC-80 berada di perkemahan ini, seingat saya, tapi itu sudah lama sekali.

Sebagai jawaban atas pertanyaan Anda,

  1. Ya, dialek BASIC tidak melewatkan loop jika awalnya puas
  2. Tidak, pengurutan FOR NEXT bukan persyaratan yang terdokumentasi, tetapi perilaku itu tidak ditentukan. Sebagai seorang profesional, jelas saya tidak pernah melakukannya. :)

Semoga ini membantu. Ini adalah bahasa yang mengerikan, tetapi jika Anda harus melakukannya ...

david.pfx
sumber
Ini sangat membantu, terima kasih. Buku ini memiliki versi DEC, versi TRS-80, dan versi komputer mikro. Program dalam versi komputer mikro ada di Microsoft 8080 basic (MITS Altair Basic Rev 4.0); itu adalah target penerjemah saya.
Wayne Conrad
Saya menggunakan MBASIC pada CP / M di sekitar tahun 1980, tetapi tidak ada mesin hobi yang sebelumnya. Anda membutuhkan sistem file! Dalam banyak hal saya akan menemukan reinkarnasi dari DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic lebih menarik, tapi saya bisa mengerti mengapa Anda tidak. Semoga berhasil! Hubungi saya jika saya bisa membantu.
david.pfx
2

Saya tidak memiliki salinan spesifikasi untuk salah satu penerjemah BASIC kuno ini di depan saya (bahkan mungkin tidak ada), tetapi saya akan mengambil risiko dan mengatakan bahwa penerjemah BASIC tidak akan menjalankan BERIKUTNYA pada loop UNTUK yang bukan miliknya, bahkan jika variabel loop memiliki nama yang sama.

Jadi, dengan kata lain, dalam contoh Anda

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

ketika baris 235 dijalankan dan pergi ke baris 220, baris 220 akan BERIKUTNYA untuk loop atas, bukan bagian bawah.

Ini terbukti dalam pesan kesalahan "BERIKUTNYA TANPA UNTUK"; penerjemah BASIC menolak BERIKUTNYA yang tidak menemukan FOR yang sesuai. Ini biasanya terjadi ketika NEXT Anda rusak, seperti pada

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

Jadi untuk menjawab pertanyaan Anda:

  • Ya, jika variabel loop berada dalam jangkauan FOR.
  • Ya, setahu saya, itulah masalahnya.
Robert Harvey
sumber
2
"penerjemah BASIC tidak akan menjalankan BERIKUTNYA pada loop FOR yang bukan miliknya" - Saya tahu setidaknya satu keluarga penerjemah BASIC lama di mana pernyataan ini salah, Anda tidak dapat menggeneralisasikan ini ke "semua penerjemah BASIC kuno".
Doc Brown
Spesifikasi ada. Cari PDP-11 BASIC.
david.pfx
1
Terima kasih telah menusuk pertanyaan aneh ini. Saya sekarang telah mengkonfirmasi bahwa BASIC yang digunakan dalam buku ini, ketika menemukan pernyataan FOR kedua yang memiliki variabel counter yang sama, lupa tentang pernyataan FOR pertama dan memulai kembali loop dari yang kedua. Ini bertentangan dengan tikamanmu di kegelapan. Ini adalah cara menjijikkan untuk menulis loop, tetapi BASIC adalah hal yang bau.
Wayne Conrad
2

Apa yang dilakukan "101 Game Komputer" BASIC

Dialek BASIC yang digunakan dalam edisi Microcomputer "101 Computer Games" akan menjalankan tubuh FOR ... NEXT loop setidaknya sekali. Ini berbeda dari BASIC-80 v. 5 .

Dari hal. i12 , daftar pengecualian untuk BASIC "normal":

UNTUK ... UNTUK ... LANGKAH

Seperti dalam BASIC standar, kecuali bahwa tes untuk mengakhiri loop dilakukan setelah h dilakukan. Yaitu, ketika program ini dijalankan:

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

"HI" akan dicetak ...

Karena itu, dialek BASIC ini tidak mengalami kesulitan untuk menemukan pernyataan NEXT, atau berbagi pernyataan berikutnya yang sama dengan beberapa pernyataan FOR. Tidak diperlukan analisis statis. Cukup jalankan setiap pernyataan saat itu terjadi, dan Anda akhirnya akan sampai ke pernyataan NEXT, di mana pun itu.

Apakah mungkin bagi BASIC-80 untuk menangani NEXT yang rusak?

Dimungkinkan untuk pernyataan FOR untuk melewatkan loop body, seperti BASIC-80 v.5 memungkinkan, dan masih memungkinkan pernyataan NEXT yang out-of-order dalam banyak kasus. Begini caranya:

  • Penerjemah mendapat dua status, "berlari," dan "melompat ke BERIKUTNYA"
  • Ketika dalam keadaan "berjalan", penerjemah mengeksekusi setiap pernyataan secara normal.
  • Saat mengevaluasi pernyataan UNTUK, jika badan loop dilewati, status diubah menjadi "melompat ke BERIKUTNYA"
  • Ketika dalam keadaan "melompati ke depan", penerjemah melewatkan setiap pernyataan kecuali BERIKUTNYA dan GOTO tanpa syarat.
    • Pernyataan GOTO tanpa syarat diikuti
    • Pernyataan NEXT, jika variabelnya cocok dengan pernyataan FOR (atau jika variabel tidak ditentukan), beralih kembali ke status "berjalan". Jika variabel tidak cocok, interpreter tetap dalam status "skipping to NEXT".

Ini akan menangani urutan patologis sederhana seperti itu dalam pertanyaan. Itu tidak akan menangani kasus di mana NEXT dicapai oleh pernyataan IF ... GOTO, atau GOSUB. Kode yang melakukan itu jauh lebih buruk daripada kode yang sudah buruk dalam pertanyaan sehingga tidak masuk akal untuk menyatakan bahwa juru bahasa tidak akan mendukung kasus-kasus seperti itu. Bahkan mungkin diizinkan bagi penerjemah untuk membakar kode tersebut.

Wayne Conrad
sumber