Implement public import parsing and add test case
This commit is contained in:
@@ -56,6 +56,12 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
module->imports = new_imports;
|
module->imports = new_imports;
|
||||||
|
|
||||||
t = tokenstream_next(ts);
|
t = tokenstream_next(ts);
|
||||||
|
bool is_public = false;
|
||||||
|
if (t.token == TOKEN_IDENTIFIER && strncmp(t.text.data, "public", t.text.length) == 0) {
|
||||||
|
is_public = true;
|
||||||
|
t = tokenstream_next(ts);
|
||||||
|
}
|
||||||
|
|
||||||
if (t.token != TOKEN_IDENTIFIER) {
|
if (t.token != TOKEN_IDENTIFIER) {
|
||||||
log_on_line(&t.location, t.location.column_end, "expected module name to import");
|
log_on_line(&t.location, t.location.column_end, "expected module name to import");
|
||||||
parser_free(module);
|
parser_free(module);
|
||||||
@@ -69,6 +75,7 @@ Module* parser_parse(TokenStream* ts) {
|
|||||||
}
|
}
|
||||||
memcpy(module->imports[module->import_count].module_name, t.text.data, t.text.length);
|
memcpy(module->imports[module->import_count].module_name, t.text.data, t.text.length);
|
||||||
module->imports[module->import_count].module_name[t.text.length] = '\0';
|
module->imports[module->import_count].module_name[t.text.length] = '\0';
|
||||||
|
module->imports[module->import_count].is_public = is_public;
|
||||||
module->import_count++;
|
module->import_count++;
|
||||||
|
|
||||||
t = tokenstream_next(ts);
|
t = tokenstream_next(ts);
|
||||||
|
|||||||
@@ -75,6 +75,18 @@ void assert_int(int expected, int actual, const char* msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void assert_true(bool condition, const char* msg) {
|
||||||
|
if (!condition) {
|
||||||
|
fail(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assert_false(bool condition, const char* msg) {
|
||||||
|
if (condition) {
|
||||||
|
fail(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void log_append(const char* msg) {
|
static void log_append(const char* msg) {
|
||||||
size_t oldLen = s_logOutput ? strlen(s_logOutput) : 0;
|
size_t oldLen = s_logOutput ? strlen(s_logOutput) : 0;
|
||||||
size_t newLen = oldLen + strlen(msg) + 1;
|
size_t newLen = oldLen + strlen(msg) + 1;
|
||||||
@@ -124,6 +136,7 @@ static TestCase s_tests[] = {
|
|||||||
{"parser_missing_semicolon_import", test_parser_missing_semicolon_import},
|
{"parser_missing_semicolon_import", test_parser_missing_semicolon_import},
|
||||||
{"parser_bad_import_name", test_parser_bad_import_name},
|
{"parser_bad_import_name", test_parser_bad_import_name},
|
||||||
{"parser_imports", test_parser_imports},
|
{"parser_imports", test_parser_imports},
|
||||||
|
{"parser_public_imports", test_parser_public_imports},
|
||||||
{"log_error", test_log_error},
|
{"log_error", test_log_error},
|
||||||
{"log_on_line", test_log_on_line},
|
{"log_on_line", test_log_on_line},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,4 +49,14 @@ void assert_log_file(const char* filepath, const char* msg);
|
|||||||
*/
|
*/
|
||||||
void assert_int(int expected, int actual, const char* msg);
|
void assert_int(int expected, int actual, const char* msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that a condition is true.
|
||||||
|
*/
|
||||||
|
void assert_true(bool condition, const char* msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that a condition is false.
|
||||||
|
*/
|
||||||
|
void assert_false(bool condition, const char* msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -63,6 +63,23 @@ static void test_parser_imports(void) {
|
|||||||
assert_not_null(m->imports, "expected imports to be parsed");
|
assert_not_null(m->imports, "expected imports to be parsed");
|
||||||
assert_int(1, m->import_count, "expected one import");
|
assert_int(1, m->import_count, "expected one import");
|
||||||
assert_str("other_module", m->imports[0].module_name, "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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parser_public_imports(void) {
|
||||||
|
TokenStream* ts = tokenstream_open("test.c", "module my_module; import public other_module;");
|
||||||
|
Module* m = parser_parse(ts);
|
||||||
|
|
||||||
|
assert_not_null(m, "expected module to be parsed");
|
||||||
|
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||||
|
|
||||||
|
assert_not_null(m->imports, "expected imports to be parsed");
|
||||||
|
assert_int(1, m->import_count, "expected one import");
|
||||||
|
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);
|
parser_free(m);
|
||||||
tokenstream_close(ts);
|
tokenstream_close(ts);
|
||||||
|
|||||||
Reference in New Issue
Block a user