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