Écrivez un programme qui prend un programme brainfuck et le compile en code machine exécutable. Vous pouvez cibler x86, x86_64, jvm (java bytecode) ou armv6, et utiliser l'un des formats exécutables suivants: ELF, a.out, fichier de classe, exe, com. L'exécutable devrait fonctionner sous Linux ou Windows (ou Java sur l'un ou l'autre).
Ni votre programme ni l'exécutable généré ne peuvent exécuter de programme externe (tel qu'un autre compilateur, assembleur ou interprète).
Le code le plus court gagne.
Réponses:
C,
866783 octetsÉtant donné que mon code génère un exécutable ELF 32 bits, je ne peux pas promettre que cela fonctionnera sur la configuration de tout le monde. Il a fallu suffisamment de modifications pour que l'exécutable arrête de faire des erreurs de segmentation sur mon ordinateur.
Pour toute personne essayant de lancer ceci:
Un programme Brainfuck est lu depuis stdin et l'ELF compilé est écrit vers stdout.
Non golfé
Dans la version non golfée du code, vous pouvez avoir une meilleure idée de ce qui se passe. Le tableau de caractères à la fin du code joué est un codage de l'ELF et de l'en-tête du programme dans le code non joué. Ce code montre également comment chaque instruction Brainfuck est traduite en bytecode.
BrainFuck à modification automatique
Afin d'économiser sur les octets, la bande de mon compilateur n'est pas allouée dans une
.bss
section ou quelque chose de fantaisiste comme ça. Au lieu de cela, la bande est de 30 000 octets nuls écrits directement après le code d'octets compilé du programme Brainfuck. Le savoir et savoir quel code d'octet est généré par mon compilateur signifie que vous pouvez générer ou modifier du code d'octet au moment de l'exécution. Une illustration simple de cette «fonctionnalité» est un programme Brainfuck qui définit sa propre valeur de sortie.Le programme quitte le bord gauche de la bande dans le code d'octet au point que le code de sortie est normalement défini sur 0. L'incrémentation de cet octet entraîne la mise à 1 du code de sortie au lieu de 0 lorsque le programme se termine. Avec persistance, cela pourrait être utilisé pour faire de la programmation au niveau du système dans Brainfuck.
la source
long long int
au lieu dechar
. Il y a certainement de la place pour moi de jouer certaines de mes déclarations de variables. Je vais voir combien je peux y arriver et mettre à jour ma réponse.Python, 1974 caractères
Vous trouverez ci-dessous les traductions du java bytecode. local 0 est un tableau d'octets représentant la bande, local 1 est le pointeur de données.
Les
xx xx
décalages permettent d'atteindre le support correspondant. # 2 estSystem.in
, # 3 estread()
, # 4 estSystem.out
, # 5 estwrite()
et # 6 estflush()
.Le préambule alloue un tableau de 30000 octets et initialise la position de la bande à 0.
L'enveloppe géante à la fin a été générée en compilant un mannequin
B.java
fichier avec du code pour l'un de chaque opcode (pour induire la génération des tables de constantes correctes et d'autres ordures), puis en effectuant une opération délicate sur celui-ci.Exécutez-le comme
Démonter avec
Je suis sûr qu'il pourrait être joué au golf encore plus. Je suis juste content que ça marche ...
la source
Code d'assemblage x86 16 bits, 104 octets
Ce code date de 2014, mais je viens de trouver la tâche.
la source