[ANN] Um compilador BASIC

54 views
Skip to first unread message

JuciÊ Andrade

unread,
Oct 26, 2019, 8:21:31 AM10/26/19
to Golang Brasil

Um compilador para a linguagem de programação BASIC.


Esta ferramenta entende o que é, nas palavras de David H. Ahl's, "o padrão de ouro para BASIC de microcomputadores: o MITS Altair 8K BASIC, Rev. 4.0 (ix)". Foi testado com cada um dos programas do livro best-seller "BASIC Computer Games".


Bruno Albuquerque

unread,
Oct 26, 2019, 9:05:48 AM10/26/19
to golang...@googlegroups.com
Legal, mas aparentemente é um transpiler e não um comprador, certo? Já que o pior do mesmo é código em C que então é compilado.

--

---
Você recebeu essa mensagem porque está inscrito no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para golang-brasi...@googlegroups.com.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/golang-brasil/8a3e239f-7f9b-4124-a00e-731f2fe5d1a3%40googlegroups.com.

Bruno Albuquerque

unread,
Oct 26, 2019, 9:07:07 AM10/26/19
to golang...@googlegroups.com
*sigh*

comprador = compilador
pior = output

JuciÊ Andrade

unread,
Oct 26, 2019, 10:15:04 AM10/26/19
to Golang Brasil
Oi, Bruno.

Sinta-se à vontade para classificar o programa como você achar melhor, ok? Sem problema nenhum.

Eu particularmente não aceito a distinção feita entre "compiler" e "transpiler", porque é uma distinção vazia, na minha opinião. Essas ferramentas leem código escrito numa linguagem e gerar código escrito numa linguagem (que pode até ser a mesma).

No caso desta ferramenta, o padrão de entrada é a linguagem BASIC e o padrão de saída é a linguagem C. Poderia ser um arquivo OBJ padrão Windows, um arquivo .o do Linux, poderia ser Assembler Intel 80386, poderia ser Assembler para o ARM, poderia ser bytecode Java, ou uma infinidade de outras coisas. Então a gente precisa considerar o que vem depois.

Se eu gerar código Assembly do 386 eu vou precisar de um Assembler 386. Se eu gerar um OBJ do 386 eu vou precisar de um linker que entenda esse formato. Se eu gerar um .HEX, que é um dos níveis mais baixos, eu vou precisar de uma CPU que seja capaz de executar o binário extraído de dentro dele. Ou seja, você sempre tem que pensar na etapa seguinte.

E por que motivo eu escolhi fazer a saída em C? Porque tendo em vista o objetivo do meu projeto, considerei esse o formato de saída mais útil. Se eu adotasse qualquer outro formato eu estaria restringindo o público alvo. Qual é a sua máquina? Eu não sei. Se eu tivesse escolhido a saída em Assembler do 386, por exemplo, seria inútil nas máquinas com ARM, entende?

Para cada um dos formatos de saída possíveis existe o mesmo problema. Por outro lado, o C é praticamente universal. É fácil obter um compilador C em qualquer plataforma que você tiver. Já com Assembler, por exemplo, não é tão fácil. Mesmo dentro de uma arquitetura há diversos formatos diferentes. Já o C é padronizado, o mesmo fonte serve em qualquer lugar.

Obrigado pelo seu interesse.
Um grande abraço.

On Saturday, October 26, 2019 at 10:05:48 AM UTC-3, Bruno Al

Bruno Albuquerque

unread,
Oct 26, 2019, 6:36:49 PM10/26/19
to golang...@googlegroups.com
Compilador gera um executável/biblioteca para uma plataforma específica. Um transpiler gera código em uma outra linguagem que então é compilada em um executável/biblioteca pra uma plataforma específica. Essas são as definições formais e embora você obviamente esteja livre pra não aceitá-las, as outras pessoas muito provavelmente não concordarão com você. :)

--

---
Você recebeu essa mensagem porque está inscrito no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para golang-brasi...@googlegroups.com.

JuciÊ Andrade

unread,
Oct 26, 2019, 7:08:11 PM10/26/19
to Golang Brasil

