mpkostek
mpkostek

Reputation: 9

Ada linker not letting me call my procedure

Here is my code:

  procedure String_To_Int(str: String) is
      str_length : Integer := str'Size / 8;  
      ASCII_Values_Array: array (Integer range 1 .. str_length) of Integer;  
  begin
      Text_Io.Put_Line(str & " has a length of " & natural'image(str_length));
      for x in 1 .. str_length loop
        ASCII_Values_Array(x) := Character'Pos(str(x));
        Text_Io.Put_Line(natural'image(ASCII_Values_Array(x)));
      end loop;
  end String_To_Int;

and I am trying to call it with:

  String_To_Int(str => "abcdefghijklmnopqrstuvwxyz");

but the compiler is telling me:

Saw '(', expected:  , :

And I have no clue what is wrong about how I am calling my procedure. I have looked at many other examples of procedure calls and this looks exactly the same. Any help is appreciated!

Upvotes: 0

Views: 98

Answers (1)

user1818839
user1818839

Reputation:

There's something you aren't telling us.

     ./test_sti;
    abcdefghijklmnopqrstuvwxyz has a length of  26
     97
     98
     99
    ...
     121
     122

Now you don't say what you're actually doing, but here's what I did.

I called String_To_Int from another procedure, in a file test_sti.adb.

with String_To_Int;

procedure test_sti is
begin
   String_To_Int(str => "abcdefghijklmnopqrstuvwxyz");
end;

Note that String_To_Int is a separate procedure, in its own file, so the with clause tells the compiler to look for it. I could have declared it locally, i.e. between "is" and "begin" and saved both the files below, but separation is probably better design.

Now anything "with"ed will have both a specification and a body - in this case, specification string_to_int.ads :

  procedure String_To_Int(str: String);

and body string_to_int.adb :

with Ada.Text_IO;
use Ada;

  procedure String_To_Int(str: String) is
      str_length : Integer := str'Size / 8;  
      ASCII_Values_Array: array (Integer range 1 .. str_length) of Integer;  
  begin
      Text_Io.Put_Line(str & " has a length of " & natural'image(str_length));
      for x in 1 .. str_length loop
        ASCII_Values_Array(x) := Character'Pos(str(x));
        Text_Io.Put_Line(natural'image(ASCII_Values_Array(x)));
      end loop;
  end String_To_Int;

and to build the lot, simply

gnatmake test_sti.adb

and the compiler works out its own dependencies, no Makefile necessary.

It's actually a bit odd (but perfectly legal) to have a separate "compilation unit" like this for just one procedure. More normally it would either be declared locally, or it would be a part of a package - either a collection of utilities like Ada.Text_IO, or something like a class if you are familiar with Java or C++.

Incidentally, String_To_Int is a very odd procedure : instead of declaring its variables as

  str_length : Integer := str'Size / 8;  
  ASCII_Values_Array: array (Integer range 1 .. str_length) of Integer;  

it's cleaner to use the attributes more consistently:

  str_length : constant natural := str'Length;  
  ASCII_Values_Array: array (str'range) of Integer;

and express the loop condition as

for x in str'range loop

Upvotes: 3

Related Questions