BASIC ค้นหาคำสั่ง NEXT ที่ไม่เป็นไปตามคำสั่งได้อย่างไรเมื่อลำตัววนซ้ำถูกข้ามไป


9

ตั้งค่าเครื่อง WABAC , Sherman คำถามนี้เกี่ยวกับ BASIC โดยทั่วไปและโดยเฉพาะของ Microsoft BASIC-80 โรงเรียนเก่าขั้นพื้นฐาน ด้วยหมายเลขบรรทัด

ล่ามขั้นพื้นฐานแบบเก่า (หรือมากกว่านั้น) มีวิธีจัดการอย่างไร ... NEXT ลูปเมื่อตัวลูปไม่ได้ถูกดำเนินการและคำสั่ง NEXT นั้นไม่เป็นระเบียบ?

คำสั่ง NEXT ที่เลิกใช้แล้วจากเวลาก่อน:

นี่คือรูทีนย่อยจากเกมAwariจาก"101 Basic Computer Games"ของ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

และนี่คือทุกสิ่งยกเว้นการควบคุมการไหล redacted:

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

นั่นนำความทรงจำที่ไม่ถูกใจกลับมาใช่ไหม? คุณสามารถได้ยินDijkstra กลิ้งอยู่ในหลุมฝังศพของเขา?

นี่คือส่วนที่น่าสนใจของสิ่งที่เกิดขึ้นในส่วนนี้:

  • FOR FOR อันที่สองเนื่องจากมันใช้ตัวแปรลูปเดียวกันแทน FOR FOR วงแรก
  • FOR ลูปสองวงใช้คำสั่ง NEXT เดียวกัน
  • คำสั่ง NEXT วงที่สองของ FOR มาก่อนตามลำดับแหล่งที่มา แต่หลังจากนั้นในลำดับการดำเนินการ

คุณอาจคิดว่าล่ามที่เริ่มต้นวนวน FOR นั้นจะเรียกใช้คำสั่งจนกว่าจะเกิดขึ้นข้ามลูป NEXT คำสั่งของคำสั่งในแหล่งที่มาไม่สำคัญในกรณีนี้ แต่เรามาดูกันว่าคู่มือพื้นฐาน 80 ได้พูดถึงเรื่องลูปสำหรับ:

คู่มือพื้นฐาน -80 บอกว่า "หมู่ ... "

เนื้อความของการวนซ้ำถูกข้ามถ้าค่าเริ่มต้นของการวนซ้ำครั้งที่เครื่องหมายของขั้นตอนเกินกว่าค่าสุดท้ายคูณด้วยเครื่องหมายของขั้นตอน

ดังนั้นตัวลูปสามารถข้ามได้ทั้งหมด

เรามีหลักฐานในรูปแบบของโปรแกรมที่เผยแพร่ว่าอย่างน้อยบางรุ่นของ BASIC กำลังค้นหาคำสั่ง NEXT ของพวกเขาแบบไดนามิก นี่เป็นเรื่องง่ายพอที่จะดำเนินการเมื่อมีการประมวลผลเนื้อหา อย่างไรก็ตามในกรณีที่ควรข้ามเนื้อหาของคำสั่ง FOR เนื่องจาก BASIC-80 อนุญาต BASIC ค้นหาคำสั่ง NEXT ได้อย่างไรเนื่องจากอาจเป็นก่อนคำสั่ง FOR ตามลำดับที่มา?

  • รุ่นพื้นฐานของ BASIC ใช้ใน "101 Basic Computer Games" เรียกใช้ลูปร่างกายอย่างน้อยหนึ่งครั้งหรือไม่?
  • BASIC-80 ต้องการให้คำสั่ง NEXT ของวงวนเกิดขึ้นหลังจากคำสั่ง FOR ตามลำดับที่มาหรือไม่

PS: ใช่ฉันกำลังเขียนล่ามพื้นฐานสำหรับโรงเรียนเก่าพื้นฐาน มันเป็นอาการป่วย


