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