diff --git a/include/lexer.h b/include/lexer.h index fcb6529..ed8c1e2 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -20,15 +20,6 @@ typedef enum { OP_DIV } Operator; -typedef enum { - ARRAY_OK = 0, - ARRAY_NULL, - ARRAY_EMPTY, - ARRAY_OUT_OF_BOUNDS, - ARRAY_NULL_ARG, - ARRAY_ALLOC, -} ASTNodeArrayErr; - typedef enum { LEXER_OK = 0, LEXER_INT_OVERFLOW, @@ -76,20 +67,6 @@ typedef struct { int64_t number; }; } I64Result; -// I prefer ot have a dynamic array for storing the "tokens" -typedef struct { - size_t len; - size_t cap; - ASTNode *data; -} ASTNodeArray; - -ASTNodeArray ASTNodeArray_init(size_t size); -void ASTNodeArray_free(ASTNodeArray *arr); -ASTNodeArrayErr ASTNodeArray_push(ASTNodeArray *arr, ASTNode node); -ASTNodeArrayErr ASTNodeArray_get(const ASTNodeArray *arr, size_t index, ASTNode *out); -// Out in pop can be NULL so it doesn't return anything -ASTNodeArrayErr ASTNodeArray_pop(ASTNodeArray *arr, size_t index, ASTNode *out); -size_t ASTNodeArray_len(ASTNodeArray *arr); // Lexer funtions as well as few functionality TokenizeResult tokenize(const char* input); diff --git a/include/parser.h b/include/parser.h index 7c2fa4f..158b348 100644 --- a/include/parser.h +++ b/include/parser.h @@ -3,33 +3,39 @@ #include "lexer.h" #include "arena.h" +#include "arraylist.h" #include typedef struct { ASTNode *head; } AST; -typedef struct { - ASTNodeArray *arr; - size_t pos; -} ASTNodeSlice; +typedef enum { + PARSER_OK = 0, + PARSER_UNEXPECTED_TOKEN, + PARSER_MISSING_OPERAND, + PARSER_UNMATCHED_PAREN, + PARSER_OUT_OF_MEMORY, +} ParserErr; typedef struct { - Arena arena; - ASTNode *tree; + bool is_valid; + union { + ParserErr err; + struct { + Arena arena; + ASTNode *tree; + }; + }; } ParseResult; -ASTNode ASTNodeSlice_peek(ASTNodeSlice *slice); -ASTNode ASTNodeSlice_next(ASTNodeSlice *slice); -bool ASTNodeSlice_is_valid(ASTNodeSlice *slice); - -ASTNode *nud(ASTNodeSlice *slice); -ASTNode *led(ASTNodeSlice *slice, size_t right_precedence); +ASTNode *nud(ArraySlice *slice); +ASTNode *led(ArraySlice *slice, size_t right_precedence); uint8_t node_lbp(ASTNode node); uint8_t node_rbp(ASTNode node); -ParseResult parse(ASTNodeArray *arr); -ASTNode *parse_expr(ASTNodeSlice *slice, Arena *arena, uint8_t min_bp); +ParseResult parse(TokenizeResult tokens); +ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp); #endif // !PARSER_H diff --git a/src/ASTNodeArray.c b/src/ASTNodeArray.c deleted file mode 100644 index a9f2053..0000000 --- a/src/ASTNodeArray.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "lexer.h" -#include - -#define NODE_ARRAY_DEFAULT_SIZE 64 -// Helps state machine for the lexer :) -typedef enum { - WAIT_FOR_NUMBER, - WAIT_FOR_OPERATOR, -} LexerState; - -ASTNodeArray ASTNodeArray_init(size_t size) { - ASTNodeArray new; - new.len = 0; // if 0 then use default - new.cap = size == 0 ? NODE_ARRAY_DEFAULT_SIZE : size; - new.data = malloc(new.cap * sizeof(ASTNode)); - return new; -} - -void ASTNodeArray_free(ASTNodeArray *arr) { - free(arr->data); - arr->cap = 0; - arr->len = 0; -} - -ASTNodeArrayErr ASTNodeArray_get(const ASTNodeArray *arr, size_t index, ASTNode *out) { - if (arr == NULL) { - return ARRAY_NULL; - } - - if (out == NULL) { - return ARRAY_NULL_ARG; - } - - if (arr->len == 0) { - return ARRAY_EMPTY; - } - - if (index >= arr->len) { - return ARRAY_OUT_OF_BOUNDS; - } - - *out = arr->data[index]; - - return ARRAY_OK; -} - -ASTNodeArrayErr ASTNodeArray_push(ASTNodeArray *arr, ASTNode node) { - if (arr == NULL) { - return ARRAY_NULL; - } - - if (arr->len >= arr->cap) { - size_t new_cap = arr->cap * 2; - ASTNode *tmp = realloc(arr->data, new_cap * sizeof(ASTNode)); - if (tmp == NULL) { - return ARRAY_ALLOC; - } - arr->data = tmp; - arr->cap = new_cap; - } - - arr->data[arr->len] = node; - arr->len = arr->len + 1; - - return ARRAY_OK; -} - -ASTNodeArrayErr ASTNodeArray_pop(ASTNodeArray *arr, size_t index, ASTNode *out) { - if (arr == NULL) { - return ARRAY_NULL; - } - - if (arr->len == 0) { - return ARRAY_EMPTY; - } - - if (index >= arr->len) { - return ARRAY_OUT_OF_BOUNDS; - } - - if (arr->cap / 4 > arr->len) { - size_t new_cap = arr->cap / 2; - ASTNode *tmp = realloc(arr->data, new_cap * sizeof(ASTNode)); - if (tmp == NULL) { - return ARRAY_ALLOC; - } - arr->data = tmp; - arr->cap = new_cap; - } - - if (out != NULL) { - ASTNode node_to_delete = arr->data[index]; - *out = node_to_delete; - } - - for (size_t i = index; i < arr->len - 1; i++) { - arr->data[index] = arr->data[index + 1]; - } - - return ARRAY_OK; -} - -size_t ASTNodeArray_len(ASTNodeArray *arr) { - if (arr == NULL) { - return 0; - } - return arr->len; -} diff --git a/src/main.c b/src/main.c index 9cc1240..89cfc64 100644 --- a/src/main.c +++ b/src/main.c @@ -19,10 +19,9 @@ int main(void) { } buf[pos] = '\0'; - ASTNodeArray context; - tokenize(buf, &context); + TokenizeResult tokens = tokenize(buf); - ParseResult par = parse(&context); + ParseResult par = parse(tokens); int64_t result = evaluate(par); diff --git a/src/parser.c b/src/parser.c index 9f454ef..a3efae0 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,4 +1,5 @@ #include "parser.h" +#include "arraylist.h" #include "lexer.h" #include "arena.h" #include @@ -41,38 +42,17 @@ uint8_t node_rbp(ASTNode node) { } } -ASTNode ASTNodeSlice_next(ASTNodeSlice *slice) { - return slice->arr->data[slice->pos++]; -} - -ASTNode ASTNodeSlice_peek(ASTNodeSlice *slice) { - return slice->arr->data[slice->pos]; -} - -bool ASTNodeSlice_is_valid(ASTNodeSlice *slice) { - if (slice->arr->len < 1) { - return false; - } - if (slice->pos >= slice->arr->len) { - return false; - } - - return true; -} - -ParseResult parse(ASTNodeArray *arr) { - ASTNodeSlice context = { - .arr = arr, - .pos = 0, - }; - Arena arena = arena_init(sizeof(ASTNode) * arr->len).arena; +ParseResult parse(TokenizeResult tokens) { + ArraySlice *context = arraylist_slice(tokens.arr, 0, arraylist_size(tokens.arr)); + Arena arena = arena_init(sizeof(ASTNode) * arraylist_size(tokens.arr)).arena; return (ParseResult) { + .is_valid = true, .arena = arena, - .tree = parse_expr(&context, &arena, 0)}; + .tree = parse_expr(context, &arena, 0)}; } -ASTNode *parse_expr(ASTNodeSlice *slice, Arena *arena, uint8_t min_bp) { +ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { arena_ensure_capacity( arena, sizeof(ASTNode), @@ -87,14 +67,15 @@ ASTNode *parse_expr(ASTNodeSlice *slice, Arena *arena, uint8_t min_bp) { ) ); - *left_side = ASTNodeSlice_next(slice); + arrayslice_next(slice, left_side); while (true) { - if (!ASTNodeSlice_is_valid(slice)) { + if (!arrayslice_is_valid(slice)) { break; } - ASTNode operator = ASTNodeSlice_peek(slice); + ASTNode operator; + arrayslice_peek(slice, &operator); uint8_t rbp = node_rbp(operator); uint8_t lbp = node_lbp(operator); @@ -102,7 +83,7 @@ ASTNode *parse_expr(ASTNodeSlice *slice, Arena *arena, uint8_t min_bp) { break; } - ASTNodeSlice_next(slice); + arrayslice_next(slice, NULL); ASTNode *right_side = parse_expr(slice, arena, rbp); arena_ensure_capacity(