diff options
author | Quinn Stephens <quinn@osmora.org> | 2024-11-03 16:53:16 -0500 |
---|---|---|
committer | Quinn Stephens <quinn@osmora.org> | 2024-11-03 16:53:16 -0500 |
commit | 71b10c1c765196a771ce05216395d6b78892a735 (patch) | |
tree | ea88735919caebb6500d0b3ae78820c083048e25 /compiler/parser | |
parent | 388025e5a7d2d7997926c6a9af8767ca9ccb12bf (diff) |
[compiler] More small refactoring
Signed-off-by: Quinn Stephens <quinn@osmora.org>
Diffstat (limited to 'compiler/parser')
-rw-r--r-- | compiler/parser/type.c | 89 |
1 files changed, 37 insertions, 52 deletions
diff --git a/compiler/parser/type.c b/compiler/parser/type.c index b86ba9c..187a2b0 100644 --- a/compiler/parser/type.c +++ b/compiler/parser/type.c @@ -14,51 +14,6 @@ #define HASHMAP_ROWS 8 -static void -free_all(struct hashmap *map) -{ - struct hashmap_entry *ent, *next; - - for (size_t r = 0; r < map->n_rows; r++) { - ent = (struct hashmap_entry*)map->rows[r].head; - while (ent != (struct hashmap_entry*)&map->rows[r]) { - next = (struct hashmap_entry*)ent->list_entry.next; - free(ent); - ent = next; - } - } -} - -static bool -parse_type_ref(struct parser *ctx, struct type **typ_out, int *n_ptrs_out) -{ - struct type *typ; - int n_ptrs; - - /* Find type */ - typ = (struct type*)hashmap_find(ctx->types, ctx->tok.hash); - if (typ == NULL) { - tok_error(&ctx->tok, "type \"%.*s\" not found\n", (int)ctx->tok.len, ctx->tok.pos); - return false; - } - - /* Find number of pointers */ - n_ptrs = 0; - while (next_token(ctx)->kind == TK_STAR) { - n_ptrs++; - } - - /* Ensure number of pointers is allowed */ - if (typ->size == 0 && n_ptrs < 1) { - tok_error(&ctx->tok, "type \"%.*s\" can only be used in a pointer\n", (int)typ->name_len, typ->name); - return false; - } - - *typ_out = typ; - *n_ptrs_out = n_ptrs; - return true; -} - static bool parse_alias(struct parser *ctx, struct type *typ) { @@ -112,7 +67,7 @@ parse_enum(struct parser *ctx, struct type *typ) next_token(ctx); while (ctx->tok.kind != TK_RBRACE) { if (ctx->tok.kind != TK_IDENTIFIER) { - tok_error(&ctx->tok, "expected enum member name\n"); + tok_error(&ctx->tok, "expected member name or \"}\"\n"); error = true; break; } @@ -130,7 +85,7 @@ parse_enum(struct parser *ctx, struct type *typ) } if (ctx->tok.kind != TK_RBRACE) { - tok_error(&ctx->tok, "expected \",\" or \"}\" after enum member name\n"); + tok_error(&ctx->tok, "expected \",\" or \"}\" after member name\n"); error = true; break; } @@ -138,7 +93,7 @@ parse_enum(struct parser *ctx, struct type *typ) /* Free hashmap data if error occurred */ if (error) { - free_all(&typ->members); + hashmap_free_entries(&typ->members); free(typ->members.rows); return false; } @@ -174,7 +129,7 @@ parse_struct(struct parser *ctx, struct type *typ) next_token(ctx); while (ctx->tok.kind != TK_RBRACE) { if (ctx->tok.kind != TK_IDENTIFIER) { - tok_error(&ctx->tok, "expected type name\n"); + tok_error(&ctx->tok, "expected member type name or \"}\"\n"); error = true; break; } @@ -185,7 +140,7 @@ parse_struct(struct parser *ctx, struct type *typ) } if (ctx->tok.kind != TK_IDENTIFIER) { - tok_error(&ctx->tok, "expected struct member name\n"); + tok_error(&ctx->tok, "expected member name\n"); error = true; break; } @@ -209,7 +164,7 @@ parse_struct(struct parser *ctx, struct type *typ) off += mem->size; if (next_token(ctx)->kind != TK_SEMICOLON) { - tok_error(&ctx->tok, "expected \";\" after struct member name\n"); + tok_error(&ctx->tok, "expected \";\" after member name\n"); error = true; break; } @@ -218,7 +173,7 @@ parse_struct(struct parser *ctx, struct type *typ) /* Free hashmap data if error occurred */ if (error) { - free_all(&typ->members); + hashmap_free_entries(&typ->members); free(typ->members.rows); return false; } @@ -285,3 +240,33 @@ parse_type(struct parser *ctx) /* Add type to parser's registry */ hashmap_add(ctx->types, &typ->hashmap_entry); } + +bool +parse_type_ref(struct parser *ctx, struct type **typ_out, int *n_ptrs_out) +{ + struct type *typ; + int n_ptrs; + + /* Find type */ + typ = (struct type*)hashmap_find(ctx->types, ctx->tok.hash); + if (typ == NULL) { + tok_error(&ctx->tok, "type \"%.*s\" not found\n", (int)ctx->tok.len, ctx->tok.pos); + return false; + } + + /* Find number of pointers */ + n_ptrs = 0; + while (next_token(ctx)->kind == TK_STAR) { + n_ptrs++; + } + + /* Ensure number of pointers is allowed */ + if (typ->size == 0 && n_ptrs < 1) { + tok_error(&ctx->tok, "type \"%.*s\" can only be used in a pointer\n", (int)typ->name_len, typ->name); + return false; + } + + *typ_out = typ; + *n_ptrs_out = n_ptrs; + return true; +} |