หนังสือ Ahl ได้รับการตีพิมพ์ครั้งแรกโดย DEC ในปี 1973 โดยมีพื้นฐานมาจาก Microsoft BASIC เป็นเวลาสองปี โปรแกรมอาจจะทำใน RT-11 BASIC หรือ BASIC-PLUS นอกเหนือจากส่วนขยายเฉพาะระบบภาษาถิ่นส่วนใหญ่เข้ากันได้และฉันใช้งานโปรแกรมจากหนังสือ DEC เวอร์ชันต่าง ๆ ในหลาย ๆ ระบบด้วยความยากลำบากเพียงเล็กน้อยหรือไม่มีเลย คุณอาจพบแหล่งข้อมูลที่ถูกแยกส่วนที่มีเอกสารของ Applesoft BASIC ROM รหัสที่ใช้งานNEXTคำสั่งเริ่มต้นที่ $ DCF9
Blrfl

ไม่ทราบเกี่ยวกับ BASIC-80 แต่ฉันแน่ใจ 100% ว่า Commodore Basic (ซึ่งเป็น Microsoft BASIC V2) จะดำเนินการวนรอบหนึ่งครั้งเสมอและลำดับของคำสั่งในแหล่งข้อมูลไม่สำคัญ - เหมือนกับที่คุณสงสัย
Doc Brown

คำตอบ:


7

สิ่งนี้นำกลับมาครั้งเก่า ...

ฉันมีสำเนาของหนังสือเล่มที่ 3 ฉบับที่ 1975 ฉันตรวจสอบรายชื่อของคุณแล้วไม่ใช่แบบดั้งเดิม ในซอร์สโค้ดต้นฉบับคำสั่งไม่มีช่องว่างและการกำหนดที่มีคำหลัก LET ตัวอย่างเช่น

200 LETK=M:GOSUB600

ภาษาถิ่นคือ DIGITAL PDP-11 BASIC (ไม่ใช่ Basic-plus หรือ BASIC-80) จากประสบการณ์เกมเหล่านี้ไม่ได้ทำงานได้กับทุกภาษาของ BASIC ฉันมีความทรงจำที่คลุมเครือในการจำเกมเหล่านี้อีกหลายเกมเพื่อให้พวกเขาสามารถใช้ภาษาถิ่นอื่นได้ โครงสร้างลูปที่น่ากลัวแบบนี้เป็นปัญหาแน่นอน

ฉันมีประสบการณ์กับภาษาต่าง ๆ กว่า 20 ภาษาของภาษาเบสิกและฉันสามารถบอกคุณได้ว่านี่เป็นคำถามที่ถูกรบกวนในเวลานั้น มี 2 ​​ค่ายหลัก

ในค่ายหนึ่งมีล่ามเต็มรูปแบบซึ่งแยกแต่ละบรรทัดใหม่ทุกครั้งที่เห็น พวกเขาจัดการวงวน FOR โดยกดลงบนสแต็กระบุโดยตัวแปรแล้วสแกนกองซ้อนเพื่อจับคู่กับแต่ละ NEXT หากพวกเขาข้ามลูปพวกเขาจะต้องสแกนแหล่งที่มาสำหรับ NEXT บางคนทำบางคนไม่ได้

ค่ายอื่นคือโทเค็นไคเซอร์หรือคอมไพเลอร์ พวกเขาจะสแกนทุกบรรทัดก่อนทำการประมวลผลและแปลงเป็นรูปแบบภายในบางประเภท พวกเขาจับคู่กับ FOR / NEXT ลูปและตรวจสอบหาเป้าหมาย GOTO และ GOSUB ที่หายไป DEC และ BASIC-80 อยู่ในค่ายนี้อย่างที่ฉันจำได้ แต่มันนานมาแล้ว

