home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / nlists.adb < prev    next >
Text File  |  1996-09-28  |  25KB  |  954 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                               N L I S T S                                --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.13 $                             --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. --  WARNING: There is a C version of this package. Any changes to this source
  27. --  file must be properly reflected in the corresponding C header a-nlists.h
  28.  
  29. with Alloc;   use Alloc;
  30. with Atree;   use Atree;
  31. with Debug;   use Debug;
  32. with Output;  use Output;
  33. with Table;
  34.  
  35. package body Nlists is
  36.  
  37.    use Atree_Private_Part;
  38.    --  Get access to Nodes table
  39.  
  40.    ----------------------------------
  41.    -- Implementation of Node Lists --
  42.    ----------------------------------
  43.  
  44.    --  To allow efficient access to the list, both for traversal, and for
  45.    --  insertion of new entries at the end of the list, a list is stored
  46.    --  using a circular format, as indicated by the following diagram:
  47.  
  48.    --    +--------+    +-------+    +-------+         +-------+
  49.    --    |  List  |    |  1st  |    |  2nd  |         | Last  |
  50.    --    |     ------->|   -------->|   ------>....-->|   -------+
  51.    --    | Header |    | Entry |    | Entry |         | Entry |  |
  52.    --    +-----|--+    +-------+    +-------+         +-------+  |
  53.    --       ^  |                                          ^      |
  54.    --       |  |                                          |      |
  55.    --       |  + -----------------------------------------+      |
  56.    --       +--- ------------------------------------------------+
  57.  
  58.    --  The list header is an entry in the Lists table. List_Id values
  59.    --  are used to reference list headers.
  60.  
  61.    --  The First field of the list header contains Empty for a null list,
  62.    --  or a standard Node_Id value pointing to the first item on the list.
  63.    --  The Last field of the list header contains Empty for a null list or a
  64.    --  standard Node_Id value pointing to the last item on the list.
  65.  
  66.    --  The nodes within the list use the Link field to hold a normal
  67.    --  Node_Id value, which points to the next item in the list except for
  68.    --  the last item in the list, which points to the list head and is thus
  69.    --  a standard List_Id value referencing the containing list. This allows
  70.    --  a quik check for the end of the list in a list traversal (check value
  71.    --  of link for being in List_Id range), and also makes it possible to
  72.    --  find the list containing any given node (find the end of the list by
  73.    --  chasing Link fields, and then the Link field of this node references
  74.    --  the list).
  75.  
  76.    --  All nodes that are elements of a list have the In_List flag set True.
  77.    --  All nodes that are not list elements have the In_List flag set False.
  78.  
  79.    --  Note that since the Link field of a node is used both for a Parent
  80.    --  pointer and for a forward link field in a list, that list elements
  81.    --  cannot have direct parent pointers (and hence cannot be referenced
  82.    --  directly from a field in another node). However, the list header
  83.    --  itself does have a parent field.
  84.  
  85.    ------------------------
  86.    --  List Header Table --
  87.    ------------------------
  88.  
  89.    type List_Header is record
  90.       First  : Union_Id;
  91.       Last   : Union_Id;
  92.       Parent : Node_Id;
  93.    end record;
  94.  
  95.    package Lists is new Table (
  96.      Table_Component_Type => List_Header,
  97.      Table_Index_Type     => List_Id,
  98.      Table_Low_Bound      => First_List_Id,
  99.      Table_Initial        => Alloc_Lists_Initial,
  100.      Table_Increment      => Alloc_Lists_Increment,
  101.      Table_Name           => "Lists");
  102.  
  103.    -----------------------
  104.    -- Local Subprograms --
  105.    -----------------------
  106.  
  107.    procedure Set_First (List : List_Id; Node : Node_Id);
  108.    pragma Inline (Set_First);
  109.    --  Used internally in the implementation of the list routines to
  110.    --  set the first element of a list to point to a given node.
  111.  
  112.    procedure Set_Last (List : List_Id; Node : Node_Id);
  113.    pragma Inline (Set_Last);
  114.    --  Used internally in the implementation of the list routines to set the
  115.    --  last element of a list to point to a given node.
  116.  
  117.    function Node_Link (Node : Node_Id) return Node_Id;
  118.    pragma Inline (Node_Link);
  119.    --  Used internally in the implementation of the list routines to return
  120.    --  the contents of the Link field of a specified node as a node.
  121.  
  122.    function List_Link (Node : Node_Id) return List_Id;
  123.    pragma Inline (List_Link);
  124.    --  Used internally in the implementation of the list routines to return
  125.    --  the contents of the Link field of a specified node as a list.
  126.  
  127.    procedure Set_Node_Link (Node : Node_Id; To : Node_Id);
  128.    pragma Inline (Set_Node_Link);
  129.    --  Used internally in the implementation of the list routines to set
  130.    --  the Link field of a node to point to a given node.
  131.  
  132.    procedure Set_List_Link (Node : Node_Id; To : List_Id);
  133.    pragma Inline (Set_List_Link);
  134.    --  Used internally in the implementation of the list routines to set
  135.    --  the Link field of a node to point to a given list.
  136.  
  137.    function Is_At_End_Of_List (Node : Node_Id) return Boolean;
  138.    pragma Inline (Is_At_End_Of_List);
  139.    --  Used internally in the implementation of the list routines to determine
  140.    --  if a given node is the last element of a list. False for nodes that are
  141.    --  not elements of lists.
  142.  
  143.    ------------
  144.    -- Append --
  145.    ------------
  146.  
  147.    procedure Append (Node : Node_Id; To : List_Id) is
  148.    begin
  149.       pragma Assert (not Is_List_Member (Node));
  150.  
  151.       if Node = Error then
  152.          return;
  153.       end if;
  154.  
  155.       if Debug_Flag_N then
  156.          Write_Str ("Append node ");
  157.          Write_Int (Int (Node));
  158.          Write_Str (" to list ");
  159.          Write_Int (Int (To));
  160.          Write_Eol;
  161.       end if;
  162.  
  163.       if Last (To) = Empty then
  164.          Set_First (To, Node);
  165.       else
  166.          Set_Node_Link (Last (To), Node);
  167.       end if;
  168.  
  169.       Set_Last (To, Node);
  170.       Set_List_Link (Node, To);
  171.       Nodes.Table (Node).In_List := True;
  172.    end Append;
  173.  
  174.    ---------------
  175.    -- Append_To --
  176.    ---------------
  177.  
  178.    procedure Append_To (To : List_Id; Node : Node_Id) is
  179.    begin
  180.       Append (Node, To);
  181.    end Append_To;
  182.  
  183.    -----------------
  184.    -- Append_List --
  185.    -----------------
  186.  
  187.    procedure Append_List (List : List_Id; To : List_Id) is
  188.    begin
  189.       if Debug_Flag_N then
  190.          Write_Str ("Append list ");
  191.          Write_Int (Int (List));
  192.          Write_Str (" to list ");
  193.          Write_Int (Int (To));
  194.          Write_Eol;
  195.       end if;
  196.  
  197.       if Is_Empty_List (List) then
  198.          return;
  199.  
  200.       else
  201.          if Is_Empty_List (To) then
  202.             Set_First (To, First (List));
  203.          else
  204.             Set_Node_Link (Last (To), First (List));
  205.          end if;
  206.  
  207.          Set_Last (To, Last (List));
  208.          Set_List_Link (Last (List), To);
  209.  
  210.          Set_Last (List, Empty);
  211.          Set_First (List, Empty);
  212.       end if;
  213.    end Append_List;
  214.  
  215.    --------------------
  216.    -- Append_List_To --
  217.    --------------------
  218.  
  219.    procedure Append_List_To (To : List_Id; List : List_Id) is
  220.    begin
  221.       Append_List (List, To);
  222.    end Append_List_To;
  223.  
  224.    -----------
  225.    -- First --
  226.    -----------
  227.  
  228.    function First (List : List_Id) return Node_Id is
  229.    begin
  230.       pragma Assert (List in First_List_Id .. Lists.Last);
  231.       return Node_Id (Lists.Table (List).First);
  232.    end First;
  233.  
  234.    ----------------
  235.    -- Initialize --
  236.    ----------------
  237.  
  238.    procedure Initialize is
  239.       E : constant List_Id := Error_List;
  240.  
  241.    begin
  242.       Lists.Init;
  243.  
  244.       --  Allocate Error_List list header
  245.  
  246.       Lists.Increment_Last;
  247.       Set_Parent (E, Empty);
  248.       Set_First  (E, Empty);
  249.       Set_Last   (E, Empty);
  250.    end Initialize;
  251.  
  252.    ------------------
  253.    -- Insert_After --
  254.    ------------------
  255.  
  256.    procedure Insert_After (After : Node_Id; Node : Node_Id) is
  257.    begin
  258.       pragma Assert
  259.         (Is_List_Member (After) and then not Is_List_Member (Node));
  260.  
  261.       if Node = Error then
  262.          return;
  263.       end if;
  264.  
  265.       if Debug_Flag_N then
  266.          Write_Str ("Insert node");
  267.          Write_Int (Int (Node));
  268.          Write_Str (" after node ");
  269.          Write_Int (Int (After));
  270.          Write_Eol;
  271.       end if;
  272.  
  273.       if Is_At_End_Of_List (After) then
  274.          Set_Last (List_Containing (After), Node);
  275.          Set_List_Link (Node, List_Link (After));
  276.       else
  277.          Set_Node_Link (Node, Node_Link (After));
  278.       end if;
  279.  
  280.       Set_Node_Link (After, Node);
  281.       Nodes.Table (Node).In_List := True;
  282.    end Insert_After;
  283.  
  284.    -------------------
  285.    -- Insert_Before --
  286.    -------------------
  287.  
  288.    procedure Insert_Before (Before : Node_Id; Node : Node_Id) is
  289.       L : List_Id;
  290.       N : Node_Id;
  291.  
  292.    begin
  293.       pragma Assert (Is_List_Member (Before) and not Is_List_Member (Node));
  294.  
  295.       if Node = Error then
  296.          return;
  297.       end if;
  298.  
  299.       if Debug_Flag_N then
  300.          Write_Str ("Insert node");
  301.          Write_Int (Int (Node));
  302.          Write_Str (" before node ");
  303.          Write_Int (Int (Before));
  304.          Write_Eol;
  305.       end if;
  306.  
  307.       L := List_Containing (Before);
  308.  
  309.       if First (L) = Before then
  310.          Set_First (L, Node);
  311.  
  312.       else
  313.          N := First (L);
  314.  
  315.          while Node_Link (N) /= Before loop
  316.             N := Node_Link (N);
  317.          end loop;
  318.  
  319.          Set_Node_Link (N, Node);
  320.       end if;
  321.  
  322.       Set_Node_Link (Node, Before);
  323.       Nodes.Table (Node).In_List := True;
  324.    end Insert_Before;
  325.  
  326.    -----------------------
  327.    -- Insert_List_After --
  328.    -----------------------
  329.  
  330.    procedure Insert_List_After (After : Node_Id; List : List_Id) is
  331.    begin
  332.       pragma Assert (Is_List_Member (After));
  333.  
  334.       if Debug_Flag_N then
  335.          Write_Str ("Insert list ");
  336.          Write_Int (Int (List));
  337.          Write_Str (" after node ");
  338.          Write_Int (Int (After));
  339.          Write_Eol;
  340.       end if;
  341.  
  342.       if Is_Empty_List (List) then
  343.          return;
  344.  
  345.       else
  346.          if Is_At_End_Of_List (After) then
  347.             Set_Last (List_Containing (After), Last (List));
  348.             Set_List_Link (Last (List), List_Link (After));
  349.          else
  350.             Set_Node_Link (Last (List), Node_Link (After));
  351.          end if;
  352.  
  353.          Set_Node_Link (After, First (List));
  354.  
  355.          Set_First (List, Empty);
  356.          Set_Last (List, Empty);
  357.       end if;
  358.    end Insert_List_After;
  359.  
  360.    ------------------------
  361.    -- Insert_List_Before --
  362.    ------------------------
  363.  
  364.    procedure Insert_List_Before (Before : Node_Id; List : List_Id) is
  365.       L : List_Id;
  366.       N : Node_Id;
  367.  
  368.    begin
  369.       pragma Assert (Is_List_Member (Before));
  370.  
  371.       if Debug_Flag_N then
  372.          Write_Str ("Insert list ");
  373.          Write_Int (Int (List));
  374.          Write_Str (" before node ");
  375.          Write_Int (Int (Before));
  376.          Write_Eol;
  377.       end if;
  378.  
  379.       if Is_Empty_List (List) then
  380.          return;
  381.  
  382.       else
  383.          L := List_Containing (Before);
  384.  
  385.          if First (L) = Before then
  386.             Set_First (L, First (List));
  387.  
  388.          else
  389.             N := First (L);
  390.  
  391.             while Node_Link (N) /= Before loop
  392.                N := Node_Link (N);
  393.             end loop;
  394.  
  395.             Set_Node_Link (N, First (List));
  396.          end if;
  397.  
  398.          Set_Node_Link (Last (List), Before);
  399.  
  400.          Set_First (List, Empty);
  401.          Set_Last (List, Empty);
  402.       end if;
  403.    end Insert_List_Before;
  404.  
  405.    -----------------------
  406.    -- Is_At_End_Of_List --
  407.    -----------------------
  408.  
  409.    function Is_At_End_Of_List (Node : Node_Id) return Boolean is
  410.    begin
  411.       pragma Assert (Is_List_Member (Node));
  412.       return (Nodes.Table (Node).Link in List_Range);
  413.    end Is_At_End_Of_List;
  414.  
  415.    -------------------
  416.    -- Is_Empty_List --
  417.    -------------------
  418.  
  419.    function Is_Empty_List (List : List_Id) return Boolean is
  420.    begin
  421.       return First (List) = Empty;
  422.    end Is_Empty_List;
  423.  
  424.    --------------------
  425.    -- Is_List_Member --
  426.    --------------------
  427.  
  428.    function Is_List_Member (Node : Node_Id) return Boolean is
  429.    begin
  430.       return Nodes.Table (Node).In_List;
  431.    end Is_List_Member;
  432.  
  433.    -----------------------
  434.    -- Is_Non_Empty_List --
  435.    -----------------------
  436.  
  437.    function Is_Non_Empty_List (List : List_Id) return Boolean is
  438.    begin
  439.       return List /= No_List and then First (List) /= Empty;
  440.    end Is_Non_Empty_List;
  441.  
  442.    ----------
  443.    -- Last --
  444.    ----------
  445.  
  446.    function Last (List : List_Id) return Node_Id is
  447.    begin
  448.       pragma Assert (List in First_List_Id .. Lists.Last);
  449.       return Node_Id (Lists.Table (List).Last);
  450.    end Last;
  451.  
  452.    ------------------
  453.    -- Last_List_Id --
  454.    ------------------
  455.  
  456.    function Last_List_Id return List_Id is
  457.    begin
  458.       return Lists.Last;
  459.    end Last_List_Id;
  460.  
  461.    ---------------------
  462.    -- List_Containing --
  463.    ---------------------
  464.  
  465.    function List_Containing (Node : Node_Id) return List_Id is
  466.       N : Node_Id;
  467.  
  468.    begin
  469.       pragma Assert (Is_List_Member (Node));
  470.       N := Node;
  471.  
  472.       while not Is_At_End_Of_List (N) loop
  473.          N := Node_Link (N);
  474.       end loop;
  475.  
  476.       return List_Link (N);
  477.    end List_Containing;
  478.  
  479.    -----------------
  480.    -- List_Length --
  481.    -----------------
  482.  
  483.    function List_Length (List : List_Id) return Nat is
  484.       Result : Nat := 0;
  485.       Node   : Node_Id;
  486.  
  487.    begin
  488.       Node := First (List);
  489.  
  490.       while Present (Node) loop
  491.          Result := Result + 1;
  492.          Node := Next (Node);
  493.       end loop;
  494.  
  495.       return Result;
  496.    end List_Length;
  497.  
  498.    ---------------
  499.    -- List_Link --
  500.    ---------------
  501.  
  502.    function List_Link (Node : Node_Id) return List_Id is
  503.    begin
  504.       return List_Id (Nodes.Table (Node).Link);
  505.    end List_Link;
  506.  
  507.    -------------------
  508.    -- Lists_Address --
  509.    -------------------
  510.  
  511.    function Lists_Address return System.Address is
  512.    begin
  513.       return Lists.Table (First_List_Id)'Address;
  514.    end Lists_Address;
  515.  
  516.    --------------
  517.    -- New_List --
  518.    --------------
  519.  
  520.    function New_List return List_Id is
  521.  
  522.       procedure New_List_Debugging_Output;
  523.       --  Debugging output for debug flag N
  524.  
  525.       procedure New_List_Debugging_Output is
  526.       begin
  527.          if Debug_Flag_N then
  528.             Write_Str ("Allocate new list, returned ID = ");
  529.             Write_Int (Int (Lists.Last));
  530.             Write_Eol;
  531.          end if;
  532.       end New_List_Debugging_Output;
  533.  
  534.       pragma Inline (New_List_Debugging_Output);
  535.  
  536.    --  Start of processing for New_List
  537.  
  538.    begin
  539.       Lists.Increment_Last;
  540.       Set_Parent (Lists.Last, Empty);
  541.       Set_First (Lists.Last, Empty);
  542.       Set_Last (Lists.Last, Empty);
  543.       pragma Debug (New_List_Debugging_Output);
  544.       return (Lists.Last);
  545.    end New_List;
  546.  
  547.    --  Since the one argument case is common, we optimize to build the right
  548.    --  list directly, rather than first building an empty list and then doing
  549.    --  the insertion, which results in some unnecessary work.
  550.  
  551.    function New_List (Node : Node_Id) return List_Id is
  552.    begin
  553.       if Node = Error then
  554.          return New_List;
  555.       else
  556.          Lists.Increment_Last;
  557.          Set_Parent (Lists.Last, Empty);
  558.          Set_First (Lists.Last, Node);
  559.          Set_Last (Lists.Last, Node);
  560.          Set_List_Link (Node, Lists.Last);
  561.          Nodes.Table (Node).In_List := True;
  562.       end if;
  563.  
  564.       if Debug_Flag_N then
  565.          Write_Str ("Allocate new list, returned ID = ");
  566.          Write_Int (Int (Lists.Last));
  567.          Write_Eol;
  568.       end if;
  569.  
  570.       return (Lists.Last);
  571.    end New_List;
  572.  
  573.    function New_List (Node1, Node2 : Node_Id) return List_Id is
  574.       L : constant List_Id := New_List (Node1);
  575.  
  576.    begin
  577.       Append (Node2, L);
  578.       return L;
  579.    end New_List;
  580.  
  581.    function New_List (Node1, Node2, Node3 : Node_Id) return List_Id is
  582.       L : constant List_Id := New_List (Node1);
  583.  
  584.    begin
  585.       Append (Node2, L);
  586.       Append (Node3, L);
  587.       return L;
  588.    end New_List;
  589.  
  590.    function New_List (Node1, Node2, Node3, Node4 : Node_Id) return List_Id is
  591.       L : constant List_Id := New_List (Node1);
  592.  
  593.    begin
  594.       Append (Node2, L);
  595.       Append (Node3, L);
  596.       Append (Node4, L);
  597.       return L;
  598.    end New_List;
  599.  
  600.    function New_List
  601.      (Node1 : Node_Id;
  602.       Node2 : Node_Id;
  603.       Node3 : Node_Id;
  604.       Node4 : Node_Id;
  605.       Node5 : Node_Id)
  606.       return  List_Id
  607.    is
  608.       L : constant List_Id := New_List (Node1);
  609.  
  610.    begin
  611.       Append (Node2, L);
  612.       Append (Node3, L);
  613.       Append (Node4, L);
  614.       Append (Node5, L);
  615.       return L;
  616.    end New_List;
  617.  
  618.    function New_List
  619.      (Node1 : Node_Id;
  620.       Node2 : Node_Id;
  621.       Node3 : Node_Id;
  622.       Node4 : Node_Id;
  623.       Node5 : Node_Id;
  624.       Node6 : Node_Id)
  625.       return  List_Id
  626.    is
  627.       L : constant List_Id := New_List (Node1);
  628.  
  629.    begin
  630.       Append (Node2, L);
  631.       Append (Node3, L);
  632.       Append (Node4, L);
  633.       Append (Node5, L);
  634.       Append (Node6, L);
  635.       return L;
  636.    end New_List;
  637.  
  638.    -------------------
  639.    -- New_List_Copy --
  640.    -------------------
  641.  
  642.    function New_List_Copy (List : List_Id) return List_Id is
  643.       NL : List_Id;
  644.       E  : Node_Id;
  645.  
  646.    begin
  647.       if List = No_List then
  648.          return No_List;
  649.  
  650.       else
  651.          NL := New_List;
  652.          E := First (List);
  653.  
  654.          while Present (E) loop
  655.             Append (New_Copy (E), NL);
  656.             E := Next (E);
  657.          end loop;
  658.  
  659.          return NL;
  660.       end if;
  661.    end New_List_Copy;
  662.  
  663.    ------------------------
  664.    -- New_List_Copy_Tree --
  665.    ------------------------
  666.  
  667.    function New_List_Copy_Tree (List : List_Id) return List_Id is
  668.       NL : List_Id;
  669.       E  : Node_Id;
  670.  
  671.    begin
  672.       if List = No_List then
  673.          return No_List;
  674.  
  675.       else
  676.          NL := New_List;
  677.          E := First (List);
  678.  
  679.          while Present (E) loop
  680.             Append (New_Copy_Tree (E), NL);
  681.             E := Next (E);
  682.          end loop;
  683.  
  684.          return NL;
  685.       end if;
  686.    end New_List_Copy_Tree;
  687.  
  688.    ----------
  689.    -- Next --
  690.    ----------
  691.  
  692.    function Next (Node : Node_Id) return Node_Id is
  693.    begin
  694.       pragma Assert (Is_List_Member (Node));
  695.  
  696.       if Is_At_End_Of_List (Node) then
  697.          return Empty;
  698.       else
  699.          return Node_Link (Node);
  700.       end if;
  701.    end Next;
  702.  
  703.    --------
  704.    -- No --
  705.    --------
  706.  
  707.    function No (List : List_Id) return Boolean is
  708.    begin
  709.       return List = No_List;
  710.    end No;
  711.  
  712.    ---------------
  713.    -- Node_Link --
  714.    ---------------
  715.  
  716.    function Node_Link (Node : Node_Id) return Node_Id is
  717.    begin
  718.       return Node_Id (Nodes.Table (Node).Link);
  719.    end Node_Link;
  720.  
  721.    ---------------
  722.    -- Num_Lists --
  723.    ---------------
  724.  
  725.    function Num_Lists return Nat is
  726.    begin
  727.       return Int (Lists.Last) - Int (Lists.First) + 1;
  728.    end Num_Lists;
  729.  
  730.    ------------
  731.    -- Parent --
  732.    ------------
  733.  
  734.    function Parent (List : List_Id) return Node_Id is
  735.    begin
  736.       pragma Assert (List in First_List_Id .. Lists.Last);
  737.       return Lists.Table (List).Parent;
  738.    end Parent;
  739.  
  740.    -------------
  741.    -- Prepend --
  742.    -------------
  743.  
  744.    procedure Prepend (Node : Node_Id; To : List_Id) is
  745.    begin
  746.       if Is_Empty_List (To) then
  747.          Append (Node, To);
  748.       else
  749.          Insert_Before (First (To), Node);
  750.       end if;
  751.    end Prepend;
  752.  
  753.    ----------------
  754.    -- Prepend_To --
  755.    ----------------
  756.  
  757.    procedure Prepend_To (To : List_Id; Node : Node_Id) is
  758.    begin
  759.       Prepend (Node, To);
  760.    end Prepend_To;
  761.  
  762.    -------------
  763.    -- Present --
  764.    -------------
  765.  
  766.    function Present (List : List_Id) return Boolean is
  767.    begin
  768.       return List /= No_List;
  769.    end Present;
  770.  
  771.    ----------
  772.    -- Prev --
  773.    ----------
  774.  
  775.    function Prev (Node : Node_Id) return Node_Id is
  776.       P : Node_Id;
  777.  
  778.    begin
  779.       P := First (List_Containing (Node));
  780.  
  781.       if P = Node then
  782.          return Empty;
  783.  
  784.       else
  785.          while Node_Link (P) /= Node loop
  786.             P := Node_Link (P);
  787.          end loop;
  788.  
  789.          return P;
  790.       end if;
  791.    end Prev;
  792.  
  793.    ------------
  794.    -- Remove --
  795.    ------------
  796.  
  797.    procedure Remove (Node : Node_Id) is
  798.       L : List_Id;
  799.       N : Node_Id;
  800.  
  801.    begin
  802.       L := List_Containing (Node);
  803.  
  804.       if Debug_Flag_N then
  805.          Write_Str ("Remove node ");
  806.          Write_Int (Int (Node));
  807.          Write_Eol;
  808.       end if;
  809.  
  810.       if First (L) = Node then
  811.          if Is_At_End_Of_List (Node) then
  812.             Set_Last (L, Empty);
  813.             Set_First (L, Empty);
  814.          else
  815.             Set_First (L, Node_Link (Node));
  816.          end if;
  817.  
  818.       else
  819.          N := First (L);
  820.  
  821.          while Node_Link (N) /= Node loop
  822.             N := Node_Link (N);
  823.          end loop;
  824.  
  825.          if Is_At_End_Of_List (Node) then
  826.             Set_Last (L, N);
  827.             Set_List_Link (N, List_Link (Node));
  828.          else
  829.             Set_Node_Link (N, Node_Link (Node));
  830.          end if;
  831.       end if;
  832.  
  833.       Set_Node_Link (Node, Empty);
  834.       Nodes.Table (Node).In_List := False;
  835.    end Remove;
  836.  
  837.    -----------------
  838.    -- Remove_Head --
  839.    -----------------
  840.  
  841.    function Remove_Head (List : List_Id) return Node_Id is
  842.       N : Node_Id;
  843.  
  844.    begin
  845.       if Debug_Flag_N then
  846.          Write_Str ("Remove head of list ");
  847.          Write_Int (Int (List));
  848.          Write_Eol;
  849.       end if;
  850.  
  851.       N := First (List);
  852.  
  853.       if N = Empty then
  854.          return Empty;
  855.  
  856.       else
  857.          if Is_At_End_Of_List (N) then
  858.             Set_Last  (List, Empty);
  859.             Set_First (List, Empty);
  860.          else
  861.             Set_First (List, Node_Link (N));
  862.          end if;
  863.  
  864.          Set_Node_Link (N, Empty);
  865.          Nodes.Table (N).In_List := False;
  866.          return N;
  867.       end if;
  868.    end Remove_Head;
  869.  
  870.    -----------------
  871.    -- Remove_Next --
  872.    -----------------
  873.  
  874.    function Remove_Next (Node : Node_Id) return Node_Id is
  875.       Nxt : constant Node_Id := Next (Node);
  876.  
  877.    begin
  878.       if Nxt /= Empty then
  879.          Nodes.Table (Node).Link := Nodes.Table (Nxt).Link;
  880.          Set_Node_Link (Nxt, Empty);
  881.          Nodes.Table (Nxt).In_List := False;
  882.       end if;
  883.  
  884.       return Nxt;
  885.    end Remove_Next;
  886.  
  887.    ---------------
  888.    -- Set_First --
  889.    ---------------
  890.  
  891.    procedure Set_First (List : List_Id; Node : Node_Id) is
  892.    begin
  893.       pragma Assert (List in First_List_Id .. Lists.Last);
  894.       Lists.Table (List).First := Union_Id (Node);
  895.    end Set_First;
  896.  
  897.    --------------
  898.    -- Set_Last --
  899.    --------------
  900.  
  901.    procedure Set_Last (List : List_Id; Node : Node_Id) is
  902.    begin
  903.       pragma Assert (List in First_List_Id .. Lists.Last);
  904.       Lists.Table (List).Last := Union_Id (Node);
  905.    end Set_Last;
  906.  
  907.    -------------------
  908.    -- Set_List_Link --
  909.    -------------------
  910.  
  911.    procedure Set_List_Link (Node : Node_Id; To : List_Id) is
  912.    begin
  913.       Nodes.Table (Node).Link := Union_Id (To);
  914.    end Set_List_Link;
  915.  
  916.    -------------------
  917.    -- Set_Node_Link --
  918.    -------------------
  919.  
  920.    procedure Set_Node_Link (Node : Node_Id; To : Node_Id) is
  921.    begin
  922.       Nodes.Table (Node).Link := Union_Id (To);
  923.    end Set_Node_Link;
  924.  
  925.    ----------------
  926.    -- Set_Parent --
  927.    ----------------
  928.  
  929.    procedure Set_Parent (List : List_Id; Node : Node_Id) is
  930.    begin
  931.       pragma Assert (List in First_List_Id .. Lists.Last);
  932.       Lists.Table (List).Parent := Node;
  933.    end Set_Parent;
  934.  
  935.    ---------------
  936.    -- Tree_Read --
  937.    ---------------
  938.  
  939.    procedure Tree_Read is
  940.    begin
  941.       Lists.Tree_Read;
  942.    end Tree_Read;
  943.  
  944.    ----------------
  945.    -- Tree_Write --
  946.    ----------------
  947.  
  948.    procedure Tree_Write is
  949.    begin
  950.       Lists.Tree_Write;
  951.    end Tree_Write;
  952.  
  953. end Nlists;
  954.