summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/.ast.h.swp (renamed from src/include/.visitor.h.swp)bin12288 -> 12288 bytes
-rw-r--r--src/include/visitor.h6
-rw-r--r--src/lexer.c8
-rw-r--r--src/main.c2
-rw-r--r--src/parser.c72
-rw-r--r--src/visitor.c28
6 files changed, 83 insertions, 33 deletions
diff --git a/src/include/.visitor.h.swp b/src/include/.ast.h.swp
index febe477..c3e8ba3 100644
--- a/src/include/.visitor.h.swp
+++ b/src/include/.ast.h.swp
Binary files differ
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;
}
diff --git a/src/main.c b/src/main.c
index 7da03dc..12ec987 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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) {}