diff --git a/v0/ast.h b/v0/ast.h index cd6d270..b6010ed 100644 --- a/v0/ast.h +++ b/v0/ast.h @@ -11,7 +11,7 @@ typedef struct { /** @brief The name of the module being imported. */ - Token module_name; + const char* module_name; /** @brief Whether the import is public or not. */ bool is_public; @@ -53,7 +53,7 @@ struct TypeExpression{ */ typedef struct { /** @brief The name of the alias. */ - Token name; + const char* name; /** @brief The value of the alias. */ TypeExpression value; @@ -65,7 +65,7 @@ typedef struct { */ typedef struct { /** @brief The name of the module. */ - Token name; + const char* name; /** @brief The list of imports in the module. */ ImportDeclaration* imports; diff --git a/v0/parser.c b/v0/parser.c index d10c58e..46c26ca 100644 --- a/v0/parser.c +++ b/v0/parser.c @@ -22,7 +22,9 @@ Module* parser_parse(TokenStream* ts) { fprintf(stderr, "Out of memory\n"); exit(1); } - module->name = t; + module->name = (const char*)malloc(t.text.length + 1); + memcpy((void*)module->name, t.text.data, t.text.length); + ((char*)module->name)[t.text.length] = '\0'; module->imports = NULL; module->import_count = 0; module->aliases = NULL; @@ -60,8 +62,12 @@ Module* parser_parse(TokenStream* ts) { parser_free(module); return NULL; } + + char* name = (char*)malloc(t.text.length + 1); + memcpy(name, t.text.data, t.text.length); + name[t.text.length] = '\0'; - module->imports[module->import_count] = (ImportDeclaration){ .module_name = t, .is_public = is_public }; + module->imports[module->import_count] = (ImportDeclaration){ .module_name = name, .is_public = is_public }; module->import_count++; t = tokenstream_next(ts); @@ -72,8 +78,6 @@ Module* parser_parse(TokenStream* ts) { } } - // Now t holds the first non-import token. If it's not TOKEN_ALIAS, return. - // If it is, process it. while (t.token == TOKEN_ALIAS) { AliasDeclaration* new_aliases = realloc(module->aliases, (module->alias_count + 1) * sizeof(AliasDeclaration)); if (!new_aliases) { @@ -88,8 +92,11 @@ Module* parser_parse(TokenStream* ts) { parser_free(module); return NULL; } + char* name = (char*)malloc(t.text.length + 1); + memcpy(name, t.text.data, t.text.length); + name[t.text.length] = '\0'; AliasDeclaration alias; - alias.name = t; + alias.name = name; t = tokenstream_next(ts); if (t.token != TOKEN_ASSIGN) { @@ -124,10 +131,17 @@ Module* parser_parse(TokenStream* ts) { void parser_free(Module* module) { if (module == NULL) return; if (module->imports != NULL) { + for(size_t i = 0; i < module->import_count; i++) { + free((void*)module->imports[i].module_name); + } free(module->imports); } if (module->aliases != NULL) { + for(size_t i = 0; i < module->alias_count; i++) { + free((void*)module->aliases[i].name); + } free(module->aliases); } + free((void*)module->name); free(module); } diff --git a/v0/test_parser.c b/v0/test_parser.c index 75c8a46..f986a9b 100644 --- a/v0/test_parser.c +++ b/v0/test_parser.c @@ -8,7 +8,7 @@ static void test_parser_module_name(void) { Module* m = parser_parse(ts); assert_not_null(m, "expected module to be parsed"); - assert_string("my_module", m->name.text, "expected name 'my_module'"); + assert_str("my_module", m->name, "expected name 'my_module'"); parser_free(m); tokenstream_close(ts); } @@ -58,11 +58,11 @@ static void test_parser_imports(void) { Module* m = parser_parse(ts); assert_not_null(m, "expected module to be parsed"); - assert_string("my_module", m->name.text, "expected name 'my_module'"); + assert_str("my_module", m->name, "expected name 'my_module'"); assert_not_null(m->imports, "expected imports to be parsed"); assert_int(1, (int)m->import_count, "expected one import"); - assert_string("other_module", m->imports[0].module_name.text, "expected import name 'other_module'"); + assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'"); assert_false(m->imports[0].is_public, "expected import to not be public"); parser_free(m); tokenstream_close(ts); @@ -73,11 +73,11 @@ static void test_parser_public_imports(void) { Module* m = parser_parse(ts); assert_not_null(m, "expected module to be parsed"); - assert_string("my_module", m->name.text, "expected name 'my_module'"); + assert_str("my_module", m->name, "expected name 'my_module'"); assert_not_null(m->imports, "expected imports to be parsed"); assert_int(1, (int)m->import_count, "expected one import"); - assert_string("other_module", m->imports[0].module_name.text, "expected import name 'other_module'"); + assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'"); assert_true(m->imports[0].is_public, "expected import to be public"); parser_free(m); tokenstream_close(ts); @@ -86,9 +86,9 @@ static void test_parser_public_imports(void) { static void test_parser_alias_simple(void) { Module* m = test_get_ast(); - assert_int(1, m->alias_count, "expected correct number of aliases"); + assert_int(1, (int)m->alias_count, "expected correct number of aliases"); AliasDeclaration alias = m->aliases[0]; - assert_string("myalias", alias.name.text, "expected correct alias name"); + assert_str("myalias", alias.name, "expected correct alias name"); assert_int(TYPE_EXPRESSION_BUILTIN, alias.value.tag, "expected correct alias tag"); assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32"); assert_true(alias.value.builtin.isSigned, "expected signed");