Cours 3: Instructions

Objectif: Affectation. Instructions conditionnelles. Expression.
Condition. Sous-programme, procédure et fonction, spécification et corps.
Procédures et fonctions d'entrées-sorties des types de base.

Extrait du manuel de référence (RM95):


       sequence_of_statements ::= statement {statement}

       statement ::=
          {label} simple_statement | {label} compound_statement

       simple_statement ::= null_statement
          | assignment_statement              | exit_statement
          | goto_statement                    | procedure_call_statement
          | return_statement                  | entry_call_statement
          | requeue_statement                 | delay_statement
          | abort_statement                   | raise_statement
          | code_statement

       compound_statement ::=
            if_statement                      | case_statement
          | loop_statement                    | block_statement
          | accept_statement                  | select_statement

       assignment_statement ::=
          variable_name := expression;

Le caractère ";" termine une instruction (il ne sépare pas).
Le signe d'affectation est ":=".
Le terme à gauche du signe d'affectation doit être un objet variable.
Le terme à droite est une expression: un objet variable ou constant ou une opération entre un objet et une sous-expression.
L'effet d'une instruction d'affectation est de ranger la valeur de l'expression à droite du signe d'affectation dans l'objet à gauche.

Extrait du manuel de référence (RM95):


       Examples of assignment statements:

       Value := Max_Value - 1;
       Shade := Blue;

       U := Dot_Product(V, W);            -- function call

       Examples involving scalar subtype conversions:

       I, J : Integer range 1 .. 10 := 5;
       K    : Integer range 1 .. 20 := 15;
        ...

       I := J;  --  identical ranges
       K := J;  --  compatible ranges
       J := K;  --  will raise Constraint_Error if K > 10

Extrait du manuel de référence (RM95):


       if_statement ::=
           if condition then
             sequence_of_statements
          {elsif condition then
             sequence_of_statements}
          [else
             sequence_of_statements]
           end if;

       condition ::= boolean_expression

Une instruction conditionnelle se compose d'une condition principale et d'éventuelles conditions secondaires.
Chaque condition commande la séquence d'instructions qui suit.
Eventuellement, une dernière séquence n'est commandée par aucune condition (partie "else").

La condition principale est évaluée.
Si sa valeur est True (une condition est une expression à valeur booléenne), la séquence qu'elle commande est exécutée.
Si sa valeur est False, sa séquence n'est pas exécutée et la condition suivante est évaluée.
On continue ainsi jusqu'à ce que soit une condition ait la valeur True (et sa séquence est exécutée), soit la dernière séquence est atteinte (et elle est exécutée).
Au plus une séquence est exécutée (aucune si les conditions valent toutes False et s'il n'y a pas de partie "else").

Extrait du manuel de référence (RM95):


       Examples of if statements:

       if Month = December and Day = 31 then
          Month := January;
          Day   := 1;
          Year  := Year + 1;
       end if;

Autres exemples:


       if (X < Y) and (X < Z) then
          M := X;
       elsif (Y < X) and (Y < Z) then
          M := Y;
       else
          M := Z;
       end if;

Expression

Extrait du manuel de référence (RM95):


       expression ::=
            relation {and relation} | relation {and then relation}
          | relation {or relation}  | relation {or else relation}
          | relation {xor relation}

       relation ::=
            simple_expression [relational_operator simple_expression]
          | simple_expression [not] in range
          | simple_expression [not] in subtype_mark

       simple_expression ::= [unary_adding_operator] term {binary_adding_operator term}

       term ::= factor {multiplying_operator factor}

       factor ::= primary [** primary] | abs primary | not primary

       primary ::=
          numeric_literal | null | string_literal | aggregate
        | name | qualified_expression | allocator | (expression)

Extrait du manuel de référence (RM95):


       Examples of primaries:

       4.0                --  real literal
       Pi                 --  named number
       Sum                --  variable
       Integer'Last       --  attribute
       Sine(X)            --  function call
       Color'(Blue)       --  qualified expression
       Real(M*N)          --  conversion
       (Line_Count + 10)  --  parenthesized expression

       Examples of expressions:

       Volume                      -- primary
       not Destroyed               -- factor
       2*Line_Count                -- term
       -4.0                        -- simple expression
       -4.0 + A                    -- simple expression
       B**2 - 4.0*A*C              -- simple expression
       Password(1 .. 3) = "Bwv"    -- relation
       Count in Small_Int          -- relation
       Count not in Small_Int      -- relation
       Index = 0 or Item_Hit       -- expression
       (Cold and Sunny) or Warm    -- expression (parentheses are required)
       A**(B**C)                   -- expression (parentheses are required)

Procédure et fonction. Déclaration (prototype).

Un programme Ada est composé d'unités de programme.
Les paquetages, les procédures et les fonctions sont des unités de programme.
Une unité de programme se compose d'une déclaration et d'un corps.

