-- Demonstrates how to create other names for packages, subroutines, exceptions, objects
-- Typically used to shorten names
-- Normal scope rules apply for the renamed entity

with Ada.Text_IO; use Ada.Text_IO; 
with Ada.Long_Long_Integer_Text_IO; 
with Ada.Float_Text_IO; 
with Ada.IO_Exceptions;
 
procedure new_names  is 
    --  A subtype provides a new name for types:
    subtype Long is Long_Long_Integer;
    l : Long := 1;

    -- Renames gives new names to other things

    -- Packages
    package tio  renames Ada.Text_IO;
    package ftio renames Ada.Float_Text_IO;
    package ltio renames Ada.Long_Long_Integer_Text_IO;

    -- Procedures and functions
    procedure putln(S : String) renames Ada.Text_IO.put_line;

    -- Attribute that are functions
    function min(i, j: Integer) return Integer renames Integer'min;
    function img(i: Integer) return String renames Integer'image;
    -- Example: putln (img(i));

    -- Rename a procedure, and give some default values:
    procedure put(item: float; 
                  fore: Natural := 5; 
                  aft:  Natural := 2; 
                  exp:  Natural := 0) 
        renames ftio.put;

    -- Exceptions
    EOF: exception renames Ada.IO_Exceptions.End_Error;

    -- A type for the examples below
    type Colors is (red, blue, green);

    -- Attribute functions:
    function next(c: Colors) return Colors renames Colors'succ;
    function img(i: Colors) return String renames Colors'image;

    -- Enumeration literals are actually defined as functions:
    function rouge return Colors renames red;  -- for French speakers
    c: Colors := rouge;
    
    type A_Long_Name_For_A_Pair is record
        x, y: Integer;
    end record;

    --  Subtypes can be used to give a new name to a type
    subtype Pair is A_Long_Name_For_A_Pair;

    p: Pair := (1, 2);

    -- Rename an object
    q: Integer renames p.x;

    subtype Small_Int is Positive range 1 .. 3;

    -- We will rename the elements of these arrays
    a: array (Small_Int) of Integer := (others => 0);

    a_long_array_variable_name: array(Small_Int) of Pair
                                := (others => (others => 0));


begin
    -- Specific array elements can be renamed
    -- Index i must be known
   for i in Small_Int loop
      declare
         x: Integer renames a(i);
         px: Integer renames a_long_array_variable_name(i).x;
      begin
         put(x'img);
         put(px'img);
      end;
   end loop;

    put_line(img(c));
    put_line(img(next(c)));
    put(12.3456);
    new_line;
    tio.put_line(img(q));
    putln (img (q));

end new_names;

-- Output:
--| 0 0 0 0 0 0
--|RED
--|BLUE
--|   12.35
--| 1