-- Shows addresses of local variables decreasing
-- Shows addresses of heap elements increase
-- Shows creation, address, and access of dangling reference
-- Shows reallocation at address of dangling reference
with Unchecked_Conversion;
with Unchecked_Deallocation;
with Text_IO; use Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure aliasedLocal is

    type IntPointer is access all Integer;
    -- all is required when accessing local variables

    type AddressType is mod 2**32;

    package Address_IO is new Text_IO.Modular_IO (Num => AddressType);
    use Address_IO;

    function Convert is new Unchecked_Conversion (
                Source => IntPointer, Target => AddressType);

    procedure Dispose is new Unchecked_Deallocation (
                Object => Integer, Name => IntPointer);

    i, j, k: aliased Integer := 99;
    p, q: IntPointer;

begin
    p := i'access;
    put_line("p.all: " & p.all'img);
    -- dispose(p); -- Compiles, but causes runtime eror

    -- Addresses of locals decrease
    put_line("address in p of i" & convert(p)'img);

    p := j'access;
    put_line("address in p of j" & convert(p)'img);

    p := k'access;
    put_line("address in p of k" & convert(p)'img);

    -- Addresses on heap increase
    q := new Integer;  put_line("q.all:" & q.all'img);  
    put_line("address in q on heap" & convert(q)'img);  

    p := new Integer'(33);  put_line("p.all:" & p.all'img);  
    put_line("address in p on heap" & convert(p)'img);  

    -- Create an alias
    q := p; 

    -- Create and dereference a dangling reference
    dispose(p); put_line("q.all unallocated:" & q.all'img);  
    put_line("address in p on heap after deallocation" & convert(p)'img);  
    put_line("address in q on heap after deallocation" & convert(q)'img);  

    -- Reallocate usually uses the same address
    p := new Integer'(44); 
    put_line("address in p after reallocation" & convert(p)'img);  
    put_line("p.all: " & p.all'img);  
    put_line("q.all: " & q.all'img);  

end aliasedLocal;
-- p.all:  99
-- address in p of i 3214940764
-- address in p of j 3214940760
-- address in p of k 3214940756
-- q.all: 0
-- address in q on heap 134539296
-- p.all: 33
-- address in p on heap 134539312
-- q.all unallocated: 0
-- address in p on heap after deallocation 0
-- address in q on heap after deallocation 134539312
-- address in p after reallocation 134539312
-- p.all:  44
-- q.all:  44