Defina a máquina WABAC , Sherman. Esta pergunta é sobre o BASIC em geral, e o BASIC-80 da Microsoft em particular. Velha escola básica. Com números de linha.
Como (ou melhor) os intérpretes do BASIC da velha escola lidam com loops FOR ... NEXT quando o corpo do loop não foi executado e a instrução NEXT apareceu fora de ordem?
Uma instrução NEXT fora de ordem do tempo anterior:
Aqui está uma sub-rotina do jogo 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
e aqui está tudo, exceto o controle de fluxo redigido:
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
Isso traz de volta memórias não tão boas? Você pode ouvir Dijkstra rolando em seu túmulo?
Aqui está a parte interessante do que está acontecendo neste fragmento:
- O segundo loop FOR, uma vez que usa a mesma variável de loop, substitui o primeiro loop FOR
- Os dois loops FOR compartilham a mesma instrução NEXT
- A instrução NEXT do segundo loop FOR vem antes, na ordem de origem, mas depois, na ordem de execução
Você pode supor, então, que o intérprete, após iniciar um loop FOR, simplesmente executa instruções até que ocorra no loop NEXT. A ordem da declaração na fonte não importa neste caso. Mas vamos ver o que o manual basic80 tem a dizer sobre os loops FOR:
O manual do basic-80 diz "moo ..."
O corpo do loop é pulado se o valor inicial do loop multiplicar o sinal da etapa exceder o valor final multiplicar o sinal da etapa.
Portanto, o corpo do loop pode ser ignorado completamente.
Temos evidências, na forma de programas publicados, de que pelo menos algumas versões do BASIC estavam localizando dinamicamente suas declarações NEXT. Isso é fácil o suficiente quando o corpo do loop está sendo executado. No entanto, no caso em que o corpo da instrução FOR deve ser ignorado, como permite o BASIC-80, como o BASIC localizou a instrução NEXT, considerando que ela pode estar antes da instrução FOR na ordem de origem?
- A versão do BASIC usada em "101 Basic Computer Games" sempre executava o corpo do loop pelo menos uma vez?
- O BASIC-80 exigiu que a instrução NEXT de um loop FOR ocorresse após a instrução FOR, na ordem de origem?
PS: Sim, estou escrevendo um intérprete BASIC para o BASIC da velha escola. É uma doença.
fonte
NEXT
instrução começa em $ DCF9.Respostas:
Isso traz de volta os velhos tempos ...
Eu tenho uma cópia do livro, terceira impressão, 1975. Eu verifiquei sua listagem e ela não é original. No código fonte original, as instruções não têm espaços e as atribuições têm a palavra-chave LET. Por exemplo
O dialeto é DIGITAL PDP-11 BASIC (não Basic-plus ou BASIC-80). Por experiência, nem todos esses jogos funcionaram em todos os dialetos do BASIC. Tenho uma vaga lembrança de ter que recodificar vários desses jogos para fazê-los funcionar em outros dialetos. Esse tipo de estrutura horrível de loop era definitivamente um problema.
Eu tive experiência com mais de 20 dialetos diferentes do BASIC e posso dizer que essa era uma pergunta irritante na época. Havia 2 campos principais.
Em um campo, havia os intérpretes completos, que analisavam cada linha novamente a cada vez que eram vistos. Eles manipularam um loop FOR empurrando-o em uma pilha, identificada por sua variável, e depois varrendo a pilha em busca de uma correspondência com cada NEXT. Se eles pulassem um loop, teriam que procurar na fonte o NEXT. Alguns fizeram, outros não.
O outro campo eram os tokenizers ou semi-compiladores. Eles varriam todas as linhas antes da execução e as convertiam para algum tipo de formato interno. Eles também encontraram loops FOR / NEXT e verificaram a falta de alvos GOTO e GOSUB. DEC e BASIC-80 estavam neste campo, pelo que me lembro, mas faz muito tempo.
Em resposta às suas perguntas,
Espero que isto ajude. Essas são linguagens horríveis, mas se você precisar ...
fonte
Não tenho uma cópia da especificação para um desses intérpretes antigos do BASIC na minha frente (talvez nem exista), mas vou me expor e dizer que o intérprete do BASIC não executará um NEXT em um loop FOR que não pertence a ele, mesmo que a variável do loop tenha o mesmo nome.
Então, em outras palavras, no seu exemplo
quando a linha 235 é executada e vai para a linha 220, a linha 220 PRÓXIMO do loop FOR superior, não o inferior.
Isso é evidente na mensagem de erro "NEXT without FOR"; o intérprete BASIC rejeita qualquer PRÓXIMO para o qual não encontrou um FOR correspondente. Isso normalmente acontece quando você deixa seus PRÓXIMOS fora de ordem, como em
Então, para responder às suas perguntas com marcadores:
fonte
O que o BASIC "101 Jogos de Computador" faz
O dialeto do BASIC usado na edição de microcomputador "101 Computer Games" executará o corpo de um loop FOR ... NEXT pelo menos uma vez. Isso difere do BASIC-80 v. 5 .
Da p. i12 , listando exceções ao BASIC "normal":
PARA ... PASSO
Por esse motivo, esse dialeto do BASIC não tem problemas para localizar a instrução NEXT ou compartilhar a mesma instrução seguinte com várias instruções FOR. Nenhuma análise estática é necessária. Simplesmente execute todas as instruções à medida que elas ocorrerem, e você chegará à instrução NEXT, onde quer que esteja.
É possível para o BASIC-80 lidar com um NEXT fora de ordem?
É possível que uma instrução FOR ignore o corpo do loop, como permite o BASIC-80 v.5, e ainda permita instruções NEXT fora de ordem na maioria dos casos. Aqui está como:
Isso lidaria com seqüências patológicas simples, como a da questão. Ele não trataria dos casos em que o NEXT fosse alcançado por uma instrução IF ... GOTO ou um GOSUB. O código que faz isso é muito pior do que o já ruim na pergunta, e não é irracional declarar simples que o intérprete não dará suporte a esses casos. Pode até ser permitido ao intérprete incendiar esse código.
fonte