summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c22
-rw-r--r--src/hash_table.c33
-rw-r--r--src/include/ast.h2
-rw-r--r--src/include/stack.h2
-rw-r--r--src/main.c16
-rw-r--r--src/parser.c10
-rw-r--r--src/stack.c7
-rw-r--r--src/visitor.c126
8 files changed, 174 insertions, 44 deletions
diff --git a/src/ast.c b/src/ast.c
index e1a8e6c..faffacd 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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);
diff --git a/src/main.c b/src/main.c
index 92e7764..9eec089 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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)