• [^] # Re: Dans l'art voluptueuse de ne rien comprendre

    Posté par . En réponse au journal EDSL et F-algèbres. Évalué à 1.

    Visiblement on est pas très fort pour communiquer :-).

    Je vais faire du pas à pas sur un exemple :-p.

    typedef toto int;
    int a = 1;
    toto b = 2;

    L'arbre pourrait ressembler à ça :

    expr = SEQ (TYPEDEF ("toto", "int"), (SEQ (VARDEF ("int", "a", INT 1), VARDEF ("toto", "b", INT 2))))

    Mon algorithme fait son petit fold et accumule les contraintes. Alors, comme on parle d'un langage assez compliqué, on admet qu'on ne peut pas mettre d'expressions à droite d'une égalité (c'est vraiment nul, mais sinon il faut plus de travail pour déterminer le type, c'est pénible, et cela n'est que « local » à l'expression).

    On peut donc écrire un bout de code dans ce genre là dans une disjonction de cas
    ocaml
    VARDEF (le_type, le_nom, (INT x)) -> { references = construire_un_singleton le_nom ; contraintes = construire_un_singleton (EQ "int" le_nom) ; declarations = empty_set }

    On peut aussi écrire un truc qui dit : ah bah oui, c'est bien défini

    TYPEDEF (a,b) -> { references = construire_un_singleton b ; contraintes = construire_un_singleton (EQ a b) ; declarations = construire_un_singleton a }

    On doit aussi écrire le cas où on tombe sur un SEQ, pour cela, on se contente de fusionner les contraintes et les références avec union_set.

    SEQ (a,b) -> { references = union_set a.references b.references ; contraintes = union_set a.contraintes b.contraintes }

    Je n'écris pas la fonction en entier, mais voilà comment ça tourne :

    evalue_type expr (* entre dans la fonction *)
    SEQ (x,y) (* fait l'appel récursif droit *)
    TYPEDEF ("toto","int") (* c'est un truc « final » : on applique la fonction de calcul *)
    { references = { "int" }; contraintes = { EQ ("int", "toto") }; declarations = { "toto" } }
    (* on a terminé l'appel récursif droit, on fait l'appel récursif gauche *)
    SEQ (z,t) (* fait l'appel récursif droit *)
    VARDEF ("int", "a", INT 1) (* c'est un truc « final » : on applique la fonction de calcul *)
    { references = { "int" }; contraintes = { EQ ("int", "int") }; declarations = {} }
    (* on a terminé l'appel récursif droit, on fait l'appel récursif gauche *)
    VARDEF ("toto", "b", INT 2) (* c'est un truc « final » : on applique la fonction de calcul *)
    { references = { "toto" }; contraintes = { EQ ("toto", "int") }; declarations = {} } 
    (* on a terminé gauche et droite, on fusionne les deux résultats car c'est ce qu'il faut faire avec un SEQ *)
    { references = { "toto", "int" }; contraintes = { EQ ("toto", "int") ; EQ ("int", "int") }; declaration {} }
    (* on a terminé gauche et droite pour la grosse expression, on fusionne les deux résultats car c'est encore un SEQ *)
    { references = { "toto", "int" }; contraintes = { EQ ("int", "toto") ; EQ ("toto", "int") ; EQ ("int", "int") }; declarations = {"toto"} }

    Alors j'ai très mal choisi la notation EQ qui correspond à ta flèche -> ... Mais après, une fois qu'on a ce résultat, on peut regarder si tout ce qui est référencé est déclaré : ici ce n'est pas le cas, car on devrait dire que « int » est toujours déclaré. Ensuite, on peut éventuellement regarder si le graphe est bien fait au niveau des contraintes.