TD Compilation numéro 1


L'objectif de ces exercices est d'appliquer les schémas d'évaluation et de compilation sur des objectifs simples.
  1. Calculette
    Définir la fonction calcul qui prend une expression arithmétique en paramètre et l'évalue.
    L'expression ne doit contenir que des nombres et des opérateurs arithmétiques usuels.
    On commencera en ne traitant que des opérateurs binaires. 

  2. Interprétation d'automates

  3. Compilation d'automates
    Écrire la fonction compile-auto, qui prend en argument un automate et retourne une fonction d'interprétation de mot, qui prend en argument un mot et retourne vrai/faux suivant que l'automate reconnaît le mot ou pas. L'invariant suivant doit être vérifié :
    (eval-auto auto mot) = (apply (compile-auto auto) mot ()) Voir le poly de compilation pour plus de détails.

  4. Tester backquote
    Voir le poly de LISP pour plus de détails.

    Pour comprendre ce que fait backquote, il est intéressant d'analyser la valeur de `(toto , titi truc ,@tata tutu) ou de toute autre expression backquotée.
    Pour cela, on peut regarder '`(toto , titi truc ,@tata tutu) : comme print restitue la forme bacquotée d'origine, on analysera la valeur en en prenant les car et cdr successifs.
    Essayez avec macroexpand.
    Expliquer.

  5. Implémenter backquote
    L'objectif est de définir le fonctionnement du caractère backquote en définissant une fonction backquotify qui transforme l'expression backquotée en une expression de construction de liste.
    Pour cela, il faut d'abord supposer que ",x" est lu (fonction read) comme la liste (unquote x), de la même manière que "'x" est lu (quote x). Idem pour ",@x" qui est lu (splice-unquote x).
    On procède par étapes
    1. dans un premier temps, on définit backquotify pour qu'il transforme l'expression `(e1 e2 .. en) en (list 'e1 ... 'en) ;
    2. on traite ensuite le cas où des ei sont de la forme (unquote fi) de telle sorte que l'expression produite comporte alors fi à la place de 'ei ;
    3. on généralise alors à un arbre : la récursion ne se fait pas seulement sur le cdr mais aussi sur le car ;
    4. on traite ensuite le cas des (splice-unquote x) : attention, il faut alors faire une récursion de la cellule "du dessus"  (rare contre-exemple à la règle consistant à ne tester dans une récursion que la cellule courante) ;
    5. on finit par la définition d'une fonction de simplification qui fait l'inverse de l'étape 1 en reconstruisant des constantes et qui simplifie les appels imbriqués (append, cons et list* ou list, etc.)

    On peut alors vérifier, que ça marche :
    (bacquotify '((lambda ((unquote (caar args))) (splice-unquote body)) (unquote (cadar args))))
    doit retourner quelque-chose comme :
    (list (list* 'lambda (list (caar args)) body) (cadar args))
    On peut même comparer ce que votre version produit avec le résultat de la version du système, que la question précédente permet d'obtenir.