Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Otter Project (French)

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

Otter Project (French)

Comment réutiliser un projet réalisé rapidement dans le cadre d'un cours pour créer un compilateur nouveau et sympathique ?

Avatar for Stanislas Signoud

Stanislas Signoud

February 14, 2014

More Decks by Stanislas Signoud

Other Decks in Programming

Transcript

  1. Cette présentation... ★ Origines ★ Principe du projet ★ Objectifs

    et résultats ★ Démonstration ★ Pour aller plus loin... 2
  2. Un séjour à l’EPFL ★ Introduction to Computer Graphics ★

    Computer Supported Collaborative Work ★ Distributed Algorithms ★ TCP/IP Networking (Advanced) ★ Compiler Construction ★ Médias, Culture et Société ★ Comportement Organisationnel, partie I 4
  3. Un cours en particulier ★ Introduction to Computer Graphics ★

    Computer Supported Collaborative Work ★ Distributed Algorithms ★ TCP/IP Networking (Advanced) ★ Compiler Construction ★ Médias, Culture et Société ★ Comportement Organisationnel, partie I 5
  4. Comment ? ★ ...en Scala. ★ ...quatre heures par semaine.

    ★ ...en binôme. ★ ...des labs consécutifs. ★ ...et beaucoup, beaucoup de travail. 8
  5. toolc : un compilateur Compile le TOOL, un langage fictif

    : ★ Orienté objet ★ Avec des types définis par l’utilisateur ★ Avec des types prédéfinis (Int, Bool, String, Int[]) 11
  6. Exemple object Factorial { def main() : Unit = {

    println(new Fact().computeFactorial(10)); } } class Fact { def computeFactorial(num : Int) : Int = { var num_aux : Int; if (num < 1) num_aux = 1; else num_aux = num * (this.computeFactorial(num - 1)); return num_aux; } } 12
  7. État des lieux ★ toolc a été créé rapidement ◦

    Code peu et mal commenté ◦ Code peu propre, redondant ◦ Code non testé (!) ◦ Franglais (!!!) ★ Un fonctionnement simple 14
  8. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker CodeGenerator a =

    1 + b[2 * 8]… ID(a) ASSIGN INTEGERLITERAL(1) PLUS ID(b) OBRACKET … 17
  9. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker CodeGenerator ID(a) ASSIGN

    INTEGERLITERAL(1) PLUS … Assignment(Identifier(a), Addition (IntegerLiteral(1), …) 18
  10. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker CodeGenerator Assignment(Identifier(a), Addition(IntegerLiteral(1),

    Identifier(b)) Assignment(Identifier✻(a), Addition (IntegerLiteral(1), Identifier✻(b)) ✻ avec symboles 19
  11. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker CodeGenerator Assignment(Identifier✻(a), Addition(IntegerLiteral(1),

    Identifier✻(b)) ✻ avec symboles Assignment†(Identifier†✻(a), Addition† (IntegerLiteral†(1), Identifier✻†(b)) ✻ avec symboles † avec types 20
  12. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker CodeGenerator Assignment†(Identifier†✻(a), Addition†(IntegerLiteral†(1),

    Identifier✻†(b)) ✻ avec symboles † avec types 0: iload_1 1: iconst_1 2: if_icmpgt 7 5: iconst_1 6: ireturn 7: iload_1 8: aload_0 9: iload_1 10: iconst_1 11: isub 21
  13. Fonctionnement de toolc Lexer Parser Analyzer TypeChecker Code Generator Assignment†(Identifier†✻(a),

    Addition†(IntegerLiteral†(1), Identifier✻†(b)) ✻ avec symboles † avec types 0: iload_1 1: iconst_1 2: if_icmpgt 7 5: iconst_1 6: ireturn 7: iload_1 8: aload_0 9: iload_1 10: iconst_1 11: isub cafebabe + 22
  14. Projet spécifique « Pourquoi ne pas continuer sur un sujet

    touchant à la compilation, sujet que tu avais pris à l’EPFL ? » → Reprendre toolc et en faire une v1 correcte 24
  15. toolc v1.0 ★ Améliorer la documentation ★ Améliorer le code

    ★ Améliorer le langage… ➢ Est-ce vraiment encore toolc ? 25
  16. Les mains libres ★ Pour documenter ★ Pour tester ★

    Pour réécrire ★ Pour relicencier ★ Pour partager ★ Pour étendre le langage ! 27
  17. Ré-empaqueter $ yaourt -S gradle # or setup.exe, etc. $

    git clone <url> $ cd otterc $ gradle build 31
  18. Documenter ★ Documenter de manière exhaustive toutes les classes, méthodes

    ★ scaladoc permet de générer une documentation très agréable à parcours 32
  19. Réécrire ★ Clarifier ◦ Supprimer tous les “raccourcis d’écriture” dans

    les signatures de méthodes et paramètres de classes ◦ Standardiser et formater le code à-la-Scala ★ Réécrire les points peu clairs ◦ S’assurer d’une compréhension complète du compilateur ◦ Améliorer la qualité du code 33
  20. Tester ★ Tests unitaires ◦ Sur les classes qui s’y

    prêtent le mieux ◦ Compliqué, fastidieux mais pertinent ★ Tests fonctionnels ◦ Sélection parmi une pool de programmes existants en TOOL (compatibles avec otterc) ◦ Création de cas de tests pour les extensions 34
  21. Étendre ★ Rendre les points-virgules facultatifs ★ Ajouter la surcharge

    d’opérateurs simples ★ Autoriser les expressions comme instructions ★ Autoriser les assignations comme expressions ★ Autoriser la surcharge de méthodes ★ Inférer le type des variables (dans les déclarations) 35
  22. Étendre Rendre les points-virgules facultatifs var a : Int; a

    = 56; if (a < 42) { this.whatever(a); }; return 6; VAR ID(a) COLON INT SEMICOLON ID(a) ASSIGN INTEGERLITERAL (56) SEMICOLON IF OPAREN ID (A) LESS INTEGERLITERAL(42) CPAREN OBLOCK THIS DOT ID (whatever) OPAREN ID(a) CPAREN SEMICOLON CBLOCK SEMICOLON RETURN INTEGERLITERAL(6) SEMICOLON 37
  23. Étendre Rendre les points-virgules facultatifs var a : Int; a

    = 56; if (a < 42) { this.whatever(a); }; return 6; VAR ID(a) COLON INT SEMICOLON ID(a) ASSIGN INTEGERLITERAL (56) SEMICOLON IF OPAREN ID (A) LESS INTEGERLITERAL(42) CPAREN OBLOCK THIS DOT ID (whatever) OPAREN ID(a) CPAREN SEMICOLON CBLOCK SEMICOLON RETURN INTEGERLITERAL(6) SEMICOLON 38
  24. Étendre Rendre les points-virgules facultatifs var a : Int a

    = 56 if (a < 42) { this.whatever(a) } return 6 VAR ID(a) COLON INT ID(a) ASSIGN INTEGERLITERAL(56) IF OPAREN ID(A) LESS INTEGERLITERAL(42) CPAREN OBLOCK THIS DOT ID(whatever) OPAREN ID(a) CPAREN CBLOCK RETURN INTEGERLITERAL(6) 39
  25. Étendre Rendre les points-virgules facultatifs var a : Int a

    = 56 if (a < 42) { this.whatever(a) } return 6 VAR ID(a) COLON INT ID(a) ASSIGN INTEGERLITERAL(56) IF OPAREN ID(A) LESS INTEGERLITERAL(42) CPAREN OBLOCK THIS DOT ID(whatever) OPAREN ID(a) CPAREN CBLOCK RETURN INTEGERLITERAL(6) UNEXPECTED ID(a) EXPECTING SEMICOLON 40
  26. Étendre Rendre les points-virgules facultatifs • « S’attendre à tout

    », et couper au bon endroit les suites de token ◦ Complexe avec de nombreux cas possibles • Prendre en compte les \n, les ignorer sauf en cas de point virgule attendu ◦ Simple et efficace 41
  27. Étendre Rendre les points-virgules facultatifs var a : Int↲ a

    = 56↲ if (a < 42) {↲ this.whatever(a)↲ }↲ return 6↲ VAR ID(a) COLON INT NEWLINE ID(a) ASSIGN INTEGERLITERAL (56) NEWLINE IF OPAREN ID(A) LESS INTEGERLITERAL(42) CPAREN OBLOCK NEWLINE THIS DOT ID(whatever) OPAREN ID(a) CPAREN NEWLINE CBLOCK NEWLINE RETURN INTEGERLITERAL(6) NEWLINE 42
  28. Étendre Rendre les points-virgules facultatifs var a : Int a

    = 56 if (a < 42) { this.whatever(a) } return 6 VAR ID(a) COLON INT NEWLINE ID(a) ASSIGN INTEGERLITERAL (56) NEWLINE IF OPAREN ID(A) LESS INTEGERLITERAL(42) CPAREN OBLOCK NEWLINE THIS DOT ID(whatever) OPAREN ID(a) CPAREN NEWLINE CBLOCK NEWLINE RETURN INTEGERLITERAL(6) NEWLINE 43
  29. Étendre Rendre les points-virgules facultatifs ★ \n → NEWLINE ★

    Accepter NEWLINE à la place de SEMICOLON ★ Ignorer NEWLINE sinon Quelques lignes rajoutées, un résultat efficace. 44
  30. Étendre Ajouter la surcharge d’opérateurs a = (b.times(c)).plus(d) a =

    b * c + d T <: TObject * TAny → TObject si TObject contient une méthode times qui prends un seul paramètre a * b → a.times(b) si a est de type Object 45
  31. Étendre Ajouter la surcharge d’opérateurs T <: TObject * TAny

    → TObject si TObject contient une méthode times qui prends un seul paramètre TypeChecker Analyzer TypeChecker CodeGenerator Expander 47
  32. Étendre Ajouter la surcharge d’opérateurs a * b → a.times(b)

    si a est de type Object TypeChecker CodeGenerator Expander Analyzer 48
  33. Étendre Ajouter la surcharge d’opérateurs ★ Étendre le TypeChecker pour

    gérer la surcharge d’opérateurs ★ Ajouter un Expender pour ajouter les noeuds de l’arbre manquant 49
  34. Étendre Autoriser les expressions comme instr. 15 + 20 //

    An expression println(“Yes”); // A statement 50
  35. Étendre Autoriser les assignations comme expressions target = expression; target[abcd]

    = expression; ★ Modifier quelques règles de TypeChecking ★ Retourner la nouvelle valeur prise 52
  36. Étendre Inférer le type des variables ★ Inférence simple sur

    les variables immédiatement initialisées ★ Appel de l’Analyzer depuis le TypeChecker 56
  37. Quelques ouvertures... ★ Créer un tutoriel/aide-mémoire ★ Autoriser les appels

    à des bibliothèques standard de la JVM ★ Rendre le code plus générique ◦ Challenge : ne pas en perdre la simplicité ! 61