codea: chmod a-x symtable.*
[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->soffset);
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, int soffset)
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), soffset(%i)\n", tab, ident, type, check, param_index, soffset);
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 || (type == S_VAR && tab_lookup(tab, ident, S_PARM) != 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         new_elm->param_index = param_index;
57         new_elm->soffset = soffset;
58
59         if(tab == SYMNULL) return new_elm;
60
61         while(elm->next != SYMNULL) {
62                 elm = elm->next;
63         }
64         elm->next = new_elm;
65         
66         return tab;
67 }
68
69 struct symbol *tab_lookup(struct symbol *tab, char *ident, short type)
70 {
71         struct symbol *elm = tab;
72
73         if(tab == SYMNULL) return SYMNULL;
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->soffset);
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