0
votes

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!

1
I don't know ada, and don't know why i am reading this, but is it illegal to have a space after a function name? array (Integer range 1 .. str_length) => array(Integer range 1 .. str_length) - Grady Player
Yes, that is okay, I just made the change and recompiled and still got the same thing - mpkostek
No need to calculate str_length, you can just use str'Length. Or str'Range or str'First..str'Last - egilhh
@Grady : there may be some languages where spaces between tokens are illegal, but Ada isn't one of them. If spaces help readability, use them. - user_1818839
You need to show us the context of that call. Even if the procedure String_To_Int is not visible, that call would not result in a syntax error message. The call is correct; you've probably put the call in a context where a statement is not permitted. Show us the source file containing the call (narrow it down to a minimal example if you can). - Keith Thompson

1 Answers

3
votes

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