Convert existing Ada code to a package for reuse; I have very basic problems with the conversion

Hi;

There is a Rosetta Code task written in Ada located at:

which references a package (“Base_Conversion”) I don’t see bundled with the GNAT Ada compiler and I don’t see elsewhere on the Rosetta Code web site.

However, in the Rosetta Code Task located at:

there are two functions defined as part of the task which perform the work the package I want to write.

So I tried to leverage the two functions into a package spec and a package body, with the calls to the two functions placed in a test driver.

I obviously do not sufficiently understand what is required in the spec to make this work correctly.

Here are my error messages from the attempt to compile the driver code:

gnatmake ./test_number_base_conversion.adb
gcc -c -I./ -I- ./test_number_base_conversion.adb
gcc -c -I./ -I- ./base_conversion.adb
base_conversion.adb:5:04: error: “Max_Base” conflicts with declaration at base_conversion.ads:5
base_conversion.adb:6:12: error: “Base_Type” conflicts with declaration at base_conversion.ads:6
gnatmake: “./base_conversion.adb” compilation error

The Ada code I have written is enclosed below.

Thanks,
Retired Build Engineer

with Ada.Text_IO; use Ada.Text_IO;
with Base_Conversion; use Base_Conversion;

procedure Test_Number_Base_Conversion is
begin
   Put_Line ("26 converted to base 16 is " & To_Base (26, 16));
   Put_Line
     ("1a (base 16) is decimal" & Integer'Image (To_Decimal ("1a", 16)));
end Test_Number_Base_Conversion;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;

package Base_Conversion is
   Max_Base : constant := 36;
   subtype Base_Type is Integer range 2 .. Max_Base;
   function To_Decimal (Value : String; Base : Base_Type) return Integer;
   function To_Base (Value : Natural; Base : Base_Type) return String;
end Base_Conversion;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;

package body Base_Conversion is
   Max_Base : constant := 36;
   subtype Base_Type is Integer range 2 .. Max_Base;
   Num_Digits : constant String := "0123456789abcdefghijklmnopqrstuvwxyz";
   Invalid_Digit : exception;

   function To_Decimal (Value : String; Base : Base_Type) return Integer is
      use Ada.Strings.Fixed;
      Result        : Integer := 0;
      Decimal_Value : Integer;
      Radix_Offset  : Natural := 0;
   begin
      for I in reverse Value'Range loop
         Decimal_Value := Index (Num_Digits, Value (I .. I)) - 1;
         if Decimal_Value < 0 then
            raise Invalid_Digit;
         end if;
         Result       := Result + (Base**Radix_Offset * Decimal_Value);
         Radix_Offset := Radix_Offset + 1;
      end loop;
      return Result;
   end To_Decimal;

   function To_Base (Value : Natural; Base : Base_Type) return String is
      use Ada.Strings.Unbounded;
      Result     : Unbounded_String := Null_Unbounded_String;
      Temp       : Natural          := Value;
      Base_Digit : String (1 .. 1);
   begin
      if Temp = 0 then
         return "0";
      end if;
      while Temp > 0 loop
         Base_Digit (1) := Num_Digits ((Temp mod Base) + 1);
         if Result = Null_Unbounded_String then
            Append (Result, Base_Digit);
         else
            Insert (Source => Result, Before => 1, New_Item => Base_Digit);
         end if;
         Temp := Temp / Base;
      end loop;
      return To_String (Result);
   end To_Base;

end Base_Conversion;

The error message says exactly what’s wrong.
Max_Base and Base_Type are defined twice. Once in the package specification and once in the package body.
Just remove the declarations in the package body and you’re done.

2 Likes

Thank you!

So simple, so obvious (SIGH)

Retired Build Engineer