#include #include #include #include #include "symboltable.h" #define MAX_KEY 256 #define SIZE 109 #define MAX_STACK 256 static char* undo_stack[MAX_STACK]; static int undo_sp = 0; void undo_stack_push(char* s) { undo_stack[undo_sp++] = s; } char* undo_stack_pop() { char *s = undo_stack[--undo_sp]; return s; } extern void yyerror(char* err); void yyerror(char* err) { fprintf(stderr, "%s\n", err); } typedef struct _bucket { char key[MAX_KEY]; struct _bucket* next; void* binding; } bucket; static bucket* table[SIZE]; unsigned hash(char* s) { unsigned h = 0; char* t; for (t = s; *t; t++) h = h * 65599 + *t; return h; } bucket* add_bucket(char* key, void* binding, bucket* next) { bucket* b = malloc(sizeof(bucket)); if (b == NULL) yyerror("Alloc error\n"); strcpy(b->key, key); b->binding = binding; b->next = next; return b; } void insert(char* key, void* binding) { undo_stack_push(strdup(key)); unsigned i = hash(key) % SIZE; table[i] = add_bucket(key, binding, table[i]); } void* lookup(char* key) { unsigned i = hash(key) % SIZE; bucket* b; for (b = table[i]; b; b = b->next) if (strcmp(b->key, key) == 0) return b->binding; return NULL; } void delete(char* key) { unsigned i = hash(key) % SIZE; bucket* head = table[i]; assert(strcmp(head->key, key) == 0); table[i] = head->next; free(head->binding); free(head); } void begin_scope() { undo_stack_push(NULL); } void end_scope() { while(1) { char *s = undo_stack_pop(); if (s == NULL) break; delete(s); free(s); } } void* make_binding(int x) { int* b = (int*)malloc(sizeof(int)); *b = x; return (void*)b; } int main() { begin_scope(); insert("x", make_binding(1)); insert("y", make_binding(2)); insert("z", make_binding(3)); printf("x: %d\n", *(int*)lookup("x")); printf("y: %d\n", *(int*)lookup("y")); printf("z: %d\n", *(int*)lookup("z")); begin_scope(); insert("y", make_binding(5)); insert("w", make_binding(4)); printf("x: %d\n", *(int*)lookup("x")); printf("y: %d\n", *(int*)lookup("y")); printf("z: %d\n", *(int*)lookup("z")); printf("w: %d\n", *(int*)lookup("w")); end_scope(); printf("x: %d\n", *(int*)lookup("x")); printf("y: %d\n", *(int*)lookup("y")); printf("z: %d\n", *(int*)lookup("z")); end_scope(); return 0; }