]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-compiler/NameKey.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-compiler / NameKey.mod
CommitLineData
1eee94d3
GM
1(* NameKey.mod provides a dynamic binary tree name to key.
2
83ffe9cd 3Copyright (C) 2001-2023 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius.mulley@southwales.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 NameKey ;
23
24
25FROM SYSTEM IMPORT ADR ;
26FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
27FROM Indexing IMPORT Index, InitIndex, GetIndice, PutIndice, InBounds ;
28FROM StrIO IMPORT WriteString, WriteLn ;
29FROM StdIO IMPORT Write ;
30FROM NumberIO IMPORT WriteCard ;
31FROM StrLib IMPORT StrLen ;
32FROM libc IMPORT strlen ;
33FROM ASCII IMPORT nul ;
34
35
36TYPE
37 PtrToChar = POINTER TO CHAR ;
38
39 NameNode = POINTER TO Node ;
40 Node = RECORD
41 Data : PtrToChar ;
42 Key : Name ;
43 Left,
44 Right: NameNode ;
45 END ;
46
47 Comparison = (less, equal, greater) ;
48
49VAR
50 BinaryTree: NameNode ;
51 KeyIndex : Index ;
52 LastIndice: CARDINAL ;
53
54
55(*
56 GetKey - returns the name, a, of the key, Key.
57*)
58
59PROCEDURE GetKey (key: Name; VAR a: ARRAY OF CHAR) ;
60VAR
61 p : PtrToChar ;
62 i, higha: CARDINAL ;
63BEGIN
64 p := KeyToCharStar(key) ;
65 i := 0 ;
66 higha := HIGH(a) ;
67 WHILE (p#NIL) AND (i<=higha) AND (p^#nul) DO
68 a[i] := p^ ;
69 INC(p) ;
70 INC(i)
71 END ;
72 IF i<=higha
73 THEN
74 a[i] := nul
75 END
76END GetKey ;
77
78
79(*
80 IsKey - returns TRUE if string, a, is currently a key.
81 We dont use the Compare function, we inline it and avoid
82 converting, a, into a String, for speed.
83*)
84
85PROCEDURE IsKey (a: ARRAY OF CHAR) : BOOLEAN ;
86VAR
87 child : NameNode ;
88 p : PtrToChar ;
89 i,
90 higha : CARDINAL ;
91BEGIN
92 (* firstly set up the initial values of child, using sentinal node *)
93 child := BinaryTree^.Left ;
94 IF child#NIL
95 THEN
96 REPEAT
97 i := 0 ;
98 higha := HIGH(a) ;
99 p := KeyToCharStar(child^.Key) ;
100 WHILE (i<=higha) AND (a[i]#nul) DO
101 IF a[i]<p^
102 THEN
103 child := child^.Left ;
104 i := higha
105 ELSIF a[i]>p^
106 THEN
107 child := child^.Right ;
108 i := higha
109 ELSE
110 IF (a[i]=nul) OR (i=higha)
111 THEN
112 IF p^=nul
113 THEN
114 RETURN( TRUE )
115 ELSE
116 child := child^.Left
117 END
118 END ;
119 INC(p)
120 END ;
121 INC(i)
122 END ;
123 UNTIL child=NIL
124 END ;
125 RETURN( FALSE ) ;
126END IsKey ;
127
128
129(*
130 DoMakeKey - finds the name, n, in the tree or else create a name.
131 If a name is found then the string, n, is deallocated.
132*)
133
134PROCEDURE DoMakeKey (n: PtrToChar; higha: CARDINAL) : Name ;
135VAR
136 result: Comparison ;
137 father,
138 child : NameNode ;
139 k : Name ;
140BEGIN
141 result := FindNodeAndParentInTree(n, child, father) ;
142 IF child=NIL
143 THEN
144 IF result=less
145 THEN
146 NEW(child) ;
147 father^.Left := child
148 ELSIF result=greater
149 THEN
150 NEW(child) ;
151 father^.Right := child
152 END ;
153 WITH child^ DO
154 Right := NIL ;
155 Left := NIL ;
156 INC(LastIndice) ;
157 Key := LastIndice ;
158 Data := n ;
159 PutIndice(KeyIndex, Key, n)
160 END ;
161 k := LastIndice
162 ELSE
163 DEALLOCATE(n, higha+1) ;
164 k := child^.Key
165 END ;
166 RETURN( k )
167END DoMakeKey ;
168
169
170(*
171 MakeKey - returns the Key of the symbol, a. If a is not in the
172 name table then it is added, otherwise the Key of a is returned
173 directly. Note that the name table has no scope - it merely
174 presents a more convienient way of expressing strings. By a Key.
175*)
176
177PROCEDURE MakeKey (a: ARRAY OF CHAR) : Name ;
178VAR
179 n, p : PtrToChar ;
180 i,
181 higha : CARDINAL ;
182BEGIN
183 higha := StrLen(a) ;
184 ALLOCATE(p, higha+1) ;
185 IF p=NIL
186 THEN
187 HALT (* out of memory error *)
188 ELSE
189 n := p ;
190 i := 0 ;
191 WHILE i<higha DO
192 p^ := a[i] ;
193 INC(i) ;
194 INC(p)
195 END ;
196 p^ := nul ;
197
198 RETURN( DoMakeKey(n, higha) )
199 END
200END MakeKey ;
201
202
203(*
204 makekey - returns the Key of the symbol, a. If a is not in the
205 name table then it is added, otherwise the Key of a is returned
206 directly. Note that the name table has no scope - it merely
207 presents a more convienient way of expressing strings. By a Key.
208 These keys last for the duration of compilation.
209*)
210
211PROCEDURE makekey (a: ADDRESS) : Name ;
212VAR
213 n,
214 p, pa : PtrToChar ;
215 i,
216 higha : CARDINAL ;
217BEGIN
218 IF a=NIL
219 THEN
220 RETURN( NulName )
221 ELSE
222 higha := strlen(a) ;
223 ALLOCATE(p, higha+1) ;
224 IF p=NIL
225 THEN
226 HALT (* out of memory error *)
227 ELSE
228 n := p ;
229 pa := a ;
230 i := 0 ;
231 WHILE i<higha DO
232 p^ := pa^ ;
233 INC(i) ;
234 INC(p) ;
235 INC(pa)
236 END ;
237 p^ := nul ;
238
239 RETURN( DoMakeKey(n, higha) )
240 END
241 END
242END makekey ;
243
244
245(*
246 LengthKey - returns the StrLen of Key.
247*)
248
249PROCEDURE LengthKey (Key: Name) : CARDINAL ;
250VAR
251 i: CARDINAL ;
252 p: PtrToChar ;
253BEGIN
254 p := KeyToCharStar(Key) ;
255 i := 0 ;
256 WHILE p^#nul DO
257 INC(i) ;
258 INC(p)
259 END ;
260 RETURN( i )
261END LengthKey ;
262
263
264(*
265 Compare - return the result of Names[i] with Names[j]
266*)
267
268PROCEDURE Compare (pi: PtrToChar; j: Name) : Comparison ;
269VAR
270 pj: PtrToChar ;
271 c1, c2: CHAR ;
272BEGIN
273 pj := KeyToCharStar(j) ;
274 c1 := pi^ ;
275 c2 := pj^ ;
276 WHILE (c1#nul) OR (c2#nul) DO
277 IF c1<c2
278 THEN
279 RETURN( less )
280 ELSIF c1>c2
281 THEN
282 RETURN( greater )
283 ELSE
284 INC(pi) ;
285 INC(pj) ;
286 c1 := pi^ ;
287 c2 := pj^
288 END
289 END ;
290 RETURN( equal )
291END Compare ;
292
293
294(*
295 FindNodeAndParentInTree - search BinaryTree for a name.
296 If this name is found in the BinaryTree then
297 child is set to this name and father is set to the node above.
298 A comparison is returned to assist adding entries into this tree.
299*)
300
301PROCEDURE FindNodeAndParentInTree (n: PtrToChar; VAR child, father: NameNode) : Comparison ;
302VAR
303 result: Comparison ;
304BEGIN
305 (* firstly set up the initial values of child and father, using sentinal node *)
306 father := BinaryTree ;
307 child := BinaryTree^.Left ;
308 IF child=NIL
309 THEN
310 RETURN( less )
311 ELSE
312 REPEAT
313 result := Compare(n, child^.Key) ;
314 IF result=less
315 THEN
316 father := child ;
317 child := child^.Left
318 ELSIF result=greater
319 THEN
320 father := child ;
321 child := child^.Right
322 END
323 UNTIL (child=NIL) OR (result=equal) ;
324 RETURN( result )
325 END
326END FindNodeAndParentInTree ;
327
328
329(*
330 IsSameExcludingCase - returns TRUE if key1 and key2 are
331 the same. It is case insensitive.
332 This function deliberately inlines CAP for speed.
333*)
334
335PROCEDURE IsSameExcludingCase (key1, key2: Name) : BOOLEAN ;
336VAR
337 pi, pj: PtrToChar ;
338 c1, c2: CHAR ;
339BEGIN
340 IF key1=key2
341 THEN
342 RETURN( TRUE )
343 ELSE
344 pi := KeyToCharStar(key1) ;
345 pj := KeyToCharStar(key2) ;
346 c1 := pi^ ;
347 c2 := pj^ ;
348 WHILE (c1#nul) AND (c2#nul) DO
349 IF (c1=c2) OR
350 (((c1>='A') AND (c1<='Z')) AND (c2=CHR(ORD(c1)-ORD('A')+ORD('a')))) OR
351 (((c2>='A') AND (c2<='Z')) AND (c1=CHR(ORD(c2)-ORD('A')+ORD('a'))))
352 THEN
353 INC(pi) ;
354 INC(pj) ;
355 c1 := pi^ ;
356 c2 := pj^
357 ELSE
358 (* difference found *)
359 RETURN( FALSE )
360 END
361 END ;
362 RETURN( c1=c2 )
363 END
364END IsSameExcludingCase ;
365
366
367(*
368 KeyToCharStar - returns the C char * string equivalent for, key.
369*)
370
371PROCEDURE KeyToCharStar (key: Name) : ADDRESS ;
372BEGIN
373 IF (key=NulName) OR (NOT InBounds(KeyIndex, key))
374 THEN
375 RETURN( NIL )
376 ELSE
377 RETURN( GetIndice(KeyIndex, key) )
378 END
379END KeyToCharStar ;
380
381
382PROCEDURE WriteKey (key: Name) ;
383VAR
384 s: PtrToChar ;
385BEGIN
386 s := KeyToCharStar(key) ;
387 WHILE (s#NIL) AND (s^#nul) DO
388 Write(s^) ;
389 INC(s)
390 END
391END WriteKey ;
392
393
394(*
395 CharKey - returns the key[i] character.
396*)
397
398PROCEDURE CharKey (key: Name; i: CARDINAL) : CHAR ;
399VAR
400 p: PtrToChar ;
401BEGIN
402 IF i >= LengthKey (key)
403 THEN
404 HALT
405 END ;
406 p := KeyToCharStar (key) ;
407 INC (p, i) ;
408 RETURN p^
409END CharKey ;
410
411
412BEGIN
413 LastIndice := 0 ;
414 KeyIndex := InitIndex(1) ;
415 NEW(BinaryTree) ;
416 BinaryTree^.Left := NIL
417END NameKey.