-- -- Simple linked list. Just reads in some integers, places them into a -- stack-like linked list, then prints them out again in reverse order. -- Input terminated with -1. This uses the optional Unchecked_Deallocation -- to explicitly free storage. -- -- This requests the generic method method to explicitly free storage. with Ada.Unchecked_Deallocation; use Ada; with Gnat.Io; use Gnat.Io; procedure ll2 is type Node; -- There is some type node. type Node_Ptr is access Node; -- Node_Ptr points to those. type Node is record -- Now I'll tell you what Node is. Data: Integer; Next: Node_Ptr; end record; -- This declares the Free procedure as the de-allocator for the -- node type. Free is the traditional name, but we could have -- used any procedure name. procedure Free is new Unchecked_Deallocation(Node, Node_Ptr); -- This turns off the GC for this type, if there is any. pragma Controlled(Node_Ptr); Head: Node_Ptr; -- Head of the list. New_Node: Node_Ptr; -- Created node. Scan_Ptr: Node_Ptr; -- Scan the list. In_Int: Integer; -- Input integer. Zombie: Node_Ptr; -- The node about to die. begin -- Read in a list of integers to -1. loop -- Read and integer, stopping at -1. Put("> "); Get(In_Int); exit when In_Int = -1; -- Create a node for it, filled in. The initial values on new are -- optional, but useful to fill in the new space, much like a -- constructor. New_Node := new Node'(In_Int, null); -- Link it into the list. (Actually, we could have set Next to be head -- when we created the node in the last stmt, but I thought it would -- be clearer this way.) New_Node.Next := Head; Head := New_Node; end loop; -- Now print out the integers (backwards.) Scan_Ptr := Head; loop -- If the list is entirely empty, bail out now. exit when Scan_Ptr = null; -- Print, go to next, and free the node printed. Put(Scan_Ptr.Data); Zombie := Scan_Ptr; Scan_Ptr := Scan_Ptr.Next; Free(Zombie); -- If there is no next, we are done. exit when Scan_Ptr = null; -- Since there is a next, print a space to separate the items. Put(" "); end loop; New_Line; end ll2;