summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2023-01-05 21:02:26 -0800
committerPreston Pan <preston@nullring.xyz>2023-01-05 21:02:26 -0800
commit5ecf1f46aae4994662bd8e3df189f8d60b49a304 (patch)
tree91b6a15d65c9e8d7a5e7ae87712830b1bf4f4eca
parent7ff373076c59af3ba166e5080b8ecead569d5a44 (diff)
bind works for real, I think this works now
-rw-r--r--hash_table_new.c130
-rw-r--r--src/hash_table.c33
-rw-r--r--src/include/visitor.h2
-rw-r--r--src/main.c9
-rw-r--r--src/parser.c5
-rw-r--r--src/stack.c6
-rw-r--r--src/visitor.c19
7 files changed, 176 insertions, 28 deletions
diff --git a/hash_table_new.c b/hash_table_new.c
new file mode 100644
index 0000000..8722a60
--- /dev/null
+++ b/hash_table_new.c
@@ -0,0 +1,130 @@
+#include "./include/hash_table.h"
+#include "./include/ast.h"
+#include "./include/macros.h"
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+pair_t *init_pair(char *key, ast_t *value) {
+ pair_t *p = (pair_t *)malloc(sizeof(pair_t));
+ if (p == NULL)
+ die("malloc on pair");
+ p->key = key;
+ p->value = value;
+ return p;
+}
+
+sl_node_t *init_sl_node(char *key, ast_t *value) {
+ sl_node_t *n = (sl_node_t *)malloc(sizeof(sl_node_t));
+ if (n == NULL)
+ die("malloc on node");
+ n->value = init_pair(key, value);
+ n->next = NULL;
+ return n;
+}
+
+/*** SINGLY LINKED LIST FUNCTIONS ***/
+sl_list_t *init_sl_list() {
+ sl_list_t *l = (sl_list_t *)malloc(sizeof(sl_list_t));
+ if (l == NULL)
+ die("malloc on list");
+ l->size = 0;
+ l->head = NULL;
+ return l;
+}
+
+/* TODO: fix segfault bug */
+void sl_list_add(sl_list_t *l, char *key, ast_t *value) {
+ if (l->head == NULL) {
+ l->head = init_sl_node(key, value);
+ l->size++;
+ return;
+ } else {
+ sl_node_t *cur = l->head;
+ while (cur->next != NULL)
+ cur = cur->next;
+ cur->next = init_sl_node(key, value);
+ l->size++;
+ }
+}
+
+ast_t *sl_list_get(sl_list_t *l, char *key) {
+ sl_node_t *cur = l->head;
+ printf("in hash table get\n");
+ while (cur != NULL) {
+ if (cur->value == NULL) {
+ printf("unlucky\n");
+ }
+ if (strcmp(cur->value->key, key) == 0)
+ return cur->value->value;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+bool sl_list_exists(sl_list_t *l, char *key) {
+ if (sl_list_get(l, key) != NULL)
+ return true;
+ return false;
+}
+
+void sl_list_free(sl_list_t *l) {
+ sl_node_t *cur = l->head;
+ sl_node_t *tmp;
+ while (cur != NULL) {
+ tmp = cur;
+ cur = cur->next;
+ free(cur);
+ }
+ free(l);
+}
+
+/*** HASH TABLE FUNCTIONS ***/
+hash_table_t *init_hash_table(int size) {
+ hash_table_t *h = (hash_table_t *)malloc(sizeof(hash_table_t));
+ if (h == NULL)
+ die("malloc on hash table");
+ h->size = size;
+ h->buckets = malloc(sizeof(sl_list_t *));
+ if (h->buckets == NULL)
+ die("malloc on buckets");
+ for (int i = 0; i < h->size; i++)
+ h->buckets[i] = init_sl_list();
+ return h;
+}
+
+void hash_table_add(hash_table_t *h, char *key, ast_t *value) {
+ if (hash_table_exists(h, key)) {
+ printf("BUG!\n");
+ return;
+ }
+ sl_list_t *l = h->buckets[hash(key, h->size)];
+ sl_list_add(l, key, value);
+}
+
+ast_t *hash_table_get(hash_table_t *h, char *key) {
+ sl_list_t *l = h->buckets[hash(key, h->size)];
+ return sl_list_get(l, key);
+}
+
+bool hash_table_exists(hash_table_t *h, char *key) {
+ printf("in hash table\n");
+ sl_list_t *l = h->buckets[hash(key, h->size)];
+ return sl_list_exists(l, key);
+}
+
+void hash_table_free(hash_table_t *h) {
+ for (int i = 0; i < h->size; i++)
+ sl_list_free(h->buckets[i]);
+ free(h);
+}
+
+/* DJB2 HASH FUNCTION */
+unsigned long hash(char *key, int size) {
+ unsigned long hash = 5381;
+ int c;
+ while ((c = *key++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ return hash % size;
+}
diff --git a/src/hash_table.c b/src/hash_table.c
index c3c77a4..99508e9 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -36,14 +36,29 @@ sl_list_t *init_sl_list() {
/* TODO: fix segfault bug */
void sl_list_add(sl_list_t *l, char *key, ast_t *value) {
+ sl_node_t *cur = l->head;
+ bool modified = false;
if (l->head == NULL) {
l->head = init_sl_node(key, value);
l->size++;
return;
- } else {
- sl_node_t *cur = l->head;
- while (cur->next != NULL)
- cur = cur->next;
+ }
+
+ for (int i = 0; i < l->size - 1; i++) {
+ if (strcmp(cur->value->key, key) == 0) {
+ cur->value->value = value;
+ modified = true;
+ break;
+ }
+ cur = cur->next;
+ }
+
+ if (strcmp(cur->value->key, key) == 0) {
+ cur->value->value = value;
+ modified = true;
+ }
+
+ if (!modified) {
cur->next = init_sl_node(key, value);
l->size++;
}
@@ -51,8 +66,6 @@ void sl_list_add(sl_list_t *l, char *key, ast_t *value) {
ast_t *sl_list_get(sl_list_t *l, char *key) {
sl_node_t *cur = l->head;
- if (cur == NULL)
- return NULL;
for (int i = 0; i < l->size; i++) {
if (strcmp(cur->value->key, key) == 0)
return cur->value->value;
@@ -70,10 +83,10 @@ bool sl_list_exists(sl_list_t *l, char *key) {
void sl_list_free(sl_list_t *l) {
sl_node_t *cur = l->head;
sl_node_t *tmp;
- while (cur != NULL) {
+ for (int i = 0; i < l->size; i++) {
tmp = cur;
cur = cur->next;
- free(cur);
+ free(tmp);
}
free(l);
}
@@ -93,10 +106,6 @@ hash_table_t *init_hash_table(int size) {
}
void hash_table_add(hash_table_t *h, char *key, ast_t *value) {
- if (hash_table_exists(h, key)) {
- printf("BUG!\n");
- return;
- }
sl_list_t *l = h->buckets[hash(key, h->size)];
sl_list_add(l, key, value);
}
diff --git a/src/include/visitor.h b/src/include/visitor.h
index 54f43f0..de73248 100644
--- a/src/include/visitor.h
+++ b/src/include/visitor.h
@@ -6,7 +6,7 @@
#include "./stack.h"
typedef struct {
- hash_table_t *symbol_table;
+ parser_t *p;
hash_table_t *eval_table;
stack_t *stack_frame;
ast_t *root;
diff --git a/src/main.c b/src/main.c
index 2c192cb..f418925 100644
--- a/src/main.c
+++ b/src/main.c
@@ -78,13 +78,14 @@ int main(int argc, char **argv) {
/* print(res); */
/* DONE: TEST NON-BUILTIN FUNCTIONS (stack frame) */
- lexer_t *lexer = init_lexer("((lambda (x y) (+ x y)) (+ 3 4) 4)");
+ lexer_t *lexer = init_lexer(
+ "(bind hello 3) ((lambda (x y) (+ x y)) (+ hello 4) 4) (+ 3 4)");
parser_t *parser = init_parser(lexer);
visitor_t *visitor = init_visitor(parser);
-
ast_t *root = eval(visitor);
- ast_t *res = root->subnodes[0];
- print(res);
+ print_root(root);
+ /* ast_t *res = root->subnodes[0]; */
+ /* print(res); */
/* TODO: TEST REPL POSSIBILITY */
/* printf("Welcome to the NXS REPL.\n"); */
diff --git a/src/parser.c b/src/parser.c
index 5b8e4fb..b5fc57e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -14,7 +14,7 @@ parser_t *init_parser(lexer_t *lexer) {
p->i = 0;
p->tokens = malloc(sizeof(token_t *));
- p->symbol_table = init_hash_table(400);
+ p->symbol_table = init_hash_table(100);
p->finished = false;
if (p->tokens == NULL)
die("malloc on p->tokens");
@@ -132,7 +132,8 @@ void parse_bind(parser_t *parser) {
parser_move(parser);
ast_t *expr = parse_expr(parser); /* unevaluated expr will be evaluated when
hash table transfers to visitor JIT */
-
+ if (expr == NULL)
+ parser_error(parser);
hash_table_add(parser->symbol_table, name, expr);
if (parser->tokens[parser->i]->type != TOKEN_RPAREN)
diff --git a/src/stack.c b/src/stack.c
index 21a8b35..c5e753e 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -25,7 +25,11 @@ void stack_push(stack_t *s, hash_table_t *h) {
s->stack[s->cur] = h;
}
-hash_table_t *stack_peek(stack_t *s) { return s->stack[s->cur]; }
+hash_table_t *stack_peek(stack_t *s) {
+ if (s->stack == NULL)
+ return NULL;
+ return s->stack[s->cur];
+}
hash_table_t *stack_pop(stack_t *s) {
hash_table_t *h = s->stack[s->cur];
diff --git a/src/visitor.c b/src/visitor.c
index 44b89ef..135c4d5 100644
--- a/src/visitor.c
+++ b/src/visitor.c
@@ -11,9 +11,9 @@ visitor_t *init_visitor(parser_t *p) {
visitor_t *v = (visitor_t *)malloc(sizeof(visitor_t));
if (v == NULL)
die("malloc on visitor");
+ v->p = p;
v->stack_frame = init_stack();
- v->symbol_table = p->symbol_table;
- v->eval_table = init_hash_table(1000);
+ v->eval_table = init_hash_table(100);
v->root = parse_all(p);
return v;
}
@@ -67,24 +67,28 @@ bool is_built_in(ast_t *e) {
* =, equal (for strings), input */
ast_t *eval_symbol(visitor_t *v, ast_t *e) {
/* hash_table_t *lmao = stack_peek(v->stack_frame); */
+ hash_table_t *h = stack_peek(v->stack_frame);
+
if (is_built_in(e))
return e;
/* first, it looks in the stack frame for a variable */
- else if (hash_table_exists(stack_peek(v->stack_frame), e->string_value))
+ else if (h != NULL && hash_table_exists(h, e->string_value)) {
return hash_table_get(stack_peek(v->stack_frame), e->string_value);
+ }
/* Then the variables that have already been evaluated */
- else if (hash_table_exists(v->eval_table, e->string_value))
+ else if (hash_table_exists(v->eval_table, e->string_value)) {
return hash_table_get(v->eval_table, e->string_value);
-
+ }
/* then it goes into the symbol table, evaluates the variable if it finds it
* and puts it in the list of variables that have already been evaluated */
- else if (hash_table_exists(v->symbol_table, e->string_value)) {
- ast_t *unevaled = hash_table_get(v->symbol_table, e->string_value);
+ else if (hash_table_exists(v->p->symbol_table, e->string_value)) {
+ ast_t *unevaled = hash_table_get(v->p->symbol_table, e->string_value);
ast_t *eval = eval_expr(v, unevaled);
hash_table_add(v->eval_table, e->string_value, eval);
return eval;
} else {
eval_error(v, e);
+ return NULL;
}
}
@@ -427,7 +431,6 @@ ast_t *eval_list(visitor_t *v, ast_t *e) {
}
ast_t *eval_expr(visitor_t *v, ast_t *e) {
- /* ast_type_print(e); */
if (is_self_evaluating(e))
return e;
else if (e->type == AST_PAIR && is_proper_list(e))