BASIC định vị câu lệnh NEXT không theo thứ tự như thế nào khi phần thân vòng lặp bị bỏ qua


9

Đặt máy WABAC , Sherman. Câu hỏi này là về BASIC nói chung và BASIC-80 của Microsoft nói riêng. Trường cũ cơ bản. Với số dòng.

Làm thế nào (hoặc, đúng hơn, đã làm) các thông dịch viên BASIC trường học cũ xử lý các vòng lặp TIẾP THEO khi thân vòng lặp không được thực thi và câu lệnh NEXT xuất hiện không theo thứ tự?

Một tuyên bố NEXT không theo thứ tự từ trước đó:

Đây là một chương trình con từ trò chơi Awari trong "101 trò chơi máy tính cơ bản" của 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

và đây là với tất cả mọi thứ trừ điều khiển luồng được điều chỉnh lại:

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

Điều đó có mang lại những kỷ niệm không đẹp? Bạn có thể nghe thấy Dijkstra lăn lộn trong mộ của mình không?

Đây là phần thú vị của những gì xảy ra trong đoạn này:

  • Vòng lặp FOR thứ hai, vì nó sử dụng cùng một biến vòng lặp, thay thế vòng lặp FOR đầu tiên
  • Hai vòng lặp FOR chia sẻ cùng một câu lệnh TIẾP THEO
  • Câu lệnh NEXT của vòng lặp FOR thứ hai xuất hiện trước nó, theo thứ tự nguồn, nhưng sau nó, theo thứ tự thực hiện

Sau đó, bạn có thể cho rằng trình thông dịch, đã bắt đầu một vòng lặp FOR, chỉ cần chạy các câu lệnh cho đến khi nó xảy ra trên vòng lặp NEXT. Thứ tự của câu lệnh trong nguồn không quan trọng trong trường hợp này. Nhưng hãy xem hướng dẫn cơ bản80 nói gì về các vòng lặp FOR:

Hướng dẫn cơ bản-80 nói "moo ..."

Phần thân của vòng lặp được bỏ qua nếu giá trị ban đầu của vòng lặp nhân với dấu của bước vượt quá giá trị cuối cùng nhân với dấu của bước.

Vì vậy, cơ thể vòng lặp có thể được bỏ qua hoàn toàn.

Chúng tôi có bằng chứng, dưới dạng các chương trình được xuất bản, rằng ít nhất một số phiên bản BASIC đã tự động định vị các tuyên bố NEXT của họ. Điều này đủ dễ thực hiện khi thân vòng lặp đang được thực thi. Tuy nhiên, trong trường hợp phần thân của câu lệnh FOR bị bỏ qua, vì BASIC-80 cho phép, BASIC đã định vị câu lệnh NEXT như thế nào, cho rằng nó có thể nằm trước câu lệnh FOR theo thứ tự nguồn?

  • Có phải phiên bản BASIC được sử dụng trong "101 trò chơi máy tính cơ bản" luôn thực thi thân vòng lặp ít nhất một lần không?
  • BASIC-80 có yêu cầu câu lệnh NEXT của vòng lặp FOR xảy ra sau câu lệnh FOR, theo thứ tự nguồn không?

PS: Vâng, tôi đang viết một thông dịch viên BASIC cho BASIC trường học cũ. Đó là một căn bệnh.


Cuốn sách Ahl ban đầu được xuất bản bởi DEC vào năm 1973, trước Microsoft BASIC hai năm. Các chương trình có thể đã được thực hiện trong RT-11 BASIC hoặc BASIC-PLUS. Khác với các tiện ích mở rộng dành riêng cho hệ thống, hầu hết các phương ngữ đều tương thích và tôi đã chạy các chương trình từ phiên bản DEC của cuốn sách trên một số hệ thống với rất ít hoặc không gặp khó khăn. Bạn có thể tìm thấy các nguồn tài liệu đã được tháo rời, được ghi lại của ROM Applesoft BASIC. Mã thực hiện NEXTcâu lệnh bắt đầu từ $ DCF9.
Blrfl

Không biết về BASIC-80, nhưng tôi chắc chắn 100% rằng Commodore Basic (là Microsoft BASIC V2) luôn thực hiện vòng lặp một lần và thứ tự của các câu lệnh trong nguồn không quan trọng - giống như bạn nghi ngờ.
Doc Brown

Câu trả lời:


7

