will
will

Reputation: 5081

How (may?) I export Ada type based on a "new" type from a generic?

I'm pretty sure this is a trap for new Ada people. I feel there is something simple needed to get this right. I have some older code with the declaration for a Send_Command procedure with a Command_String_Type type parameter based on the Ada.Strings.Bounded generic module.

old

 -- -- -- command.ads -- -- --

    -- nothing relevant, Send_command is/was internal to module.
     :

 -- -- -- command.adb -- -- --

    -- Type to hold command to send while it is being constructed.
 package Command_String_Type is
      new Ada.Strings.Bounded.Generic_Bounded_Length(Max => Command_Max);

     :
     :

 procedure   Send_Command( 
                 Command_String : in Command_String_Type.Bounded_String ); 

This: Command_String_Type is used as the parameter type for the Send_Command procedure this module must export from this module.

My trouble comes when I attempt to declare the Command_String_Type in the modules specification (.ads) file. I can't get the syntax straight to 'export' this type specification for this procedure.

target

 -- -- -- command_interface.ads -- -- --

 package Command_Interface is

      Command_Max : constant := 200;
        :

    -- WANTED ... export Command_String_Type from this module

    -- Type to hold command to send while it is being constructed.
   package Command_String_Type is
        new Ada.Strings.Bounded.Generic_Bounded_Length(Max => Command_Max);

     :
     :

   procedure   Send_Command( 
                   Command_String : in Command_String_Type.Bounded_String ); 
     :

 end Command_Interface; -- specification


 -- -- -- command_interface.adb -- -- --

 package body Command_Interface is

         :
   procedure   Send_Command( 
                   Command_String : in Command_String_Type.Bounded_String ) 
   is
   begin
         :
        -- implementation ...
         :
   end Send_Command;

 end Command_Interface; --package

Naturally enough the Ada-95 compiler wants a "Command_String_Type" as shown above. Wanted to put the Send_Command procedure in the command_interface package. And export that for other modules to use. This procedure depends on the Command_String_Type

  1. At first I did a straight paste of the package Command_String_Type is new Ada.Strings... construct -- And received errors.
    • That is the code above under the "target" heading.
  2. I thought that a type declaration in the .ADS file would work because the error complains about "no type" -- Again I have errors.
  3. I then also got errors using Subtype.
  4. (update... ) Declared Command_String_Type as private -- Still having compile errors
  5. My last effort was to make a Command_String_Type_XX subtype of Command_String_Type with the idea that I could thus expose the subtype in the declaration.

So far I'm none for five. I've been reading books and looking at training notes, I'm disappointed I can't find some example that 'exports' a string type from a bounded string -- I'm still looking, of course, however I'm beginning to wonder if what I think of as straightforward as it would be in other languages. Is this possible and permitted with Ada. Gratitude in advance for your suggestions.

Upvotes: 0

Views: 308

Answers (1)

Simon Wright
Simon Wright

Reputation: 25511

The spec you propose looks fine:

with  Ada.Strings.Bounded;
package Command_Interface is
   Command_Max : constant := 200;
   package Command_String_Type is
     new Ada.Strings.Bounded.Generic_Bounded_Length (Max => Command_Max);
   procedure Send_Command
     (Command_String : in Command_String_Type.Bounded_String);
end Command_Interface;

and so does the body (this is a demo, of course):

with Ada.Text_IO;
package body Command_Interface is
   procedure Send_Command
     (Command_String : in Command_String_Type.Bounded_String) is
   begin
      Ada.Text_IO.Put_Line (Command_String_Type.To_String (Command_String));
   end Send_Command;
end Command_Interface;

and now we come to use it. You’ve created the package Command_String_Type in the visible part of Command_Interface, so you can reference it as Command_Interface.Command_String_Type:

with Command_Interface;
procedure Check_Command_Interface is
begin
   Command_Interface.Send_Command
     (Command_Interface.Command_String_Type.To_Bounded_String ("hello!"));
end Check_Command_Interface;

You might think this is all getting a bit verbose. You could shorten the instantiation’s name, e.g.

   package Command is
     new Ada.Strings.Bounded.Generic_Bounded_Length (Max => Command_Max);

or you could use the package renaming trick near the call,

procedure Check_Command_Interface_2 is
   package CICST renames Command_Interface.Command_String_Type;
begin
   Command_Interface.Send_Command (CICST.To_Bounded_String ("hello!"));
end Check_Command_Interface_2;

or you could go overboard and use:

procedure Check_Command_Interface_3 is
   use Command_Interface.Command_String_Type;
begin
   Command_Interface.Send_Command (To_Bounded_String ("hello!"));
end Check_Command_Interface_3;

Upvotes: 3

Related Questions