summaryrefslogtreecommitdiff
path: root/compiler/parser
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser')
-rw-r--r--compiler/parser/type.c89
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;
+}