In che modo BASIC localizza un'istruzione NEXT out-of-order quando il corpo del loop viene saltato

9

Imposta 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, lo facevano) gestiscono i cicli FOR ... NEXT quando il corpo del ciclo non è stato eseguito e l'istruzione NEXT è apparuta fuori servizio?

Una dichiarazione NEXT out-of-order dall'ora precedente:

Ecco una subroutine dal gioco Awari 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

e qui è con tutto tranne il controllo del 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

Questo riporta a ricordi non così carini? 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 di essa, nell'ordine di esecuzione

Si potrebbe supporre, quindi, che l'interprete, dopo aver avviato un ciclo FOR, esegua semplicemente le istruzioni finché non avviene attraverso il ciclo NEXT. In questo caso, l'ordine della dichiarazione nella fonte non è rilevante. Ma vediamo cosa ha da dire il manuale di base80 sui loop di FOR:

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

The body of the loop is skipped if the initial value of the loop times the sign of the step exceeds the final value times the sign of the step.

Quindi, il corpo del ciclo può essere saltato interamente.

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

  • La versione di BASIC utilizzata in "101 Basic Computer Games" esegue sempre il corpo del loop almeno una volta?
  • BASIC-80 ha richiesto che l'istruzione NEXT del 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.

    
posta Wayne Conrad 17.02.2014 - 00:42
fonte

3 risposte

2

Che cosa è il BASIC "101 Giochi per computer"

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

Da pag. i12 , che elenca le eccezioni al "normale" BASIC:

FOR ... TO ... STEP

As in standard BASIC, except that the test for ending the loop is made after it h as been executed. That is, when this program is run:

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

"HI" will be printed...

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 otterrai l'istruzione NEXT, ovunque si trovi.

È possibile che BASIC-80 gestisca un NEXT fuori ordine?

È possibile che un'istruzione FOR salti il corpo del ciclo, come consentito dal BASIC-80 v.5, e che comunque permetta istruzioni NEXT fuori sequenza nella maggior parte dei casi. Ecco come:

  • L'interprete ottiene due stati, "in esecuzione" e "ignora SUCCESSIVO"
  • Quando si trova nello stato "in esecuzione", l'interprete esegue normalmente ogni istruzione.
  • Quando si valuta un'istruzione FOR, se si desidera saltare il corpo del ciclo, lo stato viene modificato in "ignora SUCCESSIVO"
  • Quando nello stato "saltando al prossimo", 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), torna allo stato "in esecuzione". Se la variabile non corrisponde, l'interprete rimane nello stato "saltando alla PROSSIMA".

Questo gestirà sequenze patologiche semplici come quella nella domanda. Non gestiva i casi in cui la NEXT era stata raggiunta da un'istruzione IF ... GOTO o da un 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 permesso all'interprete di dare fuoco a tale codice.

    
risposta data 20.02.2014 - 18:41
fonte
7

Questo riporta indietro i vecchi tempi ...

Ho una copia del libro, 3rd printing, 1975. Ho controllato la tua inserzione e non è originale. Nel codice sorgente originale le dichiarazioni non hanno spazi e le assegnazioni hanno la parola chiave LET. Ad 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 lavorare su altri dialetti. Questo tipo di orribile struttura ad anello era sicuramente un problema.

Ho avuto esperienza con oltre 20 dialetti diversi di BASIC e posso dirvi che questa era una domanda irritata all'epoca. C'erano 2 campi principali.

In un campo c'erano gli interpreti completi, che analizzavano ogni riga di nuovo 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 NEXT. Se hanno saltato un ciclo, avrebbero dovuto scansionare la sorgente per il NEXT. Alcuni lo hanno fatto, altri no.

L'altro campo era i tokenizer o semi-compilatori. Esaminerebbero tutte le linee prima dell'esecuzione e convertirle in una sorta di formato interno. Hanno anche abbinato i loop FOR / NEXT e hanno controllato gli obiettivi GOTO e GOSUB mancanti. DEC e BASIC-80 erano in questo campo, come ricordo, ma è passato molto 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 questo aiuti. Queste sono lingue orribili, ma se devi farlo ...

    
risposta data 17.02.2014 - 14:39
fonte
2

Non ho una copia delle specifiche per uno di questi antichi interpreti BASIC di fronte a me (potrebbe anche non esistere), ma ho intenzione di uscire su un arto e dire che l'interprete BASIC sarà non eseguire un NEXT su un ciclo FOR che non gli appartiene, anche se la variabile loop 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 riga 235 viene eseguita e passa alla riga 220, la riga 220 NEXT il ciclo FOR in alto, non in basso.

Questo è evidente nel messaggio di errore "NEXT without FOR"; l'interprete BASIC rifiuta qualsiasi NEXT per il quale non ha trovato un FOR corrispondente. Questo accade tipicamente quando si ottiene il NEXT 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 di loop si trova nel raggio di FOR.
  • Sì, per quanto ne so, è il caso.
risposta data 17.02.2014 - 00:50
fonte

Leggi altre domande sui tag