9 date 2007.11.11.22.35.22; author khansen; state Exp;
14 date 2007.08.09.20.33.57; author khansen; state Exp;
19 date 2007.08.08.22.40.43; author khansen; state Exp;
24 date 2007.07.22.13.33.26; author khansen; state Exp;
29 date 2004.12.14.01.50.05; author kenth; state Exp;
34 date 2004.12.06.04.52.53; author kenth; state Exp;
39 date 2004.06.30.07.55.57; author kenth; state Exp;
54 * $Id: symtab.c,v 1.6 2007/08/09 20:33:57 khansen Exp khansen $
56 * Revision 1.6 2007/08/09 20:33:57 khansen
59 * Revision 1.5 2007/08/08 22:40:43 khansen
60 * recursive symbol table lookup
62 * Revision 1.4 2007/07/22 13:33:26 khansen
63 * convert tabs to whitespaces
65 * Revision 1.3 2004/12/14 01:50:05 kenth
68 * Revision 1.2 2004/12/06 04:52:53 kenth
71 * Revision 1.1 2004/06/30 07:55:57 kenth
77 * (C) 2004 Kent Hansen
79 * The XORcyst is free software; you can redistribute it and/or modify
80 * it under the terms of the GNU General Public License as published by
81 * the Free Software Foundation; either version 2 of the License, or
82 * (at your option) any later version.
84 * The XORcyst is distributed in the hope that it will be useful,
85 * but WITHOUT ANY WARRANTY; without even the implied warranty of
86 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87 * GNU General Public License for more details.
89 * You should have received a copy of the GNU General Public License
90 * along with The XORcyst; if not, write to the Free Software
91 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
95 * This file contains functions for symbol table management.
103 #define SAFE_FREE(a) if (a) { free(a); a = NULL; }
105 /* Stack of symbol tables */
106 static symtab *symtab_stack[32] = { NULL };
107 static int stack_index = 0;
109 static void symtab_entry_finalize(symtab_entry *);
111 /*---------------------------------------------------------------------------*/
114 * Gets the entry in the tree with minimum key.
116 static symtab_entry *binary_min(symtab_entry *p)
118 if (p == NULL) { return NULL; }
119 while (p->left != NULL) {
127 * Gets the entry in the tree with maximum key.
129 static symtab_entry *binary_max(symtab_entry *p)
131 if (p == NULL) { return NULL; }
132 while (p->right != NULL) {
140 * Gets the successor of an entry.
142 static symtab_entry *binary_succ(symtab_entry *p)
145 if (p == NULL) { return NULL; }
146 if (p->right != NULL) { return binary_min(p->right); }
148 while ((e != NULL) && (p == e->right)) {
157 * Gets the predecessor of an entry.
159 static symtab_entry *binary_pred(symtab_entry *p)
162 if (p == NULL) { return NULL; }
163 if (p->left != NULL) { return binary_max(p->left); }
165 while ((e != NULL) && (p == e->left)) {
174 * Inserts a new entry in a binary tree.
175 * It's implemented recursively although that's a bad thing.
176 * @@param p The root of the tree
177 * @@param e A new entry to be inserted
179 static void binary_insert(symtab_entry *p, symtab_entry *e)
181 int r = strcmp(p->id, e->id);
183 /* Follow left branch */
184 if (p->left == NULL) {
185 p->left = e; /* Entry inserted successfully */
189 binary_insert(p->left, e); /* Call recursively */
193 /* Follow right branch */
194 if (p->right == NULL) {
195 p->right = e; /* Entry inserted successfully */
199 binary_insert(p->right, e); /* Call recursively */
203 /* Symbol already present */
208 * Deletes an entry from a binary tree.
209 * @@param p Root node
210 * @@param z Entry to delete
212 static void binary_delete(symtab *st, symtab_entry *z)
217 if ((st == NULL) || (z == NULL)) { return; }
219 if ((z->left == NULL) || (z->right == NULL)) {
226 if (y->left != NULL) {
241 else if (y == p->left) {
249 symtab_finalize(z->symtab);
251 z->id = (char *)malloc(strlen(y->id)+1);
253 strcpy(z->id, y->id);
257 z->ref_count = y->ref_count;
259 z->symtab = y->symtab;
264 symtab_entry_finalize(y);
269 * Searches for an entry in a binary tree.
270 * @@param p Root node
271 * @@param id Identifier (search key)
273 static symtab_entry *binary_search(symtab_entry *p, const char *id)
276 while ((p != NULL) && ((r = strcmp(p->id, id)) != 0)) {
277 p = (r < 0) ? p->left : p->right;
282 /*---------------------------------------------------------------------------*/
284 static symtab_entry *lookup(symtab *st, const char *id, int recurse)
288 e = binary_search(st->root, id);
289 if (e != NULL) { return e; }
291 } while (recurse && st);
296 * Looks up the specified id in the current symbol table.
298 symtab_entry *symtab_lookup(const char *id)
300 return lookup(symtab_tos(), id, 0);
304 * Looks up the specified id in the current symbol table.
306 symtab_entry *symtab_lookup_recursive(const char *id)
308 return lookup(symtab_tos(), id, 1);
312 * Looks up the specified id in the global symbol table.
314 symtab_entry *symtab_global_lookup(const char *id)
316 return lookup(symtab_stack[0], id, 0);
320 * Enters something into a symbol table.
321 * @@param id Identifier
322 * @@param type Type of symbol (*_SYMBOL)
323 * @@param def External definition (may be <code>NULL</code>)
324 * @@param flags Initial flags
326 symtab_entry *symtab_enter(const char *id, symbol_type type, astnode *def, int flags)
328 symtab *st = symtab_tos();
329 /* See if this id already exists */
330 symtab_entry *e = symtab_lookup(id);
332 /* Duplicate symbol. */
333 // printf("error: symtab_enter(): `%s' already exists\n", id);
336 // printf("symtab_enter(): '%s' @@ %.8X\n", id, st);
337 /* Allocate new entry */
338 e = (symtab_entry *)malloc(sizeof(symtab_entry));
341 e->id = (char *)malloc(strlen(id)+1);
350 e->struc.size = NULL;
351 e->struc.fields = NULL;
352 e->field.offset = NULL;
353 e->field.size = NULL;
358 /* Put it into symbol table */
359 if (st->root == NULL) {
360 st->root = e; /* This is the root element */
363 /* Insert entry in binary tree */
364 binary_insert(st->root, e);
367 /* Return the newly created symbol table entry */
371 /*---------------------------------------------------------------------------*/
374 * Finalizes a single symbol table entry.
376 static void symtab_entry_finalize(symtab_entry *e)
378 ordered_field_list *list;
379 ordered_field_list *next;
380 // printf("symtab_finalize(): `%s'\n", e->id);
381 /* Special finalizing */
386 case CONSTANT_SYMBOL:
387 astnode_finalize(e->def);
391 astnode_finalize(e->def);
397 /* Free list of in-order field identifiers */
398 for (list = e->struc.fields; list != NULL; list = next) {
402 symtab_finalize(e->symtab);
403 astnode_finalize(e->struc.size);
407 symtab_finalize(e->symtab);
411 astnode_finalize(e->def);
412 astnode_finalize(e->field.offset);
413 astnode_finalize(e->field.size);
423 /* Common finalizing */
429 * Finalizes a symbol table entry recursively,
430 * by first finalizing its children before finalizing itself.
432 static void symtab_entry_finalize_recursive(symtab_entry *e)
434 if (e == NULL) return;
435 symtab_entry_finalize_recursive(e->left);
436 symtab_entry_finalize_recursive(e->right);
437 symtab_entry_finalize(e);
441 * Finalizes a symbol table.
442 * @@param st The symbol table to finalize
444 void symtab_finalize(symtab *st)
446 if (st == NULL) return;
447 symtab_entry_finalize_recursive(st->root);
451 /*---------------------------------------------------------------------------*/
454 * Gets top of symbol table stack.
458 if (stack_index == 0) { return NULL; }
459 return symtab_stack[stack_index-1];
463 * Creates a symbol table and pushes it on the symbol table stack.
465 symtab *symtab_create()
467 symtab *st = (symtab *)malloc(sizeof(symtab));
470 st->parent = symtab_tos();
477 * Pushes a symbol table onto the stack.
479 void symtab_push(symtab *st)
481 symtab_stack[stack_index++] = st;
485 * Pops a symbol table from the stack.
489 return symtab_stack[--stack_index];
493 * Removes an entry from the symbol table.
494 * The memory associated with the entry is freed.
495 * @@param id Identifier of the entry to remove
497 void symtab_remove(const char *id)
499 symtab *st = symtab_tos();
500 symtab_entry * e = symtab_lookup(id);
501 if (e == NULL) { return; } /* Nothing to remove */
502 binary_delete(st, e);
505 /*---------------------------------------------------------------------------*/
508 * Gets the number of entries of the given type.
510 int symtab_type_count(symbol_type type)
512 symtab *st = symtab_tos();
514 symtab_entry *e = binary_min(st->root);
516 if ((type == ANY_SYMBOL) || (e->type == type)) {
525 * Removes all entries of a given type from the symbol table.
526 * The memory associated with the entries is freed.
527 * @@param type Type of symbols to remove
529 void symtab_remove_by_type(symbol_type type)
532 /* Declare array to hold identifiers */
533 symbol_ident_list list;
534 /* List the entry identifiers */
535 int count = symtab_list_type(type, &list);
536 /* Remove the entries one by one */
537 for (i=0; i<count; i++) {
538 symtab_remove(list.idents[i]);
540 /* Finalize the array of identifiers */
541 symtab_list_finalize(&list);
544 /*---------------------------------------------------------------------------*/
546 static void indent(int n)
549 for (i=0; i<n; i++) {
557 static void symtab_entry_print_recursive(symtab_entry *e, int level)
559 if (e == NULL) { return; }
561 symtab_entry_print_recursive(e->left, level+1);
562 printf("%s\n", e->id);
563 symtab_entry_print_recursive(e->right, level+1);
571 symtab *st = symtab_tos();
572 symtab_entry_print_recursive(st->root, 0);
575 /*---------------------------------------------------------------------------*/
578 * Gets the number of entries in the symbol table.
582 return symtab_type_count(ANY_SYMBOL);
586 * Lists the entries in a symbol table that are of a certain type.
587 * @@param type The symbol type (*_SYMBOL)
588 * @@param list List which will receive the array of identifiers
590 int symtab_list_type(symbol_type type, symbol_ident_list *list)
592 symtab *st = symtab_tos();
594 list->size = symtab_type_count(type);
595 list->idents = (char **)malloc(list->size * sizeof(char *) );
596 if (list->idents != NULL) {
597 symtab_entry *e = binary_min(st->root);
599 if ((type == ANY_SYMBOL) || (e->type == type)) {
601 list->idents[i] = (char *)malloc(strlen(e->id)+1);
602 if (list->idents[i] != NULL) {
603 strcpy(list->idents[i], e->id);
610 /* Return the number of entries listed */
615 * Lists all identifiers in the symbol table.
617 int symtab_list(symbol_ident_list *list)
619 return symtab_list_type(ANY_SYMBOL, list);
623 * Lists all identifiers in the symbol table which has ONE OR MORE of the
625 * If flag is zero it is ignored.
627 int symtab_list_flag(int flag, symbol_ident_list *list)
634 * Lists all identifiers in the symbol table of a given type which has
635 * ONE OR MORE of the given flags set.
636 * If flag is zero it is ignored.
638 int symtab_list_type_flag(symbol_type type, int flag, symbol_ident_list *list)
645 * Finalizes a list of identifiers.
647 void symtab_list_finalize(symbol_ident_list *list)
650 for (i=0; i<list->size; i++) {
651 SAFE_FREE(list->idents[i]);
653 SAFE_FREE(list->idents);
665 * $Id: symtab.c,v 1.5 2007/08/08 22:40:43 khansen Exp khansen $
676 @recursive symbol table lookup
681 * $Id: symtab.c,v 1.4 2007/07/22 13:33:26 khansen Exp khansen $
685 static symtab_entry *lookup(symtab *st, const char *id)
694 return lookup(symtab_tos(), id);
697 return lookup(symtab_stack[0], id);
703 @convert tabs to whitespaces
708 * $Id: symtab.c,v 1.3 2004/12/14 01:50:05 kenth Exp $
712 // while (st != NULL) {
725 st->parent = NULL; // symtab_tos();
726 symtab_push(st); /* NB! */
737 * $Id: symtab.c,v 1.2 2004/12/06 04:52:53 kenth Exp kenth $
741 if (p == NULL) { return NULL; }
742 while (p->left != NULL) {
748 if (p == NULL) { return NULL; }
749 while (p->right != NULL) {
756 if (p == NULL) { return NULL; }
757 if (p->right != NULL) { return binary_min(p->right); }
759 while ((e != NULL) && (p == e->right)) {
767 if (p == NULL) { return NULL; }
768 if (p->left != NULL) { return binary_max(p->left); }
770 while ((e != NULL) && (p == e->left)) {
777 int r = strcmp(p->id, e->id);
779 /* Follow left branch */
780 if (p->left == NULL) {
781 p->left = e; /* Entry inserted successfully */
785 binary_insert(p->left, e); /* Call recursively */
789 /* Follow right branch */
790 if (p->right == NULL) {
791 p->right = e; /* Entry inserted successfully */
795 binary_insert(p->right, e); /* Call recursively */
799 /* Symbol already present */
806 if ((st == NULL) || (z == NULL)) { return; }
808 if ((z->left == NULL) || (z->right == NULL)) {
815 if (y->left != NULL) {
830 else if (y == p->left) {
838 symtab_finalize(z->symtab);
840 z->id = (char *)malloc(strlen(y->id)+1);
842 strcpy(z->id, y->id);
846 z->ref_count = y->ref_count;
848 z->symtab = y->symtab;
853 symtab_entry_finalize(y);
858 while ((p != NULL) && ((r = strcmp(p->id, id)) != 0)) {
859 p = (r < 0) ? p->left : p->right;
865 // while (st != NULL) {
866 e = binary_search(st->root, id);
867 if (e != NULL) { return e; }
873 return lookup(symtab_tos(), id);
876 return lookup(symtab_stack[0], id);
879 symtab *st = symtab_tos();
880 /* See if this id already exists */
881 symtab_entry *e = symtab_lookup(id);
883 /* Duplicate symbol. */
884 // printf("error: symtab_enter(): `%s' already exists\n", id);
887 // printf("symtab_enter(): '%s' @@ %.8X\n", id, st);
888 /* Allocate new entry */
889 e = (symtab_entry *)malloc(sizeof(symtab_entry));
892 e->id = (char *)malloc(strlen(id)+1);
901 e->struc.size = NULL;
902 e->struc.fields = NULL;
903 e->field.offset = NULL;
904 e->field.size = NULL;
909 /* Put it into symbol table */
910 if (st->root == NULL) {
911 st->root = e; /* This is the root element */
914 /* Insert entry in binary tree */
915 binary_insert(st->root, e);
918 /* Return the newly created symbol table entry */
922 ordered_field_list *list;
923 ordered_field_list *next;
924 // printf("symtab_finalize(): `%s'\n", e->id);
925 /* Special finalizing */
930 case CONSTANT_SYMBOL:
931 astnode_finalize(e->def);
935 astnode_finalize(e->def);
941 /* Free list of in-order field identifiers */
942 for (list = e->struc.fields; list != NULL; list = next) {
946 symtab_finalize(e->symtab);
947 astnode_finalize(e->struc.size);
951 symtab_finalize(e->symtab);
955 astnode_finalize(e->def);
956 astnode_finalize(e->field.offset);
957 astnode_finalize(e->field.size);
967 /* Common finalizing */
972 if (e == NULL) return;
973 symtab_entry_finalize_recursive(e->left);
974 symtab_entry_finalize_recursive(e->right);
975 symtab_entry_finalize(e);
978 if (st == NULL) return;
979 symtab_entry_finalize_recursive(st->root);
983 if (stack_index == 0) { return NULL; }
984 return symtab_stack[stack_index-1];
987 symtab *st = (symtab *)malloc(sizeof(symtab));
990 st->parent = NULL; // symtab_tos();
991 symtab_push(st); /* NB! */
996 symtab_stack[stack_index++] = st;
999 return symtab_stack[--stack_index];
1002 symtab *st = symtab_tos();
1003 symtab_entry * e = symtab_lookup(id);
1004 if (e == NULL) { return; } /* Nothing to remove */
1005 binary_delete(st, e);
1008 symtab *st = symtab_tos();
1010 symtab_entry *e = binary_min(st->root);
1012 if ((type == ANY_SYMBOL) || (e->type == type)) {
1021 /* Declare array to hold identifiers */
1022 symbol_ident_list list;
1023 /* List the entry identifiers */
1024 int count = symtab_list_type(type, &list);
1025 /* Remove the entries one by one */
1026 for (i=0; i<count; i++) {
1027 symtab_remove(list.idents[i]);
1029 /* Finalize the array of identifiers */
1030 symtab_list_finalize(&list);
1034 for (i=0; i<n; i++) {
1039 if (e == NULL) { return; }
1041 symtab_entry_print_recursive(e->left, level+1);
1042 printf("%s\n", e->id);
1043 symtab_entry_print_recursive(e->right, level+1);
1046 symtab *st = symtab_tos();
1047 symtab_entry_print_recursive(st->root, 0);
1050 return symtab_type_count(ANY_SYMBOL);
1053 symtab *st = symtab_tos();
1055 list->size = symtab_type_count(type);
1056 list->idents = (char **)malloc(list->size * sizeof(char *) );
1057 if (list->idents != NULL) {
1058 symtab_entry *e = binary_min(st->root);
1060 if ((type == ANY_SYMBOL) || (e->type == type)) {
1062 list->idents[i] = (char *)malloc(strlen(e->id)+1);
1063 if (list->idents[i] != NULL) {
1064 strcpy(list->idents[i], e->id);
1071 /* Return the number of entries listed */
1075 return symtab_list_type(ANY_SYMBOL, list);
1087 for (i=0; i<list->size; i++) {
1088 SAFE_FREE(list->idents[i]);
1090 SAFE_FREE(list->idents);
1101 * $Id: symtab.c,v 1.1 2004/06/30 07:55:57 kenth Exp $
1106 // TODO: other types: finalize(e->def)
1123 static symtab *symtab_stack[1];
1126 static void binary_insert(symtab_entry *p, symtab_entry *e) {
1130 /* Should call symtab_entry_finalize(y) here */
1137 static symtab_entry *binary_search(symtab_entry *p, const char *id) {
1141 * Looks up the specified id.
1143 symtab_entry *symtab_lookup(const char *id) {
1146 /* Start looking in the closest namespace */
1147 symtab *st = symtab_tos();
1148 while (st != NULL) {
1156 symtab_entry *symtab_enter(const char *id, symbol_type type, void *def, int flags)
1159 printf("'%s' already defined; using previous definition.\n", e->id);
1160 /* Return the previous definition of id */
1164 // printf("Entering '%s' @@ %d\n", id, st);
1170 return symtab_stack[0];
1173 * Creates a symbol table.
1179 symtab_stack[0] = st;
1182 return symtab_stack[0];
1194 * Lists the entries in a symbol table.