Update ast interface

This commit is contained in:
2026-04-29 11:24:42 +02:00
parent 9035cc639c
commit e09bd72441
3 changed files with 29 additions and 15 deletions
+3 -3
View File
@@ -11,7 +11,7 @@
typedef struct { typedef struct {
/** @brief The name of the module being imported. */ /** @brief The name of the module being imported. */
Token module_name; const char* module_name;
/** @brief Whether the import is public or not. */ /** @brief Whether the import is public or not. */
bool is_public; bool is_public;
@@ -53,7 +53,7 @@ struct TypeExpression{
*/ */
typedef struct { typedef struct {
/** @brief The name of the alias. */ /** @brief The name of the alias. */
Token name; const char* name;
/** @brief The value of the alias. */ /** @brief The value of the alias. */
TypeExpression value; TypeExpression value;
@@ -65,7 +65,7 @@ typedef struct {
*/ */
typedef struct { typedef struct {
/** @brief The name of the module. */ /** @brief The name of the module. */
Token name; const char* name;
/** @brief The list of imports in the module. */ /** @brief The list of imports in the module. */
ImportDeclaration* imports; ImportDeclaration* imports;
+19 -5
View File
@@ -22,7 +22,9 @@ Module* parser_parse(TokenStream* ts) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
exit(1); 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->imports = NULL;
module->import_count = 0; module->import_count = 0;
module->aliases = NULL; module->aliases = NULL;
@@ -61,7 +63,11 @@ Module* parser_parse(TokenStream* ts) {
return NULL; return NULL;
} }
module->imports[module->import_count] = (ImportDeclaration){ .module_name = t, .is_public = is_public }; 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 = name, .is_public = is_public };
module->import_count++; module->import_count++;
t = tokenstream_next(ts); 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) { while (t.token == TOKEN_ALIAS) {
AliasDeclaration* new_aliases = realloc(module->aliases, (module->alias_count + 1) * sizeof(AliasDeclaration)); AliasDeclaration* new_aliases = realloc(module->aliases, (module->alias_count + 1) * sizeof(AliasDeclaration));
if (!new_aliases) { if (!new_aliases) {
@@ -88,8 +92,11 @@ Module* parser_parse(TokenStream* ts) {
parser_free(module); parser_free(module);
return NULL; 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; AliasDeclaration alias;
alias.name = t; alias.name = name;
t = tokenstream_next(ts); t = tokenstream_next(ts);
if (t.token != TOKEN_ASSIGN) { if (t.token != TOKEN_ASSIGN) {
@@ -124,10 +131,17 @@ Module* parser_parse(TokenStream* ts) {
void parser_free(Module* module) { void parser_free(Module* module) {
if (module == NULL) return; if (module == NULL) return;
if (module->imports != NULL) { if (module->imports != NULL) {
for(size_t i = 0; i < module->import_count; i++) {
free((void*)module->imports[i].module_name);
}
free(module->imports); free(module->imports);
} }
if (module->aliases != NULL) { if (module->aliases != NULL) {
for(size_t i = 0; i < module->alias_count; i++) {
free((void*)module->aliases[i].name);
}
free(module->aliases); free(module->aliases);
} }
free((void*)module->name);
free(module); free(module);
} }
+7 -7
View File
@@ -8,7 +8,7 @@ static void test_parser_module_name(void) {
Module* m = parser_parse(ts); Module* m = parser_parse(ts);
assert_not_null(m, "expected module to be parsed"); 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); parser_free(m);
tokenstream_close(ts); tokenstream_close(ts);
} }
@@ -58,11 +58,11 @@ static void test_parser_imports(void) {
Module* m = parser_parse(ts); Module* m = parser_parse(ts);
assert_not_null(m, "expected module to be parsed"); 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_not_null(m->imports, "expected imports to be parsed");
assert_int(1, (int)m->import_count, "expected one import"); 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"); assert_false(m->imports[0].is_public, "expected import to not be public");
parser_free(m); parser_free(m);
tokenstream_close(ts); tokenstream_close(ts);
@@ -73,11 +73,11 @@ static void test_parser_public_imports(void) {
Module* m = parser_parse(ts); Module* m = parser_parse(ts);
assert_not_null(m, "expected module to be parsed"); 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_not_null(m->imports, "expected imports to be parsed");
assert_int(1, (int)m->import_count, "expected one import"); 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"); assert_true(m->imports[0].is_public, "expected import to be public");
parser_free(m); parser_free(m);
tokenstream_close(ts); tokenstream_close(ts);
@@ -86,9 +86,9 @@ static void test_parser_public_imports(void) {
static void test_parser_alias_simple(void) { static void test_parser_alias_simple(void) {
Module* m = test_get_ast(); 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]; 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(TYPE_EXPRESSION_BUILTIN, alias.value.tag, "expected correct alias tag");
assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32"); assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32");
assert_true(alias.value.builtin.isSigned, "expected signed"); assert_true(alias.value.builtin.isSigned, "expected signed");