เพื่อตอบคำถามของคุณ

  1. ใช่ภาษาถิ่นของ BASIC จะข้ามลูปถ้าเริ่มพอใจ
  2. ไม่การจัดลำดับของ FOR NEXT ไม่ใช่ข้อกำหนดของเอกสาร แต่พฤติกรรมนั้นไม่ได้กำหนดไว้ ในฐานะมืออาชีพเห็นได้ชัดว่าฉันไม่เคยทำ :)

หวังว่านี่จะช่วยได้ ภาษาเหล่านี้น่ากลัว แต่ถ้าคุณต้องทำ ...


สิ่งนี้มีประโยชน์มากขอบคุณ หนังสือเล่มนี้มีรุ่น DEC, รุ่น TRS-80 และรุ่นไมโครคอมพิวเตอร์ โปรแกรมในรุ่นไมโครคอมพิวเตอร์นั้นอยู่ใน Microsoft 8080 basic (MITS Altair Basic Rev 4.0); นั่นคือเป้าหมายของล่ามของฉัน
Wayne Conrad

ฉันใช้ MBASIC กับ CP / M ในราวปี 1980 แต่ไม่มีเครื่องจักรงานอดิเรกก่อนหน้านี้เลย คุณต้องการระบบไฟล์! ในหลาย ๆ ทางฉันจะพบว่าการเกิดใหม่ของ DEC / DG / HP / CAI / Prime / Interdata / Tektronix พื้นฐานน่าสนใจยิ่งขึ้น แต่ฉันเข้าใจได้ว่าทำไมคุณถึงไม่ทำ ขอให้โชคดี! ติดต่อฉันหากฉันสามารถช่วย
david.pfx

2

ฉันไม่มีสำเนาของข้อกำหนดสำหรับล่ามภาษาเบสิกโบราณเหล่านี้ต่อหน้าฉัน (อาจไม่มีอยู่จริง) แต่ฉันจะออกไปที่ขาและพูดว่าล่ามพื้นฐานจะไม่ดำเนินการ NEXT สำหรับวงวน FOR ที่ไม่ได้เป็นของมันแม้ว่าตัวแปรลูปจะมีชื่อเหมือนกันก็ตาม

ดังนั้นในคำอื่น ๆ ในตัวอย่างของคุณ

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 จะถัดไปด้านบนสำหรับการวนรอบไม่ใช่ด้านล่าง

นี่คือประจักษ์ในข้อความแสดงข้อผิดพลาด "NEXT ไม่มีสำหรับ" ล่าม BASIC ปฏิเสธ NEXT ใด ๆ ที่ไม่พบ FOR ที่ตรงกัน สิ่งนี้มักจะเกิดขึ้นเมื่อคุณได้รับคำสั่งซื้อครั้งต่อไปของคุณเช่นเดียวกับใน

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

ดังนั้นเพื่อตอบคำถามสัญลักษณ์แสดงหัวข้อย่อยของคุณ:

  • ใช่ถ้าตัวแปรลูปอยู่ในช่วงของ FOR
  • ใช่ฉันรู้ว่าเป็นกรณี

2
"ล่ามพื้นฐานจะไม่ดำเนินการ NEXT ในวงวน FOR ที่ไม่ได้เป็นของมัน" - ฉันรู้ว่าอย่างน้อยหนึ่งตระกูลล่ามพื้นฐานที่คำสั่งนี้ผิดคุณไม่สามารถพูดเรื่องนี้กับ "ล่ามพื้นฐานโบราณทั้งหมด"
Doc Brown

มีสเป็คอยู่ ค้นหา PDP-11 พื้นฐาน
david.pfx

1
ขอบคุณสำหรับการแทงด้วยคำถามแปลก ๆ นี้ ตอนนี้ฉันได้ยืนยันแล้วว่า BASIC ที่ใช้ในหนังสือเมื่อพบคำสั่ง FOR ที่สองที่มีตัวแปรตัวนับเดียวกันลืมเกี่ยวกับคำสั่ง FOR แรกและรีสตาร์ทลูปจากลูปที่สอง สิ่งนี้ขัดแย้งกับการแทงของคุณในที่มืด มันเป็นวิธีที่น่ารังเกียจในการเขียนลูป แต่ BASIC เป็นสิ่งที่มีกลิ่นแรงอยู่แล้ว
Wayne Conrad

