Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.

Slides:



Advertisements
Présentations similaires
La boucle for : init7.c et init71.c
Advertisements

Rappels C.
SI3 MAM3 Hydro Nathan Cohen Igor Litovsky Christophe Papazian
Au programme du jour …. Un peu plus de structures de données
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Langages objet Définitions Traduction des méthodes en C++
Approfondissement du langage
(Classes prédéfinies – API Java)
C.
Chap 1 Grammaires et dérivations.
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Chapitre IV. Structures linéaires (piles, files, listes chaînées)
Chapitre III Héritage (début)
Programmation orientée objet
OCaml - Les listes L3 MI.
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Expressions et assignations
Analyse lexicale Généralités Expressions rationnelles Automates finis
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
POO-L3 H. Fauconnier1 Tableau et héritage Y[] yA=new Y[3]; X[] xA=yA; //ok xA[0]=new Y(); xA[1]=new X(); //non xA[1]=new Z(); //non Object XX[]int[] YZY[]Z[]
Chapitre VII Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres.
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
Les Classes les structures en C (struct) regroupent des variables : structuration de l'analyse mais problèmes de cohérence problèmes de sécurité d'accès.
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Introduction à la programmation (Java)
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
Principes de programmation
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
LIFI-Java 2004 Séance du Jeudi 9 sept. Cours 1. La notion de langage Décrire une tâche à effectuer –programme Écrire à un haut niveau –facile pour lutilisateur.
Chapitre 9 Les sous-programmes.
1-1 Chapitre 5: Les variables Introduction Les noms Les variables Les attributions (bindings) Portée et durée de vie L'environnement de référence Les noms.
Chapitre III Héritage. POO-L3 H. Fauconnier2 Chapitre III: Héritage A) Extensions généralités Affectation et transtypage B) Méthodes Surcharge et signature.
COURS DE PROGRAMMATION ORIENTEE OBJET :
COURS DE PROGRAMMATION ORIENTEE OBJET :
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Héritage et composition
Animateur : Med HAIJOUBI
Le langage C Structures de données
2.1 - Historique Chapitre 2 : Introduction au langage C++
JavaScript Nécessaire Web.
4 Introduction des objets. Les chaînes et tableaux
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
La notion de type revisitée en POO
Les adresses des fonctions
JavaScript.
Cours 9 Exceptions (fin) Généricité. POO-L3 H. Fauconnier2 Chaînage d'exceptions  Une exception peut être causée par une autre.  il peut être utile.
11/04/ L'héritage Cours 7 Cours 7.
Un survol du language C.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Arbres binaires et tables de hachage
Tutorat en bio-informatique
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
Le langage Racket (Lisp)
ETNA – 1ème année Guillaume Belmas –
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Les surcharges d'opérateurs
TABLEAUX des POINTEURS TRAITEMENT DE STRUCTURES
ISBN Chapitre 10 L'implémentation des sous- programmes.
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Héritage Conception par Objet et programmation Java
Les bases de l’algorithmique
PRO-1027 Programmation Scientifique en C
pour les programmeurs en C++ Java 2 Part 1 3 Histoire de Java Projet de connexion des machines: 1991 Le nom Java a été introduit dans un café Développé.
BlueJ_III 1 Java, les objets : tout de suite ! Interaction entre objets Notes de cours associées au chapitre 3 tutorial BlueJ
Transcription de la présentation:

Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité

Les types en programmation Les types sont une caractéristique des langages évolués Représentation des structures de données Permet la détection d'erreurs Contrôle de types statique (à la compilation) Contrôle de types dynamique (à l'exécution) Langages à objets : enrichissement des possibilités de typage... code final analyseur syntaxique contrôleur de types générateur de code intermédiaire générateur de code final

Expressions de types Expressions représentant les types des objets Types de base booléen, caractère, entier, réel... et type vide Constructeurs de types tableaux, pointeurs... voir planche suivante Noms de types nécessaires pour les types à définition récursive (exemple : liste chaînée) Variables de types nécessaires pour la généricité (fonctions sur les types)

Constructeurs de types Tableau tableau(I, T) : tableaux d'éléments de type T indicés par des indices de type I Produit T 1 T 2 : couples d'un élément de type T 1 et d'un de type T 2 Enregistrement De même plus des noms pour les champs Pointeur pointeur(T) : pointeurs sur un objet de type T Fonction D R : fonctions de D (type du paramètre) dans R (type de la valeur de retour)

Expressions de types On peut aussi représenter les expressions de types par des arbres ou des graphes acycliques orientés (directed acyclic graph, DAG) char pointeur integer char pointeur integer char char pointer(integer)