"A compiler is a computer program that translates computer code written in one programming language (the source language) into another language (the target language)."

Eu já entendi o seu argumento, Bruno. Obrigado.

Everton Marques

unread,
Oct 26, 2019, 10:50:15 PM10/26/19
to golang...@googlegroups.com
Juciê,

Também escrevi um compilador parecido, mas de BASIC para Go:


De repente a gente pode trocar umas ideias.

Abraços,
Everton


--

---
Você recebeu essa mensagem porque está inscrito no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para golang-brasi...@googlegroups.com.

JuciÊ Andrade

unread,
Oct 27, 2019, 6:28:54 AM10/27/19
to golang...@googlegroups.com

Everton, estou aqui navegando nos teus fontes, contente feito um moleque em loja de doces. Que bacana, cara! Estou vendo os caminhos que você trilhou, as opções que você fez. É uma sensação gostosa essa.

Nem sei por onde eu começo, Everton. Se você morasse aqui perto eu ia te chamar pra tomar um café na padaria e conversar um monte.

Bom, primeiro, "Caraka, Muleke!". É grande o seu projeto, hein! Bem mais ambicioso que o meu. Vi que além do compilador você também teve a preocupação de fazer uma parte que interpretasse linha por linha. Eu confesso que nem pensei nisso. A linguagem que o seu compilador entende é maior. Os computadores de 50 anos atrás nem tinham monitor de vídeo, então não havia comando para mover o cursor na tela, por exemplo. O meu compilador não abrange isso. Já o seu compilador aceita um BASIC mais recente, mais completo, tem esses comandos e muitos outros. O meu compilador é um projeto bem mais modesto que o seu.

Vi também que você escreveu uma grande quantidade de testes, exercitando cada pedacinho do seu compilador, como manda o figurino, coisa que eu também não fiz. Eu sou preguiçoso, viu Everton, então só peguei um monte de programinhas prontos que eu achei na Internet e fui submetendo um por um ao processo de compilação pra ver no que dava. Eu tinha os cento e poucos programas do livro do David Ahl. Comecei do menorzinho e, à medida que ia resolvendo os problemas, ia caminhando em direção aos maiores. Deu certo. Só tem que, quando algo não funcionava eu tinha que vasculhar pra descobrir onde estava o problema, porque eu não tinha ideia onde procurar: se era no lexer, ou no parser, ou em qualquer outra parte. Já se eu tivesse escrito os testes direitinho, daria pra saber exatamente em qual parte estaria o problema. Bom, toda abordagem tem seus prós e contras, não é verdade?

Você sim, vai entender a minha dor. É difícil fazer a parte de leitura do código em BASIC, hein? Fiquei surpreso, eu achei que seria mais fácil. Esse BASIC antigo foi pensado pelo John Kemeny para ser bem flexível, de modo a deixar os estudantes de programação à vontade. Então o programador não era obrigado a separar as palavras, nem botar ponto-e-vírgula nos lugares certos. Junte a isso o fato que os computadores daquela época tinham uma quantidade de memória exígua e que qualquer pontuação nos fontes ocuparia um espaço precioso. Resultado: muitos programas em BASIC são difíceis de ler. É difícil pra gente e pros compiladores também. Inúmeras vezes o meu analisador léxico enroscava em alguma situação onde ele entendia que era uma coisa e na verdade era outra. Eu lembro que só pra resolver onde terminava o nome das variáveis e começava a parte seguinte eu apanhei bastante.

Quando o meu analisador léxico já estava conseguindo engolir todos os programas em BASIC sem engasgar eu comecei a trabalhar no parser, o analisador sintático. Pensei que seria mais fácil. Ah, tolinho! Aí foi que a porca torceu o rabo. Sempre que eu resolvia um problema eu pensava "agora sim. Agora vai funcionar pra todos." Que nada. Resolvia uma situação e se enroscava já no programa seguinte.

