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 / elists.adb < prev    next >
Text File  |  1996-09-28  |  12KB  |  393 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                               E L I S T S                                --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.11 $                             --
  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
  27. --  source file must be properly reflected in the C header a-elists.h.
  28.  
  29. with Alloc;   use Alloc;
  30. with Debug;   use Debug;
  31. with Output;  use Output;
  32. with Table;
  33.  
  34. package body Elists is
  35.  
  36.    -------------------------------------
  37.    -- Implementation of Element Lists --
  38.    -------------------------------------
  39.  
  40.    --  Element lists are composed of three types of entities. The element
  41.    --  list header, which references the first and last elements of the
  42.    --  list, the elements themselves which are singly linked and also
  43.    --  reference the nodes on the list, and finally the nodes themselves.
  44.    --  The following diagram shows how an element list is represented:
  45.  
  46.    --       +----------------------------------------------------+
  47.    --       |  +------------------------------------------+      |
  48.    --       |  |                                          |      |
  49.    --       V  |                                          V      |
  50.    --    +-----|--+    +-------+    +-------+         +-------+  |
  51.    --    |  Elmt  |    |  1st  |    |  2nd  |         |  Last |  |
  52.    --    |  List  |--->|  Elmt |--->|  Elmt  ---...-->|  Elmt ---+
  53.    --    | Header |    |   |   |    |   |   |         |   |   |
  54.    --    +--------+    +---|---+    +---|---+         +---|---+
  55.    --                      |            |                 |
  56.    --                      V            V                 V
  57.    --                  +-------+    +-------+         +-------+
  58.    --                  |       |    |       |         |       |
  59.    --                  | Node1 |    | Node2 |         | Node3 |
  60.    --                  |       |    |       |         |       |
  61.    --                  +-------+    +-------+         +-------+
  62.  
  63.    --  The list header is an entry in the Elists table. The values used for
  64.    --  the type Elist_Id are subscripts into this table. The First_Elmt field
  65.    --  (Lfield1) points to the first element on the list, or to No_Elmt in the
  66.    --  case of an empty list. Similarly the Last_Elmt field (Lfield2) points to
  67.    --  the last element on the list or to No_Elmt in the case of an empty list.
  68.  
  69.    --  The elements themselves are entries in the Elmts table. The Next field
  70.    --  of each entry points to the next element, or to the Elist header if this
  71.    --  is the last item in the list. The Node field points to the node which
  72.    --  is referenced by the corresponding list entry.
  73.  
  74.    --------------------------
  75.    --  Element List Tables --
  76.    --------------------------
  77.  
  78.    type Elist_Header is record
  79.       First : Elmt_Id;
  80.       Last  : Elmt_Id;
  81.    end record;
  82.  
  83.    package Elists is new Table (
  84.      Table_Component_Type => Elist_Header,
  85.      Table_Index_Type     => Elist_Id,
  86.      Table_Low_Bound      => First_Elist_Id,
  87.      Table_Initial        => Alloc_Elists_Initial,
  88.      Table_Increment      => Alloc_Elists_Increment,
  89.      Table_Name           => "Elists");
  90.  
  91.    type Elmt_Item is record
  92.       Node : Node_Id;
  93.       Next : Union_Id;
  94.    end record;
  95.  
  96.    package Elmts is new Table (
  97.      Table_Component_Type => Elmt_Item,
  98.      Table_Index_Type     => Elmt_Id,
  99.      Table_Low_Bound      => First_Elmt_Id,
  100.      Table_Initial        => Alloc_Elmts_Initial,
  101.      Table_Increment      => Alloc_Elmts_Increment,
  102.      Table_Name           => "Elmts");
  103.  
  104.    -----------------
  105.    -- Append_Elmt --
  106.    -----------------
  107.  
  108.    procedure Append_Elmt (Node : Node_Id; To : Elist_Id) is
  109.       L : constant Elmt_Id := Elists.Table (To).Last;
  110.  
  111.    begin
  112.       Elmts.Increment_Last;
  113.       Elmts.Table (Elmts.Last).Node := Node;
  114.       Elmts.Table (Elmts.Last).Next := Union_Id (To);
  115.  
  116.       if L = No_Elmt then
  117.          Elists.Table (To).First := Elmts.Last;
  118.       else
  119.          Elmts.Table (L).Next := Union_Id (Elmts.Last);
  120.       end if;
  121.  
  122.       Elists.Table (To).Last  := Elmts.Last;
  123.  
  124.       if Debug_Flag_N then
  125.          Write_Str ("Append new element Elmt_Id = ");
  126.          Write_Int (Int (Elmts.Last));
  127.          Write_Str (" to list Elist_Id = ");
  128.          Write_Int (Int (To));
  129.          Write_Str (" referencing Node_Id = ");
  130.          Write_Int (Int (Node));
  131.          Write_Eol;
  132.       end if;
  133.    end Append_Elmt;
  134.  
  135.    ------------------
  136.    -- Prepend_Elmt --
  137.    ------------------
  138.  
  139.    procedure Prepend_Elmt (Node : Node_Id; To : Elist_Id) is
  140.       F : constant Elmt_Id := Elists.Table (To).First;
  141.  
  142.    begin
  143.       Elmts.Increment_Last;
  144.       Elmts.Table (Elmts.Last).Node := Node;
  145.  
  146.       if F = No_Elmt then
  147.          Elists.Table (To).Last := Elmts.Last;
  148.          Elmts.Table (Elmts.Last).Next := Union_Id (To);
  149.       else
  150.          Elmts.Table (Elmts.Last).Next := Union_Id (F);
  151.       end if;
  152.  
  153.       Elists.Table (To).First  := Elmts.Last;
  154.  
  155.    end Prepend_Elmt;
  156.  
  157.    -----------------------
  158.    -- Insert_Elmt_After --
  159.    -----------------------
  160.  
  161.    procedure Insert_Elmt_After (Node : Node_Id; Elmt : Elmt_Id) is
  162.       N : constant Union_Id := Elmts.Table (Elmt).Next;
  163.  
  164.    begin
  165.  
  166.       pragma Assert (Elmt /= No_Elmt);
  167.  
  168.       Elmts.Increment_Last;
  169.       Elmts.Table (Elmts.Last).Node := Node;
  170.       Elmts.Table (Elmts.Last).Next := N;
  171.  
  172.       Elmts.Table (Elmt).Next := Union_Id (Elmts.Last);
  173.  
  174.       if N in Elist_Range then
  175.          Elists.Table (Elist_Id (N)).Last := Elmts.Last;
  176.       end if;
  177.    end Insert_Elmt_After;
  178.  
  179.    --------------------
  180.    -- Elists_Address --
  181.    --------------------
  182.  
  183.    function Elists_Address return System.Address is
  184.    begin
  185.       return Elists.Table (First_Elist_Id)'Address;
  186.    end Elists_Address;
  187.  
  188.    -------------------
  189.    -- Elmts_Address --
  190.    -------------------
  191.  
  192.    function Elmts_Address return System.Address is
  193.    begin
  194.       return Elmts.Table (First_Elmt_Id)'Address;
  195.    end Elmts_Address;
  196.  
  197.    ----------------
  198.    -- First_Elmt --
  199.    ----------------
  200.  
  201.    function First_Elmt (List : Elist_Id) return Elmt_Id is
  202.    begin
  203.       return Elists.Table (List).First;
  204.    end First_Elmt;
  205.  
  206.    ----------------
  207.    -- Initialize --
  208.    ----------------
  209.  
  210.    procedure Initialize is
  211.    begin
  212.       Elists.Init;
  213.       Elmts.Init;
  214.    end Initialize;
  215.  
  216.    ------------------------
  217.    -- Is_Empty_Elmt_List --
  218.    ------------------------
  219.  
  220.    function Is_Empty_Elmt_List (List : Elist_Id) return Boolean is
  221.    begin
  222.       return Elists.Table (List).First = No_Elmt;
  223.    end Is_Empty_Elmt_List;
  224.  
  225.    -------------------
  226.    -- Last_Elist_Id --
  227.    -------------------
  228.  
  229.    function Last_Elist_Id return Elist_Id is
  230.    begin
  231.       return Elists.Last;
  232.    end Last_Elist_Id;
  233.  
  234.    ---------------
  235.    -- Last_Elmt --
  236.    ---------------
  237.  
  238.    function Last_Elmt (List : Elist_Id) return Elmt_Id is
  239.    begin
  240.       return Elists.Table (List).Last;
  241.    end Last_Elmt;
  242.  
  243.    ------------------
  244.    -- Last_Elmt_Id --
  245.    ------------------
  246.  
  247.    function Last_Elmt_Id return Elmt_Id is
  248.    begin
  249.       return Elmts.Last;
  250.    end Last_Elmt_Id;
  251.  
  252.    -------------------
  253.    -- New_Elmt_List --
  254.    -------------------
  255.  
  256.    function New_Elmt_List return Elist_Id is
  257.    begin
  258.       Elists.Increment_Last;
  259.       Elists.Table (Elists.Last).First := No_Elmt;
  260.       Elists.Table (Elists.Last).Last  := No_Elmt;
  261.  
  262.       if Debug_Flag_N then
  263.          Write_Str ("Allocate new element list, returned ID = ");
  264.          Write_Int (Int (Elists.Last));
  265.          Write_Eol;
  266.       end if;
  267.  
  268.       return Elists.Last;
  269.    end New_Elmt_List;
  270.  
  271.    ---------------
  272.    -- Next_Elmt --
  273.    ---------------
  274.  
  275.    function Next_Elmt (Elmt : Elmt_Id) return Elmt_Id is
  276.       N : constant Union_Id := Elmts.Table (Elmt).Next;
  277.  
  278.    begin
  279.       if N in Elist_Range then
  280.          return No_Elmt;
  281.       else
  282.          return Elmt_Id (N);
  283.       end if;
  284.    end Next_Elmt;
  285.  
  286.    --------
  287.    -- No --
  288.    --------
  289.  
  290.    function No (List : Elist_Id) return Boolean is
  291.    begin
  292.       return List = No_Elist;
  293.    end No;
  294.  
  295.    function No (Elmt : Elmt_Id) return Boolean is
  296.    begin
  297.       return Elmt = No_Elmt;
  298.    end No;
  299.  
  300.    -----------
  301.    -- Node --
  302.    -----------
  303.  
  304.    function Node (Elmt : Elmt_Id) return Node_Id is
  305.    begin
  306.       return Elmts.Table (Elmt).Node;
  307.    end Node;
  308.  
  309.    ----------------
  310.    -- Num_Elists --
  311.    ----------------
  312.  
  313.    function Num_Elists return Nat is
  314.    begin
  315.       return Int (Elmts.Last) - Int (Elmts.First) + 1;
  316.    end Num_Elists;
  317.  
  318.    -------------
  319.    -- Present --
  320.    -------------
  321.  
  322.    function Present (List : Elist_Id) return Boolean is
  323.    begin
  324.       return List /= No_Elist;
  325.    end Present;
  326.  
  327.    function Present (Elmt : Elmt_Id) return Boolean is
  328.    begin
  329.       return Elmt /= No_Elmt;
  330.    end Present;
  331.  
  332.    ----------------------
  333.    -- Remove_Last_Elmt --
  334.    ----------------------
  335.  
  336.    procedure Remove_Last_Elmt (List : Elist_Id) is
  337.       Nxt : Elmt_Id;
  338.       Prv : Elmt_Id;
  339.  
  340.    begin
  341.       Nxt := Elists.Table (List).First;
  342.  
  343.       --  Case of removing only element in the list
  344.  
  345.       if Elmts.Table (Nxt).Next in Elist_Range then
  346.          Elists.Table (List).First := No_Elmt;
  347.          Elists.Table (List).Last  := No_Elmt;
  348.  
  349.       --  Case of at least two elements in list
  350.  
  351.       else
  352.          loop
  353.             Prv := Nxt;
  354.             Nxt := Elmt_Id (Elmts.Table (Prv).Next);
  355.             exit when Elmts.Table (Nxt).Next in Elist_Range;
  356.          end loop;
  357.  
  358.          Elmts.Table (Prv).Next   := Elmts.Table (Nxt).Next;
  359.          Elists.Table (List).Last := Prv;
  360.       end if;
  361.    end Remove_Last_Elmt;
  362.  
  363.    ------------------
  364.    -- Replace_Elmt --
  365.    ------------------
  366.  
  367.    procedure Replace_Elmt (Elmt : Elmt_Id; New_Node : Node_Id) is
  368.    begin
  369.       Elmts.Table (Elmt).Node := New_Node;
  370.    end Replace_Elmt;
  371.  
  372.    ---------------
  373.    -- Tree_Read --
  374.    ---------------
  375.  
  376.    procedure Tree_Read is
  377.    begin
  378.       Elists.Tree_Read;
  379.       Elmts.Tree_Read;
  380.    end Tree_Read;
  381.  
  382.    ----------------
  383.    -- Tree_Write --
  384.    ----------------
  385.  
  386.    procedure Tree_Write is
  387.    begin
  388.       Elists.Tree_Write;
  389.       Elmts.Tree_Write;
  390.    end Tree_Write;
  391.  
  392. end Elists;
  393.