Un contrôleur de types P --> D ; E D --> T id ; D D --> T --> B C B --> char | int C --> [ num ] C C --> E --> literal | num | id | E mod E | E [ E ] literal : constante de type caractère

Schéma de traduction P --> { sommet := new Env() ; } D ; E D --> T id ; { sommet.mettre(id.name, T.type) ; } D D --> T --> B { t := B.type ; } C { T.type := C.type ; } B --> char{ B.type := caractère ; } B --> int{ B.type := entier ; } C --> { C.type := t ; } C --> [ num ] C {C.type := tableau(num.val, C 1.type) ; }

Type d'une expression E --> literalE.type := char ; E --> numE.type := integer ; E --> idE.type := lookup(id.name) ; E --> E mod EE.type := if (E 1.type = integer and E 2.type = integer) integer else error() ; E --> E [ E ] E.type := if (E 1.type = tableau(s,t) and E 2.type = integer) t else error() ;

Type d'une instruction S --> id = ES.type := if (id.type = E.type) void else error() ; S --> if ( E ) SS.type := if (E.type = boolean) S 1.type else error() ; S --> while ( E ) S S.type := if (E.type = boolean) S 1.type else error() ; S --> S ; SS.type := if (S 1.type = void and S 2.type = void) void else error() ;

Type d'une fonction E --> E ( E ) E.type := if (E 1.type = s t and E 2.type = s) t else error() ;

Déclarations de types en C Le type des fonctions tient compte de la valeur de retour, mais pas du type des paramètres D R frenvoie(R) Pour construire un type à partir d'un type fonction, on construit d'abord un type pointeur sur fonction tableau(frenvoie(int))int tab[ ]()non tableau(pointeur(frenvoie(int))) int (* tab[ ])()oui La déclaration se fait à l'envers par rapport à l'expression de type

