1 /* do not edit automatically generated by mc from symbolKey. */
2 /* symbolKey.mod provides binary tree operations for storing symbols.
4 Copyright (C) 2015-2024 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
7 This file is part of GNU Modula-2.
9 GNU Modula-2 is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GNU Modula-2 is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Modula-2; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
26 # if !defined (PROC_D)
28 typedef void (*PROC_t
) (void);
29 typedef struct { PROC_t proc
; } PROC
;
36 # include "GStorage.h"
37 #if defined(__cplusplus)
43 #include "GsymbolKey.h"
44 # include "GStorage.h"
46 # include "GNumberIO.h"
48 # include "GnameKey.h"
50 # define symbolKey_NulKey NULL
51 typedef struct symbolKey_isSymbol_p symbolKey_isSymbol
;
53 typedef struct symbolKey_performOperation_p symbolKey_performOperation
;
55 typedef struct symbolKey__T1_r symbolKey__T1
;
57 typedef symbolKey__T1
*symbolKey_symbolTree__opaque
;
59 struct symbolKey__T1_r
{
62 symbolKey_symbolTree__opaque left
;
63 symbolKey_symbolTree__opaque right
;
66 extern "C" symbolKey_symbolTree
symbolKey_initTree (void);
67 extern "C" void symbolKey_killTree (symbolKey_symbolTree
*t
);
68 extern "C" void * symbolKey_getSymKey (symbolKey_symbolTree t
, nameKey_Name name
);
69 extern "C" void symbolKey_putSymKey (symbolKey_symbolTree t
, nameKey_Name name
, void * key
);
72 delSymKey - deletes an entry in the binary tree.
74 NB in order for this to work we must ensure that the InitTree sets
75 both left and right to NIL.
78 extern "C" void symbolKey_delSymKey (symbolKey_symbolTree t
, nameKey_Name name
);
81 isEmptyTree - returns true if symbolTree, t, is empty.
84 extern "C" bool symbolKey_isEmptyTree (symbolKey_symbolTree t
);
87 doesTreeContainAny - returns true if symbolTree, t, contains any
88 symbols which in turn return true when procedure,
89 p, is called with a symbol as its parameter.
90 The symbolTree root is empty apart from the field,
91 left, hence we need two procedures.
94 extern "C" bool symbolKey_doesTreeContainAny (symbolKey_symbolTree t
, symbolKey_isSymbol p
);
97 foreachNodeDo - for each node in symbolTree, t, a procedure, p,
98 is called with the node symbol as its parameter.
99 The tree root node only contains a legal left pointer,
100 therefore we need two procedures to examine this tree.
103 extern "C" void symbolKey_foreachNodeDo (symbolKey_symbolTree t
, symbolKey_performOperation p
);
106 findNodeAndParentInTree - find a node, child, in a binary tree, t, with name equal to n.
107 if an entry is found, father is set to the node above child.
110 static void findNodeAndParentInTree (symbolKey_symbolTree__opaque t
, nameKey_Name n
, symbolKey_symbolTree__opaque
*child
, symbolKey_symbolTree__opaque
*father
);
113 searchForAny - performs the search required for doesTreeContainAny.
114 The root node always contains a nul data value,
115 therefore we must skip over it.
118 static bool searchForAny (symbolKey_symbolTree__opaque t
, symbolKey_isSymbol p
);
121 searchAndDo - searches all the nodes in symbolTree, t, and
122 calls procedure, p, with a node as its parameter.
123 It traverse the tree in order.
126 static void searchAndDo (symbolKey_symbolTree__opaque t
, symbolKey_performOperation p
);
130 findNodeAndParentInTree - find a node, child, in a binary tree, t, with name equal to n.
131 if an entry is found, father is set to the node above child.
134 static void findNodeAndParentInTree (symbolKey_symbolTree__opaque t
, nameKey_Name n
, symbolKey_symbolTree__opaque
*child
, symbolKey_symbolTree__opaque
*father
)
136 /* remember to skip the sentinal value and assign father and child */
140 Debug_Halt ((const char *) "parameter t should never be NIL", 31, (const char *) "../../gcc/m2/mc/symbolKey.mod", 29, (const char *) "findNodeAndParentInTree", 23, 203);
143 if ((*child
) != NULL
)
146 if (n
< (*child
)->name
)
148 (*father
) = (*child
);
149 (*child
) = (*child
)->left
;
151 else if (n
> (*child
)->name
)
153 /* avoid dangling else. */
154 (*father
) = (*child
);
155 (*child
) = (*child
)->right
;
157 } while (! (((*child
) == NULL
) || (n
== (*child
)->name
)));
163 searchForAny - performs the search required for doesTreeContainAny.
164 The root node always contains a nul data value,
165 therefore we must skip over it.
168 static bool searchForAny (symbolKey_symbolTree__opaque t
, symbolKey_isSymbol p
)
176 return (((*p
.proc
) (t
->key
)) || (searchForAny (t
->left
, p
))) || (searchForAny (t
->right
, p
));
178 /* static analysis guarentees a RETURN statement will be used before here. */
179 __builtin_unreachable ();
184 searchAndDo - searches all the nodes in symbolTree, t, and
185 calls procedure, p, with a node as its parameter.
186 It traverse the tree in order.
189 static void searchAndDo (symbolKey_symbolTree__opaque t
, symbolKey_performOperation p
)
193 searchAndDo (t
->right
, p
);
195 searchAndDo (t
->left
, p
);
199 extern "C" symbolKey_symbolTree
symbolKey_initTree (void)
201 symbolKey_symbolTree__opaque t
;
203 Storage_ALLOCATE ((void **) &t
, sizeof (symbolKey__T1
)); /* The value entity */
204 t
->left
= static_cast<symbolKey_symbolTree__opaque
> (NULL
);
205 t
->right
= static_cast<symbolKey_symbolTree__opaque
> (NULL
);
206 return static_cast<symbolKey_symbolTree
> (t
);
207 /* static analysis guarentees a RETURN statement will be used before here. */
208 __builtin_unreachable ();
211 extern "C" void symbolKey_killTree (symbolKey_symbolTree
*t
)
215 symbolKey_killTree (reinterpret_cast<symbolKey_symbolTree
*> (&static_cast<symbolKey_symbolTree__opaque
> ((*t
))->left
));
216 symbolKey_killTree (reinterpret_cast<symbolKey_symbolTree
*> (&static_cast<symbolKey_symbolTree__opaque
> ((*t
))->right
));
217 Storage_DEALLOCATE ((void **) &(*t
), sizeof (symbolKey__T1
));
218 (*t
) = static_cast<symbolKey_symbolTree
> (NULL
);
222 extern "C" void * symbolKey_getSymKey (symbolKey_symbolTree t
, nameKey_Name name
)
224 symbolKey_symbolTree__opaque father
;
225 symbolKey_symbolTree__opaque child
;
229 return symbolKey_NulKey
;
233 findNodeAndParentInTree (static_cast<symbolKey_symbolTree__opaque
> (t
), name
, &child
, &father
);
236 return symbolKey_NulKey
;
243 /* static analysis guarentees a RETURN statement will be used before here. */
244 __builtin_unreachable ();
247 extern "C" void symbolKey_putSymKey (symbolKey_symbolTree t
, nameKey_Name name
, void * key
)
249 symbolKey_symbolTree__opaque father
;
250 symbolKey_symbolTree__opaque child
;
252 findNodeAndParentInTree (static_cast<symbolKey_symbolTree__opaque
> (t
), name
, &child
, &father
);
255 /* no child found, now is name less than father or greater? */
258 /* empty tree, add it to the left branch of t */
259 Storage_ALLOCATE ((void **) &child
, sizeof (symbolKey__T1
));
260 father
->left
= child
;
264 if (name
< father
->name
)
266 Storage_ALLOCATE ((void **) &child
, sizeof (symbolKey__T1
));
267 father
->left
= child
;
269 else if (name
> father
->name
)
271 /* avoid dangling else. */
272 Storage_ALLOCATE ((void **) &child
, sizeof (symbolKey__T1
));
273 father
->right
= child
;
276 child
->right
= static_cast<symbolKey_symbolTree__opaque
> (NULL
);
277 child
->left
= static_cast<symbolKey_symbolTree__opaque
> (NULL
);
283 Debug_Halt ((const char *) "symbol already stored", 21, (const char *) "../../gcc/m2/mc/symbolKey.mod", 29, (const char *) "putSymKey", 9, 119);
289 delSymKey - deletes an entry in the binary tree.
291 NB in order for this to work we must ensure that the InitTree sets
292 both left and right to NIL.
295 extern "C" void symbolKey_delSymKey (symbolKey_symbolTree t
, nameKey_Name name
)
297 symbolKey_symbolTree__opaque i
;
298 symbolKey_symbolTree__opaque child
;
299 symbolKey_symbolTree__opaque father
;
301 findNodeAndParentInTree (static_cast<symbolKey_symbolTree__opaque
> (t
), name
, &child
, &father
); /* find father and child of the node */
302 if ((child
!= NULL
) && (child
->name
== name
))
304 /* Have found the node to be deleted */
305 if (father
->right
== child
)
307 /* most branch of child^.left. */
308 if (child
->left
!= NULL
)
310 /* Scan for right most node of child^.left */
312 while (i
->right
!= NULL
)
316 i
->right
= child
->right
;
317 father
->right
= child
->left
;
321 /* (as in a single linked list) to child^.right */
322 father
->right
= child
->right
;
324 Storage_DEALLOCATE ((void **) &child
, sizeof (symbolKey__T1
));
328 /* branch of child^.right */
329 if (child
->right
!= NULL
)
331 /* Scan for left most node of child^.right */
333 while (i
->left
!= NULL
)
337 i
->left
= child
->left
;
338 father
->left
= child
->right
;
342 /* (as in a single linked list) to child^.left. */
343 father
->left
= child
->left
;
345 Storage_DEALLOCATE ((void **) &child
, sizeof (symbolKey__T1
));
350 Debug_Halt ((const char *) "trying to delete a symbol that is not in the tree - the compiler never expects this to occur", 92, (const char *) "../../gcc/m2/mc/symbolKey.mod", 29, (const char *) "delSymKey", 9, 186);
356 isEmptyTree - returns true if symbolTree, t, is empty.
359 extern "C" bool symbolKey_isEmptyTree (symbolKey_symbolTree t
)
361 return static_cast<symbolKey_symbolTree__opaque
> (t
)->left
== NULL
;
362 /* static analysis guarentees a RETURN statement will be used before here. */
363 __builtin_unreachable ();
368 doesTreeContainAny - returns true if symbolTree, t, contains any
369 symbols which in turn return true when procedure,
370 p, is called with a symbol as its parameter.
371 The symbolTree root is empty apart from the field,
372 left, hence we need two procedures.
375 extern "C" bool symbolKey_doesTreeContainAny (symbolKey_symbolTree t
, symbolKey_isSymbol p
)
377 return searchForAny (static_cast<symbolKey_symbolTree__opaque
> (t
)->left
, p
);
378 /* static analysis guarentees a RETURN statement will be used before here. */
379 __builtin_unreachable ();
384 foreachNodeDo - for each node in symbolTree, t, a procedure, p,
385 is called with the node symbol as its parameter.
386 The tree root node only contains a legal left pointer,
387 therefore we need two procedures to examine this tree.
390 extern "C" void symbolKey_foreachNodeDo (symbolKey_symbolTree t
, symbolKey_performOperation p
)
392 searchAndDo (static_cast<symbolKey_symbolTree__opaque
> (t
)->left
, p
);
395 extern "C" void _M2_symbolKey_init (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])
399 extern "C" void _M2_symbolKey_fini (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])