1 /* $NetBSD: symtab.c,v 1.5 2010/12/25 23:43:30 christos Exp $ */ 2 /* Id: symtab.c,v 1.9 2010/11/24 15:12:29 tom Exp */ 3 4 #include "defs.h" 5 6 #include <sys/cdefs.h> 7 __RCSID("$NetBSD: symtab.c,v 1.5 2010/12/25 23:43:30 christos Exp $"); 8 9 /* TABLE_SIZE is the number of entries in the symbol table. */ 10 /* TABLE_SIZE must be a power of two. */ 11 12 #define TABLE_SIZE 1024 13 14 static bucket **symbol_table = 0; 15 bucket *first_symbol; 16 bucket *last_symbol; 17 18 static int 19 hash(const char *name) 20 { 21 const char *s; 22 int c, k; 23 24 assert(name && *name); 25 s = name; 26 k = *s; 27 while ((c = *++s) != 0) 28 k = (31 * k + c) & (TABLE_SIZE - 1); 29 30 return (k); 31 } 32 33 bucket * 34 make_bucket(const char *name) 35 { 36 bucket *bp; 37 38 assert(name != 0); 39 40 bp = (bucket *)MALLOC(sizeof(bucket)); 41 NO_SPACE(bp); 42 43 bp->link = 0; 44 bp->next = 0; 45 46 bp->name = MALLOC(strlen(name) + 1); 47 NO_SPACE(bp->name); 48 49 bp->tag = 0; 50 bp->value = UNDEFINED; 51 bp->index = 0; 52 bp->prec = 0; 53 bp->class = UNKNOWN; 54 bp->assoc = TOKEN; 55 strcpy(bp->name, name); 56 57 return (bp); 58 } 59 60 bucket * 61 lookup(const char *name) 62 { 63 bucket *bp, **bpp; 64 65 bpp = symbol_table + hash(name); 66 bp = *bpp; 67 68 while (bp) 69 { 70 if (strcmp(name, bp->name) == 0) 71 return (bp); 72 bpp = &bp->link; 73 bp = *bpp; 74 } 75 76 *bpp = bp = make_bucket(name); 77 last_symbol->next = bp; 78 last_symbol = bp; 79 80 return (bp); 81 } 82 83 void 84 create_symbol_table(void) 85 { 86 int i; 87 bucket *bp; 88 89 symbol_table = (bucket **)MALLOC(TABLE_SIZE * sizeof(bucket *)); 90 NO_SPACE(symbol_table); 91 92 for (i = 0; i < TABLE_SIZE; i++) 93 symbol_table[i] = 0; 94 95 bp = make_bucket("error"); 96 bp->index = 1; 97 bp->class = TERM; 98 99 first_symbol = bp; 100 last_symbol = bp; 101 symbol_table[hash("error")] = bp; 102 } 103 104 void 105 free_symbol_table(void) 106 { 107 FREE(symbol_table); 108 symbol_table = 0; 109 } 110 111 void 112 free_symbols(void) 113 { 114 bucket *p, *q; 115 116 for (p = first_symbol; p; p = q) 117 { 118 q = p->next; 119 FREE(p); 120 } 121 } 122