From 157cdbf2651503c9ef0b181796d6707faff097ad Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 8 Oct 2021 14:30:50 +0200 Subject: Add initial implementation of lists --- src/bootstrap/main.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index b346cca..a0b0f69 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -186,9 +186,16 @@ typedef struct Object { // OBJ_TYPE_LIST struct { - struct Object **list_elems; + // NOTE: Probably want to do this as a linked list using pairs. + struct Object **list; size_t list_n; }; + + // OBJ_TYPE_SYMBOL + struct { + char *symbol; + size_t symbol_n; + }; }; } Object; @@ -218,18 +225,39 @@ make_string(const char *str, size_t n) { return obj; } +Object * +make_symbol(const char *str, size_t n) { + Object *obj = malloc(sizeof(Object)); + obj->type = OBJ_TYPE_SYMBOL; + 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->type = OBJ_TYPE_NIL; + obj->list = NULL; obj->list_n = 0; return obj; } void -push_obj_to_list(Object *list, Object obj) { - assert(false && "todo: Not implemented"); +push_obj_to_list(Object *list, Object **obj) { + assert(list != NULL); + assert(list->type == OBJ_TYPE_NIL || list->type == OBJ_TYPE_LIST); + + if (obj == NULL || *obj == NULL) { + return; + } + + if (list->type == OBJ_TYPE_NIL) { + list->type = OBJ_TYPE_LIST; + } + list->list = realloc(list->list, (list->list_n + 1) * sizeof(struct Object *)); + list->list[list->list_n++] = *obj; } bool @@ -287,6 +315,29 @@ build_ast(Tokens tokens) { if (sv_equal(token, FALSE_TOKEN)) { return make_boolean(false); } + + // OBJ_TYPE_LIST + if (token.start[0] == ')') { + return NULL; + } + if (token.start[0] == '(') { + if ((i + 1) < tokens.n && tokens.start[i + 1].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) { + 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 NULL; @@ -315,8 +366,21 @@ display(Object *root) { case OBJ_TYPE_STRING: { printf("\"%.*s\"", (int)root->string_n, root->string); } break; + case OBJ_TYPE_SYMBOL: { + printf(":%.*s", (int)root->symbol_n, root->symbol); + } break; + case OBJ_TYPE_LIST: { + printf("("); + for (size_t i = 0; i < root->list_n; i++) { + display(root->list[i]); + if ((i + 1) < root->list_n) { + printf(" "); + } + } + printf(")"); + } break; default: { - printf("TYPE NOT IMPLEMENTED FOR DISPLAY\n"); + printf("TYPE NOT IMPLEMENTED FOR DISPLAY."); } break; } } -- cgit v1.2.1