In che modo BASIC individua un'istruzione NEXT fuori servizio quando il corpo del loop viene ignorato


9

Impostare la macchina WABAC , Sherman. Questa domanda riguarda BASIC in generale e Microsoft BASIC-80 in particolare. Vecchia scuola di base. Con i numeri di riga.

In che modo gli interpreti BASIC della vecchia scuola (o, piuttosto,) della vecchia scuola gestiscono i cicli FOR ... NEXT quando il corpo del loop non è stato eseguito e la frase NEXT è sembrata fuori servizio?

Un'istruzione SUCCESSIVA non funzionante rispetto ai tempi precedenti:

Ecco una subroutine del gioco Awari tratto da "101 Basic Computer Games" di 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

ed eccolo con tutto tranne il controllo di flusso redatto:

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

Riporta ricordi non così affezionati? Riesci a sentire Dijkstra rotolare nella sua tomba?

Ecco la parte interessante di ciò che sta accadendo in questo frammento:

  • Il secondo ciclo FOR, poiché utilizza la stessa variabile di ciclo, sostituisce il primo ciclo FOR
  • I due loop FOR condividono la stessa istruzione NEXT
  • La seconda istruzione NEXT del ciclo FOR viene prima di essa, nell'ordine di origine, ma dopo, nell'ordine di esecuzione

Si potrebbe supporre, quindi, che l'interprete, dopo aver avviato un ciclo FOR, esegua semplicemente le istruzioni fino a quando non si verifica nel ciclo SUCCESSIVO. In questo caso, l'ordine dell'istruzione nella fonte non ha importanza. Ma vediamo cosa ha da dire il manuale di base80 sui loop FOR:

Il manuale di base 80 dice "moo ..."

Il corpo del loop viene ignorato se il valore iniziale del loop moltiplica il segno del passaggio supera il valore finale moltiplicato per il segno del passaggio.

Quindi, il corpo del loop può essere saltato del tutto.

Abbiamo prove, sotto forma di programmi pubblicati, che almeno alcune versioni di BASIC stavano individuando dinamicamente le loro dichiarazioni SUCCESSIVE. Questo è abbastanza facile da fare quando viene eseguito il corpo del loop. Tuttavia, nel caso in cui il corpo dell'istruzione FOR debba essere ignorato, come consente BASIC-80, in che modo BASIC ha individuato l'istruzione NEXT, dato che potrebbe trovarsi prima dell'istruzione FOR nell'ordine di origine?

  • La versione di BASIC utilizzata in "101 Basic Computer Games" ha sempre eseguito il loop loop almeno una volta?
  • BASIC-80 ha richiesto che l'istruzione NEXT di un ciclo FOR si verificasse dopo l'istruzione FOR, nell'ordine di origine?

PS: Sì, sto scrivendo un interprete BASIC per BASIC vecchia scuola. È una malattia.


Il libro Ahl è stato originariamente pubblicato da DEC nel 1973, precedendo Microsoft BASIC di due anni. I programmi sarebbero stati probabilmente eseguiti in RT-11 BASIC o BASIC-PLUS. Oltre alle estensioni specifiche del sistema, la maggior parte dei dialetti erano compatibili e ho eseguito programmi dalla versione DEC del libro su diversi sistemi con poca o nessuna difficoltà. Potresti trovare illuminanti le fonti smontate e documentate della ROM BASIC di Applesoft. Il codice che implementa l' NEXTistruzione inizia da $ DCF9.
Blrfl,

Non so di BASIC-80, ma sono sicuro al 100% che Commodore Basic (che era Microsoft BASIC V2) esegue sempre il ciclo una volta, e l'ordine delle istruzioni nella fonte non ha importanza, proprio come sospetti.
Doc Brown,

Risposte:


7

Questo riporta i vecchi tempi ...

Ho una copia del libro, terza stampa, 1975. Ho controllato la tua inserzione ed è non originale. Nel codice sorgente originale le istruzioni non hanno spazi e le assegnazioni hanno la parola chiave LET. Per esempio

200 LETK=M:GOSUB600

Il dialetto è DIGITAL PDP-11 BASIC (non Basic-plus o BASIC-80). Per esperienza, non tutti questi giochi hanno funzionato su tutti i dialetti di BASIC. Ho un vago ricordo di dover ricodificare molti di questi giochi per farli funzionare su altri dialetti. Questo tipo di orribile struttura ad anello era sicuramente un problema.

Ho avuto esperienza con oltre 20 diversi dialetti di BASIC e posso dirti che questa era una domanda irritata in quel momento. C'erano 2 campi principali.

In un campo c'erano gli interpreti completi, che analizzavano ogni riga da capo ogni volta che veniva visto. Hanno gestito un ciclo FOR spingendolo su una pila, identificato dalla sua variabile, e quindi scansionando la pila per una corrispondenza con ogni SUCCESSIVO. Se avessero saltato un loop, avrebbero dovuto scansionare la fonte per il PROSSIMO. Alcuni lo hanno fatto, altri no.

L'altro campo erano i tokenizzatori o i semi-compilatori. Scansionavano tutte le linee prima dell'esecuzione e le convertivano in una sorta di formato interno. Hanno anche abbinato loop FOR / NEXT e verificato la mancanza di target GOTO e GOSUB. DEC e BASIC-80 erano in questo campo, come ricordo, ma è passato tanto tempo.

