Devo usar um compilador de fonte para fonte ou tradicional para desenvolver minha própria linguagem de programação?

4

Estou realmente interessado em escrever minha própria linguagem de programação de alto nível para fins gerais, mas estou um pouco confuso.

Eu sei que Python e Ruby foram escritos em C, o que me faz pensar que, se eu quiser escrever meu próprio 'Python', é preferível usar um compilador de origem para fonte para traduzir todo o código-fonte. da minha linguagem para C, ou eu deveria ter como alvo a linguagem assembly?

O ponto é, eu sei que eu preciso cavar no Compiler Design e entender a Análise Lexical, e todo o processo de analisar o código e gerar tokens e uma linguagem intermediária e verificar a sintaxe e erros semânticos e gerar código de saída.

No entanto, como não sou especialista em programação de baixo nível / montagem, devo usar um compilador de origem para fonte? Que desafios posso enfrentar se eu tentar compilar meu idioma para a montagem? Quais desvantagens podem existir em usar um compilador de origem para origem? Quais aspectos específicos do domínio da minha situação devo considerar ao tomar essa decisão?

    
por Ericson Willians 27.05.2015 / 01:13
fonte

6 respostas

12

Vou me concentrar na sua questão central, já que outras coisas foram respondidas em outro lugar.

Should you target a higher level language or assembly?

Fazer o software é difícil. Embora fazer uma nova linguagem possa ser bem fácil, você precisa se ater a coisas simples e evitar coisas que são difíceis de implementar. Fazendo sua primeira língua tem o problema que você não sabe o que é o "dor para implementar" coisas. E vamos encarar isso, você não está querendo criar uma nova linguagem que possa apenas implementar calculadoras baseadas em console - as coisas interessantes não serão triviais para implementar.

Então, faça um favor e meta uma linguagem que você já conhece. Criar um novo idioma e um compilador funcional é bastante difícil sem adicionar "learn assembly" à lista de tarefas. Ao se preparar para o sucesso, é mais provável que você se divirta e aprenda com o esforço.

    
por 27.05.2015 / 05:08
fonte
5

Você deve considerar a compilação para C (consulte esta e que responde), ou para algumas outras linguagens (Java, Common Lisp, Ocaml, ou até mesmo uma mistura de Javascript & C - like HOP faz ...) Você também pode compilar a representação textual de LLVM bytecode ou use a biblioteca LLVM como seu back-end, ou (se tiver o GCC 5 ou melhor) use o libgccjit (para segmentar Representações internas do GCC e lucrar com as otimizações do GCC). Você também pode escolher alguns bytecode existentes (por exemplo, JVM, Ocaml, Neko, Parrot, ...) e compilá-los. E você também pode usar alguma biblioteca JIT como libjit , GNU lightning, asmjit etc ...

Lexing & análise não é o trabalho principal de um compilador ou intérprete. Eles são as partes simples. Um compilador é principalmente transformar (muitas vezes em várias passagens) algumas representações internas (em particular Abstract Syntax Trees , mas não apenas eles) do código-fonte que está compilando. Um intérprete freqüentemente está transformando algumas representações internas, em seguida, percorrendo outras (por exemplo, algum bytecode ou alguma AST normalizada). Jogue com a GCC -fdump-tree-all , e talvez com MELT (uma DSL tipo Lisp para inspecionar e / ou transformar as representações internas do GCC). A semântica da sua linguagem de programação é mais importante que a sintaxe.

Uma parte importante é gerenciamento de memória . Você quer um coletor de lixo (é uma parte essencial da sua semântica)? E quanto a digitar (estático ou dinâmico) & inferência de tipos ? Você lida com chamadas de última hora ? Você quer homoiconicity ? metaprogramação ? Você quer fechamentos (eles geralmente precisam de um GC)? Considere o GC conservador de Boehm e / ou leia o manual do GC .

Bootstrapping compiladores é importante. Veja também este e as referências que eu dei lá. Leia também esta & que responde explicando técnicas & detalhes práticos (e deve curar sua dor de cabeça sobre "Haskell escrito em Haskell", "Ocaml escrito em Ocaml", "MELT escrito em MELT", "CAIA escrito em CAIA", "GCC ou Clang / LLVM escrito em C ++"). / p>

