1 Langage ADA
Gé n é r icit é e n A D A
■
La notion de
sous-programme
permet la réutilisation de code
■
Les
paquetages et la POO
permettent de réutiliser du code de
façon robuste en masquant une partie de celui-ci par
excapsulation
■
Il peut également être intéressant de factoriser un morceau de
code qui peut être appliqué à différents types (non parents)
●par exemple une procédure de calcul du maximum de deux nombres est la
même pour les entiers et les réels, on voudrait ne l'écrire qu'une fois
■
ADA permet déjà le
paramétrage des types
via les discriminants
■
ADA introduit également le
paramétrage des sous-programmes
et paquetages
●
une unité de programme générique est définie à partir de types génériques
●
l'utilisation d'une unité générique nécessite son instanciation par un type non
générique
P a q u e t a g e g é n é r iq u e ( 1 / 2 )
■
Un
paquetage générique
est déclaré avec le mot-clé generic
●
un paquetage peut être déclaré générique sans pour autant avoir de
paramètre générique (utile dans le cas d'un paquetage qui hérite d'un
paquetage générique)
●
si le paquetage possède des
paramètres génériques
, ceux-ci sont déclarés
avant le début du paquetage et peuvent être des variables, des types ou des
sous-programmes non génériques
■
Le
corps d'un paquetage générique
est identique à celui d'un non
générique.
generic_package_declaration ::= generic_formal_part package_specification; generic_formal_part ::= generic {generic_formal_parameter_declaration | use_clause} generic_formal_parameter_declaration ::= formal_object_declaration | formal_type_declaration | formal_subprogram_declaration | formal_package_declaration
3 Langage ADA
P a q u e t a g e g é n é r iq u e ( 2 / 2 )
generic type Element_Data is (<>); package Paquetage_Liste is type Liste is limited private; liste_vide : constant Liste; procedure init(l : out Liste); procedure affiche(l : in Liste);procedure addElement(l : in out Liste; i : in Element_Data); procedure removeElement(l : in out Liste; i : in Element_Data); private
type Element;
type Liste is access all Element; type Element is record
suivant:Liste; valeur:Element_Data; end record;
liste_vide : constant Liste := null; procedure coucou;
end Paquetage_Liste;
4 Langage ADA
I n st a n cia t io n d 'u n p a q u e t a g e g é n é r iq u e
■
Un paquetage générique est
instancié
en précisant des valeurs
pour les paramètres génériques
with Paquetage_Liste;procedure Test is
package Paquetage_Liste_Integer is new Paquetage_Liste(Integer); use Paquetage_Liste_Integer; l : Liste; begin init(l); addElement(l,1);addElement(l,2);addElement(l,3); addElement(l,4);addElement(l,5); affiche(l); addElement(l,6); affiche(l); end;
5 Langage ADA
P a r a m è t r e s d e p a q u e t a g e g é n é r iq u e ( 1 / 4 )
■
Les paramètres génériques peuvent être des
valeurs
:
●
des
constantes
(déclarées en mode
in
)
●
des
variables
partagées entre le paquetage générique et l'unité de
programme qui l'utilise (en mode
in out
)
■
Exemple : le paquetage Paquetage_Liste peut être paramétré par une
constante qui représente la longueur maximum d'une liste
generic type Element_Data is (<>); LONGUEUR_MAX : in Natural := 100; package Paquetage_Liste is ...
P a r a m è t r e s d e p a q u e t a g e g é n é r iq u e ( 2 / 4 )
■
Les paramètres génériques peuvent être des
types
:
●
types
discrets
: définit T comme désignant tout quel type
discret
●
types
entiers
: définit T comme désignant tout type
entier
●
types
réels flottants
: définit T comme désignant
tout type réel flottant
●
types
réels fixes
: définit T comme désignant tout
type réel fixe
●
types
tableaux
: définit T
comme désignant tout type de tableau respectant le type d'indice et
d'élément données
●
types
pointeurs
: définit T comme désignant tout
type de pointeur sur le type donné (qui peut être générique!)
●
types
indéterminé
: définit T comme désignant tout
type
type T is (<>); type T is range <>; type T is digits <>; type T is delta <>; type T is private;type T is array(Type_indice) of Type_Element;
7 Langage ADA
P a r a m è t r e s d e p a q u e t a g e g é n é r iq u e ( 3 / 4 )
■
Les paramètres génériques peuvent être des
sous-programmes
:
■
Il est possible de préciser le sous-programme par défaut :
●
<> indique que le sous-programme par défaut est celui de même signature
présent obligatoirement là où le paquetage est instancié
●
le nom du sous-programme par défaut peut être indiqué
formal_subprogram_declaration ::= formal_concrete_subprogram_declaration | formal_abstract_subprogram_declaration
formal_concrete_subprogram_declaration ::= with subprogram_specification [ is subprogram_default ] ; formal_abstract_subprogram_declaration ::= with subprogram_specification is abstract [
subprogram_default ] ;
subprogram_default ::= name | <> | null
8 Langage ADA
P a r a m è t r e s d e p a q u e t a g e g é n é r iq u e ( 4 / 4 )
■
Exemple : une liste peut être implémentée avec :
●différentes procédures d'ajout (en tête ou en queue)
●différentes procédures de tri
generic
type Element_Data is (<>);
with procedure addElement(l : in out Liste; i : in Element_Data); with procedure tri(l : in out Liste) is <>;
package Paquetage_Liste is type Liste is limited private; liste_vide : constant Liste; procedure init(l : out Liste); procedure affiche(l : in Liste);
procedure removeElement(l : in out Liste; i : in Element_Data); private
9 Langage ADA
P o in t e u r su r so u s- p r o g r a m m e
■
Il est possible de définir des types
pointeurs sur des
sous-programmes
dont on donne la signature
■
L'appel du sous-programme pointé se fait en spécifiant les
paramètres passés au sous-programme (ou pt.all s'il n'y a pas de
paramètre).
■
De tels pointeurs peuvent être utilisés pour rendre "génériques"
d'autres sous-programmes.
-- type pointeur sur toute procedure sans paramètre type Pointe_Procedure is access procedure;
-- type pointeur sur toute fonction ayant la signature indiquée type Pointe_Fonction is access function(j : Float) return Integer;
-- la fonction round(f : Float) return Integer doit être définie pt_fonc : Pointe_Fonction := round'ACCESS;
pt_fonct(5.4);
D ir e ct iv e s d e co m p ila t io n
■
ADA définit des
directives de compilation
introduites par le
mot-clé
pragma
.
■
Exemples :
●CONTROLLED : sur un pointeur, indique que le ramasse-miette ne doit pas s'occuper de ce pointeur, la désallocation doit être effectuée par appel à la méthode
UNCHEKED_DEALLOCATION qui est une méthode générique devant au préalable être instanciée
●ELABORATE : sur un paquetage, oblige l'éditeur de lien à construire le corps du paquetage avant les spécifications des paquetages qui utilise le premier ●INLINE : sur un sous-programme, oblige le compilateur à remplacer les appels au
sous-programme par le code du sous-programme. type pt_Int is access Integer;
pragma CONTROLLED(pt_Int);
procedure free_pt_Int is new UNCHECKED_DEALLOCATION(Integer,pt_Int); pi : pt_Int;
...
11 Langage ADA
P r o g r a m m a t io n n o n sé q u e n t ie lle e n A D A
■
ADA permet de gérer des programmes séquentiels qui
s'exécutent en pseudo-parallèlisme : les
tâches
■
Ces tâches sont des instances d'un type particulier, le type task
qui est à la fois un processus (une suite d'instructions) et un
controleur de processus (thread of control).
■
L'ordonnancement des processus en ADA est
pseudo-parallèle
●
une file de tâches permet de donner successivement la main aux différentes
tâches
■
ADA propose des mécanismes de
synchronisation
entre tâches
●
delay
: permet d'interrompre une tâche pendant une certaine durée et
lance donc l'exécution de la tâche suivante
●
mécanisme de
rendez-vous
: une tâche peut en attendre une autre avant de
poursuivre son exécution
●
...
12 Langage ADA
T y p e T â ch e
■
Un
type tâche
comporte :
●
une
spécification
qui précise son nom et éventuellement des entrées
permettant la synchronisation
●
un
corps
qui précise le processus géré par la tâche
task type Ecrivain isend Ecrivain; task body Ecrivain is
s : String(1..6); i : Integer := 0; begin
put("Donner un texte à écrire : "); get(s); new_line; while i < 100 loop put("ecriture : ");put(s);new_line; i := i + 1; end loop;
put("l'écrivain est mort, paix à son âme!"); end Ecrivain;
...
13 Langage ADA
I n st a n ce d e t â ch e
■
Une
tâche
est une instance d'un type tâche. Une tâche peut être
déclarée directement par sa spécification et son corps, ce qui
correspond à la déclaration d'un type tâche anonyme
task Ecrivain; task body Ecrivain is
s : String(1..6); i : Integer := 0; begin
put("Donner un texte à écrire : "); get(s); new_line; while i < 100 loop put("ecriture : ");put(s);new_line; i := i + 1; end loop;
put("l'écrivain est mort, paix à son âme!"); end Ecrivain;
-- la tâche a été créée lors de sa déclaration -- et démarre dès qu'elle a la main
D e la y
■
Un premier mécanisme de gestion d'une tâche consiste à
suspendre son exécution
durant une certaine durée. Pendant
cette durée, la tâche est retirée de la file des tâches.
task Ecrivain; task body Ecrivain is
s : String(1..6); i : Integer := 0; begin
put("Donner un texte à écrire : "); get(s); new_line; while i < 100 loop put("ecriture : ");put(s);new_line; delay 0.5; i := i + 1; end loop;
put("l'écrivain est mort, paix à son âme!"); end Ecrivain;
-- la tâche a été créée lors de sa déclaration -- et démarre dès qu'elle a la main
15 Langage ADA
Sy n ch r o n isa t io n ( 1 /3 )
■
La synchronisation est possible entre deux tâches en utilisant le
mécanisme du
rendez-vous
:
●
une tâche déclare une entrée (entry) et dans son corps, place un ou
plusieurs points de rendez-vous (accept) qui peuvent contenir du code
task Ecrivain1 is entry rdv; end Ecrivain1; task body Ecrivain1 is
... begin accept rdv; while i < 10 loop ... end loop; accept rdv do put("RDV"); end rdv;
put("L'écrivain 1 est mort, paix à son âme!"); end Ecrivain1;
16 Langage ADA
Sy n ch r o n isa t io n ( 2 /3 )
■
Une autre tâche peut donner rendez-vous à la première au point
de rendez-vous en plaçant un autre point dans son corps
●les deux tâches ne pourront franchir le point que lorsque toutes les deux
l'auront atteint
■
Plusieurs tâches peuvent donner rendez-vous à celle qui a
déclaré l'entrée : une file d'attente des acceptations est créée et
le point n'est franchi que lorsque la file est vide
task Ecrivain2;
task body Ecrivain2 is s : String(1..6); i : Integer := 0; begin
while i < 10 loop
put("Je suis l'écrivain 2");new_line; i := i + 1;
end loop; Ecrivain1.rdv;
put("L'écrivain 2 est mort, paix à son âme!"); Ecrivain1.rdv;
17 Langage ADA
Sy n ch r o n isa t io n ( 3 /3 )
Co m m u n ica t io n e n t r e t â ch e s ( 1 /2 )
■
Les tâches peuvent
communiquer
via les rendez-vous : les
entrées peuvent avoir des paramètres transmis lors de l'appel du
point d'entrée, récupérés par l'instruction
accept
■
Les tâches peuvent
partager des variables
sur lesquelles un
accès en exclusion mutuelle peut être installé par l'utilisation du
pragma
SHARED(nom_variable)
■
De nombreux autres mécanismes sont implémentés pour la
programmation temps-réel
(priorités des tâches, contrôle
synchrone ou asynchrone des tâches, ...)
19 Langage ADA
Co m m u n ica t io n e n t r e t â ch e s ( 2 /2 )
task Ecrivain1 is entry rdv(i : Integer); end Ecrivain1;
task body Ecrivain1 is ...
begin ...
accept rdv(i : Integer) do put("RDV ");put(i);new_line; end;
put("L'écrivain 1 est mort, paix à son âme!"); end Ecrivain1;
task Ecrivain2; task body Ecrivain2 is
... begin ... Ecrivain1.rdv(35); end Ecrivain2; 20 Langage ADA