Langage ADA 1
S o u s- p r o g r a m m e s
■Les sous-programmes permettent de déclarer et d'implémenter des traitements réutilisables.
■Les sous-programmes travaillent sur des objets (instances de types) mais pas sur des types ou des sous-programmes (pas de méta-programmation).
■Les sous-programmes peuvent être paramétrés par des types ou des sous-programmes par le mécanisme de généricité.
■Possibilité de séparer déclaration et implémentation des sous- programmes (utile pour des sous-programmes qui s'appellent mutuellement). Cela augmente la lisibilité des programmes.
P r o cé d u r e s
■Les procédures peuvent agir sur leurs paramètres et n'ont pas de valeur de retour.
■Spécification des procédures :
■Une procédure peut n'avoir aucun paramètre
procedure_specification ::= procedure defining_program_unit_name [ parameter_profile ] defining_program_unit_name ::= [ parent_unit_name . ] defining_identifier
parameter_profile ::= ( parameter_specification { ; parameter_specification } )
parameter_specification ::= defining_identifier_list : mode [ null_exclusion ] subtype_mark [
:= default_expression ]
| defining_identifier_list : access_definition [ := default_expression ] mode ::= [ in ] | in out | out
Langage ADA 3
P a ssa g e d e s p a r a m è t r e s
■ADA propose 3 modes de passage des paramètre :
●in : passage par valeur, le paramètre effectif n'est pas modifié (c'est le mode par défaut)
●out : la procédure affecte une valeur au paramètre effectif mais n'a pas accès à la valeur du paramètre effectif (qui n'a pas besoin d'être initialisée avant l'appel)
●in out : passage par variable, le paramètre effectif doit être initialisé avant l'appel et la procédure peut en modifier la valeur
■Spécifier une valeur par défaut n'est possible que pour les paramètres en mode in
■ Exemples :
procedure ecrire_bonjour;
procedure dessiner_ligne(x1,y1,x2,y2 : Integer);
procedure lire_nombre(x : out Integer);
procedure multiplie_par_2(x : in out Integer);
procedure decremente(x : in out Integer; pas : in Integer := 1);
4 Langage ADA
F o n ct io n s ( 1 /2 )
■Les fonctions ont une valeur de retour et des paramètres
■Spécification des fonctions :
function_specification ::= function defining_designator parameter_and_result_profile defining_designator ::= defining_program_unit_name | defining_operator_symbol defining_program_unit_name ::= [ parent_unit_name . ]defining_identifier defining_operator_symbol ::= operator_symbol
parameter_and_result_profile ::= [ formal_part ] return [ null_exclusion ] subtype_mark | [ formal_part ] return access_definition formal_part ::= ( parameter_specification { ; parameter_specification } )
parameter_specification ::= defining_identifier_list : mode [ null_exclusion ] subtype_mark [ := default_expression ]
| defining_identifier_list : access_definition [ := default_expression ] mode ::= [in] | in out | out
Langage ADA 5
F o n ct io n s ( 2 /2 )
■Les paramètres d'une fonction sont en mode in par défaut et il n'est pas possible de spécifier un autre mode
■Les fonctions permettent de redéfinir les opérateurs
■ Exemples :
function aleatoire return Integer;
function pgcd(a,b : Integer) return Integer;
function "+" (a,b : Integer) return Integer;
function aleatoire(domaine : in Integer := 1) return Integer;
Co r p s d e s so u s- p r o g r a m m e s
■Le corps d'un sous-programme est de même forme qu'un programme et comporte une partie déclarative et un ensemble d'instructions :
■La plupart du temps, on écrit la déclaration et le corps du sous- programme à la suite mais on peut séparer les deux.
■Le nom du sous-programme après le end est en général optionnel. Il est possible d'imbriquer des sous-programmes et alors il faut préciser le nom du sous-programme qui se termine.
subprogram_body ::= [ overriding_indicator ] subprogram_specification is declarative_part
begin
handled_sequence_of_statements end [ designator ] ;
Langage ADA 7
Ex e m p le s d e so u s- p r o g r a m m e s
function pgcd(a,b:Integer) return Integer is c : Integer;
begin
c := a rem b;
if c=0 then return b;
else return pgcd(b,c);
end if;
end;
procedure ecrire_bonjour is begin
put("bonjour");
end;
procedure decremente(x : in out Integer; pas : in Integer := 1);
procedure decremente(x : in out Integer; pas : in Integer := 1) is begin
x := x - pas;
end decremente;
8 Langage ADA
I n t é r ê t d e la d é cla r a t io n sé p a r é e
function pair(i : Integer) return Boolean;
function impair(i : Integer) return Boolean;
function pair(i : Integer) return Boolean is begin
if i=0 then return True;
else return impair(i - 1);
end if;
end;
function impair(i : Integer) return Boolean is begin
if i=0 then return False;
else return pair(i - 1);
end if;
end;
Langage ADA 9
R e d é f in it io n d 'o p é r a t e u r s
■Il est possible de redéfinir les opérateurs prévus sur les types par des fonctions. Il est possible de définir les opérateur sur de nouveaux types.
■Il est impossible de définir de nouveaux symboles d'opérateurs ni de modifier leur arité ni de changer les priorités des opérateurs!
■L'opérateur \= ne peut être redéfini. L'opérateur = ne peut être redéfini que sur les types limités et sa redéfinition entraine la redéfinition automatique de \=.
■ Exemple : function "+"(a,b : Integer) return Integer is begin
return a+b;
end;
=> la compilation génère un warning (récursivité infinie)
A p p e ls d e so u s- p r o g r a m m e s
■Les paramètres dans les appels de sous-programmes peuvent être indiqués par position ou par association
■ Exemples :
■Les opérateurs peuvent être utilisés en notation fonctionnelle.
■ Exemples : c := "+"(2,3);
d := 2 + 3;
pgcd(2,3);
pgcd(a => 2, b => 3);
pgcd(2, b => 3);
Langage ADA 11
Re n o m m a g e d e s so u s- p r o g r a m m e s
■Le renommage d'un sous-programme doit utiliser le même profil que le sous-programme renommé. Seuls les noms des
paramètres et les valeurs par défaut peuvent être modifiés.
■Le nom d'origine est toujours utilisable avec les anciens noms de paramètre et les anciennes valeurs par défaut.
■ Exemples :
function pgcd(a,b:Integer) return Integer is c : Integer;
begin
c := a rem b;
if c=0 then return b;
else return pgcd(b,c);
end if;
end;
function greatest_common_divisor(x : Integer; y : Integer := 2) return Integer renames pgcd;
12 Langage ADA
P o ly m o r p h ism e e n A D A
■Le sous-programme appelé par une instruction est déterminé à la compilation par :
●le nom du sous-programme
●le type de sa valeur de retour (fonction) ou l'absence de valeur de retour (procédure)
●les types de ses paramètres
■Si le nombre de sous-programmes correspondant à ces critères est différent de 1 (0 ou plus de 1) la compilation échoue
■Le nom d'un sous-programme peut donc être surchargé si on modifie les types de ses paramètres ou de sa valeur de retour
function pgcd(a,b : Integer) return Integer;
function pgcd(a : Integer; b : Float) return Integer;
procedure pgcd(a,b : Integer);
function pgcd(a,b : Integer) return Positive;
-- duplication de fonction détecté à la compilation (même sans appel)
Langage ADA 13
P o ly m o r p h ism e t o t a l
■On pourrait en ADA faire du polymorphisme sur les variables et pas seulement sur les sous-programmes en autorisant
l'utilisation du même identifiant pour 2 variables de types différent
●c'est possible en pratique grâce au typage fort qui permet de déterminer à tout moment le type d'une variable
■Ca n'a aucune utilité en pratique et cela diminuerait la lisibilité du code => ce n'est pas implémenté
Re n o m m a g e d e s so u s- p r o g r a m m e s
■Le renommage d'un sous-programme doit respecter les règles suivantes :
●le nouveau sous-programme doit avoir le même nombre de paramètres
●ces paramètres doivent être compatibles avec les anciens (identiques ou dérivés ou sous-types)
●une procédure ne peut être renommée que par une procédure
●une fonction ou un opérateur peuvent être renommés indifféremment par une fonction ou opérateur
■ Exemples :
function gcd(i,j : Integer) return Positive renames pgcd;
procedure gcd(i : Positive; j : Positive :=1) renames pgcd;
Langage ADA 15
Co n v e r sio n d e t y p e s
■La conversion de type est toujours explicite et fait appel à des fonctions dédiées
■Les conversions sont permises entre :
●les types numériques
●un type dérivé et son type de base
●les tableaux de même type d'indices, même dimension et même type d'éléments
■ Exemples :
i : Float := Float(pgcd(3,11));
type Vecteur is array(Integer range <>) of Float;
subtype Vecteur_10 is Vecteur(1..10);
v : Vecteur(0..100);
w : Vecteur(-10..10);
Vecteur(v); -- v ne change pas
Vecteur_10(w); -- lève une CONSTRAINT_ERROR
16 Langage ADA
Er r e u r s d 'e x é cu t io n s
■Dans tout programme, il y a des erreurs d'exécution possibles , des cas particuliers qui n'ont pas forcément été traités. On ne vise pas à les supprimer, mais à les controler (robustesse du code, tolérance aux erreurs)
●il s'agit d'erreurs d'exécution, pas d'erreur de programmation que le compilateur peut détecter.
●Exemple : un fichier que le programme essaie de lire est déjà utilisé par une autre application
■Quand il y a une erreur, on voudrait se retrouver dans un endroit du programme d’où l’on peut récupérer de l’erreur :
●Exemple : une méthode utilise un nombre passé en paramètre, nombre par lequel on divise un autre nombre. Ce nombre est donné par l'utilisateur. Si ce nombre vaut 0, on veut que l'erreur qu'il déclenche soit traitée au niveau de l'interaction avec l'utilisateur, et non à l'intérieur de la méthode.
■L'erreur doit donc pouvoir être propagée et véhiculer une description pour être traitée en dehors du contexte où elle s'est produite
=> Exception
Langage ADA 17
Ex ce p t io n
■Le mécanisme des exceptions permet de récupérer d'une erreur et de poursuivre l'exécution du programme. Il consiste
●à identifier les erreurs possibles au moment de l'écriture du programme
●à déclencher des exceptions en cas d'erreur
●à traiter ces exceptions (récupération)
■Une exception lancée par une instruction dans une partie déclaration entraine l'abandon des déclarations suivantes
■Une exception lancée par une instruction dans un corps de programme entraine la sortie immédiate de ce corps
■Une exception non traitée se propage
La g e st io n d ’ u n e e x ce p t io n
Une erreur qui lève une exception
Un contexte d’exécution
Le contexte d’exécution qui attrape l’exception
saut
Un programme qui rencontre une erreur doit en transférer le traitement à une autre partie ("exception handler") et lui donner une valeur qui décrit l’erreur (l’"exception" proprement dite)
■ Le principe d’endiguement :
● Un programme est une hiérarchie de contextes d’exécution
● Une erreur n’est visible qu’à l’intérieur d’un contexte dans cette hiérarchie
● Une routine de récupération existe à l’interface d’un contexte d’exécution, pour que l’erreur ne se propage pas vers un niveau plus elevé
Langage ADA 19
D é cla r a t io n e t la n ce m e n t d 'e x ce p t io n
■Exception est un type particulier qui permet simplement de nommer des exceptions
■Le mot-clé permettant le lancement d'exception est raise :
division_by_zero : Exception;
file_not_found : Exception;
raise Ada.IO_Exceptions.Name_Error;
raise division_by_zero;
raise; -- relance de l'exception courante -- (uniquement dans un exception handler)
20 Langage ADA
T r a it e m e n t d 'e x ce p t io n
■Les exceptions sont traitées dans des blocs particuliers en fin de corps de programme. Dans ce bloc, différents traitements peuvent être menés en fonction des exceptions
■Une exception non traitée dans le bloc de traitement est propagée. Un exception lancée dans ce bloc de traitement est toujours propagée.
...
begin
open(file, in_file, "input.txt");
divise(a,b);
exception
when file_not_found => put("Cannot open input file : ");raise;
when e : division_by_zero => put_line(exception_message(e));
when others => put("Unknown Error");
end;
Langage ADA 21
P r o p a g a t io n d 'e x ce p t io n
procedure ExceptionExample is procedure p(i : Integer) is e0,e1,e2 : Exception;
begin
if i = 0 then raise e0; end if;
if i = 1 then raise e1; end if;
if i = 2 then raise e2; end if;
exception
when e0 => put_line("exception 0");raise;
when e1 => put_line("exception 1");
end;
begin
-- p(0); -> écrit exception 0 et plante sur une exception e0 -- p(1); -> écrit exception 1 et se termine correctement -- p(2); -> plante sur une exception e2
end ExceptionExample;
Blo c
■Un bloc est une instruction particulière combinant des déclarations (optionnelles) et des instructions.
■Un bloc permet de traiter localement des exceptions
block_statement ::= [ block_statement_identifier : ] [ declare
declarative_part ] begin
handled_sequence_of_statements end [ block_identifier ] ;
procedure lire_fichiers(tab : array(Integer range <>) of String) is begin
for i in tab'FIRST..tab'LAST loop bloc_lecture :
begin
lire_fichier(tab(i));
exception
when file_not_found => put_line(tab(i) & " introuvable");
when others => put_line("Pb de lecture sur " & tab(i));
end bloc_lecture;
end loop;
end lire_fichiers;
Langage ADA 23
Ex ce p t io n s p r é d é f in ie s
■Les exceptions prédéfinies en ADA, lancées lorsqu'un contrôle prévu par le langage échoue, sont Constraint_Error, Program_Error, Storage_Error et Tasking_Error
■Le paquetage Ada.Exceptions contient plein d'autres exceptions et des méthodes pour les manipuler dont
●procedure Raise_Exception(E:in Exception_Id;
Message:in String := "");
●function Exception_Message(X : Exception_Occurrence) return String;
●...
■Il est possible de renommer les exceptions
■Ada définit de nombreux autres paquetages ...
EOF : Exception renames Ada.IO_Exceptions.End_Error;