Além disso, se você não conhece nenhuma delas, brinque com Ocaml, Common Lisp, Haskell ou Scheme (veja também SICP ). Leia o livro de Scott sobre Pragmática da Linguagem de Programação e o livro da Queinnec sobre Lisp em pequenos pedaços .

Certifique-se de que a implementação do seu idioma seja um software livre (em link você encontrará muitas outras implementações de linguagem - por exemplo, compiladores ou intérpretes).

    
por 27.05.2015 / 07:01
fonte
2

Eu fiz um trabalho profissional há três anos que usou a reflexão para entender uma interface .NET e fornecer alguma cola CIL para transformá-la em uma classe base. Foi um abridor de olhos para o nível de trabalho adicional necessário.

A maioria dos desenvolvedores de software, você se concentra nas rotas de sucesso e, se algo inesperado acontece, você pega uma exceção. Descobri que a rota de sucesso era inferior a 20% do trabalho. A estratégia usual de capturar exceções não funciona, pois as exceções ocorrem em tempo de execução, não quando você está gerando o código. Em vez disso, você precisa pensar e verificar se há qualquer combinação possível que possa quebrar seu código e, em seguida, apoiá-lo ou reprovar a compilação. Isso é muito diferente do desenvolvimento de aplicativos.

Se você deseja criar uma nova linguagem de programação e desejar que ela seja adotada por outras pessoas, sua melhor opção é encontrar um problema que não possa ser facilmente resolvido no momento. Se você criar uma nova linguagem de programação que forneça uma abordagem simples e limpa para resolver um problema complexo, as pessoas com esse problema terão um bom motivo para adotar seu idioma.

    
por 27.05.2015 / 09:10
fonte
1

Se você traduzir o que tiver para C, então você tem um sistema em funcionamento, onde quer que um compilador C esteja disponível. Que é basicamente em todo lugar. Você não precisa se preocupar com processadores diferentes, sistemas operacionais diferentes e todo o resto.

Você pode, em vez disso, compilar para o C ++, que hoje é quase tão comum quanto C, e lhe dá a vantagem de poder ocultar o trabalho que você precisa fazer em uma classe, em vez de repetir . Importante se o seu idioma tiver objetos que não podem ser traduzidos para primitivos C ou C ++.

    
por 27.05.2015 / 12:42
fonte
1

"Estou realmente interessado em escrever minha própria linguagem de programação de alto nível para fins gerais" Você é mesmo? Se você estiver verdadeiramente interessado e quiser criar sua própria linguagem completa com um compilador (nativo) para a experiência que provavelmente estaria interessada em ler sobre montagem e como a CPU funciona, você pode examinar a saída de montagem das linguagens de alto nível existentes para te dar uma ideia.

Uma fonte para o compilador nativo de código de máquina lhe dá muito mais liberdade para definir a semântica do seu idioma, se você compilar para C você está basicamente limitado ao modo C de fazer coisas, então no final você pode querer incluir tais como chamadas finais adequadas estarão fora do seu alcance. Construir um compilador nativo também é provável que seja uma experiência mais recompensadora e esclarecedora, enquanto compilar para C você está basicamente usando algo que alguém construiu C é uma linguagem muito complicada para algo para produzir (sua sintaxe é projetada para ser boa para humanos escrever não é fácil para as máquinas gerarem), você precisa se preocupar com a ordem de aninhamento das declarações, certificando-se de especificar informações suficientes para permitir que o compilador C otimize seu código efetivamente (por exemplo, usando restringir quando não houver aliasing de ponteiros). p>

Se você é pragmático e quer construir uma linguagem que será usada em um futuro próximo e você não está realmente interessado em construir o compilador tanto quanto ter um compilador de trabalho para sua linguagem então a fonte para fonte é a entretanto, esteja ciente de que sua linguagem se torna efetivamente um pré-processador (na verdade, um pré-processador é um bom lugar para começar a aprender sobre análise e análise lexical). De qualquer forma, se seu objetivo é distribuir seu idioma, tente evitar que ele se torne uma linguagem JAP (apenas outra linguagem de programação), que é uma linguagem que não oferece nada de novo e não é uma grande melhoria em relação às linguagens existentes.

    
por 02.07.2015 / 23:57
fonte
-2

Se você segmentar o LLVM, ainda precisará pré-processar e realmente compilar a entrada, mas a saída poderá estar em qualquer uma das saídas que o LLVM permitir, seja montagem ou JavaScript.

    
por 27.05.2015 / 12:48
fonte