In risposta alle tue domande,

  1. Sì, il dialetto di BASIC salta un ciclo se inizialmente soddisfatto
  2. No, il sequenziamento di FOR NEXT non era un requisito documentato, ma il comportamento non era definito. Come professionista, ovviamente non l'ho mai fatto. :)

Spero che sia di aiuto. Queste sono lingue orribili, ma se devi farlo ...


Questo è molto utile, grazie. Il libro ha una versione DEC, una versione TRS-80 e una versione per microcomputer. I programmi nella versione per microcomputer sono in Microsoft 8080 basic (MITS Altair Basic Rev 4.0); questo è l'obiettivo del mio interprete.
Wayne Conrad,

Ho usato MBASIC su CP / M intorno al 1980, ma nessuna di quelle precedenti macchine per hobbisti. Hai bisogno di un file system! Per molti aspetti troverei più interessante una reincarnazione di un DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic, ma posso capire perché potresti non farlo. Buona fortuna! Contattami se posso esserti di aiuto.
david.pfx,

2

Non ho una copia delle specifiche per uno di questi antichi interpreti BASIC di fronte a me (potrebbe anche non esistere), ma sto per uscire su un arto e dire che l'interprete BASIC non eseguirà un SUCCESSIVO su un ciclo FOR che non appartiene ad esso, anche se la variabile del ciclo ha lo stesso nome.

Quindi, in altre parole, nel tuo esempio

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

quando la linea 235 viene eseguita e va alla linea 220, la linea 220 AVANTI il ciclo FOR superiore, non quello inferiore.

Ciò è evidente nel messaggio di errore "SUCCESSIVO senza FOR"; l'interprete BASIC rifiuta qualsiasi NEXT per il quale non ha trovato un FOR corrispondente. Ciò accade in genere quando i tuoi PROSSIMI sono fuori servizio, come in

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

Quindi, per rispondere alle tue domande puntate:

  • Sì, se la variabile del ciclo rientra nell'intervallo del FOR.
  • Sì, per quanto ne so, è questo il caso.

2
"l'interprete BASIC non eseguirà un NEXT su un ciclo FOR che non gli appartiene" - Conosco almeno una famiglia di vecchi interpreti BASIC in cui questa affermazione è sbagliata, non si può generalizzare a "tutti gli antichi interpreti BASIC".
Doc Brown,

La specifica esiste. Cerca PDP-11 BASIC.
david.pfx,

1
Grazie per aver accoltellato questa strana domanda. Ho ora confermato che il BASIC usato nel libro, quando incontra la seconda istruzione FOR con la stessa variabile counter, dimentica la prima istruzione FOR e riavvia il ciclo dalla seconda. Questo contraddice la tua pugnalata nel buio. È un modo odioso di scrivere loop, ma BASIC è comunque roba puzzolente.
Wayne Conrad,

2

Cosa fa BASIC "101 Computer Games"

Il dialetto di BASIC utilizzato nell'edizione Microcomputer di "101 Computer Games" eseguirà il corpo di un ciclo FOR ... NEXT almeno una volta. Ciò differisce da BASIC-80 v. 5 .

Da p. i12 , elencando le eccezioni al BASIC "normale":

FOR ... TO ... STEP

Come in BASIC standard, tranne per il fatto che il test per terminare il loop viene eseguito dopo che è stato eseguito. Cioè, quando viene eseguito questo programma:

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

"HI" verrà stampato ...

Per questo motivo, questo dialetto di BASIC non ha problemi a localizzare l'istruzione NEXT o a condividere la stessa istruzione successiva con più istruzioni FOR. Non è richiesta alcuna analisi statica. Esegui semplicemente ogni istruzione nel momento in cui si verifica e alla fine arriverai all'istruzione SUCCESSIVA, ovunque si trovi.

È possibile per BASIC-80 gestire un NEXT fuori servizio?

È possibile che un'istruzione FOR salti il ​​corpo del loop, come consente BASIC-80 v.5, e nella maggior parte dei casi consente comunque istruzioni NEXT fuori servizio. Ecco come:

  • L'interprete ottiene due stati, "in esecuzione" e "passa a SUCCESSIVO"
  • Quando si trova nello stato "in esecuzione", l'interprete esegue normalmente ogni istruzione.
  • Quando si valuta un'istruzione FOR, se il corpo del loop deve essere ignorato, lo stato viene modificato in "saltare a SUCCESSIVO"
  • Quando si trova nello stato "Salta al successivo", l'interprete salta ogni istruzione tranne NEXT e GOTO incondizionato.
    • Viene seguita un'istruzione GOTO incondizionata
    • Un'istruzione NEXT, se la sua variabile corrisponde a quella dell'istruzione FOR (o se la variabile non è specificata), ritorna allo stato "in esecuzione". Se la variabile non corrisponde, l'interprete rimane nello stato "salta a SUCCESSIVO".

Ciò gestirà semplici sequenze patologiche come quella nella domanda. Non gestirà i casi in cui il SUCCESSIVO è stato raggiunto da un'istruzione IF ... GOTO o GOSUB. Il codice che lo fa è molto peggio del già cattivo codice nella domanda che non è irragionevole dichiarare semplicemente che l'interprete non supporterà tali casi. Potrebbe anche essere consentito all'interprete di dare fuoco a tale codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.