diff options
-rw-r--r-- | compiler/hashmap.c | 16 | ||||
-rw-r--r-- | compiler/lexer/lexer.c | 2 | ||||
-rw-r--r-- | compiler/main.c | 11 | ||||
-rw-r--r-- | compiler/parser/type.c | 89 | ||||
-rw-r--r-- | include/hashmap.h | 1 | ||||
-rw-r--r-- | include/parser/type.h | 2 |
6 files changed, 61 insertions, 60 deletions
diff --git a/compiler/hashmap.c b/compiler/hashmap.c index 0fb2e14..e5aed7b 100644 --- a/compiler/hashmap.c +++ b/compiler/hashmap.c @@ -5,6 +5,7 @@ */ #include <stddef.h> +#include <stdlib.h> #include "hashmap.h" void @@ -31,6 +32,21 @@ hashmap_find(struct hashmap *map, hash_t hash) } void +hashmap_free_entries(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; + } + } +} + +void hashmap_init(struct hashmap *map) { for (size_t r = 0; r < map->n_rows; r++) { diff --git a/compiler/lexer/lexer.c b/compiler/lexer/lexer.c index 06f7e89..2eaa067 100644 --- a/compiler/lexer/lexer.c +++ b/compiler/lexer/lexer.c @@ -103,7 +103,7 @@ lex_oper(struct lexer *ctx, struct token *tok) if (ctx->pos[1] == '>') { tok->kind = TK_ARROW; tok->len = 2; - } if (ctx->pos[1] == '-') { + } else if (ctx->pos[1] == '-') { tok->kind = TK_MINUS_MINUS; tok->len = 2; } else if (ctx->pos[1] == '=') { diff --git a/compiler/main.c b/compiler/main.c index ada6243..3666859 100644 --- a/compiler/main.c +++ b/compiler/main.c @@ -184,7 +184,7 @@ print_ptrs(int n_ptrs) static void print_alias(struct type *typ) { - printf("alias (%lu bytes, %d pointer(s))", typ->size, typ->n_ptrs); + printf("alias (%lu bytes, %d pointer(s));\n", typ->size, typ->n_ptrs); } static void @@ -207,7 +207,7 @@ print_enum(struct type *typ) } while (mem != (struct enum_member*)&typ->members.rows[r]); } - printf("}"); + printf("}\n"); } static void @@ -232,7 +232,7 @@ print_struct(struct type *typ) } while (mem != (struct struct_member*)&typ->members.rows[r]); } - printf("}"); + printf("}\n"); } static void @@ -251,12 +251,9 @@ print_type(struct type *typ) print_struct(typ); break; default: - printf("(unknown)"); + printf("(unknown);\n"); break; } - - printf(";\n"); - } int 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; +} diff --git a/include/hashmap.h b/include/hashmap.h index 26dfc61..3663754 100644 --- a/include/hashmap.h +++ b/include/hashmap.h @@ -29,6 +29,7 @@ hashmap_remove(struct hashmap_entry *entry) void hashmap_add(struct hashmap *map, struct hashmap_entry *entry); struct hashmap_entry *hashmap_find(struct hashmap *map, hash_t hash); +void hashmap_free_entries(struct hashmap *map); void hashmap_init(struct hashmap *map); #endif /* !_HASHMAP_H */ diff --git a/include/parser/type.h b/include/parser/type.h index 6a939ab..b4c16cb 100644 --- a/include/parser/type.h +++ b/include/parser/type.h @@ -7,6 +7,7 @@ #ifndef _PARSER_TYPE_H #define _PARSER_TYPE_H +#include <stdbool.h> #include <stddef.h> #include "hashmap.h" #include "parser.h" @@ -53,5 +54,6 @@ struct type { }; void parse_type(struct parser *ctx); +bool parse_type_ref(struct parser *ctx, struct type **typ_out, int *n_ptrs_out); #endif /* !_PARSER_TYPE_H */ |