La déclaration d'une procédure comprend son nom et ses paramètres formels.
La déclaration d'une fonction comprend en plus le type de son résultat.
Les paramètres formels sont les objets contenant les valeurs effectives transmises lors de l'appel.
Les paramètres formels peuvent être associés aux paramètres effectifs de trois façons:
Par défaut, le mode est "in".
Les paramètres d'une fonction doivent être en mode "in".

Extrait du manuel de référence (RM95):

       subprogram_declaration ::= subprogram_specification;

       subprogram_specification ::=
            procedure defining_program_unit_name  parameter_profile
          | 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_profile ::= [formal_part]

       parameter_and_result_profile ::= [formal_part] return subtype_mark

       formal_part ::=
          (parameter_specification {; parameter_specification})

       parameter_specification ::=
           defining_identifier_list : mode  subtype_mark [:= default_expression]
         | defining_identifier_list : access_definition [:= default_expression]

       mode ::= [in] | in out | out

Extrait du manuel de référence (RM95):


       Examples of subprogram declarations:

       procedure Traverse_Tree;
       procedure Increment(X : in out Integer);
       procedure Right_Indent(Margin : out Line_Size);
       procedure Switch(From, To : in out Link);

       function Random return Probability;

       function Min_Cell(X : Link) return Cell;
       function Next_Frame(K : Positive) return Frame;
       function Dot_Product(Left, Right : Vector) return Real;

       function "*"(Left, Right : Matrix) return Matrix;

       Examples of in parameters with default expressions:

       procedure Print_Header(Pages  : in Natural;
                   Header : in Line    :=  (1 .. Line'Last => ' ');
                   Center : in Boolean := True);

Autres exemples:


       procedure Echanger(X, Y : in out Integer);
       procedure Double_Affectation(X, Y : out Integer; A, B : in Integer);

       function Milieu3(A, B, C : Integer) return Integer;
       function Max3(A, B, C : Integer) return Integer;
       function Min3(A, B, C : Integer) return Integer;
       function Milieu5(A, B, C, D, E : Integer) return Integer;
       function Max5(A, B, C, D, E : Integer) return Integer;
       function Min5(A, B, C, D, E : Integer) return Integer;

Extrait du manuel de référence (RM95):


       subprogram_body ::=
           subprogram_specification is
              declarative_part
           begin
               handled_sequence_of_statements
           end [designator];

Extrait du manuel de référence (RM95):


       Example of procedure body:

       procedure Push(E : in Element_Type; S : in out Stack) is
       begin
          if S.Index = S.Size then
             raise Stack_Overflow;
          else
             S.Index := S.Index + 1;
             S.Space(S.Index) := E;
          end if;
       end Push;

       Example of a function body:

       function Dot_Product(Left, Right : Vector) return Real is
          Sum : Real := 0.0;
       begin
          Check(Left'First = Right'First and Left'Last = Right'Last);
          for J in Left'Range loop
             Sum := Sum + Left(J)*Right(J);
          end loop;
          return Sum;
       end Dot_Product;

L'appel de procédure est une instruction.
L'appel de fonction est une expression. La valeur de l'expression est la valeur de retour de la fonction.
L'appel conduit à l'élaboration (l'exécution de la partie déclarative) puis à l'exécution du corps.

Extrait du manuel de référence (RM95):


       procedure_call_statement ::=
           procedure_name;
         | procedure_prefix actual_parameter_part;

       function_call ::=
           function_name
         | function_prefix actual_parameter_part

       actual_parameter_part ::=
           (parameter_association {, parameter_association})

       parameter_association ::=
          [formal_parameter_selector_name =>] explicit_actual_parameter

       explicit_actual_parameter ::= expression | variable_name

Extrait du manuel de référence (RM95):


       Examples

       Examples of procedure calls:

       Traverse_Tree;
       Print_Header(128, Title, True);
       Switch(From => X, To => Next);
       Print_Header(128, Header => Title, Center => True);
       Print_Header(Header => Title, Center => True, Pages => 128);

       Examples of function calls:

       Dot_Product(U, V)
       Clock

       Examples of procedures with default expressions:

       procedure Activate(Process : in Process_Name;
                          After   : in Process_Name := No_Process;
                          Wait    : in Duration := 0.0;
                          Prior   : in Boolean := False);

       procedure Pair(Left, Right : in Person_Name := new Person); 

       Examples of their calls:

       Activate(X);
       Activate(X, After => Y);
       Activate(X, Wait => 60.0, Prior => True);
       Activate(X, Y, 10.0, False);

       Pair;
       Pair(Left => new Person, Right => new Person);

       Examples of overloaded subprograms:

       procedure Put(X : in Integer);
       procedure Put(X : in String);

       procedure Set(Tint   : in Color);
       procedure Set(Signal : in Light);

       Examples of their calls:

       Put(28);
       Put("no possible ambiguity here");

       Set(Tint   => Red);
       Set(Signal => Red);
       Set(Color'(Red));

       --  Set(Red) would be ambiguous since Red may
       --  denote a value either of type Color or of type Light

Autres exemples:


       procedure Echanger(X, Y : in out Integer) is
          Z : Integer;
       begin
          Z := Y; Y := X; X := Z;
       end Echanger;

       procedure Double_Affectation(X, Y : out Integer; A, B : Integer) is
       begin
          X := A; Y := B;
       end Double_Affectation;

       function Max3(A, B, C : Integer) return Integer is
       begin
          return Integer'Max(Integer'Max(A,B), C);
       end Max3;

       function Min3(A, B, C : Integer) return Integer is
       begin
          return Integer'Min(Integer'Min(A,B), C);
       end Min3;

       function Milieu3(A, B, C : Integer) return Integer is
       begin
          return Max3(Integer'Min(A,B), Integer'Min(A,C), Integer'Min(B,C));
       end Milieu3;

Le paquetage Ada.Text_IO est prédéfini.
Il contient un ensemble de procédures d'entrées-sorties.
Pour appeler une procédure P du paquetage, on la désigne par Ada.Text_IO.P.

Extrait du manuel de référence (RM95):


          -- Output a new line character
          procedure New_Line  (Spacing : in Positive_Count := 1);

          -- Character Input-Output
          procedure Get(Item : out Character);
          procedure Put(Item : in  Character);

          -- String Input-Output
          procedure Get(Item : out String);
          procedure Put(Item : in  String);
          procedure Get_Line(Item : out String; Last : out Natural);
          procedure Put_Line(Item : in  String);

          -- Generic packages for Input-Output of Integer Types
          generic
             type Num is range <>;
          package Integer_IO is

             Default_Width : Field := Num'Width;
             Default_Base  : Number_Base := 10;
             procedure Get(Item  : out Num;
                           Width : in  Field := 0);
             procedure Put(Item  : in Num;
                           Width : in Field := Default_Width;
                           Base  : in Number_Base := Default_Base);

          end Integer_IO;
          -- Package Integer_Text_IO is a non generic instanciation of
          -- the generic package Text_IO.Integer_IO for the predefined type Integer

          -- Generic packages for Input-Output of Real Types
          generic
             type Num is digits <>;
          package Float_IO is

             Default_Fore : Field := 2;
             Default_Aft  : Field := Num'Digits-1;
             Default_Exp  : Field := 3;
             procedure Get(Item  : out Num;
                           Width : in  Field := 0);
             procedure Put(Item : in Num;
                           Fore : in Field := Default_Fore;
                           Aft  : in Field := Default_Aft;
                           Exp  : in Field := Default_Exp);

          end Float_IO;
          -- Package Float_Text_IO is a non generic instanciation of
          -- the generic package Text_IO.Float_IO for the predefined type Float

          -- Generic package for Input-Output of Enumeration Types
          generic
             type Enum is (<>);
          package Enumeration_IO is

             Default_Width   : Field := 0;
             Default_Setting : Type_Set := Upper_Case;
             procedure Get(Item : out Enum);
             procedure Put(Item  : in Enum;
                           Width : in Field    := Default_Width;
                           Set   : in Type_Set := Default_Setting);

          end Enumeration_IO;
          -- A package Boolean_Text_IO may be instanciated with
          -- with Ada.Text_IO;
          -- package Boolean_Text_IO is new Ada.Text_IO.Enumeration_IO(Boolean);

       end Ada.Text_IO;

Exemple:


          procedure Bonjour; -- specification

          with Ada.Text_IO;  -- pour rendre visible les procedures de Text_IO
          procedure Bonjour is
            Nom : String(1..20);
          begin
            Ada.Text_IO.Put("Comment t'appelles-tu? ");
            Ada.Text_IO.Get(Nom);
            Ada.Text_IO.Put("Bonjour ");
            Ada.Text_IO.Put(Nom);
            Ada.Text_IO.New_Line;
          end Bonjour;

          procedure Milieu;

          with Ada.Text_IO;
          procedure Milieu is
            X, Y, Z: Integer;
          begin
            Ada.Text_IO.Put("Entrez trois entiers: ");
            Ada.Integer_Text_IO.Get(X);
            Ada.Integer_Text_IO.Get(Y);
            Ada.Integer_Text_IO.Get(Z);
            Ada.Integer_Text_IO.Put(Milieu3(X, Y, Z));
            Ada.Text_IO.Put(" est entre ");
            Ada.Integer_Text_IO.Put(Min3(X, Y, Z));
            Ada.Text_IO.Put(" et ");
            Ada.Integer_Text_IO.Put(Max3(X, Y, Z));
          end Milieu;