Quando o lexer e o parser estavam funcionando eu brinquei um bocado. Vi que você fez o mesmo. Eu também coloquei contadores para fazer uma estatística de quantas vezes aparecia cada uma das situações nos fontes analisados. O que mais me surpreendia era que tudo que eu pensava que não seria possível, que não seria permitido, era. Sempre tinha um programador que ia lá e fazia o que não devia, só pra atrapalhar a minha vida. "O quê? Dois FOR usando o mesmo NEXT? Tá maluco? Pode." "GOTO pra uma linha que não existe? Pode." Que raiva! Esse Kemeny era um louco! 8^)

Depois que brinquei muito de analisar as estatísticas comecei a escrever o gerador de código. Eu resolvi que cada nó da árvore sintática deveria saber como gerar o código para a sua parte. Então, por exemplo, o nó astLit tinha um método "generateC" que gerava a string no formato de um fonte em C, o nó cmdFor gerava o código em C para o comando FOR, e assim por diante. Ajudou por um lado e atrapalhou por outro. Ajudou porque ficava fácil de encontrar onde estava o método que gerava o código errado. Atrapalhou porque o gerador de código na verdade estava espalhado por todo lado! No fim eu resolvi fazer uma mudança grande e juntei todos estes pedacinhos dentro de um módulo só, o genC.go . Deu trabalho.

Olha, eu devo confessar que foi muito divertido. É emocionante saber que aqueles programas de 50 anos atrás estão rodando ali na sua máquina porque você resolveu cada um dos problemas. Uma sensação muito boa. Foi trabalhoso, mas o resultado valeu. E você, meu novo amigo Everton, sabe exatamente do que estou falando.

Obrigado por compartilhar o seu projeto. Estou lendo aqui, me deliciando.

Um grande abraço!

Ronoaldo José de Lana Pereira

unread,
Oct 28, 2019, 11:28:54 AM10/28/19
to golang...@googlegroups.com
Senhores, eu já tive a intenção (e infelizmente não passou disso) de implementar alguma forma de rodar apps Classic ASP em um server HTTP Go. Sim, é isso mesmo, loucura pura... Meu objetivo primário era o entendimento de interpretadores e compiladores, para ir ampliando meus conhecimentos, e de quebra eu poderia portar um app legado para uma runtime mais moderna, facilitando inclusive a migração do mesmo. Não sei o quanto dos projetos já implementados aqui poderiam ser aproveitados para tentar isso, mas o que acham?

--

---
Você recebeu essa mensagem porque está inscrito no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para golang-brasi...@googlegroups.com.


--
Ronoaldo Pereira

JuciÊ Andrade

unread,
Oct 29, 2019, 8:29:22 AM10/29/19
to Golang Brasil
Vamos movimentar esse forum, rapaziada! Esse aqui é o tipo de assunto em que todo mundo tem uma opinião. Põe pra fora, solta essa franga! O pior que pode acontecer é alguém discordar de você. E daí? Não vão te arrancar um pedaço. Isso é um grupo de DISCUSSÃO, ok? É pra gente colocar e debater ideias. Vamos botar essa timidez de lado, por favor.

Oi, Ronoaldo. Tudo bem com você? Vou te dar a minha opinião.

É possível sim fazer o que você quer, e se você percebeu a oportunidade, vai fundo. O mais difícil seria fazer algo 100% compatível com o restante, mas se você puder adotar uma abordagem gradual, onde vai aumentando a abrangência, creio que seja possível.

Olha, para conseguir o que você pretende tem várias etapas. Primeiro você precisa conhecer algumas técnicas.

Não recomendo que você use o meu código como base pro seu software porque eu escrevi de uma maneira muito displicente. Eu fiz sem muita preocupação com arquitetura, em fazer o treco reutilizável. Nem comentários tem nesses fontes. Já o código do Everton é mais explicado, tem testes e tudo, só que em contrapartida é maior, tem mais coisas pra entender. Talvez ele próprio queira se manifestar a dar a opinião dele.

Em vez de tentar reaproveitar essas partes, recomendo que você aprenda as técnicas lendo um bom livro. É mais fácil aprender lendo um livro que lendo software, concorda? Tendo o conhecimento e um tantinho de prática você vai ver que não é nenhum bicho de sete cabeças. Você mesmo vai conseguir escrever o que for necessário.

