Interpretador brainfuck

Para a pessoa jovem que cansou do brain rot e está em busca de coisas mais pesadas, talvez brainfuck seja a solução: uma linguagem esotérica que, com apenas 8 instruções, implementa uma Máquina de Turing completa. Isso significa que, com persistência e criatividade, a pessoa jovem pode implementar toda sorte de algoritmo!

Simulador ou interpretador brainfuck

programa:
| |
saída

Definição da linguagem

A linguagem possui apenas 8 instruções:

instrução descrição
+ soma um na célula de memória atual; quando a célula está com 255, somar um volta para 0 (comportamento circular).
- subtrai um na célula de memória atual; quando a célula está com 0, subtrair um volta para 255 (comportamento circular).
> avança para a próxima célula de memória; quando a última célula está selecionada, avançar um volta para a célula 0 (comportamento circular).
< recua para a célula de memória anterior; quando a primeira célula está selecionada, voltar um volta para a última célula (comportamento circular).
. escreve o conteúdo da célula de memória atual na saída (output), em formato hexa decimal.
, lê um byte para a célula de memória atual da entrada (input), em formato hexadecimal.
[ se a célula de memória atual não for zero, repete os comandos dentro do bloco que se encerra com ]. se for zero, pula para a instrução após o ] de fechamento do loop. loops aninhados são aceitos!
] encerra um bloco aberto por [.

Com um conjunto pequeno de instruções, até que é fácil criar um interpretador para a linguagem, mas escrever programas já é outra história — não é a toa o nome brainfuck, rssss. Dá uma olhada no programa de exemplo, sem os comentários...

+++++
>+++++++
>------
>,
<<<.
>.
>.
>.
[
    -
    >++++++++++
    [
        -
        .
    ]
    <
.
]           
    

Note que qualquer caráter diferente dos presentes na tabela de instruções devem ser ignorados pelo interpretador.

Sobre o Interpretador

A máquina virtual do interpretador tem 8 bits, ou seja, cada célula de memória tem 8 bits de tamanho. A memória do simulador desta página tem 5000 células de memória, mas este valor pode ser alterado via argumento do construtor da classe.

O interpretador é uma máquina que precisa controlar 2 ponteiros: o de memória e o de instruções. O ponteiro de memória só pode ser afetado quando o interpretador executa instruções de deslocamento de células: '>' (avançar um endereço) e '<' (recuar um endereço). O ponteiro de instruções, por outro lado, é afetado após a execução de qualquer instrução:

Com isso em conta, o modelo de trabalho do interpretador pode ser esquematizado assim:

  1. leia a próxima instrução do programa;
  2. se não existe instrução, encerre o programa;
  3. senão, execute a instrução;
  4. volte para o item 1.

É importante observar que as instruções de entrada (',') e saída ('.') só trabalham com valores em hexadecimal com tamanho de até 1 byte.

Implementação em javascript

O interpretador brainfuck desta página foi implementado como uma classe javascript, InterpretadorBrainfuck, no arquivo brainfuck.js. O construtor da classe apresenta os seguintes parâmetros:

parâmetro obrigatório descrição
fonte sim Valor string com o código fonte em brainfuck.
tamanho_memoria sim Quantidade de células de memória. No simulador desta página, estou considerando 5000 bytes.
on_output não Evento para tratar a execução da instrução de saída.
on_input não Evento para tratar a execução da instrução de entrada. No simulador desta página, o botão "entrar" é habilitado, para permitir ao usuário entrar com um byte.

Otimização do código-fonte

Para reduzir o tamanho do programa executado, todo caráter não pertencente à linguagem brainfuck é excluído.

Instrução de entrada (input)

Ao encontrar a instrução de entrada ',', o interpretador pausa a execução até que o usuário entre com um byte em hexadecimal.

O valor deve digitado como hexadecimal na caixa de texto 'entrada (hex)'. Para confirmar, o usuário deve clicar em 'entrar', que reativa o funcionamento do interpretador.

Sempre que se clica em 'entrar', o valor da caixa de texto 'entrada (hex)' é apagado.

Instrução de saída (output)

A instrução de saída '.' grava valor na célula atual na caixa de texto saída, em formato hexadecimal.

Tique-taque

Neste simulador, uma instrução brainfuck é executada a cada X ms. O valor de X deve ser informado na caixa de texto 'tempo (ms)', que aceita entre 5 e 2000 ms.

Verificação de loop

Antes de iniciar a execução do programa, o interpretador verifica se todos os loops estão bem formados, isto é, se foram abertos com um '[' e fechados com um ']'.