diff options
Diffstat (limited to 'src/treeify.c')
-rw-r--r-- | src/treeify.c | 196 |
1 files changed, 111 insertions, 85 deletions
diff --git a/src/treeify.c b/src/treeify.c index 5539d21..47f8216 100644 --- a/src/treeify.c +++ b/src/treeify.c @@ -6,6 +6,8 @@ #include <tokenize.h> #include <treeify.h> +#define INITIAL_PARAMETER_COUNT 3 + 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) { @@ -23,96 +25,110 @@ 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) +static struct token *parse_declaration(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; - } + expect(token, IDENT); - if (iterator->type == TYPE) { - iterator = parse_declaration(ctx, iterator); - continue; - } + struct node_declaration *node = malloc(sizeof(*node)); + node->callee.name = token->string; - if (iterator->type == RPAREN) - break; + node->parameters = malloc(INITIAL_PARAMETER_COUNT * sizeof(*node->parameters)); + size_t param_idx = 0; - if (iterator->type == EOL || iterator->type == END) - expect(iterator, RPAREN); + token = next(token, 1); + while (token->type != TYPEDELIM) { + if (token->type == NEWLINE || token->type == END) + expect(token, TYPEDELIM); - expect(iterator, IDENT); + if (token->type != TYPE) + expect(token, TYPE); + + // Expand parameter space if necessary + if ((param_idx + 1) % INITIAL_PARAMETER_COUNT == 0) + // TODO: Fix realloc failure check (and other mallocs too btw) + node->parameters = realloc(node->parameters, + ((param_idx / INITIAL_PARAMETER_COUNT) + 1) * + INITIAL_PARAMETER_COUNT * + sizeof(*node->parameters)); + + node->parameters[param_idx].type = token->string; + param_idx++; + + token = next(token, 1); } - return iterator; + node->parameter_count = param_idx; + + token = next(token, 1); + expect(token, TYPE); + node->callee.type = token->string; + + tree_add(ctx, DECLARATION, node); // TODO: Push to declaration/signature array instead + + expect(next(token, 1), NEWLINE); + return next(token, 2); } -static struct token *parse_declaration(struct ctx *ctx, struct token *token) +static struct token *parse_definition(struct ctx *ctx, struct token *token) { - expect(next(token, 1), TYPEDELIM); - expect(next(token, 2), PARAM); - - // Search for equal sign - struct token *iterator = token; - while ((iterator = next(iterator, 1))) { - if (iterator->type == EQUAL) - break; - if (iterator->type == EOL || iterator->type == END) - expect(iterator, EQUAL); - } + expect(token, IDENT); - struct node_declaration *node = malloc(sizeof(*node)); - node->callee.type = token->string; - node->callee.name = next(token, 2)->string; - - // Magic - size_t diff = iterator - token - 3; - assert(diff % 3 == 0); - 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; - expect(param, TYPE); - expect(next(param, 2), PARAM); - node->parameters[i].type = param->string; - node->parameters[i].name = next(param, 2)->string; + struct node_definition *node = malloc(sizeof(*node)); + node->callee.name = token->string; + + node->parameters = malloc(INITIAL_PARAMETER_COUNT * sizeof(*node->parameters)); + size_t param_idx = 0; + + token = next(token, 1); + while (token->type != IDENTDELIM) { + if (token->type == NEWLINE || token->type == END) + expect(token, IDENTDELIM); + + if (token->type != PARAM) + expect(token, PARAM); + + // Expand parameter space if necessary + if ((param_idx + 1) % INITIAL_PARAMETER_COUNT == 0) + // TODO: Fix realloc failure check (and other mallocs too btw) + node->parameters = realloc(node->parameters, + ((param_idx / INITIAL_PARAMETER_COUNT) + 1) * + INITIAL_PARAMETER_COUNT * + sizeof(*node->parameters)); + + node->parameters[param_idx].name = token->string; + param_idx++; + + token = next(token, 1); } - tree_add(ctx, DECLARATION, node); + node->parameter_count = param_idx; + + tree_add(ctx, DEFINITION, node); - return next(iterator, 1); + // TODO: Parse expression + while (token->type != NEWLINE) + token = next(token, 1); + + return next(token, 1); +} + +static struct token *parse_block(struct ctx *ctx, struct token *token) +{ + if (token->type != IDENT) + return next(token, 1); //&ctx->tokens[ctx->token_count - 1]; + + token = parse_declaration(ctx, token); + token = parse_definition(ctx, token); + expect(token, NEWLINE); + return next(token, 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 EQUAL: - case NEWLINE: - case SOMETHING: - case EOL: - default: - expect(token, SOMETHING); - } + while (token->type != END) + token = parse_block(ctx, token); - return NULL; + return token; } struct node *tree_create(void) @@ -126,7 +142,7 @@ struct node *tree_create(void) void tree_add(struct ctx *ctx, enum node_type type, void *data) { assert(ctx->tree.head); - struct node *node = malloc(sizeof(*node)); + struct node *node = calloc(sizeof(*node), 1); node->type = type; node->data = data; if (!ctx->tree.current) { @@ -139,23 +155,33 @@ void tree_add(struct ctx *ctx, enum node_type type, void *data) ctx->tree.current = node; } -void tree_destroy(struct node *tree) +void tree_destroy(struct node *node) { - // TODO: Destroy nodes - free(tree); + while (node) { + struct node *next = node->next; + + if (node->type == DEFINITION) { + struct node_definition *definition = node->data; + free(definition->parameters); + free(definition); + } else if (node->type == DECLARATION) { + struct node_declaration *declaration = node->data; + free(declaration->parameters); + free(declaration); + } + + free(node); + node = next; + } } void treeify(struct ctx *ctx) { - struct token *token = &ctx->tokens[1]; - while (token) { - if (token->type == NEWLINE || token->type == EOL) { - token = next(token, 1); - continue; - } - if (token->type == END || token->type == UNKNOWN) - break; + struct token *token = ctx->tokens; - token = parse(ctx, token); - } + while (token->type == NEWLINE) + token = next(token, 1); + + token = parse(ctx, token); + expect(token, END); } |