diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/.ast.h.swp (renamed from src/include/.visitor.h.swp) | bin | 12288 -> 12288 bytes | |||
-rw-r--r-- | src/include/visitor.h | 6 | ||||
-rw-r--r-- | src/lexer.c | 8 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/parser.c | 72 | ||||
-rw-r--r-- | src/visitor.c | 28 |
6 files changed, 83 insertions, 33 deletions
diff --git a/src/include/.visitor.h.swp b/src/include/.ast.h.swp Binary files differindex febe477..c3e8ba3 100644 --- a/src/include/.visitor.h.swp +++ b/src/include/.ast.h.swp diff --git a/src/include/visitor.h b/src/include/visitor.h index 6af052b..54f43f0 100644 --- a/src/include/visitor.h +++ b/src/include/visitor.h @@ -2,20 +2,24 @@ #define VISITOR_H #include "./ast.h" #include "./hash_table.h" +#include "./parser.h" #include "./stack.h" typedef struct { hash_table_t *symbol_table; + hash_table_t *eval_table; stack_t *stack_frame; ast_t *root; } visitor_t; void eval_error(visitor_t *v, ast_t *e); -visitor_t *init_visitor(ast_t *root); +visitor_t *init_visitor(parser_t *p); bool is_self_evaluating(ast_t *e); +bool is_built_in(ast_t *e); + ast_t *eval_symbol(visitor_t *v, ast_t *e); ast_t *eval_list(visitor_t *v, ast_t *e); diff --git a/src/lexer.c b/src/lexer.c index 02417a1..938c4eb 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -63,11 +63,13 @@ static char *char_to_string(char c) { token_t *lexer_collect_bool(lexer_t *lexer) { lexer_move(lexer); - if (lexer->c == 't') + if (lexer->c == 't') { + lexer_move(lexer); return init_token(TOKEN_BOOL, "T", lexer->row, lexer->col); - else if (lexer->c == 'f') + } else if (lexer->c == 'f') { + lexer_move(lexer); return init_token(TOKEN_BOOL, "F", lexer->row, lexer->col); - else + } else return NULL; } @@ -42,7 +42,7 @@ int main(int argc, char **argv) { /* } */ /* TEST PARSER, VISITOR, PRINTER */ - lexer_t *lexer = init_lexer("\"hello world\""); + lexer_t *lexer = init_lexer("34.4"); parser_t *parser = init_parser(lexer); ast_t *root = parse_expr(parser); diff --git a/src/parser.c b/src/parser.c index be08ac6..1fff876 100644 --- a/src/parser.c +++ b/src/parser.c @@ -85,20 +85,36 @@ ast_t *parse_symbol(parser_t *parser) { } ast_t *parse_function_args(parser_t *parser) { - token_t *t = parser->tokens[parser->i]; - - ast_t *head; ast_t *car; - ast_t *cdr; - while (t->type != TOKEN_LPAREN) { + ast_t *head = init_ast_pair(NULL, NULL); + ast_t *cur = head; + parser_move(parser); + + token_t *current_token = parser->tokens[parser->i]; + while (current_token->type != TOKEN_RPAREN) { + if (parser->tokens[parser->i]->type != TOKEN_ID) + parser_error(parser); + + car = parse_symbol(parser); + + cur->car = car; + cur->cdr = init_ast_pair(NULL, NULL); + cur = cur->cdr; + + parser_move(parser); + current_token = parser->tokens[parser->i]; } + + parser_move(parser); + return head; } + ast_t *parse_function(parser_t *parser) { parser_move(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_list(parser); + ast_t *car = parse_function_args(parser); ast_t *cdr = parse_expr(parser); /* a function can contain a single expression */ parser_eat(parser, TOKEN_RPAREN); @@ -119,37 +135,45 @@ void parse_bind(parser_t *parser) { } ast_t *parse_list(parser_t *parser) { + ast_t *car; + ast_t *head = init_ast_pair(NULL, NULL); + ast_t *cur = head; parser_move(parser); - token_t *cur = parser->tokens[parser->i]; + bool first_entry = true; - ast_t *head; - ast_t *car; - ast_t *cdr = - init_ast_pair(init_ast_pair(NULL, NULL), init_ast_pair(NULL, NULL)); - while (cur->type != TOKEN_RPAREN) { - if (cur->type == TOKEN_ID) { - if (strcmp(cur->value, "lambda") == 0 && first_entry) - return parse_function(parser); - else if (strcmp(cur->value, "bind") == 0 && first_entry) { + token_t *current_token = parser->tokens[parser->i]; + while (current_token->type != TOKEN_RPAREN) { + if (parser->tokens[parser->i]->type == TOKEN_ID) { + if (strcmp(parser->tokens[parser->i]->value, "lambda") == 0 && + first_entry) { + car = parse_function(parser); + first_entry = false; + } else if (strcmp(parser->tokens[parser->i]->value, "bind") == 0 && + first_entry) { parse_bind(parser); return NULL; + } else { + car = parse_symbol(parser); } - } else + } else { car = parse_expr(parser); - - if (car == NULL) - parser_error(parser); + if (car == NULL) + parser_error(parser); + } + cur->car = car; + cur->cdr = init_ast_pair(NULL, NULL); + cur = cur->cdr; first_entry = false; - - head = init_ast_pair(car, cdr); parser_move(parser); - cur = parser->tokens[parser->i]; + current_token = parser->tokens[parser->i]; } + parser_move(parser); + return head; } ast_t *parse_quote(parser_t *parser) { parser_move(parser); - ast_t *car = init_ast_string("quote"); + ast_t *car = init_ast_symbol("quote"); ast_t *expr = parse_expr(parser); ast_t *ret = init_ast_pair( car, init_ast_pair( diff --git a/src/visitor.c b/src/visitor.c index 98a7d92..6eb29a2 100644 --- a/src/visitor.c +++ b/src/visitor.c @@ -1,18 +1,20 @@ #include "./include/visitor.h" #include "./include/hash_table.h" #include "./include/macros.h" +#include "./include/parser.h" #include "./include/stack.h" #include <stdbool.h> #include <stdlib.h> #include <string.h> -visitor_t *init_visitor(ast_t *root) { +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->symbol_table = init_hash_table(10000); - v->root = root; + v->symbol_table = p->symbol_table; + v->eval_table = init_hash_table(10000); + v->root = parse_all(p); return v; } @@ -26,9 +28,27 @@ bool is_self_evaluating(ast_t *e) { return false; } +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) {} +ast_t *eval_symbol(visitor_t *v, ast_t *e) { + if (is_built_in(e)) + return e; + + 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); + + else if (hash_table_exists(v->eval_table, e->string_value)) + return hash_table_get(v->eval_table, e->string_value); + + else if (hash_table_exists(v->symbol_table, e->string_value)) { + ast_t *unevaled = hash_table_get(v->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 + return e; +} ast_t *eval_list(visitor_t *v, ast_t *e) {} |