f01b62aa6675810c80ada8f25a2901a62dd6bc87
[uebersetzerbau-ss10.git] / aus_sammelwut / paulchen / ublu / ss08 / abgabe / codea / symbol_table.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "symbol_table.h"
5
6 struct symbol_t *new_table(void) {
7         return (struct symbol_t *)NULL;
8 }
9
10 struct symbol_t *clone_table(struct symbol_t *table) {
11         struct symbol_t *element;
12         struct symbol_t *new_tablex;
13
14         element=table;
15         new_tablex=new_table();
16         while((struct symbol_t *)NULL!=element) {
17                 /* check return value */
18                 new_tablex=table_add_symbol(new_tablex,element->identifier,element->type,0,element->stack_offset);
19                 element=element->next;
20         }
21
22         return new_tablex;
23 }
24
25 struct symbol_t *table_add_symbol(struct symbol_t *table, char *identifier, short type, short check, int stack_offset) {
26         struct symbol_t *element;
27         struct symbol_t *new_element;
28
29         if(table_lookup(table,identifier)!=(struct symbol_t *)NULL) {
30                 if(check) {
31                         fprintf(stderr,"Duplicate field %s.\n",identifier);
32                         exit(3);
33                 }
34
35                 table=table_remove_symbol(table,identifier);
36         }
37         
38         new_element=(struct symbol_t *)malloc(sizeof(struct symbol_t));
39         new_element->next=(struct symbol_t *)NULL;
40         new_element->identifier=strdup(identifier);
41         new_element->type=type;
42         new_element->stack_offset=stack_offset;
43         new_element->param_index=-1;
44
45         if((struct symbol_t *)NULL==table) {
46                 return new_element;
47         }
48         element=table;
49
50         while((struct symbol_t *)NULL!=element->next) {
51                 element=element->next;
52         }
53
54         element->next=new_element;
55         
56         return table;
57 }
58
59 struct symbol_t *table_add_param(struct symbol_t *table, char *identifier, int param_index) {
60         struct symbol_t *element;
61         struct symbol_t *new_element;
62
63         if(table_lookup(table,identifier)!=(struct symbol_t *)NULL) {
64                 table=table_remove_symbol(table,identifier);
65         }
66         
67         new_element=(struct symbol_t *)malloc(sizeof(struct symbol_t));
68         new_element->next=(struct symbol_t *)NULL;
69         new_element->identifier=strdup(identifier);
70         new_element->type=SYMBOL_TYPE_PARAM;
71         new_element->param_index=param_index;
72
73         if((struct symbol_t *)NULL==table) {
74                 return new_element;
75         }
76         element=table;
77
78         while((struct symbol_t *)NULL!=element->next) {
79                 element=element->next;
80         }
81
82         element->next=new_element;
83         
84         return table;
85 }
86
87 struct symbol_t *table_lookup(struct symbol_t *table, char *identifier) {
88         struct symbol_t *element;
89
90         element=table;
91
92         if((struct symbol_t *)NULL==table) {
93                 return (struct symbol_t *)NULL;
94         }
95         
96         if(strcmp(element->identifier,identifier)==0) {
97                 return element;
98         }
99         
100         while((struct symbol_t *)NULL!=element->next) {
101                 element=element->next;
102                 if(strcmp(element->identifier,identifier)==0) {
103                         return element;
104                 }
105         }
106
107         return (struct symbol_t *)NULL;
108 }
109
110 struct symbol_t *table_merge(struct symbol_t *table, struct symbol_t *to_add, short check) {
111         struct symbol_t *element;
112         struct symbol_t *new_table=clone_table(table);
113         
114         element=to_add;
115         while(element!=(struct symbol_t *)NULL) {
116                 if(element->param_index!=-1) {
117                         new_table=table_add_param(new_table,element->identifier,element->param_index);
118                 }
119                 else {
120                         new_table=table_add_symbol(new_table,element->identifier,element->type,check,element->stack_offset);
121                 }
122                 element=element->next;
123         }
124
125         return new_table;
126 }
127
128 struct symbol_t *table_remove_symbol(struct symbol_t *table, char *identifier) {
129         struct symbol_t *element;
130         struct symbol_t *previous_element;
131         struct symbol_t *new_element;
132
133         if((struct symbol_t *)NULL==table) {
134                 return table;
135         }
136
137         previous_element=(struct symbol_t *)NULL;
138         element=table;
139
140         while((struct symbol_t *)NULL!=element) {
141                 if(strcmp(element->identifier,identifier)==0) {
142                         if((struct symbol_t *)NULL==previous_element) {
143                                 new_element=element->next;
144                         }
145                         else {
146                                 previous_element->next=element->next;
147                                 new_element=table;
148                         }
149                         (void)free(element->identifier);
150                         (void)free(element);
151                         return new_element;
152                 }
153                 previous_element=element;
154                 element=element->next;
155         }
156
157         return table;
158 }
159
160 void check_variable(struct symbol_t *table, char *identifier) {
161         struct symbol_t *element=table_lookup(table,identifier);
162         if(element!=(struct symbol_t *)NULL) {
163                 if(element->type!=SYMBOL_TYPE_VAR && element->type!=SYMBOL_TYPE_PARAM) {
164                         fprintf(stderr,"Identifier %s not a variable.\n",identifier);
165                         exit(3);
166                 }
167         }
168         else {
169                 fprintf(stderr,"Unknown identifier %s.\n",identifier);
170                 exit(3);
171         }
172 }
173
174 void check_field(struct symbol_t *table, char *identifier) {
175         struct symbol_t *element=table_lookup(table,identifier);
176         if(element!=(struct symbol_t *)NULL) {
177                 if(element->type!=SYMBOL_TYPE_FIELD) {
178                         fprintf(stderr,"Identifier %s not a variable.\n",identifier);
179                         exit(3);
180                 }
181         }
182         else {
183                 fprintf(stderr,"Unknown identifier %s.\n",identifier);
184                 exit(3);
185         }
186 }
187