codea: parameteranzahl wird durchgereicht und ggf. geprueft wenn die eingabe nicht...
[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->param_index : 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, int param_index)
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)\n", tab, ident, type, check, param_index);
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) {
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         if(type == S_PARM) {
57                 new_elm->param_index = param_index;
58         }
59
60         if(tab == SYMNULL) {
61                 return new_elm;
62         }
63
64         while(elm->next != SYMNULL) {
65                 elm = elm->next;
66         }
67         elm->next = new_elm;
68         
69         return tab;
70 }
71
72 struct symbol *tab_lookup(struct symbol *tab, char *ident, short type)
73 {
74         struct symbol *elm = tab;
75
76         if(tab == SYMNULL) {
77                 return SYMNULL;
78         }
79
80         do {
81                 if((elm->type & type) && (strcmp(elm->ident, ident) == 0)) {
82                         return elm;
83                 }
84                 elm = elm->next;
85         } while(elm != SYMNULL);
86
87         return SYMNULL;
88 }
89
90 struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check)
91 {
92         struct symbol *elm = to_add;
93         struct symbol *ntab = tab_clone(tab);
94 #ifdef DD
95         fprintf(stderr, "tab_merge: tab(%08X), to_add(%08X), check(%i), ntab(%08X)\n", tab, to_add, check, ntab);
96 #endif
97         
98         while(elm != SYMNULL) {
99                 ntab = tab_add_symbol(ntab, elm->ident, elm->type, check, elm->param_index ? elm->param_index : 0);
100                 elm = elm->next;
101         }
102
103         return ntab;
104 }
105
106 struct symbol *tab_remove_symbol(struct symbol *tab, char *ident, short type)
107 {
108         struct symbol *elm = tab;
109         struct symbol *previous_elm = SYMNULL;
110
111         while(elm != SYMNULL) {
112                 if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) {
113                         if(previous_elm == SYMNULL) {
114                                 tab = elm->next;
115                         } else {
116                                 previous_elm->next = elm->next;
117                         }
118                         (void)free(elm->ident);
119                         (void)free(elm);
120                         break;
121                 }
122                 previous_elm = elm;
123                 elm = elm->next;
124         }
125
126         return tab;
127 }
128
129 void check(struct symbol *tab, char *ident, short type)
130 {
131         struct symbol *elm;
132 #ifdef DD
133         fprintf(stderr, "check: tab(%08X), ident(%s), type(%i), elm(%08X)\n", tab, ident, type, elm);
134 #endif
135
136         if(type & (S_VAR | S_PARM)) {
137                 elm = tab_lookup(tab, ident, type);
138                 if(elm != SYMNULL) {
139                         return;
140                 }
141         }
142
143         /* keine passende variable gefunden?
144          * => vllt gibt es ja ein passenden feldnamen */
145         elm = tab_lookup(tab, ident, S_FIELD);
146         if(elm == SYMNULL) {
147                 fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident);
148                 exit(3);
149         }
150 }
151