Wie findet BASIC eine NEXT-Anweisung außerhalb der Reihenfolge, wenn der Schleifenkörper übersprungen wird?


9

Stellen Sie die WABAC-Maschine ein , Sherman. Diese Frage bezieht sich auf BASIC im Allgemeinen und auf Microsoft BASIC-80 im Besonderen. Old School Basic. Mit Zeilennummern.

Wie behandeln (oder besser gesagt) BASIC-Interpreter der alten Schule FOR ... NEXT-Schleifen, wenn der Schleifenkörper nicht ausgeführt wurde und die NEXT-Anweisung nicht in der richtigen Reihenfolge angezeigt wurde?

Eine nicht ordnungsgemäße NEXT-Anweisung aus der vorherigen Zeit:

Hier ist eine Unterroutine aus dem Spiel Awari aus David H. Ahls "101 Basic Computer Games" :

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

und hier ist es mit allem außer der Flusskontrolle redigiert:

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

Bringt das nicht so schöne Erinnerungen zurück? Kannst du Dijkstra in seinem Grab herumrollen hören ?

Hier ist der interessante Teil dessen, was in diesem Fragment passiert:

  • Die zweite FOR-Schleife ersetzt die erste FOR-Schleife, da sie dieselbe Schleifenvariable verwendet
  • Die beiden FOR-Schleifen haben dieselbe NEXT-Anweisung
  • Die NEXT-Anweisung der zweiten FOR-Schleife steht davor in der Quellreihenfolge, danach jedoch in der Ausführungsreihenfolge

Sie könnten also annehmen, dass der Interpreter, nachdem er eine FOR-Schleife gestartet hat, einfach Anweisungen ausführt, bis sie in der NEXT-Schleife auftreten. Die Reihenfolge der Aussage in der Quelle spielt in diesem Fall keine Rolle. Aber mal sehen, was das basic80-Handbuch über FOR-Schleifen zu sagen hat:

Das Basic-80-Handbuch sagt "moo ..."

Der Hauptteil der Schleife wird übersprungen, wenn der Anfangswert der Schleife mal das Vorzeichen des Schritts den Endwert mal das Vorzeichen des Schritts überschreitet.

Der Schleifenkörper kann also vollständig übersprungen werden.

Wir haben Beweise in Form von veröffentlichten Programmen, dass zumindest einige Versionen von BASIC ihre NEXT-Anweisungen dynamisch lokalisierten. Dies ist einfach genug, wenn der Schleifenkörper ausgeführt wird. In dem Fall, in dem der Hauptteil der FOR-Anweisung übersprungen werden sollte, wie es BASIC-80 zulässt, wie hat BASIC die NEXT-Anweisung gefunden, da sie möglicherweise vor der FOR-Anweisung in der Quellreihenfolge liegt?

  • Hat die in "101 Basic Computer Games" verwendete Version von BASIC den Loop-Body immer mindestens einmal ausgeführt?
  • Hat BASIC-80 verlangt, dass die NEXT-Anweisung einer FOR-Schleife nach der FOR-Anweisung in der Quellreihenfolge erfolgt?

PS: Ja, ich schreibe einen BASIC-Dolmetscher für Old School BASIC. Es ist eine Krankheit.


Das Ahl-Buch wurde ursprünglich 1973 von DEC veröffentlicht, zwei Jahre vor Microsoft BASIC. Die Programme wären wahrscheinlich in RT-11 BASIC oder BASIC-PLUS durchgeführt worden. Abgesehen von systemspezifischen Erweiterungen waren die meisten Dialekte kompatibel, und ich habe Programme aus der DEC-Version des Buches auf mehreren Systemen ohne oder mit geringen Schwierigkeiten ausgeführt. Möglicherweise finden Sie die zerlegten, dokumentierten Quellen des Applesoft BASIC ROM aufschlussreich. Der Code, der die NEXTAnweisung implementiert , beginnt bei $ DCF9.
Blrfl

Ich weiß nichts über BASIC-80, aber ich bin zu 100% sicher, dass Commodore Basic (Microsoft BASIC V2) die Schleife immer einmal ausführt und die Reihenfolge der Anweisungen in der Quelle keine Rolle spielt - genau wie Sie vermuten.
Doc Brown