2

พื้นฐาน "เกมคอมพิวเตอร์ 101" ทำอะไรได้บ้าง

ภาษาถิ่นของ BASIC ที่ใช้ในเกมคอมพิวเตอร์ "101 Computer Games" ของไมโครคอมพิวเตอรจะดำเนินการร่างของ FOR ... NEXT วนอย่างน้อยหนึ่งครั้ง นี้ไม่แตกต่างจากพื้นฐาน-80 v. 5

จากหน้า i12 แสดงรายการข้อยกเว้นสำหรับ "ปกติ" พื้นฐาน:

For ... กับ ... ขั้นตอน

เช่นเดียวกับใน BASIC มาตรฐานยกเว้นว่าจะทำการทดสอบการจบลูปหลังจากการดำเนินการ h นั่นคือเมื่อโปรแกรมนี้ทำงาน:

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

"HI" จะถูกพิมพ์ ...

ด้วยเหตุนั้นภาษาถิ่นของ BASIC นี้จึงไม่มีปัญหาในการค้นหาคำสั่ง NEXT หรือแบ่งปันคำสั่งถัดไปเดียวกันกับหลายคำสั่ง FOR ไม่จำเป็นต้องทำการวิเคราะห์เชิงสถิต เพียงดำเนินการทุกคำสั่งที่เกิดขึ้นและในที่สุดคุณก็จะได้รับข้อความต่อไปไม่ว่าจะอยู่ที่ไหน

เป็นไปได้หรือไม่ที่ BASIC-80 สามารถจัดการ NEXT ที่ไม่เป็นไปตามสั่งได้?

เป็นไปได้สำหรับคำสั่ง FOR ที่จะข้ามเนื้อความลูปเนื่องจาก BASIC-80 v.5 อนุญาตและยังคงอนุญาตให้ใช้คำสั่ง NEXT ที่ไม่เป็นไปตามคำสั่งในกรณีส่วนใหญ่ นี่คือวิธี:

  • ล่ามได้รับสถานะสองสถานะคือ "เรียกใช้" และ "ข้ามไปยัง NEXT"
  • เมื่ออยู่ในสถานะ "กำลังทำงาน" ล่ามจะดำเนินการทุกคำสั่งตามปกติ
  • เมื่อประเมินคำสั่ง FOR หากจะต้องข้ามเนื้อหาของลูปสถานะจะเปลี่ยนเป็น "ข้ามไปยัง NEXT"
  • เมื่ออยู่ในสถานะ "ข้ามไปยังถัดไป" ล่ามจะข้ามคำสั่งทั้งหมดยกเว้น NEXT และ GOTO ที่ไม่มีเงื่อนไข
    • คำสั่ง GOTO ที่ไม่มีเงื่อนไขถูกติดตาม
    • คำสั่ง NEXT หากตัวแปรตรงกับคำสั่ง FOR (หรือหากไม่ได้ระบุตัวแปร) ให้เปลี่ยนกลับไปเป็นสถานะ "กำลังทำงาน" หากตัวแปรไม่ตรงกันล่ามจะยังคงอยู่ในสถานะ "ข้ามไปยัง NEXT"

สิ่งนี้จะจัดการลำดับทางพยาธิวิทยาอย่างง่ายเช่นนั้นในคำถาม มันจะไม่จัดการกรณีที่ NEXT เข้าถึงได้โดยคำสั่ง IF ... GOTO หรือ GOSUB รหัสที่ทำนั้นแย่กว่ารหัสที่ไม่ดีอยู่แล้วในคำถามที่ว่ามันไม่สมเหตุสมผลที่จะประกาศว่าล่ามจะไม่รองรับกรณีดังกล่าว มันอาจจะอนุญาตให้ล่ามในการตั้งรหัสดังกล่าวในกองไฟ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.