doc: paulchen beispiele {code{a,b},gesamt} entpackt (jedes mal entpacken nervt langsa...
[uebersetzerbau-ss10.git] / aus_sammelwut / paulchen / ublu / ss08 / abgabe / gesamt / .svn / text-base / symbol_table.c.svn-base
diff --git a/aus_sammelwut/paulchen/ublu/ss08/abgabe/gesamt/.svn/text-base/symbol_table.c.svn-base b/aus_sammelwut/paulchen/ublu/ss08/abgabe/gesamt/.svn/text-base/symbol_table.c.svn-base
new file mode 100644 (file)
index 0000000..bf66a65
--- /dev/null
@@ -0,0 +1,192 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "symbol_table.h"
+
+struct symbol_t *new_table(void) {
+       return (struct symbol_t *)NULL;
+}
+
+struct symbol_t *clone_table(struct symbol_t *table) {
+       struct symbol_t *element;
+       struct symbol_t *new_tablex;
+
+       element=table;
+       new_tablex=new_table();
+       while((struct symbol_t *)NULL!=element) {
+               /* check return value */
+               if(element->param_index!=-1) {
+                       new_tablex=table_add_param(new_tablex,element->identifier,element->param_index);
+               }
+               else {
+                       new_tablex=table_add_symbol(new_tablex,element->identifier,element->type,0,element->stack_offset);
+               }
+               element=element->next;
+       }
+
+       return new_tablex;
+}
+
+struct symbol_t *table_add_symbol(struct symbol_t *table, char *identifier, short type, short check, int stack_offset) {
+       struct symbol_t *element;
+       struct symbol_t *new_element;
+
+       if(table_lookup(table,identifier)!=(struct symbol_t *)NULL) {
+               if(check) {
+                       fprintf(stderr,"Duplicate field %s.\n",identifier);
+                       exit(3);
+               }
+
+               table=table_remove_symbol(table,identifier);
+       }
+       
+       new_element=(struct symbol_t *)malloc(sizeof(struct symbol_t));
+       new_element->next=(struct symbol_t *)NULL;
+       new_element->identifier=strdup(identifier);
+       new_element->type=type;
+       new_element->stack_offset=stack_offset;
+       new_element->param_index=-1;
+
+       if((struct symbol_t *)NULL==table) {
+               return new_element;
+       }
+       element=table;
+
+       while((struct symbol_t *)NULL!=element->next) {
+               element=element->next;
+       }
+
+       element->next=new_element;
+       
+       return table;
+}
+
+struct symbol_t *table_add_param(struct symbol_t *table, char *identifier, int param_index) {
+       struct symbol_t *element;
+       struct symbol_t *new_element;
+
+       if(table_lookup(table,identifier)!=(struct symbol_t *)NULL) {
+               table=table_remove_symbol(table,identifier);
+       }
+       
+       new_element=(struct symbol_t *)malloc(sizeof(struct symbol_t));
+       new_element->next=(struct symbol_t *)NULL;
+       new_element->identifier=strdup(identifier);
+       new_element->type=SYMBOL_TYPE_PARAM;
+       new_element->param_index=param_index;
+
+       if((struct symbol_t *)NULL==table) {
+               return new_element;
+       }
+       element=table;
+
+       while((struct symbol_t *)NULL!=element->next) {
+               element=element->next;
+       }
+
+       element->next=new_element;
+       
+       return table;
+}
+
+struct symbol_t *table_lookup(struct symbol_t *table, char *identifier) {
+       struct symbol_t *element;
+
+       element=table;
+
+       if((struct symbol_t *)NULL==table) {
+               return (struct symbol_t *)NULL;
+       }
+       
+       if(strcmp(element->identifier,identifier)==0) {
+               return element;
+       }
+       
+       while((struct symbol_t *)NULL!=element->next) {
+               element=element->next;
+               if(strcmp(element->identifier,identifier)==0) {
+                       return element;
+               }
+       }
+
+       return (struct symbol_t *)NULL;
+}
+
+struct symbol_t *table_merge(struct symbol_t *table, struct symbol_t *to_add, short check) {
+       struct symbol_t *element;
+       struct symbol_t *new_table=clone_table(table);
+       
+       element=to_add;
+       while(element!=(struct symbol_t *)NULL) {
+               if(element->param_index!=-1) {
+                       new_table=table_add_param(new_table,element->identifier,element->param_index);
+               }
+               else {
+                       new_table=table_add_symbol(new_table,element->identifier,element->type,check,element->stack_offset);
+               }
+               element=element->next;
+       }
+
+       return new_table;
+}
+
+struct symbol_t *table_remove_symbol(struct symbol_t *table, char *identifier) {
+       struct symbol_t *element;
+       struct symbol_t *previous_element;
+       struct symbol_t *new_element;
+
+       if((struct symbol_t *)NULL==table) {
+               return table;
+       }
+
+       previous_element=(struct symbol_t *)NULL;
+       element=table;
+
+       while((struct symbol_t *)NULL!=element) {
+               if(strcmp(element->identifier,identifier)==0) {
+                       if((struct symbol_t *)NULL==previous_element) {
+                               new_element=element->next;
+                       }
+                       else {
+                               previous_element->next=element->next;
+                               new_element=table;
+                       }
+                       (void)free(element->identifier);
+                       (void)free(element);
+                       return new_element;
+               }
+               previous_element=element;
+               element=element->next;
+       }
+
+       return table;
+}
+
+void check_variable(struct symbol_t *table, char *identifier) {
+       struct symbol_t *element=table_lookup(table,identifier);
+       if(element!=(struct symbol_t *)NULL) {
+               if(element->type!=SYMBOL_TYPE_VAR && element->type!=SYMBOL_TYPE_PARAM) {
+                       fprintf(stderr,"Identifier %s not a variable.\n",identifier);
+                       exit(3);
+               }
+       }
+       else {
+               fprintf(stderr,"Unknown identifier %s.\n",identifier);
+               exit(3);
+       }
+}
+
+void check_field(struct symbol_t *table, char *identifier) {
+       struct symbol_t *element=table_lookup(table,identifier);
+       if(element!=(struct symbol_t *)NULL) {
+               if(element->type!=SYMBOL_TYPE_FIELD) {
+                       fprintf(stderr,"Identifier %s not a variable.\n",identifier);
+                       exit(3);
+               }
+       }
+       else {
+               fprintf(stderr,"Unknown identifier %s.\n",identifier);
+               exit(3);
+       }
+}
+