Antworten:


7

Dies bringt die alten Zeiten zurück ...

Ich habe eine Kopie des Buches, 3. Druck, 1975. Ich habe Ihren Eintrag überprüft und er ist nicht original. Im ursprünglichen Quellcode haben die Anweisungen keine Leerzeichen und Zuweisungen haben das Schlüsselwort LET. Beispielsweise

200 LETK=M:GOSUB600

Der Dialekt ist DIGITAL PDP-11 BASIC (nicht Basic-plus oder BASIC-80). Erfahrungsgemäß funktionierten nicht alle dieser Spiele in allen Dialekten von BASIC. Ich habe eine vage Erinnerung daran, dass ich einige dieser Spiele neu codieren musste, um sie dazu zu bringen, an anderen Dialekten zu arbeiten. Diese Art von schrecklicher Schleifenstruktur war definitiv ein Problem.

Ich hatte Erfahrung mit über 20 verschiedenen Dialekten von BASIC und ich kann Ihnen sagen, dass dies zu dieser Zeit eine ärgerliche Frage war. Es gab 2 Hauptlager.

In einem Lager gab es die vollständigen Dolmetscher, die jede Zeile jedes Mal neu analysierten, wenn sie gesehen wurde. Sie handhabten eine FOR-Schleife, indem sie sie auf einen Stapel schoben, der durch ihre Variable identifiziert wurde, und dann den Stapel nach einer Übereinstimmung mit jedem NEXT durchsuchten. Wenn sie eine Schleife überspringen würden, müssten sie die Quelle nach dem NÄCHSTEN durchsuchen. Einige taten es, andere nicht.

Das andere Lager waren die Tokenizer oder Semi-Compiler. Sie scannten alle Zeilen vor der Ausführung und konvertierten sie in ein internes Format. Sie haben auch FOR / NEXT-Schleifen abgeglichen und nach fehlenden GOTO- und GOSUB-Zielen gesucht. DEC und BASIC-80 waren, wie ich mich erinnere, in diesem Lager, aber es ist lange her.

Als Antwort auf Ihre Fragen,

  1. Ja, der Dialekt von BASIC überspringt eine Schleife, wenn er anfänglich erfüllt ist
  2. Nein, die Sequenzierung von FOR NEXT war keine dokumentierte Anforderung, aber das Verhalten war undefiniert. Als Profi habe ich das natürlich nie gemacht. :) :)

Hoffe das hilft. Das sind schreckliche Sprachen, aber wenn du es tun musst ...


Das ist sehr hilfreich, danke. Das Buch enthält eine DEC-Version, eine TRS-80-Version und eine Mikrocomputer-Version. Die Programme in der Mikrocomputerversion sind in Microsoft 8080 Basic (MITS Altair Basic Rev 4.0) enthalten. das ist das Ziel meines Dolmetschers.
Wayne Conrad

Ich habe MBASIC um 1980 auf CP / M verwendet, aber keine dieser früheren Hobby-Maschinen. Sie benötigen ein Dateisystem! In vielerlei Hinsicht würde ich eine Reinkarnation eines DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic interessanter finden, aber ich kann verstehen, warum Sie dies möglicherweise nicht tun. Viel Glück! Kontaktieren Sie mich, wenn ich Ihnen helfen kann.
david.pfx

2

Ich habe keine Kopie der Spezifikation für einen dieser alten BASIC-Interpreten vor mir (sie existiert möglicherweise nicht einmal), aber ich werde mich auf die Probe stellen und sagen, dass der BASIC-Interpreter a nicht ausführen wird NEXT in einer FOR-Schleife, die nicht dazu gehört, auch wenn die Schleifenvariable denselben Namen hat.

Mit anderen Worten, in Ihrem Beispiel

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

Wenn Zeile 235 ausgeführt wird und zu Zeile 220 geht, folgt Zeile 220 der oberen FOR-Schleife und nicht der unteren.

Dies ist in der Fehlermeldung "NEXT without FOR" ersichtlich. Der BASIC-Interpreter lehnt alle NEXT ab, für die er kein entsprechendes FOR gefunden hat. Dies geschieht normalerweise, wenn Sie Ihre NEXT wie in außer Betrieb setzen

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

