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