Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / ce_back / obj_back / symtable.c
1 #include <out.h>
2 #include <system.h>
3 #include "hash.h"
4 #include "header.h"
5 #include "back.h"
6
7 /* Findsym() manages the symbol table. It can be called in three ways. 
8  * 1) findsym( "string", DEFINITION) : look if string is present in the
9  *      symol table. If not create a new entry: set index into the
10  *      string_area. Return the index to the entry. Symbol_def() will
11  *      the fields.
12  * 2) findsym( "string", REFERENCE) : If string is present but never used
13  *    (see 3)) make this name extern visible and set on_valu on -1.
14  *    We use the on_valu field to distinguish between external visible 
15  *    names that are defined here and those that are defined in another file.
16  *    If the string is not present create a new entry and make the name extern
17  *    visible and set on_valu on -1.
18  *    If the name is present do nothing special.
19  * 3) findsym( "string", STORE_STRING) : this call is made to save a
20  *    copy action. The first time a name is encountered we store it
21  *    immediately in the symbol table. If the name is not present we
22  *    create a new entry and set the on_valu field on -2. In this
23  *    way we can tell later that the name is not used yet. The index 
24  *    is stored in the global varaible 'index_symbol_table' because it is
25  *    very likely that the same string is in the next call to findsym.
26  *    (After introducing a new name one does something with this name)
27  */
28
29 int             string_lengte = 0,
30                 index_symbol_table = -1;
31
32 struct Hashitem  *Hashitems ; 
33
34 /*      MAXHASH must be a power of two ... */
35 #define MAXHASH 512
36 static int       Hashtab[ MAXHASH];   
37 static int Hash();
38
39
40 int find_sym( sym, isdef)
41 char *sym;
42 int isdef;
43 {
44         register struct outname *s;
45         register struct Hashitem *ip;
46         register int h;
47
48         if (isdef != FORCE_DEF) {
49             if ( index_symbol_table != -1 )     {
50                 s = symbol_table + index_symbol_table;
51                 if ( sym == s->on_foff + string_area)  {
52                         if ( (s->on_valu == -2) && ( isdef == REFERENCE)) {
53                                 s->on_type = S_EXT; 
54                                 s->on_valu = -1;
55                         }
56                         return( index_symbol_table);
57                 }
58             }
59
60             h = Hash(sym);
61             for ( ip = Hashtab[h] + Hashitems ; ip != Hashitems; 
62                                           ip = (ip->hs_next) + Hashitems) {
63                 register char *p = sym, *q;
64
65                 s = symbol_table + ip->hs_nami;
66                 q = string_area + s->on_foff;
67                 while (*p == *q++) if (*p++ == '\0') {
68                         if ( (s->on_valu == -2) && (isdef == REFERENCE)) {
69                                   s->on_type = S_EXT; 
70                                   s->on_valu = -1;
71                         }
72                         return ip->hs_nami;
73                 }
74             }
75         }
76         
77         if ( nname >= size_symbol)  
78                 mem_symbol_hash();
79
80         s = symbol_table + nname;
81
82         if (isdef != FORCE_DEF) {
83             ip = Hashitems + nname + 1;  /* skip the first entry */
84
85             if (isdef == REFERENCE)  {
86                 s->on_type = S_EXT; 
87                 s->on_valu = -1;
88             }
89             if (isdef == STORE_STRING) {
90                 s->on_type = S_UND;
91                 s->on_valu = -2; 
92             }
93
94             ip->hs_nami = nname;
95             ip->hs_next = Hashtab[h];
96             Hashtab[h] = ip - Hashitems;
97         }
98
99         if ( sym == string) 
100                 string += string_lengte;
101         else {    /* zie C_fil, C_lin, C_lni */
102                 register char *p;
103
104                 string_lengte = 0;
105                 for( p=sym; *p != '\0' ; p++) {
106                         string_lengte++;
107                 }
108                 while ( (string + string_lengte - string_area) >= size_string) {
109                         mem_string();
110                 }
111                 for( p=sym; *p != '\0' ; p++) {
112                         *string++ = *p;
113                 }
114         }
115         if ( (string - string_area) >= size_string) {
116                 mem_string();
117         }
118         *string++ = '\0';
119         s->on_foff = string - (string_lengte + 1) - string_area;
120
121         return nname++;
122 }
123
124
125 static int Hash(sym)
126         char *sym;
127 {
128         register unsigned h;
129         register char *s = sym;
130
131         h = 0;
132         while (*s) {
133                 h = (h << 2) + *s++;
134         }
135         return (h & (MAXHASH - 1));
136 }