Điều này mang lại thời xưa ...

Tôi có một bản sao của cuốn sách, in lần thứ 3, năm 1975. Tôi đã kiểm tra danh sách của bạn và nó không phải là bản gốc. Trong mã nguồn ban đầu, các câu lệnh không có khoảng trắng và các bài tập có từ khóa LET. Ví dụ

200 LETK=M:GOSUB600

Phương ngữ là Digital PDP-11 BASIC (không phải Basic-plus hoặc BASIC-80). Từ kinh nghiệm, không phải tất cả các trò chơi này đều hoạt động trên tất cả các phương ngữ của BASIC. Tôi có một hồi ức mơ hồ về việc phải mã hóa lại một vài trong số những trò chơi này để khiến chúng hoạt động trên các phương ngữ khác. Kiểu cấu trúc vòng lặp khủng khiếp này chắc chắn là một vấn đề.

Tôi đã có kinh nghiệm với hơn 20 phương ngữ khác nhau của BASIC và tôi có thể nói với bạn rằng đây là một câu hỏi bực tức vào thời điểm đó. Có 2 trại chính.

Trong một trại có các thông dịch viên đầy đủ, đã phân tích từng dòng một lần nữa mỗi lần nó được nhìn thấy. Họ đã xử lý một vòng lặp FOR bằng cách đẩy nó lên một ngăn xếp, được xác định bởi biến của nó và sau đó quét ngăn xếp để tìm sự trùng khớp với mỗi TIẾP THEO. Nếu họ bỏ qua một vòng lặp, họ sẽ phải quét nguồn cho TIẾP THEO. Một số đã làm, một số thì không.

Trại khác là mã thông báo hoặc bán biên dịch. Họ sẽ quét tất cả các dòng trước khi thực hiện và chuyển đổi chúng thành một loại định dạng nội bộ. Họ cũng khớp các vòng lặp FOR / NEXT và kiểm tra các mục tiêu GOTO và GOSUB bị thiếu. DEC và BASIC-80 đã ở trong trại này, như tôi nhớ, nhưng đó là một thời gian dài trước đây.

Trả lời câu hỏi của bạn,

  1. Có, phương ngữ của BASIC sẽ bỏ qua một vòng lặp nếu ban đầu hài lòng
  2. Không, trình tự FOR NEXT không phải là một yêu cầu được ghi lại, nhưng hành vi không được xác định. Là một chuyên gia, rõ ràng tôi không bao giờ làm điều đó. :)

Hi vọng điêu nay co ich. Đây là những ngôn ngữ khủng khiếp, nhưng nếu bạn phải làm điều đó ...


Điều này rất hữu ích, cảm ơn bạn. Cuốn sách có phiên bản DEC, phiên bản TRS-80 và phiên bản máy vi tính. Các chương trình trong phiên bản máy vi tính nằm trong Microsoft 8080 cơ bản (MITS Altair Basic Rev 4.0); đó là mục tiêu của thông dịch viên của tôi.
Wayne Conrad

Tôi đã sử dụng MBASIC trên CP / M vào khoảng năm 1980, nhưng không có máy nào có sở thích trước đó. Bạn cần một hệ thống tập tin! Theo nhiều cách, tôi sẽ tìm thấy sự tái sinh của một DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic thú vị hơn, nhưng tôi có thể hiểu tại sao bạn có thể không. May mắn nhất! Liên lạc với tôi nếu tôi có thể giúp đỡ.
david.pfx 17/214

2

Tôi không có bản sao thông số kỹ thuật cho một trong những phiên dịch viên BASIC cổ đại này trước mặt tôi (nó thậm chí không tồn tại), nhưng tôi sẽ đi ra ngoài và nói rằng trình thông dịch BASIC sẽ không thực thi TIẾP THEO trên một vòng lặp FOR không thuộc về nó, ngay cả khi biến vòng lặp có cùng tên.

Vì vậy, nói cách khác, trong ví dụ của bạn

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

khi dòng 235 thực thi và đi đến dòng 220, dòng 220 sẽ TIẾP THEO vòng lặp FOR trên cùng chứ không phải phía dưới.

Điều này thể hiện rõ trong thông báo lỗi "TIẾP THEO KHÔNG CÓ"; trình thông dịch BASIC từ chối bất kỳ TIẾP THEO nào mà nó không tìm thấy FOR tương ứng. Điều này thường xảy ra khi bạn mất trật tự, như trong

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

