Présentation du projet
L’auteur a construit un interprète capable de lire un sous‑ensemble de la syntaxe Python en seulement 1024 octets de code C. Aucun macro, aucune bibliothèque externe, uniquement du C conforme à GNU C89. Le but était de reproduire l’apparence du code Python (définitions, deux‑points, indentation) tout en restant dans une contrainte de taille extrême.
Architecture et état interne
L’interpréteur conserve tout son état dans quelques variables globales : un tableau char src[999] contenant le programme source, un tableau int vars[256] servant de table des symboles, et des entiers pos, ch, line_start qui gèrent la position du caractère courant. Aucun objet intermédiaire n’est généré ; les expressions sont évaluées au fur et à mesure de leur parsing, typique d’un analyseur récursif descendant.
Les noms de variables sont limités à un caractère alphabétique minuscule, ce qui permet un accès direct via l’indice ASCII (vars[ch]). Cette restriction réduit fortement la taille du code de gestion de la table des symboles.
Mécanisme de parsing et exécution
Le parseur utilise des fonctions dédiées à chaque niveau grammatical. Par exemple, la fonction de somme, présentée en version lisible, montre le principe :
int parse_sum(void) {
int value = parse_term();
while (ch == '+' || ch == '-') {
if (ch == '+')
value = value + parse_term();
else
value = value - parse_term();
}
return value;
}
Dans la version golfée, la même logique est compressée en une ligne obscure qui exploite les valeurs ASCII des opérateurs (e(){for(z=t();c-43u<3;)y=44-c,z+=y*t();return z;}). Les boucles while et for sont implémentées en ré‑analysant le texte source à chaque itération ; le parseur garde la position de la condition, exécute le corps, puis revient à cette position.
Les fonctions sont traitées de façon analogue : lors de la définition, le tableau vars mémorise l’indice de début du corps, et un appel sauvegarde la position du point d’appel avant de sauter vers la fonction.
Optimisation de la taille et limites
Le code source lisible dépasse les 4800 octets. Pour atteindre la cible de 1024 octets, l’auteur a appliqué des astuces de code‑golf : renommage agressif des variables, suppression des espaces, utilisation d’opérations sur les codes ASCII, et exploitation de constructions C spécifiques (ex. for(z=t();c-43u<3;)). Aucun mécanisme de gestion d’erreurs n’est présent ; le programme suppose que le code fourni est syntaxiquement correct et que les mots‑clés sont orthographiés exactement.
Cette absence de vérification, combinée à la limitation des noms de variables et à la taille fixe du tableau source, constitue les principales limites du projet. Il ne peut pas exécuter du code Python complet, ne supporte pas les expressions de comparaison, les littéraux de chaîne complexes, ni les modules externes. Malgré cela, il démontre qu’un interprète fonctionnel, capable d’exécuter des programmes simples comme le classique FizzBuzz, peut être réalisé dans un espace mémoire extrêmement restreint.