Télécom Nancy Année 2013-2014 Rapport 1A Ajout du langage C dans la Programmer's Learning Machine GIANNINI Valentin Loria 615, rue du Jardin Botanique 54600, Villers-Lès-Nancy Maître de stage : QUINSON Martin Promotion 2016
1
Remerciement Je tiens à remercier Monsieur Martin QUINSON, chef d'équipe d'algorille au Loria, pour son accueil au sein de son équipe ainsi que de son aide avec la PLM. Je remercie également Monsieur Gérald OSTER pour son aide. Je remercie également Monsieur Jean-François SCHEID de m'avoir autorisé à faire mon stage de première année au Loria. Pour nir je remercie les membres de l'équipe AlGorille pour m'avoir accueilli. 2
Table des matières 1 Introduction 4 2 L'application existante 5 2.1 La PLM.............................. 5 2.2 L'ajout du C........................... 6 3 Solution envisagée 7 3.1 Mise en place d'un protocole................... 7 3.2 Compilation à la volé....................... 7 3.3 Lancement du programme.................... 8 4 Organisation pratique des travaux 9 4.1 Comprendre la PLM....................... 9 4.2 Mettre en place les commandes................. 9 4.3 Création d'un client C...................... 9 4.4 Compilation à la volée...................... 9 4.5 Adapter les exercices....................... 11 4.6 Modier la documentation.................... 11 4.7 Vers un version nale....................... 11 5 Problèmes rencontrés et solutions apportées 13 5.1 La séparation des commandes et de l'achage......... 13 3
1 Introduction Dans le cadre de ma première année a Télécom Nancy j'ai eu l'occasion de réaliser un stage de six semaines au Loria en tant que développeur. Ce stage avait pour but d'ajouter un langage de programmation à la PLM 1. La PLM pouvant déjà nous enseigner le Java, le Scala ou le python, il m'a été demandé d'ajouter le langage C qui est encore l'un des langages les plus utilisés et également enseigné à Télécom Nancy. La PLM est un programme écrit en Java et de ce fait, l'ajout du langage C se révèle problématique, car par rapport à Scala ou à un langage de script comme python, le C n'est pas compatible avec Java. J'ai dû trouver une solution pour allier le Java et le C dans ce programme. 1. Programmer's Learning Machine, dépôt git : https ://github.com/oster/plm 4
2 L'application existante 2.1 La PLM Le PLM est un programme simple d'utilisation permettant d'apprendre à programmer de façon ludique. Voici une image de la toute première leçon : 1. La première partie est un menu permettant de lancer son code, de voir une démo, de changer d'exercice ou de leçons,... 2. La deuxième contient la leçon ou le code utilisateur. C'est cette leçon que l'utilisateur va devoir lire pour pouvoir coder. 3. La troisième partie représente le monde dans lequel on se trouve. Ici le monde des termites où on peut voir la carte et en dessous, des commandes pour pouvoir contrôler les termites avant de vouloir coder, cela permet de se familiariser avec le monde. 4. La quatrième partie est une console, les messages d'erreurs s'acheront dedans pour dire à l'utilisateur ce qui ne fonctionne pas dans son code. Elle permet également d'acher ce que l'utilisateur voudra, comme le contenu d'une variable par exemple Cette image représente le monde des buggles, mais il existe également d'autres mondes comme le monde de la tortue ou le monde des tris. Le code que l'utilisateur écrit dans la partie de gauche sera exécutée et interagira avec la partie de droite en déplaçant le buggle par exemple. Le but de l'exercice étant de faire faire au buggle ce que la leçon demande. 5
2.2 L'ajout du C La PLM étant écrite en Java, l'ajout du Scala et du Python fut rapide et simple. En eet Scala est très proche de Java, car il exécute également dans la JVM et pour python, il existe un interpréteur de script qui permet de l'exécuter dans la JVM 2. En revanche pour ce qui est du langage C, il existe une librairie capable d'interfacer du C et du Java qui est JNI 3 mais celle-ci peut ce révéler dangereuse pour la PLM. En eet si le code C de l'utilisateur provoque une erreur de segmentation (accès à une case mémoire interdite) alors la PLM sera tué par le système d'exploitation. Nous allons voir comment j'ai fait pour que le C puisse interagir avec le Java. 2. Java Virtual Machine : machine virtuelle Java 3. Java Native Interface 6
3 Solution envisagée Pour parer cette incompatibilité entre Java et C je me suis inspiré d'un projet de RS créé par Martin Quinson (en 2010-2011). Ce projet avait pour but de créer une PLM simpliée en C, en gérant la communication entre plusieurs thread, via des tubes. Pour résumer le principe de fonctionnement, l'utilisateur va écrire du code qui va être récupéré pour être compilé. Une fois le code compilé, la PLM va le lancer et écouter via des tubes ce que demande le programme C, celui-ci enverra des commandes sous forme de numéro pour interagir avec le monde sélectionné. Une fois que le programme C aura terminé son exécution, la PLM reprendra la main et vériera la validité de ce que l'utilisateur a fait. 3.1 Mise en place d'un protocole Ce protocole mis en place entre le code élève et la PLM est ligne à ligne. Chaque ligne correspond à une commande et suit la syntaxe suivante. Elle est composée d'un nombre a trois chires, d'une liste d'arguments et du nom de la commande pour faciliter de débogage. Prenons un exemple : les buggles peuvent avancer à l'aide d'une fonction avance(nb), cette fonction dit au buggle d'avancer de nb cases. Si nb vaut 4, le code de cette commande sera "113 4 avance", la PLM saura alors que 113 correspond à l'avancement du buggle et que l'argument derrière, ici 4, dira le nombre de pas à faire. D'autres fonctions renvoient un résultat, par exemple la fonction estfaceunmur() renvoie 1 si le buggle est face à un mur, 0 sinon. Elle écrit tout simplement 0 ou 1 dans la ligne et l'envoie aussitôt. 3.2 Compilation à la volé L'une des dicultés spéciques au langage C est que le code doit être compilé sur l'architecture de la machine où il s'exécutera. De plus le compilateur C s'exécute en dehors de la JVM contrairement au compilateur Java ou Scala y est intégré. De ce fait, le code C est compilé à chaque fois à la volée, pour ce faire la PLM devra un appel système pour lancer gcc 4 an de compiler le code. C'est également elle qui dira à gcc ce qu'il faut compiler et où ça se trouve. 4. GNU Compiler Collection : Permet de compiler du code C ainsi que d'autres langages 7
3.3 Lancement du programme Tout comme avec gcc, le programme créé va être lancé par un appel système, cet appel permet notamment de relier la PLM et le programme C par trois tubes sont : Un tube "entrée standard" (stdin) qui permet d'envoyer au programme C des commandes, par défaut il s'agit du clavier. Un tube "sortie standard" (stdout) qui permet de récupérer ce que le programme C va écrire par le biais de printf notamment. Par défaut il s'agit de l'écran. Un tube "sortie d'erreur" (stderr) qui permet de récupérer les erreurs du programme C, par exemple quand il y a une division par zéro ou une erreur de segmentation. Ici ces trois tubes sont récupérés par la PLM, c'est elle qui va faire oce d'écran et de clavier pour échanger avec le programme C. 8
4 Organisation pratique des travaux 4.1 Comprendre la PLM La première étape de ce stage a été de comprendre le fonctionnement de la PLM. En eet il s'agit d'un programme assez conséquent que je n'ai pas l'habitude de traiter. Avec l'aide de Martin Quinson et de Gérald Oster j'ai pu très vite commencer mon sujet. 4.2 Mettre en place les commandes La deuxième étape a consisté en l'ajout une méthode permettant de comprendre des commandes comme décrit précédemment. Pour cela j'ai dû regarder le schéma de classe de la PLM an d'y voir une séquence d'exécution. De ce schéma j'ai pu en déduire que je devait ajouter une méthode dans la classe Entity an que cette entité puisse communiquer avec un programme extérieur à Java. Cette méthode, que j'ai appelé "command" est hérité dans toutes les sous classe, ce qui oblige à l'implémenter lorsqu'une nouvelle entité va être créée lors de l'ajout d'un type de monde par exemple. Une fois cette méthode ajoutée, des tests ont été fait sur son fonctionnement avec de simples scripts shell qui envoyaient des commandes. Ces commandes ont été écrites en dur pour chaque cas diérents. 4.3 Création d'un client C Une fois ces tests nis, j'ai réalisé un client C, c'est-à-dire le programme qui contient les mêmes fonctions que la PLM pour un monde donné. Par exemple pour les buggles, il y a les fonctions avance, recule, droite, gauche, demitour, etc. L'utilisateur appelle donc ces fonctions depuis le client. C'est ce client qui va envoyer la commande comme expliqué précédemment et c'est donc la méthode "command" qui intercepte la commande. Pour chaque monde il y a un client qui lui est très spécique, car les mondes n'orent pas les mêmes fonctions. Une fois le client créé, je l'ai compilé à la main pour que la PLM puisse le lancer. Des tests ont également été faits lors de cette étape an de vérier que les informations passent bien de part et d'autre entre la PLM et le client. 4.4 Compilation à la volée Ensuite, une fois les tests passés, j'ai implémenté la partie permettant à la PLM de compiler le programme C directement. Pour cela il faut faire un 9
appel système en demandant l'exécution de gcc. Le programme compilé est mis dans un dossier temporaire. Il est supprimé et recréé a chaque lancement de compilation par l'utilisateur. 4.5 Adapter les exercices A cette étape, la PLM est autonome pour la compilation et lancement de programme C, mais les diérentes leçons devaient êtres adaptées en C avant de pouvoir les utiliser. Cette partie fut assez longue, car il y a beaucoup de leçons et certaines étant plus compliquées, j'ai dû faire appel à certaines astuces pour pouvoir transformer le code Java en C. De plus pour chaque exercice je devais tester pour vérier son fonctionnement ainsi que la conformité avec la solution développé en Java. 4.6 Modier la documentation Pour chaque exercice il y a un énoncé décrivant ce que l'utilisateur doit faire, cet énoncé expliquant le fonctionnement des langages, j'ai dû les modier pour qu'ils s'adaptent au C. Pour cela, il y a un éditeur de leçon dans la PLM qui permet de modier les énoncés ainsi que les diérentes fonctions disponibles pour le monde. Après avoir modié les expressions régulières de cet éditeur j'ai pu faire la modication de tous les énoncés de la PLM. 4.7 Vers un version nale A partir de ce moment, la PLM est fonctionnelle pour l'apprentissage du C. Elle permet de compiler et de lancer le code d'un utilisateur et également de lui indiquer les fonctions. Mais il reste quelques petits problèmes qu'il conviendrait de corriger an que la PLM soit la plus stable et sécurisée possible. 10
5 Problèmes rencontrés et solutions apportées 5.1 La séparation des commandes et de l'achage Au début, le seul moyen pour le programme C de communiquer était les printf. Cette fonction permet d'acher à l'écran ce que l'utilisateur veut acher (comme du texte ou la valeur de variables ). Cette fonction écrit par défaut dans la sortie standard du système qui est récupérée par le Java. Le problème est que si l'utilisateur fait un printf contenant une commande (par exemple "113 4 avance") cela va déclancher une commande indésirée. Pour cela il faut séparer les commandes des achages de l'utilisateur en les faisant passer dans deux tubes diérents. Pour les commandes, c'est toujours dans stdout, mais pour les printf on crée un chier dans lequel le programme C écrit ce que l'utilisateur demande à acher sur l'écran. Un chier est utilisé car il semble impossible d'ouvrir un tube de plus en C pour communiquer avec le Java. De ce fait la sortie standard est séparé des commandes et l'utilisateur ne pourra pas interagir avec la partie qui gère les commandes. 11
Conclusion sur ce stage Ce que j'ai appris Durant ce stage j'ai pu perfectionner mon niveau en Java ainsi qu'en C notamment sur l'interaction entre eux. J'ai également découvert la façon dont on peut participer à un projet libre en proposant des améliorations au créateur du logiciel. J'ai également découvert la vie à l'intérieur d'un laboratoire ce qui m'intéresse si je veux continuer dans cette voie après Télécom Nancy. Ce qu'il reste a faire sur la PLM N'ayant pas pu faire tout ce que je pouvais faire, il reste du travail à fournir sur la PLM. L'éditeur de leçons pourrait utiliser le scala pour parser de manière plus complète les leçons. D'autres langages peuvent également y être intégrés. Et on peut même envisager une interface web an d'utiliser la PLM depuis n'importe quel navigateur. 12
Figure 1 Vue d'ensemble Figure 2 Détails des communications 13