summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQuinn Stephens <quinn@osmora.org>2025-06-09 21:49:07 -0400
committerQuinn Stephens <quinn@osmora.org>2025-06-09 21:49:07 -0400
commit065d60fc962136d03a8a74eb235901aa14d87593 (patch)
tree0c70b18522c1bcb0288db886d7a9b429481b6121 /src
parent6ff31c0dbf2f5485604936de3e6457794554fb75 (diff)
parser: Store symbols in a hashmap
Signed-off-by: Quinn Stephens <quinn@osmora.org>
Diffstat (limited to 'src')
-rw-r--r--src/main.c39
-rw-r--r--src/parser/parser.c36
2 files changed, 57 insertions, 18 deletions
diff --git a/src/main.c b/src/main.c
index 6487e03..645656c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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) {