-- A complete program that illustrates get_line,
--   an array type, and strings and arrays as parameters
--
-- The program prints all of the lines in standard input
--   along with some other information
--
-- You can run it on itself: ./rline < rline.adb

with Ada.Text_IO; use Ada.Text_IO;
procedure rline is

   type MyArray is array(1 .. 10) of character;
   --  Holds exactly 10 characters
   --
   subtype MyString is String(1 .. 10);
   --  A String of exactly 10 Characters

   -- Prints the string t, but in reverse, and a few other things
   procedure put_rev (t: String) is
   begin
      -- prints indices of first and last characters
      put(t'first'img);
      put(t'last'img & ": ");

      -- empty strings have index of first < index of last
      put(if t'last < t'first then "Empty" else "" & t(t'first));
      put(" ");

      -- print in reverse
      for i in reverse t'range loop
         put(t(i));
      end loop;

      new_line;
   end put_rev;


   -- print first and last character
   procedure p(m: MyArray) is
   begin
      put(m(1) & m(10));
   end p;

   a: MyArray := "abcdefghij";      -- Arrays of characters can be assigned string literals
   s: MyString := "abcdefghij";      -- Declare and initialize a string of exactly 10 characters
   b: array(1 .. 10) of Character;  -- structural compatibility but not name compatibility

begin
   p(a);
   put_rev(s);

   --  ada.Text_IO.put_line(a);     --  Putline only works on strings and their subtypes
   ada.Text_IO.put_line(s);     --  Putline only works on strings and their subtypes
   --  ada.Text_IO.put_line(b);     --  Putline only works on strings and their subtypes

   --  p(b);  -- Formal and actual parameters don't have the same type name


   while not end_of_file loop
      put_rev(get_line);
      --  Get_line returns the next line as a string 
      --    and that string is passed to put_rev
   end loop;


   --  Dynamically allocate string s as (potentially) a different size for each pass
   --  while not end_of_file loop
   --     declare
   --        s: string := get_line;
   --     begin
   --        put(s);
   --     end;
   --  end loop;
end rline;