Isso se baseia em uma palestra sobre compiladores que ouvi há algum tempo, mas, infelizmente, não me lembro quando ou onde.
Crie o compilador mais curto em qualquer idioma que possa se compilar. Segmente qualquer ISA razoável (68K, x86, MIPS, ARM, SPARC, IBM BAL etc.) que não tenha uma instrução "programa de compilação" (isso pode excluir algumas versões do VAX). Leia os programas de origem stdin
e imprima o código gerado para stdout
. Você pode usar a biblioteca C padrão para processamento de E / S e sequência (por exemplo, _printf
). Você não precisa compilar o idioma inteiro, apenas qualquer subconjunto que contenha o compilador (ou seja, apenas imprimir uma linguagem de montagem quine, embora impressionante, não conta como solução).
#!/usr/local/bin/tcc -run
na primeira linha do seu código C e executá-lo diretamente na linha de comando." Isso é bem legal.Respostas:
Subconjunto Haskell → C - 18926 caracteres
Isso compila um pequeno subconjunto de Haskell em C. Recursos que ele suporta:
Os maiores recursos ausentes são variáveis aninhadas (ou seja, sem lambda / let / where / case), verificação de tipo e classes de tipo. Os programas resultantes vazam memória e a autocompilação leva cerca de 200 megabytes no meu sistema (o coletor de lixo Boehm ajuda muito, mas somente se o compilador otimizar bem a recursão da cauda).
Para iniciar, remova o comentário das três primeiras linhas (não contadas na pontuação) e compile com o GHC. O compilador pega o código do subconjunto Haskell no stdin e produz o código C no stdout.
É longo, não porque a linguagem seja complexa, mas porque sou preguiçosa.
No entanto, atualmente é a soluçãomaiscurta.Não é mais. Acho que não vou ficar entediado neste fim de semana.fonte
Idioma personalizado → C - (7979)
Como a pergunta não impede a criação de meu próprio idioma, pensei em tentar.
O ambiente
O idioma tem acesso a duas pilhas, a pilha de chamadas e a pilha de dados. A pilha de chamadas é usada para as instruções de salto
{
e}
, enquanto a pilha de dados é usada pela maioria das outras instruções. A pilha de chamadas é opaca para os aplicativos.A pilha de dados pode conter três tipos diferentes de valores: inteiro, texto e vazio. Os números inteiros são do tipo intptr_t, enquanto o texto é armazenado como seqüências de caracteres em C.
o
^
instrução tem acesso ao The Array. A matriz é uma matriz constante de comprimento 17 de itens de texto. Você provavelmente deve ver a fonte do esquema de indexação, pois é um pouco instável.O idioma
O compilador
Este é o compilador. Não é jogado, e espero que possa ser reduzido consideravelmente. Deve ser possível usar o código da máquina diretamente e gerar um arquivo COM dos, mas ainda não cheguei a isso. Eu sei que isso se parece com um programa em C, mas a implementação real do compilador está desativada no final.
Atualmente, o compilador gera muitas informações de depuração no stderr.
Para compilar o código C gerado:
O conjunto de caracteres é necessário porque o compilador escapa caracteres especiais adicionando 128.
O Bootstrap
Para compilar o primeiro compilador, escrevi um intérprete python para a linguagem.
Juntando tudo
Supondo que você salvou o compilador como
compiler.cmp
e o bootstrap comobootstrap.py
, veja como construir o compilador e, em seguida, use-o para se compilar:Portanto, não sou muito programador em C, nem sou designer de idiomas; portanto, qualquer sugestão sobre como melhorar isso é bem-vinda!
Programas de exemplo
Olá Mundo!
fonte
Brainfuck estendido v0.9: 618 bytes (sem contar os feeds de linha desnecessários)
Esta é uma versão em golfe da minha primeira versão do EBF com suporte removido para comentários e código morto para suportar a remoção de variáveis.
Então, basicamente, é o BrainFuck com variáveis.
:x
cria variáveis x. O compilador sabe onde você está, então$y
irá produzir <'e>' para chegar a essa posição. Às vezes, você precisa de loops assimétricos e depois precisa informar ao compilador onde está@x
. Como EBF atual, ele compila com o Brainfuck.Essa primeira versão tinha apenas um nome de variável de caractere, mas eu usei essa versão para compilar a próxima versão e assim por diante até a versão atual que possui um conjunto impressionante de recursos. Ao compilar a partir do código-fonte do github, ele efetua o download do binário compilado manualmente para iniciar 6 versões ebf intermediárias, a fim de criar a versão atual.
Para inicializá-lo, você pode usar esse primeiro e único binário no repositório EBF git, que foi compilado manualmente com sucesso após algumas tentativas.
O Brainfuck possui algumas implementações de hardware, por exemplo. isso , isso e isso para citar alguns. Mas na maioria das vezes é tão fácil de implementar que você pode praticamente implementar um intérprete em qualquer sistema. Costumo brincar que Zozotez LISP , escrito em EBF, provavelmente é o LISP mais portátil de todos os tempos.
fonte
Hex, 550 bytes
Isso visa especificamente sistemas x86_64 executando Linux.
Nesse idioma, o código fonte consiste em bytes representados como dois dígitos hexadecimais em minúsculas
[0-9a-f][0-9a-f]
,. Esses bytes podem ter qualquer espaço em branco circundante, mas nada pode ocorrer entre os dígitos que formam um único byte. Além disso,'!'
é um caractere de comentário de linha: ele é ignorado, assim como tudo entre ele e o próximo'\n'
caractere.Se você entende o assembly x86, aqui está uma versão muito mais legível do código-fonte:
Se você extrair a linguagem assembly dos comentários abaixo
! Program Code
, poderá montar e executar o compilador Hex. Entrada e saída usam stdin e stdout.fonte
Hex
não é uma linguagem.Subconjunto Javascript -> Java, 504 bytes
fonte
05AB1E , 2 bytes (possivelmente não concorrente)
Experimente online!
Código na primeira linha de entrada, entradas nas linhas subseqüentes.
fonte
Madeira , 0 bytes
Lumber é uma linguagem de programação esotérica completa, inventada por Unrelated String escrita em apenas 10 linhas de código Prolog.
Não pode acreditar? Esses programas tiveram comentários removidos e tornam a fonte do intérprete mais concisa.
lumber_corefuncs.pl:
lumber_types.pl
lumber_corefuncs.pl recebe na biblioteca lumber_types; e, por sua vez, essa biblioteca define um módulo sem nada. Portanto, o Lumber não faz nada com entradas arbitrárias, que por sua vez são um autocompilador.
fonte
Zero , 0 bytes
fonte