f8e4f21b6d8166406ba9ce10781eb453d07d242c
[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         fprintf(stderr, "tab_clone: tab(%08X)\n", tab);
21 #endif
22
23         while(elm != SYMNULL) {
24                 ntab = tab_add_symbol(ntab, elm->ident, elm->type, 0, elm->param_index, elm->soffset);
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, int param_index, int soffset)
31 {
32         struct symbol *elm = tab;
33         struct symbol *new_elm;
34 #ifdef DD
35         fprintf(stderr, "tab_add_symbol: tab(%08X), ident(%s), type(%i), check(%i), param_index(%i), soffset(%i)\n", tab, ident, type, check, param_index, soffset);
36 #endif
37
38         if(param_index >= 6) {
39                 fprintf(stderr, "eine methode hat zu viele parameter (max. 6 inkl. this erlaubt)\n");
40                 exit(4);
41         }
42
43         if(tab_lookup(tab, ident, type) != SYMNULL || (type == S_VAR && tab_lookup(tab, ident, S_PARM) != SYMNULL)) {
44                 if(check) {
45                         fprintf(stderr, "Identifier doppelt vorhanden: \"%s\"\n", ident);
46                         exit(3);
47                 } else {
48                         tab = tab_remove_symbol(tab, ident, type);
49                 }
50         }
51         
52         new_elm = (struct symbol *) malloc(sizeof(struct symbol));
53         new_elm->next = SYMNULL;
54         new_elm->ident = strdup(ident);
55         new_elm->type = type;
56         new_elm->param_index = param_index;
57         new_elm->soffset = soffset;
58
59         if(tab == SYMNULL) {
60                 return new_elm;
61         }
62
63         while(elm->next != SYMNULL) {
64                 elm = elm->next;
65         }
66         elm->next = new_elm;
67         
68         return tab;
69 }
70
71 struct symbol *tab_lookup(struct symbol *tab, char *ident, short type)
72 {
73         struct symbol *elm = tab;
74
75         if(tab == SYMNULL) {
76                 return SYMNULL;
77         }
78
79         do {
80                 if((elm->type & type) && (strcmp(elm->ident, ident) == 0)) {
81                         return elm;
82                 }
83                 elm = elm->next;
84         } while(elm != SYMNULL);
85
86         return SYMNULL;
87 }
88
89 struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check)
90 {
91         struct symbol *elm = to_add;
92         struct symbol *ntab = tab_clone(tab);
93 #ifdef DD
94         fprintf(stderr, "tab_merge: tab(%08X), to_add(%08X), check(%i), ntab(%08X)\n", tab, to_add, check, ntab);
95 #endif
96         
97         while(elm != SYMNULL) {
98                 ntab = tab_add_symbol(ntab, elm->ident, elm->type, check, elm->param_index, elm->soffset);
99                 elm = elm->next;
100         }
101
102         return ntab;
103 }
104
105 struct symbol *tab_remove_symbol(struct symbol *tab, char *ident, short type)
106 {
107         struct symbol *elm = tab;
108         struct symbol *previous_elm = SYMNULL;
109
110         while(elm != SYMNULL) {
111                 if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) {
112                         if(previous_elm == SYMNULL) {
113                                 tab = elm->next;
114                         } else {
115                                 previous_elm->next = elm->next;
116                         }
117                         (void)free(elm->ident);
118                         (void)free(elm);
119                         break;
120                 }
121                 previous_elm = elm;
122                 elm = elm->next;
123         }
124
125         return tab;
126 }
127
128 void check(struct symbol *tab, char *ident, short type)
129 {
130         struct symbol *elm;
131 #ifdef DD
132         fprintf(stderr, "check: tab(%08X), ident(%s), type(%i), elm(%08X)\n", tab, ident, type, elm);
133 #endif
134
135         if(type & (S_VAR | S_PARM)) {
136                 elm = tab_lookup(tab, ident, type);
137                 if(elm != SYMNULL) {
138                         return;
139                 }
140         }
141
142         /* keine passende variable gefunden?
143          * => vllt gibt es ja ein passenden feldnamen */
144         elm = tab_lookup(tab, ident, S_FIELD);
145         if(elm == SYMNULL) {
146                 fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident);
147                 exit(3);
148         }
149 }
150