1--  Chain handling.
2--  Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
3--
4--  This program is free software: you can redistribute it and/or modify
5--  it under the terms of the GNU General Public License as published by
6--  the Free Software Foundation, either version 2 of the License, or
7--  (at your option) any later version.
8--
9--  This program is distributed in the hope that it will be useful,
10--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12--  GNU General Public License for more details.
13--
14--  You should have received a copy of the GNU General Public License
15--  along with this program.  If not, see <gnu.org/licenses>.
16
17package body Vhdl.Nodes_Utils is
18   function Get_Chain_Length (First : Iir) return Natural
19   is
20      Res : Natural := 0;
21      El : Iir := First;
22   begin
23      while El /= Null_Iir loop
24         Res := Res + 1;
25         El := Get_Chain (El);
26      end loop;
27      return Res;
28   end Get_Chain_Length;
29
30   procedure Append_Chain
31     (N : Iir; Field : Vhdl.Nodes_Meta.Fields_Enum; Chain : Iir)
32   is
33      use Vhdl.Nodes_Meta;
34      N_Chain : Iir;
35      Next_Chain : Iir;
36   begin
37      N_Chain := Get_Iir (N, Field);
38      if Is_Null (N_Chain) then
39         Set_Iir (N, Field, Chain);
40      else
41         loop
42            Next_Chain := Get_Chain (N_Chain);
43            if Is_Null (Next_Chain) then
44               Set_Chain (N_Chain, Chain);
45               exit;
46            end if;
47            N_Chain := Next_Chain;
48         end loop;
49      end if;
50   end Append_Chain;
51
52   procedure Chain_Init (First, Last : out Iir) is
53   begin
54      First := Null_Iir;
55      Last := Null_Iir;
56   end Chain_Init;
57
58   procedure Chain_Append (First, Last : in out Iir; El : Iir) is
59   begin
60      pragma Assert (El /= Null_Iir);
61      if First = Null_Iir then
62         First := El;
63      else
64         Set_Chain (Last, El);
65      end if;
66      Last := El;
67   end Chain_Append;
68
69   procedure Chain_Append_Chain (First, Last : in out Iir;
70                                     First_Sub, Last_Sub : Iir) is
71   begin
72      pragma Assert (First_Sub /= Null_Iir);
73      if First = Null_Iir then
74         First := First_Sub;
75      else
76         Set_Chain (Last, First_Sub);
77      end if;
78      Last := Last_Sub;
79   end Chain_Append_Chain;
80
81   procedure Chain_Append_Subchain (First, Last : in out Iir;
82                                        Sub : Iir)
83   is
84      N : Iir;
85   begin
86      pragma Assert (Sub /= Null_Iir);
87      if First = Null_Iir then
88         First := Sub;
89      else
90         Set_Chain (Last, Sub);
91      end if;
92
93      --  Update last.
94      N := Sub;
95      while N /= Null_Iir loop
96         Last := N;
97         N := Get_Chain (N);
98      end loop;
99   end Chain_Append_Subchain;
100
101   function Is_Chain_Length_One (Chain : Iir) return Boolean is
102   begin
103      return Chain /= Null_Iir and then Get_Chain (Chain) = Null_Iir;
104   end Is_Chain_Length_One;
105
106   procedure Insert_Incr (Last : in out Iir; El : Iir) is
107   begin
108      Set_Chain (El, Get_Chain (Last));
109      Set_Chain (Last, El);
110      Last := El;
111   end Insert_Incr;
112end Vhdl.Nodes_Utils;
113