]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/mc/alists.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / mc / alists.mod
CommitLineData
1eee94d3
GM
1(* alists.mod address lists module.
2
a945c346 3Copyright (C) 2015-2024 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Modula-2; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. *)
21
22IMPLEMENTATION MODULE alists ;
23
24
25FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
26
27CONST
28 MaxnoOfelements = 5 ;
29
30TYPE
31 alist = POINTER TO RECORD
32 noOfelements: CARDINAL ;
33 elements : ARRAY [1..MaxnoOfelements] OF ADDRESS ;
34 next : alist ;
35 END ;
36
37
38(*
39 initList - creates a new alist, l.
40*)
41
42PROCEDURE initList () : alist ;
43VAR
44 l: alist ;
45BEGIN
46 NEW (l) ;
47 WITH l^ DO
48 noOfelements := 0 ;
49 next := NIL
50 END ;
51 RETURN l
52END initList ;
53
54
55(*
56 killList - deletes the complete alist, l.
57*)
58
59PROCEDURE killList (VAR l: alist) ;
60BEGIN
61 IF l#NIL
62 THEN
63 IF l^.next#NIL
64 THEN
65 killList (l^.next)
66 END ;
67 DISPOSE (l)
68 END
69END killList ;
70
71
72(*
73 putItemIntoList - places an ADDRESS, c, into alist, l.
74*)
75
76PROCEDURE putItemIntoList (l: alist; c: ADDRESS) ;
77BEGIN
78 WITH l^ DO
79 IF noOfelements<MaxnoOfelements
80 THEN
81 INC (noOfelements) ;
82 elements[noOfelements] := c
83 ELSIF next#NIL
84 THEN
85 putItemIntoList (next, c)
86 ELSE
87 next := initList () ;
88 putItemIntoList (next, c)
89 END
90 END
91END putItemIntoList ;
92
93
94(*
95 getItemFromList - retrieves the nth WORD from alist, l.
96*)
97
98PROCEDURE getItemFromList (l: alist; n: CARDINAL) : ADDRESS ;
99BEGIN
100 WHILE l#NIL DO
101 WITH l^ DO
102 IF n<=noOfelements
103 THEN
104 RETURN elements[n]
105 ELSE
106 DEC (n, noOfelements)
107 END
108 END ;
109 l := l^.next
110 END ;
111 RETURN 0
112END getItemFromList ;
113
114
115(*
116 getIndexOfList - returns the index for WORD, c, in alist, l.
117 If more than one WORD, c, exists the index
118 for the first is returned.
119*)
120
121PROCEDURE getIndexOfList (l: alist; c: ADDRESS) : CARDINAL ;
122VAR
123 i: CARDINAL ;
124BEGIN
125 IF l=NIL
126 THEN
127 RETURN 0
128 ELSE
129 WITH l^ DO
130 i := 1 ;
131 WHILE i<=noOfelements DO
132 IF elements[i]=c
133 THEN
134 RETURN i
135 ELSE
136 INC(i)
137 END
138 END ;
139 RETURN noOfelements + getIndexOfList (next, c)
140 END
141 END
142END getIndexOfList ;
143
144
145(*
146 noOfItemsInList - returns the number of items in alist, l.
147*)
148
149PROCEDURE noOfItemsInList (l: alist) : CARDINAL ;
150VAR
151 t: CARDINAL ;
152BEGIN
153 IF l=NIL
154 THEN
155 RETURN 0
156 ELSE
157 t := 0 ;
158 REPEAT
159 WITH l^ DO
160 INC (t, noOfelements)
161 END ;
162 l := l^.next
163 UNTIL l=NIL;
164 RETURN t
165 END
166END noOfItemsInList ;
167
168
169(*
170 includeItemIntoList - adds an ADDRESS, c, into a alist providing
171 the value does not already exist.
172*)
173
174PROCEDURE includeItemIntoList (l: alist; c: ADDRESS) ;
175BEGIN
176 IF NOT isItemInList (l, c)
177 THEN
178 putItemIntoList (l, c)
179 END
180END includeItemIntoList ;
181
182
183(*
184 removeItem - remove an element at index, i, from the alist data type.
185*)
186
187PROCEDURE removeItem (p, l: alist; i: CARDINAL) ;
188BEGIN
189 WITH l^ DO
190 DEC (noOfelements) ;
191 WHILE i<=noOfelements DO
192 elements[i] := elements[i+1] ;
193 INC (i)
194 END ;
195 IF (noOfelements=0) AND (p#NIL)
196 THEN
197 p^.next := l^.next ;
198 DISPOSE (l)
199 END
200 END
201END removeItem ;
202
203
204(*
205 removeItemFromList - removes a ADDRESS, c, from a alist.
206 It assumes that this value only appears once.
207*)
208
209PROCEDURE removeItemFromList (l: alist; c: ADDRESS) ;
210VAR
211 p : alist ;
212 i : CARDINAL ;
213 found: BOOLEAN ;
214BEGIN
215 IF l#NIL
216 THEN
217 found := FALSE ;
218 p := NIL ;
219 REPEAT
220 WITH l^ DO
221 i := 1 ;
222 WHILE (i<=noOfelements) AND (elements[i]#c) DO
223 INC (i)
224 END ;
225 END ;
226 IF (i<=l^.noOfelements) AND (l^.elements[i]=c)
227 THEN
228 found := TRUE
229 ELSE
230 p := l ;
231 l := l^.next
232 END
233 UNTIL (l=NIL) OR found ;
234 IF found
235 THEN
236 removeItem (p, l, i)
237 END
238 END
239END removeItemFromList ;
240
241
242(*
243 isItemInList - returns true if a ADDRESS, c, was found in alist, l.
244*)
245
246PROCEDURE isItemInList (l: alist; c: ADDRESS) : BOOLEAN ;
247VAR
248 i: CARDINAL ;
249BEGIN
250 REPEAT
251 WITH l^ DO
252 i := 1 ;
253 WHILE i<=noOfelements DO
254 IF elements[i]=c
255 THEN
256 RETURN TRUE
257 ELSE
258 INC (i)
259 END
260 END
261 END ;
262 l := l^.next
263 UNTIL l=NIL ;
264 RETURN FALSE
265END isItemInList ;
266
267
268(*
269 foreachItemInListDo - calls procedure, P, foreach item in alist, l.
270*)
271
272PROCEDURE foreachItemInListDo (l: alist; p: performOperation) ;
273VAR
274 i, n: CARDINAL ;
275BEGIN
276 n := noOfItemsInList(l) ;
277 i := 1 ;
278 WHILE i<=n DO
279 p (getItemFromList (l, i)) ;
280 INC(i)
281 END
282END foreachItemInListDo ;
283
284
285(*
286 duplicateList - returns a duplicate alist derived from, l.
287*)
288
289PROCEDURE duplicateList (l: alist) : alist ;
290VAR
291 m : alist ;
292 n, i: CARDINAL ;
293BEGIN
294 m := initList () ;
295 n := noOfItemsInList (l) ;
296 i := 1 ;
297 WHILE i<=n DO
298 putItemIntoList (m, getItemFromList (l, i)) ;
299 INC (i)
300 END ;
301 RETURN m
302END duplicateList ;
303
304
305END alists.