Déclarations de types en C int (* tab[ ])()inttype de base (* tab[ ])() déclarateur (Dtor) Dtor * ( )( ) ][ tab tableau pointeur frenvoie int déclarateurexpression de type marque de fonction marque de pointeur marque de tableau

Schéma de traduction P --> D ; E D --> D ; D D --> basic Dtor { addType(Dtor.id, Dtor.constr || basic.type) ; } basic --> char { basic.type := char ; } basic --> int { basic.type := integer ; } Dtor --> Dtor [ ] { Dtor.constr := Dtor 1.constr || array ; Dtor.id := Dtor 1.id ; } Dtor --> Dtor ( ) { Dtor.constr := Dtor 1.constr || freturns ; Dtor.id := Dtor 1.id ; }

Schéma de traduction Dtor --> * Dtor { Dtor.constr := Dtor 1.constr || pointer ; Dtor.id := Dtor 1.id ; } Dtor --> ( Dtor ) { Dtor.constr := Dtor 1.constr ; Dtor.id := Dtor 1.id ; } Dtor --> id { Dtor.constr := "" ; Dtor.id := id.entry ; } Pour déclarer plusieurs variables avec le même type de base : D --> basic { list.basic := basic.type ;} list list --> Dtor { addType(Dtor.id, Dtor.constr || list.basic) ; } list --> { list 1.basic := list.basic ;} list, Dtor { addType(Dtor.id, Dtor.constr || list.basic) ; }

Equivalence d'expressions de types Vérification de l'équivalence boolean equiv(s, t) { if (s et t sont du même type de base) return true ; else if (s == tableau(s1, s2) && t == tableau(t1, t2)) return equiv(s1, t1) && equiv(s2, t2) ; etc. On tolère une différence comme les dimensions d'un tableau passé en paramètre

Equivalence d'expressions de types Deux types d'équivalence - structurelle : quand on tombe sur un nom de type, on le remplace par l'expression qu'il représente puis on continue la comparaison - nominale : quand on tombe sur un nom de type, on le compare directement

Equivalence d'expressions de types Exemple d'implémentation pour le langage C Pour plus d'efficacité on teste d'abord l'égalité sur une expression simplifiée codée par un entier On ne tient pas compte des dimensions des tableaux ni des types des paramètres des fonctions Codage des constructeurs de types pointer()array()freturns() Codage des types de base booleancharintegerreal

Conversions de types L'addition des réels et l'addition des entiers sont des opérations distinctes car la représentation des données est distincte Exemple : l'expression x + i où x est un réel et i un entier nécessite une conversion Traduction en représentation postfixe : x i intToReal real+ où real+ désigne l'addition des réels Conversions implicites (coercion) faites par le compilateur Conversions explicites (casting) exemple en C : (float) 10

Conversions implicites E --> numE.type := integer ; E --> num.numE.type := real ; E --> idE.type := lookup(id.entry) ; E --> E op EE.type := if (E 1.type=integer and E 2.type=integer) integer ; else if (E 1.type=integer and E 2.type=real) real ; etc.

Surcharge des opérateurs Cas où un même symbole représente plusieurs opérateurs L'opérateur à appliquer est choisi en fonction du contexte Exemple : + désigne l'addition des entiers ou des matrices On considère un opérateur comme une fonction Schéma de traduction pour calculer les types possibles d'une expression E --> idE.types := lookup(id.entry) E --> E ( E )E.types := { t | il existe un s dans E 2.types tel que s t est dans E 1.types }

Surcharge des opérateurs Exemple : l'opérateur * peut prendre des opérandes entiers ou complexes et le résultat peut être entier ou complexe E.types={i, c} E.types={i} *.types= {i i i, i i c, c c c} 5 3 E.types={i}

Surcharge des méthodes en Java class A { int a, b; A(int a, int b){this.a = a; this.b = b; } } class B{ private A couple; B(int a, int b){couple = new A(a,b); } B(A couple){this.couple = new A(couple.a, couple.b); } A getA( ){ return couple;} void ajouter(int inc){getA().a += inc; getA().b += inc; } void ajouter(B couple){ this.getA().a += couple.getA().a; this.getA().b += couple.getA().b; } }

Surcharge des méthodes en Java Définitions de plusieurs méthodes de même nom dans la même classe ou interface (ou par héritage) Les méthodes surchargées diffèrent par leur signature Signature d'une méthode : nombre, ordre et type des paramètres formels void ajouter(int inc){ void ajouter(B couple){

Surcharge des méthodes en Java B c1 = new B(3, 5); B c2; System.out.println("c1=" + c1); c1.ajouter(5); System.out.println("c1=" + c1); c2 = new B(c1.getA()); c2.ajouter(c1); Sélection de la méthode pour un appel Utilisation du type des paramètres effectifs S'ils correspondent exactement à la signature d'une des méthodes, elle est sélectionnée Le type de retour n'intervient pas

Surcharge des méthodes en Java Sélection de la méthode pour un appel Utilisation du type des paramètres effectifs S'ils ne correspondent exactement à la signature d'aucune des méthodes, on cherche des correspondances par conversion de type

Sélection de méthode surchargée Exemple d'algorithme de sélection de méthode surchargée S'il n'y a pas de correspondance exacte avec une des signatures concurrentes, on utilise les conversions ascendantes double float byte... interface classe mère classe fille...

Sélection de méthode surchargée pour chaque signature concurrente s { distance (s) = 0 ; pour chaque paramètre distance (s) += nombre de conversions ascendantes directes pour passer du type du paramètre effectif au type du paramètre formel ; } calculer la distance minimale m ; s'il existe une seule signature s telle que distance(s) == m sélectionner s ; sinon erreur de syntaxe ;

Fonctions génériques Fonctions dont les paramètres ou la valeur de retour sont de type non précisé Exemples L'opérateur & du C : si E est de type t, alors & E est de type pointer(t) Les fonctions génériques du langage ADA Certaines fonctions en langage CAML

Exemple Calcul de la longueur d'une liste Exemple non générique en C typedef struct cell { int info ; struct cell * link ; } cell ; int length(cell * list) { int len = 0 ; while (list) { len ++ ; list = list -> link ; } return len ; } On est obligé de connaître le type des éléments de la liste pour déclarer le type cell et la fonction

Exemple Exemple générique en ML fun length(list) = if null(list) then 0 else length(tl(list)) + 1 ; null() et tl() sont prédéfinies

Un langage avec généricité P --> D ; E D --> D ; D | id : Q Q --> typeVar. Q | T T --> basicType | unaryConstructor ( T ) | typeVar | T T | ( T ) E --> E ( E ) | E, E | id

Exemple Déclaration de la fonction de déréférencement deref :. pointer( ) ; Déclaration d'un pointeur q : pointer(pointer(integer)) ; Arbre syntaxique de l'expression deref(deref(q)) apply.type= deref.type=.pointer( ) q.type=pointer(pointer(integer)) apply.type= deref.type=.pointer( )

Exemple Des occurrences distinctes d'une fonction générique n'ont pas nécessairement le même type Les types des variables doivent être unifiés Ils ne peuvent plus être déterminés à partir de leurs constituants apply.type= =integer deref.type=.pointer( ) q.type=pointer(pointer(integer)) apply.type= =pointer(integer) deref.type=.pointer( )