BFPY
Récemment, il y a eu plusieurs sujets de création de langages de programmation (avec Acid et Seventh). Quand nohar a décidé de créer Pulp, un environnement d'exécution pour faciliter la compilation de nos langages, je me suis un peu penché sur le monde de la compilation et de l'informatique bas niveau. D'ordinaire, je suis plutôt tourné vers le haut niveau, mais étonnamment cela m'a beaucoup intéressé. Du coup depuis quelques semaines je joue avec le bytecode de python, j'essaye d'écrire des programmes de différents paradigmes en bytecode pour trouver le meilleur jeu d'instruction, etc…
Et puis, dans le sujet de Pulp, quelqu'un a parlé de Brainfuck, et je me suis dit qu'il ferait une bonne VM (pas vraiment performant avec les 10 millions de + qu'il faut pour charger un seul int, mais c'est marrant). Du coup je me suis lancé dans la création d'un transpilateur Python vers Brainfuck.
Je procède très simplement: je désassemble la fonction que je veux transpiler, et je traduis chaque instruction en Brainfuck, en utilisant la mémoire comme une pile.
Exemple
Imaginons que je veuille transpiler une fonction foo
définie par lambda x, y, z: x * 6 + y - z
et l'appeler avec les arguments 8, 4 et 5 (pour obtenir 47 donc):
1 2 3 4 5 6 7 8 | from bfpy import Bytecode, Machine foo = lambda x, y, z: x * 6 + y - z bf = Bytecode.from_function(foo, x=8, y=4, z=5) print(bf) # bytecode brainfuck obtenu vm = Machine(bf) vm.run() print(vm.current) # affiche l'élément en haut de la pile, ici 47 |
Ce code m'affiche ceci lorsque je l'exécute:
1 2 | >++++++++>++++++[-<[>>+>+<<<-]>>>[<<<+>>>-]<<]<[-]>>[-<<+>>]<<>++++[<+>-]<>+++++[<->-]< 47 |
Ce qu'il reste à faire
- Implémenter un système de type en mémoire, de sorte à ce que la taille d'un élément de la pile ne soit pas restreint à un octet, mais puisse s'étendre sur plusieurs (notamment pour les chaines de caractère).
- Implémenter un environnement dans la mémoire BF et un algorithme qui trouve un endroit libre dans la mémoire pour stocker des objets Python (actuellement l'environnement est un dictionnaire à part entière).
- Compléter la traduction des instructions du bytecode Python, car pour l'instant je n'implémente que le chargement de constantes et de variables, et les opérateurs arithmétiques.
Ça fait beaucoup de choses à faire pour un projet complètement inutile, mais comme je suis en vacances, j'en profite
Source
Vous pouvez télécharger BFPY (même si ça n'a pas (encore) beaucoup d'intérêt) ici.