J’ai avancé sur l’interpréteur de PULP en Rust. Voici les nouveautés de la journée.
- La vérification de l’intégrité du fichier grâce à son condensat MD5 est opérationnelle.
- Les tests de la phase de parsing sont exhaustifs et commentés.
- La fonction principale a également sa série de tests élémentaires.
- Les tests sont regroupés dans un même module.
- Un certain nombre d’erreurs possibles supplémentaires sont détectées.
Le plus important qu’il reste à faire, c’est compléter les tests. Et si vous voulez participer, vous êtes les bienvenus. Même si vous ne connaissez pas beaucoup de Rust, vous pouvez vous entraîner, car ce qui reste, ce sont les tests les plus simples à écrire. En effet, il manque les tests portant sur cette fonction. Ou plus exactement, il faudrait compléter les tests existants pour atteindre l’exhaustivité : vous pouvez suivre le modèle pour vous aider.
Par ailleurs, il manque du matériel pour des tests « grandeur nature », c’est-à-dire des fichiers de bytecode complets réalisant un véritable travail. N’hésitez pas à en générer, c’est le meilleur moyen de tester intégralement l’interpréteur.
Il va cependant y avoir un problème avec ça, et là, je m’adresse surtout à @nohar. À l’heure actuelle, comme rien ne définit de quelle manière les différents segments doivent être exécutés, j’ai pris le parti de tous les exécuter dans l’ordre où ils apparaissent dans le fichier, et d’afficher à l’écran le sommet de la pile tel qu’il est à la fin de l’exécution de chaque segment.
Cela n’est cependant pas idéal, car cela ne me permet pas de tester automatiquement qu’un programme complet donne bien le résultat attendu. Il faudrait :
- d’une part, qu’une règle soit définie quant à la manière dont les segments sont exécutés. Je vois deux possibilités pour cette première version de la spec (ça peut changer dans les versions suivantes de la spec, ce n’est pas gênant) :
- seul le premier segment est exécuté et les suivants sont ignorés,
- un nouveau type de segment est introduit qui décide dans quel ordre les segments sont exécutés, et ce qui doit advenir du résultat des segments qui ne sont pas le dernier (sans doute overkill pour une v0.1.0) ;
- d’autre part, que la fonction principale de l’interpréteur renvoie soit le résultat du tout dernier segment exécuté (c’est-à-dire le sommet de la pile), soit un code d’erreur si le programme
abort
avant terme (ce qui n’est pas possible dans la version actuelle du bytecode, mais sera très certainement indispensable dans une version postérieure). Et surtout, que cette API ne change plus jamais dans les versions ultérieures du bytecode, pour ne pas se retrouver avec des signatures de type différentes pour la fonction principale.
Ces deux points permettraient également de considérablement simplifier l’écriture d’une fonction wrapper pour que la bibliothèque soit appelable depuis C, C++, Python, Haskell, etc., permettant à d’autres participants de l’utiliser pour leurs exécutables.