Alguém me enviou isso e afirmou que é um olá, mundo em Brainfuck (e espero que sim ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Eu sei o básico que funciona movendo um ponteiro e aumentando e diminuindo coisas ...
Mesmo assim, quero saber como isso realmente funciona? Como ele imprime qualquer coisa na tela em primeiro lugar? Como ele codifica o texto? Eu não entendo nada...
brainfuck
esoteric-languages
speeder
fonte
fonte
Respostas:
1. Básico
Para entender o Brainfuck, você deve imaginar um conjunto infinito de células inicializadas por
0
cada um.Quando o programa Brainfuck é iniciado, ele aponta para qualquer célula.
Se você mover o ponteiro para a direita,
>
você está movendo o ponteiro da célula X para a célula X + 1Se você aumentar o valor da célula,
+
obterá:Se você aumentar o valor da célula novamente,
+
obterá:Se você diminuir o valor da célula,
-
obterá:Se você mover o ponteiro para a esquerda,
<
você está movendo o ponteiro da célula X para a célula X-12. Entrada
Para ler caracteres, você usa vírgula
,
. O que ele faz é: Ler o caractere da entrada padrão e gravar seu código ASCII decimal na célula real.Dê uma olhada na tabela ASCII . Por exemplo, código decimal de
!
is33
, whilea
is97
.Bem, vamos imaginar que a memória do seu programa BF seja semelhante a:
Assumindo que a entrada padrão representa
a
, se você usar o,
operador vírgula , o que BF faz é ler oa
código ASCII decimal97
para a memória:Você geralmente quer pensar dessa maneira, mas a verdade é um pouco mais complexa. A verdade é que o BF não lê um caractere, mas um byte (seja ele qual for). Deixe-me mostrar um exemplo:
Em linux
estampas:
que é um caráter polonês específico. Este caractere não é codificado pela codificação ASCII. Nesse caso, é a codificação UTF-8, então costumava ocupar mais de um byte na memória do computador. Podemos provar isso fazendo um despejo hexadecimal:
que mostra:
Zeros são compensados.
82
é o primeiro e oc5
segundo byte representandoł
(para que possamos lê-los).|..|
é a representação gráfica que não é possível neste caso.Bem, se você passar
ł
como entrada para o seu programa BF que lê byte único, a memória do programa será semelhante a:Porque
197
? Bem,197
decimal éc5
hexadecimal. Parece familiar? Claro. É o primeiro byte deł
!3. Saída
Para imprimir o caractere, você usa o ponto.
.
O que ele faz é: Assumindo que tratamos o valor real da célula como código ASCII decimal, imprime o caractere correspondente na saída padrão.Bem, vamos imaginar que a memória do seu programa BF seja semelhante a:
Se você usar o operador ponto (.) Agora, o que BF faz é imprimir:
Porque o
a
código decimal em ASCII é97
.Então, por exemplo, programa BF como este (97 mais 2 pontos):
Aumentará o valor da célula que aponta para até 97 e imprime 2 vezes.
4. Loops
Em BF, o loop consiste no início
[
e no final do loop]
. Você pode pensar que é como em C / C ++, onde a condição é o valor real da célula.Dê uma olhada no programa BF abaixo:
++
incrementa o valor real da célula duas vezes:E
[]
é assimwhile(2) {}
, então é um loop infinito.Digamos que não queremos que esse loop seja infinito. Podemos fazer por exemplo:
Portanto, cada vez que um loop faz um loop, ele diminui o valor real da célula. Assim que o valor real da célula
0
terminar o loop:Vamos considerar outro exemplo de loop finito:
Este exemplo mostra que não devemos terminar o loop na célula em que o loop começou:
No entanto, é uma boa prática terminar onde começamos. Por quê ? Porque se o loop termina em outra célula, ele começou, não podemos assumir onde o ponteiro da célula estará. Para ser honesto, essa prática torna a foda cerebral menos foda.
fonte
A Wikipedia tem uma versão comentada do código.
Para responder às suas perguntas, o
,
e.
caracteres são usados para E / S. O texto é ASCII.O artigo da Wikipedia também continua com um pouco mais de profundidade.
fonte
,
e.
é usado para E / S, da mesma forma que o C imprime usandoputchar
. É um detalhe de implementação tratado pelo compilador.Para responder à pergunta de como ele sabe o que imprimir, adicionei o cálculo dos valores ASCII à direita do código onde ocorre a impressão:
fonte
Brainfuck tem o mesmo nome. Ele usa apenas 8 caracteres, o
> [ . ] , - +
que o torna a linguagem de programação mais rápida de aprender, mas mais difícil de implementar e entender. … .E faz você finalmente acabar fodendo seu cérebro.Ele armazena valores na matriz: [72] [101] [108] [111]
deixe, inicialmente o ponteiro apontando para a célula 1 da matriz:
>
mova o ponteiro para a direita em 1<
mova o ponteiro para a esquerda em 1+
incrementa o valor da célula em 1-
incrementa o valor do elemento em 1.
imprime o valor da célula atual.,
leva a entrada para a célula atual.[ ]
loop, +++ [-] contador de 3 contagens bcz tem 3 ′ + 'antes dele, e - diminui a variável de contagem em 1 valor.os valores armazenados nas células são valores ascii:
portanto, referindo-se ao array acima: [72] [101] [108] [108] [111] se você combinar os valores ASCII, você descobrirá que é Hello Writetern
Parabéns! você aprendeu a sintaxe do BF
——- Algo mais ———
vamos fazer nosso primeiro programa, isto é, Hello World , após o qual você poderá escrever seu nome nesta linguagem.
quebrando em pedaços:
Faz uma matriz de 4 células (número de>) e define um contador de 10 algo como: —- código psuedo—-
porque o valor do contador é armazenado na célula 0 e> move para a célula 1 atualiza seu valor em + 7> move para a célula 2 incrementa 10 para seu valor anterior e assim por diante….
<<<
retorna para a célula 0 e diminui seu valor em 1portanto, após a conclusão do loop, temos o array: [70,100,30,10]
move para o primeiro elemento e incrementa seu valor em 2 (dois '+') e então imprime ('.') caractere com esse valor ascii. por exemplo, em python: chr (70 + 2) # imprime 'H'
move-se para o segundo incremento de célula 1 para seu valor 100 + 1 e imprime ('.') seu valor, ou seja, chr (101) chr (101) #impressa 'e' agora não há> ou <na próxima peça, então assume o valor presente do último elemento e incremento apenas para ele
elemento mais recente = 101, portanto, 101 + 7 e imprime-o duas vezes (pois há dois '..') chr (108) #prints l duas vezes pode ser usado como
——— Onde é usado? ——-
É apenas uma linguagem de piada feita para desafiar os programadores e não é usada em praticamente qualquer lugar.
fonte
Todas as respostas são completas, mas falta um pequeno detalhe: impressão. Ao construir o seu tradutor de brainfuck, você também considera o personagem
.
, isto é realmente o que uma declaração impressa se parece no brainfuck. Portanto, o que seu tradutor cerebral deve fazer é, sempre que encontrar um.
caractere, ele imprimirá o byte atualmente apontado.Exemplo:
suponha que você tenha ->
char *ptr = [0] [0] [0] [97] [0]
... se esta é uma afirmação de brainfuck:>>>.
seu ponteiro deve ser movido 3 espaços para a direita em:,[97]
então agora*ptr = 97
, depois de fazer isso, seu tradutor encontra um.
, ele deve então chamarou qualquer instrução de impressão equivalente para imprimir o byte apontado atualmente, que tem o valor 97 e a letra
a
será então impressa nostd_output
.fonte
Acho que você está perguntando como o Brainfuck sabe o que fazer com todo o código. Há um analisador escrito em uma linguagem de nível superior, como Python, para interpretar o que significa um ponto ou o que um sinal de adição significa no código.
Assim, o analisador lerá seu código linha por linha e dirá ok, há um símbolo>, então eu tenho que avançar a localização da memória, o código é simplesmente, if (conteúdo nessa localização da memória) ==>, memlocation = + memlocation que é escrito em uma linguagem de nível superior, da mesma forma se (conteúdo na localização da memória) == ".", então imprima (conteúdo da localização da memória).
Espero que esteja entendido. tc
fonte