Programmation fonctionnelle : projet 2011
Cette page peut être mise à jour, avec informations complémentaires,
précisions, questions
bonus, etc. Pensez à y revenir souvent.
Correction d'un problème ncurses dans l'interface pour les questions
bonus : nouvelle interface ICI [tar.gz].
Projet à rendre pour le 18/11 à 17h, aucun retard ne sera toléré.
Des soutenances pourront être organisées ensuite.
Un rendu de projet comprend :
- Un rapport précisant vos choix, les problèmes techniques qui se
posent et les solutions trouvées ; il précise en conclusion les
limites de votre programme. Le rapport sera de préférence composé
avec LaTeX.
- Un code abondamment commenté ; la première partie des
commentaires sera systématiquement de la forme
my_function : ...type...
my_function x1 x2 x3 retourne ...blabla en fonction de x1 x2 et x3
Préconditions : c'est-à-dire conditions sur les paramètres pour une bonne
utilisation (pas de typage ici).
Informations additionnelles si des techniques particulières méritent
d'être mentionnées.
Protocole de dépôt
Vous devez rendre
- Votre rapport (en pdf) et
- Vos fichiers de code
rassemblés dans une archive tar gzippée identifiée
comme votre_prénom_votre_nom.tgz.
La commande devrait ressembler à :
tar cvfz randolph_carter.tgz rapport.pdf base.ml
autres_truc_éventuels.ml* ...
Lisez le man ! et testez le contenu de votre archive (une
commande comme par exemple :
tar
tvf randolph_carter.tgz doit lister les fichiers et donner leur
taille). Une archive qui ne contient pas les
fichiers demandés ne sera pas excusable.
Votre archive doit être déposée sur la machine lunix31 dans le
dépôt IIE1-IPF1-1. Suivez les indications.
Le dépôt sera ouvert à partir de lundi 13. Il sera fermé le 18. Je
relèverai les archives à 17h.
Sujet
On souhaite programmer un éditeur de texte « à la emacs » avec des
fonctions simples : insérer ou effacer un caractère, se déplacer avec
les flèches, sauver ou charger un ficher de texte, revenir à un état
précédent (undo).
La notion principale à manipuler est la notion de buffer. On
travaille localement dans un buffer au niveau d'une ligne (le
buffer contient une séquence de lignes). Le curseur est positionné
localement dans une ligne, laquelle contient une séquence de
caractères. Un environnement contient un buffer courant et
les moyens de revenir à un état précédent.
Vous devrez déclarer au moins les deux types buffer
et env (noms imposés).
Pour simplifier, on ne considérera que des caractères non
accentués.
Interface
Les événements clavier et l'affichage seront gérés à l'aide d'un
code que nous vous
fournirons ICI [tar.gz]
(archive tar gzippée à copier dans votre compte école) et avec lequel
vous interagirez au moyen de quelques fonctions très simples
imposées. L'affichage se fera dans une fenêtre de 5 lignes, la ligne
du milieu étant dans la mesure du possible la ligne où on travaille
localement. Les commandes spéciales seront :
- [f1] Undo
- [f5] Load
- [f9] Save
Le type des
actions possibles est le type somme suivant (imposé) :
type action =
| Undo
| Save of (string -> unit)
| Load of string
| Left
| Right
| Up
| Down
| Backspace
| Delete
| Char of char
Description des fonctions
Un appui sur une touche du clavier doit se traduire par un déplacement
du curseur, une insertion ou un effacement de caractère, un appel à
sauvegarde du buffer courant ou à son remplissage par la lecture d'un
fichier enregistré. On pourra s'inspirer du comportement d'emacs en
cas de doute.
Déplacements
Une action provenant d'une pression sur les
touches fléchées (Left, Right, Up, Down) entraîne une
modification de la position du curseur (position courante).
- À gauche : déplacement à gauche dans la ligne courante. Si on est
en début de ligne alors on va en fin de la ligne précédente. Si on
est en début de buffer alors rien ne se passe.
- À droite : déplacement à droite dans la ligne courante. Si on est
en fin de ligne alors on va en début de ligne suivante. Si on est en
fin de buffer alors rien ne se passe.
- En haut : déplacement dans la ligne du dessus, au min de la
position dans la ligne de départ et de la longueur de la ligne du
dessus. Si on est au début du buffer, rien ne se passe.
- En bas : déplacement dans la ligne du dessous, au min de la
position dans la ligne de départ et de la longueur de la ligne du
dessous. Si on est à la fin du buffer, rien ne se passe.
Modification du contenu
Les touches non fléchées entraînent pour la plupart des modifications
du buffer. Les comportements attendus sont
:
- Effacement Backspace : le caractère précédant la position
courante est effacé, tous les caractères (à et) suivant la position
courante sont décalés d'une position vers la gauche.
- Effacement Delete : le caractère à la position courante
est effacé, tous les caractères le suivant sont décalés d'une
position vers la gauche.
- Undo : on revient au buffer précédant la dernière
modification du contenu.
- Caractère standard Char c : insertion du
caractère c dans la ligne courante
(localement) à la position courante (localement). Les caractères
suivants dans la ligne sont donc décalés d'une position vers la
droite.
Sauvegarde et lecture de fichier
- L'action Save f contient la fonction f de
sauvegarde d'un buffer converti en chaîne de caractères.
- L'action Load s contient la chaîne s
que vous devrez alors convertir en buffer pour pouvoir travailler.
Fonctions imposées
- get_buffer_content : buffer → string*string
get_buffer_content b retourne une paire de chaînes
de caractères dont le membre à gauche est constitué des caractères des
deux lignes précédant la position courante dans le buffer b
et dont le membre à droite est constitué des caractères de la ligne
courante et des deux lignes la suivant.
- get_current_buffer : env → buffer
get_current_buffer e extrait le buffer courant de
l'environnement e.
- empty_env : env
L'environnement vide.
- apply_action : env → action → env
apply_action e a retourne l'environnement
résultant de l'application de l'action a dans
l'environnement e.
Vous pouvez au choix traiter une (ou plusieurs) question bonus parmi
les suivantes. Ne pas essayer d'y répondre ne retire pas de point.
- Telle que spécifié plus haut, le déplacement vertical dans le
buffer risque rapidement de mettre le curseur au niveau du premier
caractère d'une ligne (à cause du min). Implanter différemment cette
fonctionnalité pour qu'une séquence de déplacements verticaux
passant plusieurs fois par une ligne y laisse le curseur à sa position
lors du premier passage (comportement dans emacs par exemple).
Une nouvelle interface est
disponible ICI [tar.gz]
(nouvelle version avec pb. ncurses corrigé). Le
type action comporte désormais un constructeur
supplémentaire Special retourné lors de l'appui sur [f12].
Au choix :
- Implanter un redo (inverse de undo...) correspondant à
l'action Special. Si aucun redo n'est possible,
l'environnement reste inchangé.
- Implanter une justification d'un paragraphe (texte entre deux
lignes vides) à 70 caractères. Cette justification sera souple
c'est-à-dire juste une limitation des lignes à 70 caractères
maximum, sans couper de mot. (Cfr [Esc-q] dans emacs.)
- Implanter une justification comme précédemment mais stricte
cette fois : des espaces seront ajoutés tous les n mots
(intervalle à déterminer dans chaque cas) pour que la longueur des
lignes fasse exactement 70 caractères. (Cfr [Esc-1] [Esc-q] dans
emacs.)
- Implanter une fonction qui complète (termine) un mot qu'on a
commencé à taper en fonction de mots déjà présents dans le texte.