From 036943d920182fe2c50e00cee2c667f6686e464a Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 8 Oct 2021 15:06:54 +0200 Subject: Change parser to work consuming tokens --- src/bootstrap/main.c | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index a0b0f69..fad3333 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -153,6 +153,17 @@ tokenize(StringView sv) { return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; } +StringView * +consume_token(Tokens *tokens) { + if (tokens->n == 0) { + return NULL; + } + StringView *ret = tokens->start; + tokens->start = &tokens->start[1]; + tokens->n--; + return ret; +} + typedef enum ObjectType { OBJ_TYPE_FIXNUM, OBJ_TYPE_BOOL, @@ -278,27 +289,27 @@ token_is_fixnum(StringView token) { #define FALSE_TOKEN (StringView){"false", 5} Object * -build_ast(Tokens tokens) { +build_ast(Tokens *tokens) { // DEBUG: Printing tokens. - // printf("N_TOKENS: %ld\n", tokens.n); - // for (size_t i = 0; i < tokens.n; i++) { + // printf("N_TOKENS: %ld\n", tokens->n); + // for (size_t i = 0; i < tokens->n; i++) { // printf("TOKEN: "); - // sv_write(tokens.start[i]); - // printf("\tN: %ld", tokens.start[i].n); + // sv_write(tokens->start[i]); + // printf("\tN: %ld", tokens->start[i].n); // printf("\n"); // } // TODO: Report error if we haven't consumed all the tokens? - for (size_t i = 0; i < tokens.n; i++) { - StringView token = tokens.start[i]; + while (tokens->n > 0) { + StringView *token = consume_token(tokens); // OBJ_TYPE_FIXNUM - if (token_is_fixnum(token)) { + if (token_is_fixnum(*token)) { // Convert token to fixnum. ssize_t num = 0; int sign = 1; - for (size_t i = 0; i < token.n; i++) { - char c = token.start[i]; + for (size_t i = 0; i < token->n; i++) { + char c = token->start[i]; if (c == '-') { sign = -1; continue; @@ -309,35 +320,32 @@ build_ast(Tokens tokens) { } // OBJ_TYPE_BOOL - if (sv_equal(token, TRUE_TOKEN)) { + if (sv_equal(*token, TRUE_TOKEN)) { return make_boolean(true); } - if (sv_equal(token, FALSE_TOKEN)) { + if (sv_equal(*token, FALSE_TOKEN)) { return make_boolean(false); } // OBJ_TYPE_LIST - if (token.start[0] == ')') { + if (token->start[0] == ')') { return NULL; } - if (token.start[0] == '(') { - if ((i + 1) < tokens.n && tokens.start[i + 1].start[0] == ')') { + if (token->start[0] == '(') { + if (tokens->n > 0 && tokens->start[0].start[0] == ')') { return make_empty_list(); } Object *list = make_empty_list(); Object *next_obj = NULL; - while (((i + 1) < tokens.n) && (next_obj = build_ast((Tokens){&tokens.start[i + 1], tokens.n - i - 1})) != NULL) { + while (tokens->n > 0 && (next_obj = build_ast(tokens)) != NULL) { push_obj_to_list(list, &next_obj); - // FIXME: must consume tokens instead, otherwise recursive lists - // will not work. - i++; } return list; } // OBJ_TYPE_SYMBOL - return make_symbol(token.start, token.n); + return make_symbol(token->start, token->n); } return NULL; @@ -393,7 +401,8 @@ main(void) { while (true) { printf(REPL_PROMPT); StringView line = read_line(); - Object *ast = build_ast(tokenize(line)); + Tokens tokens = tokenize(line); + Object *ast = build_ast(&tokens); if (ast) { display(ast); printf("\n"); -- cgit v1.2.1