diff options
author | Preston Pan <preston@nullring.xyz> | 2023-01-05 21:02:26 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2023-01-05 21:02:26 -0800 |
commit | 5ecf1f46aae4994662bd8e3df189f8d60b49a304 (patch) | |
tree | 91b6a15d65c9e8d7a5e7ae87712830b1bf4f4eca | |
parent | 7ff373076c59af3ba166e5080b8ecead569d5a44 (diff) |
bind works for real, I think this works now
-rw-r--r-- | hash_table_new.c | 130 | ||||
-rw-r--r-- | src/hash_table.c | 33 | ||||
-rw-r--r-- | src/include/visitor.h | 2 | ||||
-rw-r--r-- | src/main.c | 9 | ||||
-rw-r--r-- | src/parser.c | 5 | ||||
-rw-r--r-- | src/stack.c | 6 | ||||
-rw-r--r-- | src/visitor.c | 19 |
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; @@ -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)) |