diff --git a/soutenance.md b/soutenance.md new file mode 100644 index 0000000..8404e1b --- /dev/null +++ b/soutenance.md @@ -0,0 +1,152 @@ +# Rapport C-repl en C++ + +## Architecture + +### Lexer (Alaric, lexer.cpp) + +Première étape de l'interprétation du langage. Le code à l'état brut est transformé en un tableau de tokens. +Le lexer avance dans le texte en essayant de matcher chaque type de token, parfois à l'aide de `regex`, dans un ordre bien choisi. +Lors de cette étape, les constantes littérales sont d'ores et déjà parsées et stockées dans leur type interne. + + +### Parsing (Augustin, parser.cpp) + +Le parser transforme le tableau de tokens en un `AST (Abstract Syntax Tree)`. +Il procède par backtracking en suivant les règles de la grammaire définie dans `types.hpp`. + + +### Analyse statique (Augustin, analysis.cpp) + +Avant d'exécuter le programme, cette étape infère le type de chacun des éléments du programme (stocké sous forme d'`AST`) et vérifie la validité de chaque opération. + +Une "mémoire virtuelle", copie affaiblie de la mémoire actuelle de la repl, sert à stocker les types des variables. +Le type de chaque noeud de l'`AST` est calculé récursivement puis la validité des types passés aux opérateurs est vérifiée, +en s'appuyant notamment sur les règles de casting définies dans `casting.cpp`. + + +### Évaluation (Alaric, eval.cpp) + +Les noeuds de l'`AST` sont évalués de manière récursive. +Des exceptions sont utilisées en interne pour traiter les instructions `break`, `continue` et `return`. + + +### Mémoire (Alaric, memory.cpp) + +`Memory` définit une structure de mémoire réutilisable qui sert lors de l'analyse statique et de l'évaluation. +Elle gère notamment les `scopes`. + + +#### Types (types.hpp) + +Rassemble les définitions de type communes à tout le projet. + + +#### Execute (execute.cpp) + +Encapsule toutes les étapes de l'interprétation du code brut aux résultats. + + +#### Lecture de l'entrée (main.c, input.c) + +Gère le traitement des arguments en ligne de commande et l'interface utilisateur de la repl: la partie "interactive" de la repl. + + +#### Casting (casting.cpp) + +Définit les règles de casting entre les types. + + +#### Erreurs (errors.cpp) + +Définit les erreurs, leur affichage. + + +#### Utilitaires (utils.cpp, debug.cpp) + +Fonctions utilitaires et de débogage. + + +## Appropriation + +Certaines parties du langage C ne sont pas spécifiées dans le standard et varient ainsi d'un compilateur à l'autre. Nous avons parfois fait des choix arbitraires, en privilégiant l'option la plus naturelle. + +La repl ne permet pas les `undefined behavior` dans la mesure où ceux-ci sont protégés par le C++. +Par exemple, il n'est pas possible de lire une variable non-initialisée: cela produira une erreur. + +Il a été choisi que toute instruction ait une valeur et un type. Cela permet d'afficher une valeur de retour à l'utilisateur lorsqu'il entre une ou plusieurs instructions. +Pour les `statements`, ce type est toujours `void`, représenté en interne par la valeur `monostate`. Cependant, certaines `expression-statements` peuvent avoir un type non-`void`. Les `expressions` ont évidemment une valeur. + + +## Features + +### Types + +Les types `int`, `double`, `void` et les fonctions composées de ces mêmes types sont supportés. + + +### Instructions + +Les instructions suivantes sont implémentées: + +- Opérateurs arithmétiques binaires (`+`, `-`, `*`, `/`, `%`) et unaires (`+`, `-`) +- Opérateurs logiques (`&&`, `||`, `!`) +- Opérateurs de comparaison génériques (`==`, `!=`) +- Opérateurs de comparaison arithmétique (`<=`, `<`, `>=`, `>`) +- Opérateurs d'incrémentation gauche et droite (`++`, `--`) +- Opérateur virgule (`,`) +- Déclarations de variables avec et sans initialisation (`int x;`, `int x = 1;`) +- Assignation de variables (`x = 1`) +- Conditionnelles (`if (..) ..`, `if (..) .. else (..) ..`) +- Boucles (`for`, `while`) avec contrôle (`break`, `continue`) +- Définition de blocs (`{}`) +- Déclaration de fonctions avec et sans corps (`int foo(int x);`, `int foo(int x) { .. };`) +- Appels de fonctions (`foo(1)`) + + +### Scopes et closures + +L'interpréteur prend en charge les `scopes` de bloc et de fonction, ainsi que pour les `for`, comme attendu dans le langage C. +Il gère également les `closures` comme il se doit dans un langage impératif non-fonctionnel. +Une implémentation qui convient à ce type langage (mais pas aux langages multi-paradigmes) est une tableau de pointeurs. + + +### Contrôle de flot + +La repl ne comporte pas de contrôle de flot avant l'évaluation-même de l'AST. +En conséquence, les erreurs associées sont détectées à la volée lors de l'évaluation. + + +### Erreurs + +La repl comporte un système d'erreur riche avec messages d'erreur et position dans le code. +Celles-ci sont divisées en 4 catégories en fonction de l'étape à laquelle elles interviennent: + +- `SyntaxError`: lexer et parsing +- `ControlError`: en raison de l'absence de contrôle de flot préalable, à divers endroits +- `TypeError`: analyse statique +- `RuntimeError`: évaluation + +Les `RuntimeErrors` sont accompagnées d'une `stack trace` contenant la position dans le code des appels de fonction récursifs. + + +### Librairie standard + +Les fonctions suivantes sont proposées pour interagir directement avec la repl: + +- `clear_memory()` réinitialise la mémoire (non supporté hors de la scope globale) +- `dump_memory()` affiche l'état actuel de la mémoire +- `dump_history()` affiche l'historique du code passé en entrée + + +### Interface utilisateur + +Le système d'entrée est pratique : il permet de se déplacer dans la ligne actuelle et de naviguer dans l'historique du code entré. +Les lignes sont automatiquement numérotées pendant que la saisie. +Pour permettre les sauts de ligne multiples, il est nécessaire de taper `;;` pour indiquer au programme que l'on a terminé son entrée. +Le résultat de l'évaluation du programme est alors affiché. + + +## Tests + +Une suite de tests automatisée est disponible : elle teste les différentes parties du code, les fonctionnalités du langage ainsi que chaque type d'erreur. +Des programmes plus conséquents sont disponibles dans `./example`. \ No newline at end of file diff --git a/soutenance.png b/soutenance.png new file mode 100644 index 0000000..c0eb733 Binary files /dev/null and b/soutenance.png differ