diff options
Diffstat (limited to 'src/treeify.c')
-rw-r--r-- | src/treeify.c | 100 |
1 files changed, 76 insertions, 24 deletions
diff --git a/src/treeify.c b/src/treeify.c index 32a12c2..8da6481 100644 --- a/src/treeify.c +++ b/src/treeify.c @@ -1,32 +1,62 @@ #include <assert.h> +#include <stdio.h> #include <stdlib.h> #include <log.h> #include <tokenize.h> #include <treeify.h> -static void expected(enum token_type type) +static void __expect(struct ctx *ctx, struct token *token, enum token_type type, const char *file, + int line, const char *func, const char *type_enum) { - err("Expected token of type %d while creating tree!\n", type); + if (token->type != type) { + printf("[DBG] %s:%d: %s\n", file, line, func); + token_print(ctx, token); + err("Expected token of type %s!\n", type_enum); + } } -static void unexpected(struct ctx *ctx, struct token *token) -{ - token_print(ctx, token); - err("Unexpected token while creating tree!\n"); -} +#define expect(token, type) __expect(ctx, token, type, __FILE__, __LINE__, __func__, #type) static struct token *next(struct token *token, size_t i) { return token + i; } +static struct token *parse_declaration(struct ctx *ctx, struct token *token); +static struct token *parse_expression(struct ctx *ctx, struct token *token) +{ + struct node_expression *node = malloc(sizeof(*node)); + // TODO: Push expressions into tree (using subtrees) + + struct token *iterator = token; + while ((iterator = next(iterator, 1))) { + if (iterator->type == LPAREN) { + iterator = parse_expression(ctx, iterator); + continue; + } + + if (iterator->type == TYPE) { + iterator = parse_declaration(ctx, iterator); + continue; + } + + if (iterator->type == RPAREN) + break; + + if (iterator->type == EOL || iterator->type == END) + expect(iterator, RPAREN); + + expect(iterator, IDENT); + } + + return iterator; +} + static struct token *parse_declaration(struct ctx *ctx, struct token *token) { - if (next(token, 1)->type != TYPEDELIM) - unexpected(ctx, next(token, 1)); - if (next(token, 2)->type != PARAM) - unexpected(ctx, next(token, 2)); + expect(next(token, 1), TYPEDELIM); + expect(next(token, 2), PARAM); // Search for equal sign struct token *iterator = token; @@ -34,7 +64,7 @@ static struct token *parse_declaration(struct ctx *ctx, struct token *token) if (iterator->type == EQUAL) break; if (iterator->type == EOL || iterator->type == END) - expected(EQUAL); + expect(iterator, EQUAL); } struct node_declaration *node = malloc(sizeof(*node)); @@ -47,46 +77,69 @@ static struct token *parse_declaration(struct ctx *ctx, struct token *token) node->parameters = malloc((diff / 3 + 1) * sizeof(*node->parameters)); for (size_t i = 0; i < diff / 3; i++) { struct token *param = token + (i + 1) * 3; - assert(param->type == TYPE); - assert(next(param, 2)->type == PARAM); + expect(param, TYPE); + expect(next(param, 2), PARAM); node->parameters[i].type = param->string; node->parameters[i].name = next(param, 2)->string; } + tree_add(ctx, DECLARATION, node); + return next(iterator, 1); } static struct token *parse(struct ctx *ctx, struct token *token) { switch (token->type) { + case LPAREN: + return parse_expression(ctx, token); case TYPE: return parse_declaration(ctx, token); + case RPAREN: + return next(token, 1); + case END: + return NULL; case UNKNOWN: case TYPEDELIM: case PARAM: case IDENT: case OPERATOR: - case LPAREN: - case RPAREN: case EQUAL: case NEWLINE: + case SOMETHING: case EOL: - case END: default: - unexpected(ctx, token); + expect(token, SOMETHING); } return NULL; } -struct tree *tree_create(void) +struct node *tree_create(void) { - struct tree *tree = malloc(sizeof(*tree)); - tree->node = NULL; + struct node *tree = malloc(sizeof(*tree)); + tree->prev = NULL; + tree->next = NULL; return tree; } -void tree_destroy(struct tree *tree) +void tree_add(struct ctx *ctx, enum node_type type, void *data) +{ + assert(ctx->tree.head); + struct node *node = malloc(sizeof(*node)); + node->type = type; + node->data = data; + if (!ctx->tree.current) { + ctx->tree.head->next = node; + node->prev = ctx->tree.head; + } else { + ctx->tree.current->next = node; + node->prev = ctx->tree.current; + } + ctx->tree.current = node; +} + +void tree_destroy(struct node *tree) { // TODO: Destroy nodes free(tree); @@ -96,12 +149,11 @@ void treeify(struct ctx *ctx) { struct token *token = &ctx->tokens[1]; while (token) { - assert(token->type != UNKNOWN); if (token->type == NEWLINE || token->type == EOL) { token = next(token, 1); continue; } - if (token->type == END) + if (token->type == END || token->type == UNKNOWN) break; token = parse(ctx, token); |