Vì vậy, để trả lời câu hỏi gạch đầu dòng của bạn:

  • Có, nếu biến vòng lặp nằm trong phạm vi của FOR.
  • Vâng, theo hiểu biết của tôi, đó là trường hợp.

2
"Trình thông dịch BASIC sẽ không thực hiện TIẾP THEO trên vòng lặp FOR không thuộc về nó" - Tôi biết ít nhất một gia đình phiên dịch BASIC cũ trong đó tuyên bố này sai, bạn không thể khái quát nó cho "tất cả các thông dịch viên BASIC cổ đại".
Doc Brown

Các thông số kỹ thuật tồn tại. Tìm kiếm PDP-11 BASIC.
david.pfx

1
Cảm ơn bạn đã đâm một câu hỏi kỳ lạ này. Bây giờ tôi đã xác nhận rằng BASIC được sử dụng trong cuốn sách, khi gặp câu lệnh FOR thứ hai có cùng biến đếm, quên đi câu lệnh FOR đầu tiên và khởi động lại vòng lặp từ câu lệnh thứ hai. Điều này mâu thuẫn với vết đâm của bạn trong bóng tối. Đó là một cách khó chịu để viết các vòng lặp, nhưng BASIC dù sao cũng là thứ có mùi.
Wayne Conrad

2

BASIC "101 trò chơi máy tính" làm gì

Phương ngữ BASIC được sử dụng trong phiên bản Microcomputer của "101 trò chơi máy tính" sẽ thực thi phần thân của vòng lặp FOR ... NEXT ít nhất một lần. Điều này không khác với BASIC-80 v. 5 .

Từ P. i12 , liệt kê các ngoại lệ đối với BASIC "bình thường":

CHO ... ĐẾN ... BƯỚC

Như trong BASIC tiêu chuẩn, ngoại trừ việc kiểm tra kết thúc vòng lặp được thực hiện sau khi nó h được thực thi. Đó là, khi chương trình này được chạy:

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

"HI" sẽ được in ...

Do đó, phương ngữ BASIC này không gặp khó khăn khi định vị câu lệnh NEXT hoặc chia sẻ cùng một câu lệnh tiếp theo với nhiều câu lệnh FOR. Không cần phân tích tĩnh. Đơn giản chỉ cần thực hiện mọi câu lệnh khi nó xảy ra, và cuối cùng bạn sẽ nhận được câu lệnh NEXT, bất kể nó ở đâu.

BASIC-80 có thể xử lý TIẾP THEO không theo thứ tự không?

Có thể cho câu lệnh FOR bỏ qua phần thân vòng lặp, vì BASIC-80 v.5 cho phép và vẫn cho phép các câu lệnh NEXT không theo thứ tự trong hầu hết các trường hợp. Đây là cách thực hiện:

  • Trình thông dịch có hai trạng thái, "đang chạy" và "chuyển sang TIẾP THEO"
  • Khi ở trạng thái "đang chạy", trình thông dịch sẽ thực thi mọi câu lệnh một cách bình thường.
  • Khi đánh giá một câu lệnh FOR, nếu phần thân vòng lặp bị bỏ qua, trạng thái được thay đổi thành "bỏ qua sang TIẾP THEO"
  • Khi ở trạng thái "chuyển sang tiếp theo", trình thông dịch bỏ qua mọi câu lệnh ngoại trừ TIẾP THEO và GOTO vô điều kiện.
    • Một tuyên bố GOTO vô điều kiện được theo sau
    • Câu lệnh NEXT, nếu biến của nó khớp với câu lệnh FOR (hoặc nếu biến không được chỉ định), sẽ chuyển về trạng thái "đang chạy". Nếu biến không khớp, trình thông dịch vẫn ở trạng thái "chuyển sang TIẾP THEO".

Điều này sẽ xử lý các chuỗi bệnh lý đơn giản như trong câu hỏi. Nó sẽ không xử lý các trường hợp đạt được NEXT bằng câu lệnh IF ... GOTO hoặc GOSUB. Mã làm điều đó tệ hơn nhiều so với mã đã xấu trong câu hỏi đến mức không hợp lý khi tuyên bố đơn giản rằng trình thông dịch sẽ không hỗ trợ các trường hợp như vậy. Thậm chí có thể cho phép trình thông dịch đặt mã đó vào lửa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.