codea: codegeruest wird generiert :)
[uebersetzerbau-ss10.git] / codea / symtable.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "symtable.h"
5
6 #if 0
7 #define DD
8 #endif
9
10 struct symbol *tab_new(void)
11 {
12         return SYMNULL;
13 }
14
15 struct symbol *tab_clone(struct symbol *tab)
16 {
17         struct symbol *elm = tab;
18         struct symbol *ntab = tab_new();
19 #ifdef DD
20         printf("tab_clone: tab(%08X)\n", tab);
21 #endif
22
23         while(elm != SYMNULL) {
24                 ntab = tab_add_symbol(ntab, elm->ident, elm->type, 0);
25                 elm = elm->next;
26         }
27         return ntab;
28 }
29
30 struct symbol *tab_add_symbol(struct symbol *tab, char *ident, short type, short check)
31 {
32         struct symbol *elm = tab;
33         struct symbol *new_elm;
34 #ifdef DD
35         printf("tab_add_symbol: tab(%08X), ident(%s), type(%i), check(%i)\n", tab, ident, type, check);
36 #endif
37
38         if(tab_lookup(tab, ident, type) != SYMNULL) {
39                 if(check) {
40                         fprintf(stderr, "Identifier doppelt vorhanden: \"%s\"\n", ident);
41                         exit(3);
42                 } else {
43                         tab = tab_remove_symbol(tab, ident, type);
44                 }
45         }
46         
47         new_elm = (struct symbol *) malloc(sizeof(struct symbol));
48         new_elm->next = SYMNULL;
49         new_elm->ident = strdup(ident);
50         new_elm->type = type;
51
52         if(tab == SYMNULL) {
53                 return new_elm;
54         }
55
56         while(elm->next != SYMNULL) {
57                 elm = elm->next;
58         }
59         elm->next = new_elm;
60         
61         return tab;
62 }
63
64 struct symbol *tab_lookup(struct symbol *tab, char *ident, short type)
65 {
66         struct symbol *elm = tab;
67
68         if(tab == SYMNULL) {
69                 return SYMNULL;
70         }
71
72         do {
73                 if((elm->type & type) && (strcmp(elm->ident, ident) == 0)) {
74                         return elm;
75                 }
76                 elm = elm->next;
77         } while(elm != SYMNULL);
78
79         return SYMNULL;
80 }
81
82 struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check)
83 {
84         struct symbol *elm = to_add;
85         struct symbol *ntab = tab_clone(tab);
86 #ifdef DD
87         printf("tab_merge: tab(%08X), to_add(%08X), check(%i), ntab(%08X)\n", tab, to_add, check, ntab);
88 #endif
89         
90         while(elm != SYMNULL) {
91                 ntab = tab_add_symbol(ntab, elm->ident, elm->type, check);
92                 elm = elm->next;
93         }
94
95         return ntab;
96 }
97
98 struct symbol *tab_remove_symbol(struct symbol *tab, char *ident, short type)
99 {
100         struct symbol *elm = tab;
101         struct symbol *previous_elm = SYMNULL;
102
103         while(elm != SYMNULL) {
104                 if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) {
105                         if(previous_elm == SYMNULL) {
106                                 tab = elm->next;
107                         } else {
108                                 previous_elm->next = elm->next;
109                         }
110                         (void)free(elm->ident);
111                         (void)free(elm);
112                         break;
113                 }
114                 previous_elm = elm;
115                 elm = elm->next;
116         }
117
118         return tab;
119 }
120
121 void check(struct symbol *tab, char *ident, short type)
122 {
123         struct symbol *elm;
124 #ifdef DD
125         printf("check: tab(%08X), ident(%s), type(%i), elm(%08X)\n", tab, ident, type, elm);
126 #endif
127
128         if(type & (S_VAR | S_PARM)) {
129                 elm = tab_lookup(tab, ident, type);
130                 if(elm != SYMNULL) {
131                         return;
132                 }
133         }
134
135         /* keine passende variable gefunden?
136          * => vllt gibt es ja ein passenden feldnamen */
137         elm = tab_lookup(tab, ident, S_FIELD);
138         if(elm == SYMNULL) {
139                 fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident);
140                 exit(3);
141         }
142 }
143