From aa699fc05d0945528c9ccf2b9b3d7e53e425d186 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 8 Oct 2021 13:20:00 +0200 Subject: Add initial ast construction for fixnum/bool --- src/bootstrap/main.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 184 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 98f313b..b346cca 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -1,5 +1,7 @@ -#include #include +#include +#include +#include #include "shorthand.h" @@ -15,6 +17,19 @@ sv_write(StringView sv) { } } +bool +sv_equal(StringView a, StringView b) { + if (a.n == b.n) { + for (size_t i = 0; i < a.n; i++) { + if (a.start[i] != b.start[i]) { + return false; + } + } + return true; + } + return false; +} + StringView read_line(void) { #define RL_BUF_SIZE 1024 @@ -121,6 +136,7 @@ tokenize(StringView sv) { .n = 1, }; } break; + // TODO: Handle double quotes and escaped quotes. default: { token_n++; } break; @@ -134,23 +150,174 @@ tokenize(StringView sv) { }; } + return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; +} + +typedef enum ObjectType { + OBJ_TYPE_FIXNUM, + OBJ_TYPE_BOOL, + OBJ_TYPE_NIL, + OBJ_TYPE_SYMBOL, + OBJ_TYPE_STRING, + OBJ_TYPE_PAIR, + OBJ_TYPE_LIST, +} ObjectType; + +typedef struct Object { + ObjectType type; + union { + // OBJ_TYPE_FIXNUM + ssize_t fixnum; + + // OBJ_TYPE_BOOL + bool boolean; + + // OBJ_TYPE_STRING + struct { + char *string; + size_t string_n; + }; + + // OBJ_TYPE_PAIR + struct { + struct Object *car; + struct Object *cdr; + }; + + // OBJ_TYPE_LIST + struct { + struct Object **list_elems; + size_t list_n; + }; + }; +} Object; + +Object * +make_fixnum(ssize_t num) { + Object *obj = malloc(sizeof(Object)); + obj->type = OBJ_TYPE_FIXNUM; + obj->fixnum = num; + return obj; +} + +Object * +make_boolean(bool b) { + Object *obj = malloc(sizeof(Object)); + obj->type = OBJ_TYPE_BOOL; + obj->boolean = b; + return obj; +} + +Object * +make_string(const char *str, size_t n) { + Object *obj = malloc(sizeof(Object)); + obj->type = OBJ_TYPE_STRING; + obj->string = malloc(sizeof(char) * n); + memcpy(obj->string, str, n); + obj->string_n = n; + return obj; +} + +Object * +make_empty_list(void) { + Object *obj = malloc(sizeof(Object)); + obj->type = OBJ_TYPE_LIST; + obj->list_elems = NULL; + obj->list_n = 0; + return obj; +} + +void +push_obj_to_list(Object *list, Object obj) { + assert(false && "todo: Not implemented"); +} + +bool +token_is_fixnum(StringView token) { + for (size_t i = 0; i < token.n; i++) { + char c = token.start[i]; + if (i == 0 && c == '-') { + continue; + } + if (!isdigit(c)) { + return false; + } + } + return true; +} + +#define TRUE_TOKEN (StringView){"true", 4} +#define FALSE_TOKEN (StringView){"false", 5} + +Object * +build_ast(Tokens tokens) { // DEBUG: Printing tokens. - printf("N_TOKENS: %ld\n", n); - for (size_t i = 0; i < n; i++) { - printf("TOKEN: "); - sv_write(tokens_buf[i]); - printf("\tN: %ld", tokens_buf[i].n); - printf("\n"); + // 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); + // 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]; + + // OBJ_TYPE_FIXNUM + 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]; + if (c == '-') { + sign = -1; + continue; + } + num = num * 10 + (c - '0'); + } + return make_fixnum(num * sign); + } + + // OBJ_TYPE_BOOL + if (sv_equal(token, TRUE_TOKEN)) { + return make_boolean(true); + } + if (sv_equal(token, FALSE_TOKEN)) { + return make_boolean(false); + } } - return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; + return NULL; } void -display(StringView sv) { - if (sv.n != 0) { - sv_write(sv); - printf("\n"); +display(Object *root) { + if (root == NULL) { + return; + } + + switch (root->type) { + case OBJ_TYPE_FIXNUM: { + printf("%zd", root->fixnum); + } break; + case OBJ_TYPE_BOOL: { + if (root->boolean) { + printf("true"); + } else { + printf("false"); + } + } break; + case OBJ_TYPE_NIL: { + printf("()"); + } break; + case OBJ_TYPE_STRING: { + printf("\"%.*s\"", (int)root->string_n, root->string); + } break; + default: { + printf("TYPE NOT IMPLEMENTED FOR DISPLAY\n"); + } break; } } @@ -162,8 +329,11 @@ main(void) { while (true) { printf(REPL_PROMPT); StringView line = read_line(); - tokenize(line); - display(line); + Object *ast = build_ast(tokenize(line)); + if (ast) { + display(ast); + printf("\n"); + } } return 0; } -- cgit v1.2.1