O que aprendi (até agora) criando um compilador

Primeiro ponto para deixar claro, não sou um cientista da computação.

Em 2017 eu me aventurei com criptomoedas e me apaixonei pelo Burstcoin. Ele tem a possibilidade de programação contratos inteligentes na blockchain. Na época não consegui criar um contrato, pois só havia uma ferramenta para programação e o código deveria ser programado em um tipo específico de assembly.

O tempo passou e agora em 2021 resolvi me aventurar novamente. Já há uma ferramenta para programação em alto nível (Blocktalk) mas entrei pelo desafio. Consegui fazer meu primeiro contrato inteligente (em assembly) e senti a dificuldade de converter um simples código em C para as instruções de máquina.

Num rompante de coragem e desconhecimento do assunto resolvi que iria criar um compilador. Peguei um projeto interessante (CaptCC) de um protótipo de compilador de C escrito em Javascript e fiquei uma semana batendo cabeça no código, entre entender e estudar o assunto. Cheguei a desistir, mas dois dias depois percebi que minha abordagem estava errada. Eu não conseguiria fazer algo bom que não fosse com funções recursivas.

Vários aqui já sabem o que é uma função recursiva e o princípio de funcionamento com o tradicional exemplo de calcular o fatorial. Mas se vc tem uma série de objetos de tipos diferentes, o buraco é muito mais embaixo. Quebrei a cabeça vários dias também pra descobrir que se começa pelo final em uma função recursiva.

É muito interessante esse salto, de onde uma linguagem de programação se assemelha a uma linguagem humana para passar para uma corrente de instruções de computadores. Entendi um pouco mais sobre a beleza do pensamento humano, comunicação e linguagem. Cada pessoa é como uma função recursiva, onde cada frase é uma sentença e cada palavra tem um significado semelhante mas distinto entre as pessoas. A vivência de cada um, a cada momento, altera um pouco mais do que será a pessoa no futuro. Talvez seja por isso que o ser humano gasta seus 10-12 primeiros anos de vida pra conseguir pensar “por si mesmo”, e talvez por isso a mudança a si próprio precisa ser construída dia após dia.

Quando parecia que eu estava próximo do final, comecei alguns testes e descobri comportamentos estranhos do compilador. Entendi então a necessidade de criar uma série de testes que fossem realizados a cada alteração, de modo a garantir que consertar um ponto não quebre algo inesperado. Os test cases me tomaram um grande tempo para fazer centenas de combinações possível, mas sem eles certamente o resultado não seria satisfatório. Parece que quando se trata de função recursiva, não há dois “jeitos certos” de fazer!

Por fim, o projeto (opensource, claro) está disponível no GitHub - deleterium/BurstAT-Compiler: Parser and compiler for arithmetic operations: C-like to BursAT assembly , onde já recebi uma contribuição estilosa do @yet1dev . Também é mais fácil ir direto na github-pages pra quem quiser rodar já no seu navegador:

Obrigado pela atenção, pela paciência e se alguém da área se interessar, poderia me explicar se é (muito) necessário mudar a ordem das operações de mesma precedência para “esquerda para direita”? Ex: a=b/c/d atualmente está compilando para a=b/(c/d), ou seja da direita para a esquerda.

9 Curtidas

Querendo ou não um microprocessador é uma espécie de cérebro, mas trocando os impulsos elétricos por zeros e uns. Se você for ver, as linguagens de programação funcionam em um computador de maneira semelhante aos idiomas no nosso cérebro. Existem conceitos muito mais abstratos na linguagem humana, though. Afinal, um computador só precisa saber fazer o que lhe foi ordenado, enquanto nosso cérebro faz milhares de tarefas simultaneamente, desde processar cálculos complexos até manter o pulso e a respiração “em segundo plano”.

1 Curtida

é só o caso da linguagem que vc ta usando esse comportamento? pq acredito que esse seja o jeito certo de ler essa equação. Na verdade escrever sem os parenteses é errado e pode confundir até mesmo calculadoras. O uso dos parênteses é essencial na matemática para determinar quais “partes” da equação serão resolvidas.

1 Curtida

O link em “Usage” no README.md esta quebrado.

1 Curtida