Um Ihre Fragen mit Aufzählungszeichen zu beantworten:

  • Ja, wenn sich die Schleifenvariable im Bereich von FOR befindet.
  • Ja, meines Wissens ist das der Fall.

2
"Der BASIC-Interpreter führt kein NEXT in einer FOR-Schleife aus, die nicht dazu gehört." - Ich kenne mindestens eine Familie alter BASIC-Interpreter, bei denen diese Aussage falsch ist. Sie können dies nicht auf "alle alten BASIC-Interpreter" verallgemeinern.
Doc Brown

Die Spezifikation existiert. Suchen Sie nach PDP-11 BASIC.
david.pfx

1
Vielen Dank, dass Sie sich mit dieser seltsamen Frage befasst haben. Ich habe jetzt bestätigt, dass das im Buch verwendete BASIC bei der Begegnung mit der zweiten FOR-Anweisung mit derselben Zählervariablen die erste FOR-Anweisung vergisst und die Schleife von der zweiten neu startet. Dies widerspricht Ihrem Stich in die Dunkelheit. Es ist eine abscheuliche Art, Loops zu schreiben, aber BASIC stinkt sowieso.
Wayne Conrad

2

Was die "101 Computerspiele" BASIC machen

Der in der Microcomputer-Ausgabe von "101 Computer Games" verwendete BASIC-Dialekt führt den Text einer FOR ... NEXT-Schleife mindestens einmal aus. Dies unterscheidet sich von BASIC-80 v. 5 .

Ab p. i12 , Auflistung von Ausnahmen zu "normalem" BASIC:

FÜR ... ZU ... SCHRITT

Wie in Standard-BASIC, außer dass der Test zum Beenden der Schleife durchgeführt wird, nachdem sie ausgeführt wurde. Das heißt, wenn dieses Programm ausgeführt wird:

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

"HI" wird gedruckt ...

Aus diesem Grund hat dieser Dialekt von BASIC keine Probleme, die NEXT-Anweisung zu finden oder dieselbe nächste Anweisung mit mehreren FOR-Anweisungen zu teilen. Es ist keine statische Analyse erforderlich. Führen Sie einfach jede Anweisung so aus, wie sie auftritt, und Sie gelangen schließlich zur nächsten Anweisung, wo immer sie sich befindet.

Ist es für BASIC-80 möglich, einen NEXT außerhalb der Reihenfolge zu verarbeiten?

Es ist möglich, dass eine FOR-Anweisung den Schleifenkörper überspringt, wie es BASIC-80 v.5 zulässt, und in den meisten Fällen auch NEXT-Anweisungen außerhalb der Reihenfolge zulässt. Hier ist wie:

  • Der Interpreter erhält zwei Zustände: "Laufen" und "Springen zu WEITER".
  • Im "laufenden" Zustand führt der Interpreter jede Anweisung normal aus.
  • Wenn bei der Auswertung einer FOR-Anweisung der Schleifenkörper übersprungen werden soll, wird der Status in "Überspringen zu NEXT" geändert.
  • Im Status "Überspringen zum nächsten" überspringt der Interpreter jede Anweisung mit Ausnahme von NEXT und bedingungslosem GOTO.
    • Eine bedingungslose GOTO-Anweisung wird befolgt
    • Eine NEXT-Anweisung wechselt, wenn ihre Variable mit der FOR-Anweisung übereinstimmt (oder wenn die Variable nicht angegeben ist), in den Status "running" zurück. Wenn die Variable nicht übereinstimmt, bleibt der Interpreter im Status "Springen zu WEITER".

Dies würde einfache pathologische Sequenzen wie die in der Frage behandeln. Fälle, in denen der NEXT von einer IF ... GOTO-Anweisung oder einem GOSUB erreicht wurde, wurden nicht behandelt. Code, der dies tut, ist so viel schlimmer als der bereits schlechte Code in der Frage, dass es nicht unangemessen ist, einfach zu erklären, dass der Interpreter solche Fälle nicht unterstützt. Es kann sogar zulässig sein, dass der Dolmetscher einen solchen Code in Brand setzt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.