aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hash.c143
-rw-r--r--hash.h27
-rw-r--r--node.c10
-rw-r--r--node.h6
4 files changed, 184 insertions, 2 deletions
diff --git a/hash.c b/hash.c
new file mode 100644
index 0000000..21ddb1a
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,143 @@
+#include <stdio.h>
+#include <stdilb.h>
+#include <assert.h>
+#include <string.h>
+
+#include "node.h"
+#include "hash.h"
+
+scope* mkscope(prev)
+scope* prev;
+{
+ int i;
+
+ scope *p = malloc(sizeof(scope));
+ assert(p);
+
+ for (i = 0; i < HASH_SIZE; i++)
+ p->table[i] = NULL;
+
+ p->next = next;
+ p->function_boundry = 0;
+
+ return p;
+}
+
+void free_scope(s)
+scope *s;
+{
+ int i;
+
+ if (!s)
+ return;
+
+ for (i = 0; i < HASH_SIZE; i++) {
+ free_nodes(s->table[i]);
+ }
+
+ free(s);
+}
+
+/*Copied from Compilers, Aho*/
+#define EOS '\0'
+int hashpjw(s)
+char* s;
+{
+ char *p;
+ unsigned h = 0, g;
+
+ for (p = s; *p != EOS; p++) {
+ h = (h<<4) + *p;
+ if (g = h & 0xf0000000) {
+ h^= g>>24;
+ h^= g;
+ }
+ }
+
+ return h % HASH_SIZE;
+}
+
+scope* push_scope(root);
+scope* root;
+{
+ scope *p = mkscope();
+ p->next = root;
+ return p;
+}
+
+scope* pop_scope(root);
+scope *root;
+{
+ scope *p;
+
+ if (!root)
+ return NULL;
+
+ p = root->next;
+
+ free_scope(root);
+ return p;
+}
+
+node* scope_insert(s, name)
+scope *s;
+char *name;
+{
+ int hash = hashpwj(name);
+
+ node *tmp = root->table[hash];
+ return root->table[hash] = list_insert(tmp, name);
+}
+
+node* scope_search(root, name)
+scope *root;
+char *name;
+{
+ int hash = hashpwj(name);
+
+ node *tmp = root->table[hash];
+ return list_search(tmp, name);
+}
+
+node* scope_search_all(root, name)
+scope *root;
+char *name;
+{
+ scope *p;
+ node *tmp;
+
+ for (p = root; p; p = p->next)
+ if (tmp = scope_search(p, name))
+ return tmp;
+
+ return NULL;
+}
+
+node* scope_safe_search(root, name)
+scope *root;
+char *name;
+{
+ scope *p;
+ node *tmp;
+
+ for (p = root; p; p = p->next) {
+ if (tmp = scope_search(p, name))
+ return tmp;
+ if (p->f)
+ return NULL
+ }
+
+ return NULL;
+}
+
+void print_scope(s)
+scope *s;
+{
+ int i;
+ node_t * tmp;
+ for (i = 0; i < HASH_SIZE; i++) {
+ for( tmp=s->table[i]; tmp; tmp = tmp->next) {
+ fprintf(stderr, "\t%s\n", tmp->name);
+ }
+ }
+}
diff --git a/hash.h b/hash.h
new file mode 100644
index 0000000..8a8cdb1
--- /dev/null
+++ b/hash.h
@@ -0,0 +1,27 @@
+#ifndef SCOPE_H
+#define SCOPE_H
+
+#define HASH_SIZE 211
+
+typedef struct hash {
+ node* table[HASH_SIZE];
+ struct hash *prev, *next;
+ char function_boundry;
+} scope;
+
+scope* mkscope(scope*);
+void free_scope(scope*);
+
+/*stack routines*/
+scope* pop_scope(scope*);
+scope* push_scope(scope*);
+
+/*helpers*/
+node* scope_insert(scope*, char*);
+node* scope_search_all(scope*, char*);
+node* scope_search(scope*, char*);
+node* scope_safe_search_all(scope*, char*);
+
+/*hash function*/
+int hash_pwj(char*);
+#endif
diff --git a/node.c b/node.c
index e1b7920..ca6548b 100644
--- a/node.c
+++ b/node.c
@@ -41,3 +41,13 @@ char * str;
p->next = root;
return p;
}
+
+void free_list(n)
+node *n;
+{
+ node *tmp;
+
+ for(tmp = n; tmp; tmp = n = n->next) {
+ free(tmp);
+ }
+}
diff --git a/node.h b/node.h
index 5206db4..90e3936 100644
--- a/node.h
+++ b/node.h
@@ -13,7 +13,9 @@ typedef struct node_s {
node* mknode(char *);
/* helpers */
-node* search(node*, char *);
-node* insert(node*, char*);
+node* list_search(node*, char *);
+node* list_insert(node*, char*);
+
+void free_list(node*);
#endif