diff options
author | Quinn Stephens <quinn@osmora.org> | 2025-06-09 21:49:07 -0400 |
---|---|---|
committer | Quinn Stephens <quinn@osmora.org> | 2025-06-09 21:49:07 -0400 |
commit | 065d60fc962136d03a8a74eb235901aa14d87593 (patch) | |
tree | 0c70b18522c1bcb0288db886d7a9b429481b6121 | |
parent | 6ff31c0dbf2f5485604936de3e6457794554fb75 (diff) |
parser: Store symbols in a hashmap
Signed-off-by: Quinn Stephens <quinn@osmora.org>
-rw-r--r-- | include/parser.h | 4 | ||||
-rw-r--r-- | src/main.c | 39 | ||||
-rw-r--r-- | src/parser/parser.c | 36 |
3 files changed, 60 insertions, 19 deletions
diff --git a/include/parser.h b/include/parser.h index d0dadbe..a362613 100644 --- a/include/parser.h +++ b/include/parser.h @@ -30,11 +30,13 @@ #ifndef _PARSER_H #define _PARSER_H 1 +#include "hashmap.h" #include "lexer.h" struct parser { struct lexer *lexer; struct token tok; + struct hashmap syms; }; static inline bool @@ -43,6 +45,6 @@ parser_advance(struct parser *ctx) return lexer_next(ctx->lexer, &ctx->tok); } -bool parser_parse(struct lexer *lexer); +bool parser_parse(struct parser *ctx); #endif /* !_PARSER_H */ @@ -31,13 +31,43 @@ #include "lexer.h" #include "log.h" #include "parser.h" +#include "parser/ast.h" static const char *src = "void test();\nint main();"; +static void +print_func(struct ast_node *func) +{ + log_debug("found function \"%.*s\" (return type %s)\n", func->name_len, func->name, func->type->name); +} + +static void +print_syms(struct hashmap *syms) +{ + struct list *list; + struct ast_node *node; + + /* Iterate hashmap rows */ + for (size_t r = 0; r < syms->row_count; r++) { + /* Iterate row entries */ + list = &syms->rows[r]; + node = (struct ast_node *)list->head; + while (node != (struct ast_node *)list) { + if (node->kind == NOK_FUNCTION) { + print_func(node); + } + + node = (struct ast_node *)node->hashmap_entry.list_entry.next; + } + } +} + int main(int argc, char **argv) { struct lexer lexer; + struct parser parser; + bool success; (void)argc; (void)argv; @@ -47,9 +77,12 @@ main(int argc, char **argv) return EXIT_FAILURE; } - if (!parser_parse(&lexer)) { - return EXIT_FAILURE; + parser.lexer = &lexer; + parser.syms.rows = NULL; + success = parser_parse(&parser); + if (parser.syms.rows != NULL) { + print_syms(&parser.syms); } - return EXIT_SUCCESS; + return success ? EXIT_SUCCESS:EXIT_FAILURE; } diff --git a/src/parser/parser.c b/src/parser/parser.c index d8b1982..4f8543c 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -35,6 +35,8 @@ #include "parser/ast.h" #include "parser/types.h" +#define SYMS_HASHMAP_ROWS 16 + static void tok_error(struct token *tok, const char *fmt, ...) { @@ -49,6 +51,8 @@ tok_error(struct token *tok, const char *fmt, ...) static bool parse_func_decl(struct parser *ctx, struct ast_node *func) { + func->kind = NOK_FUNCTION; + /* * TODO: Parse parameters. */ @@ -69,12 +73,7 @@ parse_func_decl(struct parser *ctx, struct ast_node *func) return false; } - /* - * TODO: Keep track of nodes. - */ - log_debug("Parsed function \"%.*s\" (return type %s)\n", func->name_len, func->name, func->type->name); - free(func); - + hashmap_add(ctx->syms, &func->hashmap_entry); parser_advance(ctx); return true; } @@ -130,27 +129,34 @@ parse_decl(struct parser *ctx) } bool -parser_parse(struct lexer *lexer) +parser_parse(struct parser *ctx) { - struct parser ctx; bool success; log_debug("parsing...\n"); - ctx.lexer = lexer; - if (!parser_advance(&ctx)) { + if (!parser_advance(ctx)) { log_error("failed to get first token\n"); return false; } - while (ctx.tok.kind != TOK_EOF) { - if (ctx.tok.kind == TOK_UNKNOWN) { - tok_error(&ctx.tok, "unrecognized token\n"); + ctx->syms.rows = malloc(SYMS_HASHMAP_ROWS * sizeof(struct list)); + if (ctx->syms.rows == NULL) { + log_error("failed to allocate memory for symbol hashmap\n"); + return false; + } + + ctx->syms.row_count = SYMS_HASHMAP_ROWS; + hashmap_init(ctx->syms); + + while (ctx->tok.kind != TOK_EOF) { + if (ctx->tok.kind == TOK_UNKNOWN) { + tok_error(&ctx->tok, "unrecognized token\n"); return false; } - if ((ctx.tok.flags & TF_BUILTIN_TYPE) || ctx.tok.kind == TOK_IDENTIFIER) { - success = parse_decl(&ctx); + if ((ctx->tok.flags & TF_BUILTIN_TYPE) || ctx->tok.kind == TOK_IDENTIFIER) { + success = parse_decl(ctx); } if (!success) { |