interfacepackagerecordada

Ada instanciation of a generic package with an implementation of a limited interface


I have a limited interface defined in my_interface_package.ads.

package My_Interface_Package is

   type My_Interface is limited interface;

   procedure Procedure_1 (Some_Parameter : in out My_Interface) is null;
   procedure Procedure_2 (Some_Parameter_1 : in out My_Interface; Some_Parameter_2 : in String) is abstract;

end My_Interface_Package;

The type My_Class implements this interface (in my_class_package.ads and my_class_package.adb).

with My_Interface_Package;

package My_Class_Package is

   type My_Class is limited new My_Interface_Package.My_Interface with record
      Some_Element : Boolean;
   end record;

   overriding procedure Procedure_1 (Some_Parameter : in out My_Class);
   overriding procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String);

end My_Class_Package;
with Ada.Text_IO;

package body My_Class_Package is

   procedure Procedure_1 (Some_Parameter : in out My_Class) is
   begin
      Ada.Text_IO.Put_Line("Inside Procedure_1.");
   end;

   procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String) is
   begin
      Ada.Text_IO.Put_Line("Inside Procedure_2.");
   end;

end My_Class_Package;

I have a generic package My_Generic_Package defined in my_generic_package.ads and my_generic_package.adb. It expects a type My_Generic_Type. I want this type to accept any concrete implementation of the interface My_Interface.

with My_Interface_Package;

generic
   type My_Generic_Type is limited new My_Interface_Package.My_Interface with private; -- The problem seems to be in this declaration.
package My_Generic_Package is

   type My_Generic_Class is record
      Element : My_Generic_Type;
   end record;

   procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class);
   procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String);

end My_Generic_Package;
with Ada.Text_IO;

package body My_Generic_Package is

   procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class) is
   begin
      Ada.Text_IO.Put_Line("Calling Procedure_1.");
      Procedure_1(Some_Parameter);
   end;

   procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String) is
   begin
      Ada.Text_IO.Put_Line("Calling Procedure_2.");
      Procedure_2(Some_Parameter_1, Some_Parameter_2);
   end;

end My_Generic_Package;

My main.adb:

with Ada.Text_IO;
with My_Class_Package;
with My_Generic_Package;

procedure Main is
   package My_Instanciated_Package is new My_Generic_Package(My_Generic_Type => My_Class_Package.My_Class);
   My_Object : My_Instanciated_Package.My_Generic_Class;
begin
   My_Instanciated_Package.Calling_Procedure_1(My_Object);
   My_Instanciated_Package.Calling_Procedure_2(My_Object, "some_string");
   Ada.Text_IO.Put_Line("Program terminated.");
end Main;

GNAT 12.2.0 tells me my_generic_package.ads:3:73: missing ";" (he doesn't want the 'with private' part, but even without it, also fail).

I have tried a bunch of other declaration but ultimatly (trying to inspire myself from wikibooks), all failed. Any idea of what's wrong ?


Solution

  • You have one of two compiler bugs. Either you posted the wrong code and the compiler is incorrectly flagging that line, or you posted the right code and the compiler is complaining about the wrong line. Your function bodies in My_Generic_Packge, as listed above, are wrong. They should be using ".Element" appended to each usage of the instances of Some_Parameter and Some_Parameter_1.

    package body My_Generic_Package is
    
       procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class) is
       begin
          Ada.Text_IO.Put_Line("Calling Procedure_1.");
          Procedure_1(Some_Parameter.Element);  -- NOTE CHANGE
       end;
    
       procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String) is
       begin
          Ada.Text_IO.Put_Line("Calling Procedure_2.");
          Procedure_2(Some_Parameter_1.Element, Some_Parameter_2);  -- NOTE CHANGE
       end;
    
    end My_Generic_Package;
    

    Full code that compiles on the online jdoodle Ada compiler (GNAT 11):

    with Ada.Text_IO; use Ada.Text_IO;
    
    procedure jdoodle is
        package My_Interface_Package is
    
           type My_Interface is limited interface;
        
           procedure Procedure_1 (Some_Parameter : in out My_Interface) is null;
           procedure Procedure_2 (Some_Parameter_1 : in out My_Interface; Some_Parameter_2 : in String) is abstract;
        
        end My_Interface_Package;
        
        package My_Class_Package is
    
           type My_Class is limited new My_Interface_Package.My_Interface with record
              Some_Element : Boolean;
           end record;
        
           overriding procedure Procedure_1 (Some_Parameter : in out My_Class);
           overriding procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String);
        
        end My_Class_Package;
        
        package body My_Class_Package is
    
           procedure Procedure_1 (Some_Parameter : in out My_Class) is
           begin
              Ada.Text_IO.Put_Line("Inside Procedure_1.");
           end;
        
           procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String) is
           begin
              Ada.Text_IO.Put_Line("Inside Procedure_2.");
           end;
        
        end My_Class_Package;
        
        generic
           type My_Generic_Type is limited new My_Interface_Package.My_Interface with private; -- The problem seems to be in this declaration.
        package My_Generic_Package is
        
           type My_Generic_Class is record
              Element : My_Generic_Type;
           end record;
        
           procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class);
           procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String);
        
        end My_Generic_Package;
        
        package body My_Generic_Package is
    
           procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class) is
           begin
              Ada.Text_IO.Put_Line("Calling Procedure_1.");
              Procedure_1(Some_Parameter.Element);
           end;
        
           procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String) is
           begin
              Ada.Text_IO.Put_Line("Calling Procedure_2.");
              Procedure_2(Some_Parameter_1.Element, Some_Parameter_2);
           end;
        
        end My_Generic_Package;
        
        package My_Instanciated_Package is new My_Generic_Package(My_Generic_Type => My_Class_Package.My_Class);
        My_Object : My_Instanciated_Package.My_Generic_Class; 
    begin
        My_Instanciated_Package.Calling_Procedure_1(My_Object);
        My_Instanciated_Package.Calling_Procedure_2(My_Object, "some_string");
        Ada.Text_IO.Put_Line("Program terminated.");
    end jdoodle;
    

    REF: https://www.jdoodle.com/ia/IxJ