diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast.c | 22 | ||||
-rw-r--r-- | src/hash_table.c | 33 | ||||
-rw-r--r-- | src/include/ast.h | 2 | ||||
-rw-r--r-- | src/include/stack.h | 2 | ||||
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/parser.c | 10 | ||||
-rw-r--r-- | src/stack.c | 7 | ||||
-rw-r--r-- | src/visitor.c | 126 |
8 files changed, 174 insertions, 44 deletions
@@ -1,6 +1,6 @@ #include "./include/ast.h" +#include <stdio.h> #include <stdlib.h> - /* A very... lightweight version of "inheritance" */ ast_t *init_ast(int type) { ast_t *a = (ast_t *)malloc(sizeof(ast_t)); @@ -64,3 +64,23 @@ ast_t *init_ast_root(ast_t **subnodes, int size) { a->root_size = size; return a; } + +void ast_type_print(ast_t *e) { + if (e->type == AST_FUNCTION) { + printf("Function\n"); + } else if (e->type == AST_INT) { + printf("Integer\n"); + } else if (e->type == AST_FLOAT) { + printf("Float\n"); + } else if (e->type == AST_BOOL) { + printf("Bool\n"); + } else if (e->type == AST_SYMBOL) { + printf("Symbol\n"); + } else if (e->type == AST_PAIR) { + printf("Pair\n"); + } else if (e->type == AST_STRING) { + printf("String\n"); + } else if (e->type == AST_ROOT) { + printf("Root Node\n"); + } +} diff --git a/src/hash_table.c b/src/hash_table.c index 99508e9..c3c77a4 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -36,29 +36,14 @@ 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; - } - - 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) { + } else { + sl_node_t *cur = l->head; + while (cur->next != NULL) + cur = cur->next; cur->next = init_sl_node(key, value); l->size++; } @@ -66,6 +51,8 @@ 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; @@ -83,10 +70,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; - for (int i = 0; i < l->size; i++) { + while (cur != NULL) { tmp = cur; cur = cur->next; - free(tmp); + free(cur); } free(l); } @@ -106,6 +93,10 @@ 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/ast.h b/src/include/ast.h index a5095e1..c99564d 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -50,4 +50,6 @@ ast_t *init_ast_symbol(char *value); ast_t *init_ast_function(ast_t *car, ast_t *cdr); ast_t *init_ast_root(ast_t **subnodes, int size); + +void ast_type_print(ast_t *e); #endif diff --git a/src/include/stack.h b/src/include/stack.h index e8047c8..5a58f0b 100644 --- a/src/include/stack.h +++ b/src/include/stack.h @@ -6,7 +6,7 @@ typedef struct { int cur; } stack_t; -stack_t *init_stack(int ht_size); +stack_t *init_stack(); void stack_push(stack_t *s, hash_table_t *h); @@ -83,7 +83,7 @@ int main(int argc, char **argv) { /* DONE: TEST PARSING AND STORING BINDINGS */ /* lexer_t *lexer = init_lexer("(bind x \"hello world\")"); */ /* parser_t *parser = init_parser(lexer); */ - /* ast_t *root = parse_all(parser); */ + /* parse_all(parser); */ /* if (hash_table_exists(parser->symbol_table, "x")) { */ /* printf("YES!\n"); */ /* ast_t *str = hash_table_get(parser->symbol_table, "x"); */ @@ -92,11 +92,21 @@ int main(int argc, char **argv) { /* TODO: TEST HASH TABLE COLLISIONS */ /* DONE: TEST BUILTIN FUNCTIONS */ - lexer_t *lexer = init_lexer("(/ (+ 3.0 4.0) 4)"); + /* lexer_t *lexer = init_lexer("(* (+ 3.0 4.0) 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); */ + /* TODO: TEST NON-BUILTIN FUNCTIONS (stack frame) */ + + lexer_t *lexer = init_lexer("((lambda (x y) (+ x y)) (+ 3.0 4.0) 4)"); parser_t *parser = init_parser(lexer); visitor_t *visitor = init_visitor(parser); + ast_t *root = eval(visitor); ast_t *res = root->subnodes[0]; - printf("%f\n", res->float_value); + print(res); + return 0; } diff --git a/src/parser.c b/src/parser.c index 16be8e1..5b8e4fb 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(1000); + p->symbol_table = init_hash_table(400); p->finished = false; if (p->tokens == NULL) die("malloc on p->tokens"); @@ -112,8 +112,6 @@ ast_t *parse_function_args(parser_t *parser) { ast_t *parse_function(parser_t *parser) { parser_eat(parser, TOKEN_LPAREN); - /* TODO: actually write a helper function that also keeps track - of the amount of arguments and checks that they are all identifiers.*/ ast_t *car = parse_function_args(parser); ast_t *cdr = parse_expr(parser); /* a function can contain a single expression */ @@ -134,11 +132,13 @@ 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 */ + hash_table_add(parser->symbol_table, name, expr); + if (parser->tokens[parser->i]->type != TOKEN_RPAREN) + parser_error(parser); + parser_move(parser); - /* if (parser->tokens[parser->i]->type != TOKEN_RPAREN) */ - /* parser_error(parser); */ } ast_t *parse_list(parser_t *parser) { diff --git a/src/stack.c b/src/stack.c index 4898d83..21a8b35 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1,9 +1,10 @@ #include "./include/stack.h" #include "./include/hash_table.h" #include "./include/macros.h" +#include <stdio.h> #include <stdlib.h> -stack_t *init_stack(int ht_size) { +stack_t *init_stack() { stack_t *s = (stack_t *)malloc(sizeof(stack_t)); if (s == NULL) die("malloc on stack"); @@ -16,9 +17,9 @@ void stack_push(stack_t *s, hash_table_t *h) { if (s->stack == NULL) { s->stack = malloc(sizeof(hash_table_t *)); if (s->stack == NULL) - die("malloc on stack within stack"); + die("malloc on stack within stack_push"); } else { - s->stack = realloc(s->stack, 2 + s->cur); + s->stack = realloc(s->stack, (2 + s->cur) * sizeof(hash_table_t *)); } s->cur++; s->stack[s->cur] = h; diff --git a/src/visitor.c b/src/visitor.c index d5f5a8f..cbe72d8 100644 --- a/src/visitor.c +++ b/src/visitor.c @@ -11,7 +11,7 @@ visitor_t *init_visitor(parser_t *p) { visitor_t *v = (visitor_t *)malloc(sizeof(visitor_t)); if (v == NULL) die("malloc on visitor"); - v->stack_frame = init_stack(512); + v->stack_frame = init_stack(); v->symbol_table = p->symbol_table; v->eval_table = init_hash_table(1000); v->root = parse_all(p); @@ -66,13 +66,15 @@ bool is_built_in(ast_t *e) { /* Special symbols: car, cdr, quote, *, /, +, -, %, inc, dec, >, <, >=, <=, /=, * =, equal (for strings), input */ ast_t *eval_symbol(visitor_t *v, ast_t *e) { + /* hash_table_t *lmao = stack_peek(v->stack_frame); */ + printf("%s\n", e->string_value); 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)) + if (stack_peek(v->stack_frame) == NULL) { + printf("Does not work\n"); + } else if (hash_table_exists(stack_peek(v->stack_frame), 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)) return hash_table_get(v->eval_table, e->string_value); @@ -84,8 +86,10 @@ ast_t *eval_symbol(visitor_t *v, ast_t *e) { ast_t *eval = eval_expr(v, unevaled); hash_table_add(v->eval_table, e->string_value, eval); return eval; - } else + } else { + printf("eval symbol error\n"); eval_error(v, e); + } } /* Helper function to get the size of an AST linked list; useful for checking @@ -107,7 +111,6 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { ast_t *args = e->cdr; int arg_size; int cmp = get_list_size(args); - /* BUILT-IN FUNCTIONS */ if (function->type == AST_SYMBOL) { if (strcmp(function->string_value, "+") == 0) { @@ -124,6 +127,7 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { } else if ((arg1->type == AST_FLOAT) && (arg2->type == AST_INT)) { return init_ast_float(arg1->float_value + arg2->int_value); } else if ((arg1->type == AST_FLOAT) && (arg2->type) == AST_FLOAT) { + printf("plus evaled\n"); return init_ast_float(arg1->float_value + arg2->float_value); } else eval_error(v, e); @@ -189,8 +193,105 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { return init_ast_int(arg1->int_value * arg2->int_value); } else eval_error(v, e); + } else if (strcmp(function->string_value, "car") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_PAIR)) { + return arg1->car; + } else + eval_error(v, e); + } else if (strcmp(function->string_value, "quote") == 0) { + if (cmp != 1) + eval_error(v, e); + ast_t *arg1 = args->car; + return arg1; + } else if (strcmp(function->string_value, "len") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_STRING)) { + return init_ast_int(strlen(arg1->string_value)); + } else + eval_error(v, e); + } else if (strcmp(function->string_value, "bool?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_BOOL)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "int?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_INT)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "float?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_FLOAT)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "symbol?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_SYMBOL)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "func?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_FUNCTION)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "pair?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_PAIR)) { + return init_ast_bool(true); + } else + return init_ast_bool(false); + } else if (strcmp(function->string_value, "atoi") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if ((arg1->type == AST_STRING)) { + int a = atoi(arg1->string_value); + return init_ast_int(a); + } else + eval_error(v, e); } } + /* printf("debug 2\n"); */ /* NON BUILT-INS */ /* Checking that the parameters are actually valid */ if (function->type != AST_FUNCTION) @@ -198,30 +299,35 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { arg_size = get_list_size(function->car); + /* printf("%d\n", arg_size); */ if (arg_size != cmp) eval_error(v, e->car); - - hash_table_t *stack_frame = init_hash_table(512); + hash_table_t *stack_frame = init_hash_table(100); ast_t *cur_arg_name = function->car; ast_t *cur_arg = args; char *name; ast_t *evaled_arg; - while (cur_arg != NULL && cur_arg_name != NULL) { + while (cur_arg->cdr != NULL && cur_arg_name->cdr != NULL) { + ast_type_print(cur_arg->car); name = cur_arg_name->car->string_value; + printf("name: %s\n", name); evaled_arg = eval_expr(v, cur_arg->car); + /* printf("%f\n", evaled_arg->float_value); */ hash_table_add(stack_frame, name, evaled_arg); + printf("after hash_add\n"); cur_arg_name = cur_arg_name->cdr; cur_arg = cur_arg->cdr; } stack_push(v->stack_frame, stack_frame); ast_t *res = eval_expr(v, function->cdr); stack_frame = stack_pop(v->stack_frame); - hash_table_free(stack_frame); + /* hash_table_free(stack_frame); */ return res; } 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) |