Configura la máquina WABAC , Sherman. Esta pregunta es sobre BASIC en general, y BASIC-80 de Microsoft en particular. Vieja escuela básica. Con números de línea.
¿Cómo manejan (o mejor dicho) los intérpretes BASIC de la vieja escuela los bucles FOR ... NEXT cuando el cuerpo del bucle no se ejecutó y la instrucción NEXT apareció fuera de orden?
Una declaración NEXT fuera de servicio del tiempo anterior:
Aquí hay una subrutina del juego Awari de "101 Basic Computer Games" de 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
y aquí está con todo excepto el control de flujo redactado:
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
¿Eso te trae recuerdos no tan cariñosos? ¿Puedes oír a Dijkstra rodando en su tumba?
Aquí está la parte interesante de lo que está sucediendo en este fragmento:
- El segundo bucle FOR, ya que usa la misma variable de bucle, reemplaza el primer bucle FOR
- Los dos bucles FOR comparten la misma instrucción NEXT
- La segunda instrucción NEXT del bucle FOR viene antes, en orden de origen, pero después, en orden de ejecución
Puede suponer, entonces, que el intérprete, después de haber iniciado un ciclo FOR, simplemente ejecuta declaraciones hasta que sucede a través del ciclo NEXT. El orden de la declaración en la fuente no importa en este caso. Pero veamos qué dice el manual basic80 sobre los bucles FOR:
El manual básico-80 dice "mu ..."
El cuerpo del bucle se omite si el valor inicial del bucle multiplicado por el signo del paso excede el valor final multiplicado por el signo del paso.
Por lo tanto, el cuerpo del bucle se puede omitir por completo.
Tenemos evidencia, en forma de programas publicados, de que al menos algunas versiones de BASIC estaban localizando dinámicamente sus declaraciones NEXT. Esto es bastante fácil de hacer cuando se ejecuta el cuerpo del bucle. Sin embargo, en el caso en el que se debe omitir el cuerpo de la instrucción FOR, como lo permite BASIC-80, ¿cómo BASIC ubicó la instrucción NEXT, dado que podría estar antes de la instrucción FOR en orden de origen?
- ¿La versión de BASIC utilizada en "101 Juegos básicos de computadora" siempre ejecutó el cuerpo del bucle al menos una vez?
- ¿BASIC-80 requirió que se produjera una instrucción NEXT del bucle FOR después de la instrucción FOR, en orden de origen?
PD: Sí, estoy escribiendo un intérprete BASIC para BASIC de la vieja escuela. Es una enfermedad.
fuente
NEXT
declaración comienza en $ DCF9.Respuestas:
Esto trae de vuelta los viejos tiempos ...
Tengo una copia del libro, tercera impresión, 1975. Revisé su listado y no es original. En el código fuente original, las declaraciones no tienen espacios y las asignaciones tienen la palabra clave LET. Por ejemplo
El dialecto es DIGITAL PDP-11 BASIC (no Basic-plus o BASIC-80). Por experiencia, no todos estos juegos funcionaron en todos los dialectos de BASIC. Tengo un vago recuerdo de tener que volver a codificar varios de estos juegos para que funcionen en otros dialectos. Este tipo de estructura de bucle horrible fue definitivamente un problema.
Tenía experiencia con más de 20 dialectos diferentes de BASIC y puedo decirle que esta era una pregunta molesta en ese momento. Hubo 2 campamentos principales.
En un campamento estaban los intérpretes completos, que analizaban cada línea de nuevo cada vez que se veía. Manejaron un bucle FOR empujándolo en una pila, identificado por su variable, y luego escaneando la pila para encontrar una coincidencia con cada SIGUIENTE. Si se saltaban un bucle, tendrían que escanear la fuente en busca de NEXT. Algunos lo hicieron, otros no.
El otro campamento eran los tokenizadores o semi-compiladores. Escanearían todas las líneas antes de la ejecución y las convertirían a algún tipo de formato interno. También combinaron los bucles FOR / NEXT y comprobaron la falta de objetivos GOTO y GOSUB. DEC y BASIC-80 estaban en este campamento, según recuerdo, pero hace mucho tiempo.
En respuesta a tus preguntas,
Espero que esto ayude. Estos son idiomas horribles, pero si tienes que hacerlo ...
fuente
No tengo una copia de la especificación para uno de estos antiguos intérpretes BASIC frente a mí (puede que ni siquiera exista), pero voy a ponerme nervioso y decir que el intérprete BASIC no ejecutará un SIGUIENTE en un bucle FOR que no le pertenece, incluso si la variable del bucle tiene el mismo nombre.
En otras palabras, en tu ejemplo
cuando la línea 235 se ejecuta y va a la línea 220, la línea 220 SIGUIRÁ el bucle FOR superior, no el inferior.
Esto es evidente en el mensaje de error "SIGUIENTE sin FOR"; el intérprete BÁSICO rechaza cualquier SIGUIENTE para el cual no encontró un FOR correspondiente. Esto suele suceder cuando obtiene sus NEXT fuera de servicio, como en
Entonces, para responder a sus preguntas con viñetas:
fuente
Lo que hace el BASIC "101 juegos de computadora"
El dialecto de BASIC utilizado en la edición Microcomputer de "101 Computer Games" ejecutará el cuerpo de un bucle FOR ... NEXT al menos una vez. Esto difiere de BASIC-80 v. 5 .
De p. i12 , enumerando excepciones a BASIC "normal":
PARA ... A ... PASO
Debido a eso, este dialecto de BASIC no tiene problemas para localizar la declaración NEXT o compartir la misma declaración siguiente con varias declaraciones FOR. No se requiere análisis estático. Simplemente ejecute cada declaración a medida que ocurra, y eventualmente llegará a la siguiente declaración, donde sea que esté.
¿Es posible que BASIC-80 maneje un NEXT fuera de servicio?
Es posible que una instrucción FOR omita el cuerpo del bucle, como lo permite BASIC-80 v.5, y aún permite instrucciones NEXT fuera de orden en la mayoría de los casos. Así es cómo:
Esto manejaría secuencias patológicas simples como la de la pregunta. No manejaría los casos en que el SIGUIENTE fue alcanzado por una declaración IF ... GOTO o un GOSUB. El código que hace eso es mucho peor que el código ya malo en la pregunta que no es irracional declarar simplemente que el intérprete no admitirá tales casos. Incluso podría ser permisible que el intérprete incendie dicho código.
fuente