:: Enseignements :: Master :: M2 :: 2011-2012 :: Machine Virtuelle (et bazard autour ...) ::
[LOGO]

Lab 1


Une des choses que vous avez pu remarqué en écrivant le code de SimpleGen est qu'il n'est pas facile de générer du code lorsque l'on ne sait pas par exemple si l'appel à la fonction est une instruction ou une expression.
De façon général, lorsque le language est plus compliqué qu'une calculette, il est préférable d'analyser le code une première fois puis dans un second temps d'effectuer la génération du code en ayant garder les informations nécessaire calculer lors de la phase d'analyze.
Nous allons donc implanter un typechecker, dont le rôle est premier est de propager les types sur l'AST pour facilier la génération. La propagation des types va s'effectuer dans le sesn classique, des noeuds vers la racine ; par exemple, 1 est de type int, 2 aussi, donc 1 + 2 est de type int. Nous verrons plus tard, qu'il existe aussi une propagation des types dans le sens opposé.
En plus des types, on voudra vérifier et garder les informations def-use ; par exemple, la variable a d'une expression correspond à la déclaration a dans tel block pour que lors de la génération, on est pas besoin de re-calculer cette relation.
Le but de ce premier lab est donc d'écrire le Typechecker qui nous permettra après d'écrire un générateur de code utilisant le type-checker.

Exercice 1 - Lab 1

Comme pour l'interpreteur ou pour le générateur nous allons procéder en utilisant les mêmes grandes étapes.

  1. Quel est la valeur que l'on doit renvoyer lors d'une visite d'une expression ?
    Même question avec une expression.
  2. Implanter les méthodes du visiteur liées à la déclaration et l'utilisation de variables ainsi que toutes les méthodes permettant de tester l'exemple ci_dessous.
             {  
               var a = 1
               print(a)
             }
             

    Comment faire pour que la fonction print soit reconnue ?
  3. Tester que les variables déclarées dans un block masquent bien les variables des blocks englobants, sinon modifiez le code en conséquence.
             {  
               var a = 1     // a1
               { 
                 var a = 2   // a2
                 print(a)    // a is a2
               }
               print(a)      // a is a1
             }
             
  4. Ecrire les méthodes du visiteur correspondant au if et if/else.
  5. Implanter le visiteur de la boucle for ainsi que de break et continue en vérifiant bien que les labels existent et que break/continue sont appelés uniquement dans une boucle.
  6. Implanter les expressions binaires correspondant aux tests ==, != ainsi que && et ||. Attention, à bien respecter la sémantique du langage foo.
  7. Ajouter les opérations de comparaisons <, <=, > et >=.
  8. Ajouter les opérateurs +, -, *, / et %. Attention à la promotion des entiers vers les doubles et le + avec les chaines de caractère.
  9. Ecrire les méthodes du visiteur correspondant à l'appel de fonction en se rappelant qu'une fonction peut appeler une fonction déclarer après dans le fichier de script.