Case Statements in Ada


type dimension is (row, col);
function A (num: …; dim: in out dimension) return integer is

case dim is
when row => return my_array(num).row;–? ok
when col => A (… ) ;
– ^ returns my_array(num).col
end case;

------------------------------------ use example
my_row := A(num:num_range; dim:in out dimension);

with this case statement, can I put a single line of code, rather than a sub program call after the =>?

The case statement has the production sequence_of_statements as the element after the arrow (=>), so yes, you can have a sequence of one statement.

tks a million; most examples are a sub program call

How odd.
I think one of the most natural examples would be writing a simple virtual machine.

Type Instruction is (Add, Sub, Done);
Type VM is limited private;

Procedure Execute( Object : in out VM );
Procedure Load   ( Object : in out VM;
                   Input  : in out Root_Stream_Type'Class );
-- …
Procedure Execute( Object : in out VM ) is
  Finished : Boolean:= False;
Begin
  Run:
  Loop
    case Object.Program(Object.Program_Counter) is
      when Add =>
         declare
            Left   : Integer renames Object.Registers(1);
            Right  : Integer renames Object.Registers(2);
         begin
            Left:= Left + Right;
         exception
            when Constraint_Error => Object.Flags( Overflow ):= True;
         end;
      when Sub => -- Same, but for "-".
      when Done => Finished:= True;
    end case;
    Exit Run when Finished;
    Object.Program_Counter:= Positive'Succ( Object.Program_Counter );
  End Loop Run;
End Execute;

Very nice and thanks. From some stupidity on my part, I didn’t get that following the => can be any code block, but not only a call to a sub program.

You can also embed case statements into assignments, doing something like this:

   type Answer is (No, Yes, Other, DisableDefault);

   function Get_Answer
     (Prompt         : String;
      Default_Answer : Answer := DisableDefault;
      Provided_Text  : String := "")
   return Answer is
      Question : constant String :=
        Prompt & " [" &
        (case Default_Answer is
          when Yes    => "Y/n",
          when No     => "y/N",
          when others => "y/n") &
        "] " &
        (if Provided_Text'Length > 0 then
             " (" & Provided_Text & ")" else "") & " >";
   begin
      loop
         Put (Question);
         declare
            Response : constant String :=
              Trim (To_Lower (Get_Line), Ada.Strings.Both);
         begin
            if Response'Length = 0 and then Default_Answer /= DisableDefault
            then
               return Default_Answer;
            elsif Response = "y" or else Response = "yes" then
               return Yes;
            elsif Response = "n" or else Response = "no" then
               return No;
            else
               Put_Line ("Invalid response.");
            end if;
         end;
      end loop;
   end Get_Answer;

That is technically not a case statement.
It’s one of the “expression statements” — the way to understand the difference is whether or not it returns a value: like a procedure, a [normal] statement does not return a value, but like a function an expression resolves to a value.

3 Likes

If you’re having trouble finding code samples, you might be able to find some at https://search.ada-lang.io/

Strictly speaking it’s a “case expression”, and was introduced in Ada 2012.

1 Like

Yes, but IIRC, it along with if-expressions, make up expression-statements.

The actual Ada RM term is “conditional expression”.

1 Like

Ah! Thanks for the reminder.