From f90cad2b96d99316578c4012d50f3a92b661cb37 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Schaetzen Date: Wed, 29 Apr 2026 11:43:14 +0200 Subject: [PATCH] Use proper public keyword --- v0/parser.c | 33 +++++++++++++++++++++++++++++---- v0/test.c | 3 +++ v0/test_parser.c | 17 +++++++++++++++++ v0/tests/parser_alias_array.c2 | 3 +++ v0/token.c | 2 +- v0/token.h | 1 + 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 v0/tests/parser_alias_array.c2 diff --git a/v0/parser.c b/v0/parser.c index 46c26ca..73dbabe 100644 --- a/v0/parser.c +++ b/v0/parser.c @@ -52,7 +52,7 @@ Module* parser_parse(TokenStream* ts) { t = tokenstream_next(ts); bool is_public = false; - if (t.token == TOKEN_IDENTIFIER && strncmp(t.text.data, "public", t.text.length) == 0) { + if (t.token == TOKEN_PUBLIC) { is_public = true; t = tokenstream_next(ts); } @@ -106,17 +106,34 @@ Module* parser_parse(TokenStream* ts) { } t = tokenstream_next(ts); - if (t.token != TOKEN_IDENTIFIER || strncmp(t.text.data, "int32", t.text.length) != 0) { + + TypeExpression type; + if (t.token == TOKEN_IDENTIFIER && strncmp(t.text.data, "int32", t.text.length) == 0) { + type = (TypeExpression){ .tag = TYPE_EXPRESSION_BUILTIN, .builtin = { .bitSize = 32, .isSigned = true } }; + t = tokenstream_next(ts); + if (t.token == TOKEN_BRACKET_OPEN) { + t = tokenstream_next(ts); + if (t.token != TOKEN_BRACKET_CLOSE) { + log_on_line(&t.location, t.location.column_end, "expected ']'"); + parser_free(module); + return NULL; + } + TypeExpression* inner = malloc(sizeof(TypeExpression)); + *inner = type; + type = (TypeExpression){ .tag = TYPE_EXPRESSION_ARRAY, .array = { .array = inner } }; + t = tokenstream_next(ts); + } + } else { log_on_line(&t.location, t.location.column_end, "expected type"); parser_free(module); return NULL; } - alias.value = (TypeExpression){ .tag = TYPE_EXPRESSION_BUILTIN, .builtin = { .bitSize = 32, .isSigned = true } }; + + alias.value = type; module->aliases[module->alias_count] = alias; module->alias_count++; - t = tokenstream_next(ts); if (t.token != TOKEN_SEMICOLON) { log_on_line(&t.location, t.location.column_end, "expected ';'"); parser_free(module); @@ -128,6 +145,13 @@ Module* parser_parse(TokenStream* ts) { return module; } +void free_type_expression(TypeExpression* expr) { + if (expr->tag == TYPE_EXPRESSION_ARRAY) { + free_type_expression(expr->array.array); + free(expr->array.array); + } +} + void parser_free(Module* module) { if (module == NULL) return; if (module->imports != NULL) { @@ -139,6 +163,7 @@ void parser_free(Module* module) { if (module->aliases != NULL) { for(size_t i = 0; i < module->alias_count; i++) { free((void*)module->aliases[i].name); + free_type_expression(&module->aliases[i].value); } free(module->aliases); } diff --git a/v0/test.c b/v0/test.c index 084d10a..3a0d8d8 100644 --- a/v0/test.c +++ b/v0/test.c @@ -195,6 +195,7 @@ static TestCase s_tests[] = { {"parser_imports", test_parser_imports}, {"parser_public_imports", test_parser_public_imports}, {"parser_alias_simple", test_parser_alias_simple}, + {"parser_alias_array", test_parser_alias_array}, {"log_error", test_log_error}, {"log_on_line", test_log_on_line}, {"log_on_line_variadic", test_log_on_line_variadic}, @@ -222,6 +223,7 @@ int main(int argc, char** argv) { s_currentTestName = s_tests[i].name; log_set_output(log_append); printf("%s...", s_tests[i].name); + fflush(stdout); s_failMsg = NULL; if (setjmp(s_testJmp) == 0) { @@ -237,6 +239,7 @@ int main(int argc, char** argv) { printf(" [FAIL]: %s\n", s_failMsg ? s_failMsg : ""); failedTests[failedCount++] = s_tests[i].name; } + fflush(stdout); } if (s_testSource) free(s_testSource); diff --git a/v0/test_parser.c b/v0/test_parser.c index f986a9b..eae846f 100644 --- a/v0/test_parser.c +++ b/v0/test_parser.c @@ -86,6 +86,7 @@ static void test_parser_public_imports(void) { static void test_parser_alias_simple(void) { Module* m = test_get_ast(); + assert_not_null(m, "expected module to be parsed"); assert_int(1, (int)m->alias_count, "expected correct number of aliases"); AliasDeclaration alias = m->aliases[0]; assert_str("myalias", alias.name, "expected correct alias name"); @@ -93,3 +94,19 @@ static void test_parser_alias_simple(void) { assert_int(32, alias.value.builtin.bitSize, "expected bitSize 32"); assert_true(alias.value.builtin.isSigned, "expected signed"); } + +static void test_parser_alias_array(void) { + Module* m = test_get_ast(); + + assert_not_null(m, "expected module to be parsed"); + assert_int(1, (int)m->alias_count, "expected correct number of aliases"); + AliasDeclaration alias = m->aliases[0]; + assert_str("myalias", alias.name, "expected correct alias name"); + assert_int(TYPE_EXPRESSION_ARRAY, alias.value.tag, "expected correct alias tag"); + TypeExpression* valueType = alias.value.array.array; + assert_not_null(valueType, "expected pointer to array type"); + assert_int(TYPE_EXPRESSION_BUILTIN, valueType->tag, "expected correct type tag"); + assert_int(32, valueType->builtin.bitSize, "expected bitSize 32"); + assert_true(valueType->builtin.isSigned, "expected signed"); +} + diff --git a/v0/tests/parser_alias_array.c2 b/v0/tests/parser_alias_array.c2 new file mode 100644 index 0000000..65139ba --- /dev/null +++ b/v0/tests/parser_alias_array.c2 @@ -0,0 +1,3 @@ +module mymodule; + +alias myalias = int32[]; diff --git a/v0/token.c b/v0/token.c index f65c3e4..7fab939 100644 --- a/v0/token.c +++ b/v0/token.c @@ -26,11 +26,11 @@ typedef struct { const char* keyword; TokenType token; } KeywordMap; - static const KeywordMap keywords[] = { {"module", TOKEN_MODULE}, {"import", TOKEN_IMPORT}, {"alias", TOKEN_ALIAS}, + {"public", TOKEN_PUBLIC}, {"void", TOKEN_VOID}, }; diff --git a/v0/token.h b/v0/token.h index 679d376..da2011f 100644 --- a/v0/token.h +++ b/v0/token.h @@ -15,6 +15,7 @@ typedef enum { TOKEN_IMPORT, TOKEN_SEMICOLON, TOKEN_ALIAS, + TOKEN_PUBLIC, /* Symbols */ TOKEN_PARENT_OPEN,