A maioria das pessoas que se interessa pelo assunto "compiladores" já começa pelo clássico "dragon book", do Aho/Sethi/Ullman. Daí elas caem do cavalo! NÃO FAÇA ISSO. O dragon book é um livro muito abrangente, complicado, e voltado para pessoas com formação matemática. Quem olha aquele livro pensa "treco complicado esse. Não é pra mim, não".

Para com isso, meu filho. Olha, leia o livrinho do Niklaus Wirth, que é um começo muito melhor:


É um livro pequeno, de cento e poucas páginas, muito fácil de ler e entender, extremamente bem feito e direto ao que interessa, sem teorias sobre conjuntos nem notação matemática cabulosa. Quem não sabe quem é o Niklaus Wirth, se informe.

Depois, se um dia você quiser se aprofundar no assunto, aí sim você lê o dragon book e outros tantos. Pra começo não.

Te garanto que depois de ler o livrinho você vai olhar a tarefa que tem adiante e vai pensar "Deixa, que é nóiz!"

Abraço e boa sorte no seu projeto. No mínimo você vai aprender um montão, independente do resultado final.

Alex Sandro Garzao

unread,
Nov 26, 2019, 2:26:58 PM11/26/19
to golang...@googlegroups.com
Oi pessoal,

Antes de tudo, parabéns pelo projeto de vocês!

Confesso que não vi os fontes, mas pela iniciativa de vocês, e pelo tipo de projeto (compiladores), já curti hehehe

Eu já desenvolvi alguns "toy compilers", por vários motivos (interesse pessoal, trabalhos de aula, ...). Alguns fiz tudo "from scratch", tipo, só usando a standard library da linguagem. Outros, usei geradores de parsers como Lex/Yacc, Flex/Bison, JavaCC e AntLR.

Bom, o que eu gostaria é de comentar sobre os geradores de parsers. Não estou argumentando que os projetos devem ou não utilizar um gerador de parser, mas o ponto é que, dependendo do objetivo do projeto, usar um gerador de parsers acelera bastante o desenvolvimento. Toda esta parte de análise léxica e sintática, no geral, é abstraída pelos geradores, e o desenvolvimento do compilador, em si, praticamente inicia na fase de análise semântica, geração de código, ...

Enfim, eu só queria colocar este ponto. Se vocês curtem entender este parte de análise léxica/sintática, show de bola, façam tudo "na munheca", sem usar libs e/ou geradores. Mas, caso o que interesse para vocês seja mais o resultado do projeto como um todo, vale dar uma olhada em algum gerador.

Abraços! E parabéns novamente!


--

---
Você recebeu essa mensagem porque está inscrito no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para golang-brasi...@googlegroups.com.


--
Atenciosamente,

------------------------------------------------------------------
Alex Sandro Garzão
E-mail: alexg...@gmail.com
Fone: (51) 98165 0486
LinkedIn: http://br.linkedin.com/in/alexgarzao/
------------------------------------------------------------------

Everton Marques

unread,
Nov 26, 2019, 6:56:19 PM11/26/19
to golang...@googlegroups.com
Alex,

Aqui foi usado goyacc pra gerar o parser:


O analisador léxico está manual mesmo, mas ficou bem mais complexo do que eu gostaria, infelizmente.

Abraços,
Everton


JuciÊ Andrade

unread,
Nov 27, 2019, 9:52:57 AM11/27/19
to Golang Brasil
Alex, obrigado pelo apoio. O meu compilador foi feito `a mao mesmo, porque eu fiz so' pela farra, sem pressa.

Everton, as regrinhas do BASIC foram feitas para facilitar pro usuario final. O Kemeny partiu do principio que o usuario seria um semi leigo tentando usar um computador. E' diferente de COBOL, por exemplo, onde parte-se da suposicao que o usuario e' um programador profissional. O COBOL exige espacos separando as palavras, tudo nas colunas e divisoes certinhas, o BASIC nao. Entao no BASIC o analisador lexico tem que fazer magica pra adivinhar onde as palavras terminam. Tambem apanhei bastante.


Reply all
Reply to author
Forward
0 new messages