summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/hashmap.c16
-rw-r--r--compiler/lexer/lexer.c2
-rw-r--r--compiler/main.c11
-rw-r--r--compiler/parser/type.c89
4 files changed, 58 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;
+}