|  |  |  | @@ -135,6 +135,101 @@ MunitResult test_symbol_add_import(const MunitParameter params[], void *data) { | 
		
	
		
			
				|  |  |  |  |     return MUNIT_OK; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void test_symbol_update(const char *name, ast_node_t *first, symbol_kind_t first_kind, ast_node_t *second, | 
		
	
		
			
				|  |  |  |  |                         symbol_kind_t second_kind, bool should_succeed, bool should_update) { | 
		
	
		
			
				|  |  |  |  |     symbol_table_t *table = nullptr; | 
		
	
		
			
				|  |  |  |  |     symbol_table_alloc(&table); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     munit_assert_size(table->len, ==, 0); | 
		
	
		
			
				|  |  |  |  |     error_t *err = symbol_table_update(table, first); | 
		
	
		
			
				|  |  |  |  |     munit_assert_null(err); | 
		
	
		
			
				|  |  |  |  |     munit_assert_size(table->len, ==, 1); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     symbol_t *symbol = symbol_table_lookup(table, name); | 
		
	
		
			
				|  |  |  |  |     munit_assert_not_null(symbol); | 
		
	
		
			
				|  |  |  |  |     munit_assert_int(first_kind, ==, symbol->kind); | 
		
	
		
			
				|  |  |  |  |     munit_assert_ptr_equal(first, symbol->node); | 
		
	
		
			
				|  |  |  |  |     munit_assert_string_equal(symbol->name, name); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     err = symbol_table_update(table, second); | 
		
	
		
			
				|  |  |  |  |     if (should_succeed) | 
		
	
		
			
				|  |  |  |  |         munit_assert_null(err); | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         munit_assert_ptr_equal(err, err_symbol_table_incompatible_symbols); | 
		
	
		
			
				|  |  |  |  |     munit_assert_size(table->len, ==, 1); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     symbol = symbol_table_lookup(table, name); | 
		
	
		
			
				|  |  |  |  |     if (should_update) { | 
		
	
		
			
				|  |  |  |  |         munit_assert_not_null(symbol); | 
		
	
		
			
				|  |  |  |  |         munit_assert_int(second_kind, ==, symbol->kind); | 
		
	
		
			
				|  |  |  |  |         munit_assert_ptr_equal(second, symbol->node); | 
		
	
		
			
				|  |  |  |  |         munit_assert_string_equal(symbol->name, name); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         munit_assert_not_null(symbol); | 
		
	
		
			
				|  |  |  |  |         munit_assert_int(first_kind, ==, symbol->kind); | 
		
	
		
			
				|  |  |  |  |         munit_assert_ptr_equal(first, symbol->node); | 
		
	
		
			
				|  |  |  |  |         munit_assert_string_equal(symbol->name, name); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     symbol_table_free(table); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | MunitResult test_symbol_upgrade_valid(const MunitParameter params[], void *data) { | 
		
	
		
			
				|  |  |  |  |     ast_node_t *root; | 
		
	
		
			
				|  |  |  |  |     tokenlist_t *list; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     symbols_setup_test(&root, &list, "tests/input/symbols.asm"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     ast_node_t *reference = root->children[3]->children[1]->children[0]->children[0]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *label = root->children[2]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *import_directive = root->children[0]->children[1]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *export_directive = root->children[1]->children[1]; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // real upgrades | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", reference, SYMBOL_REFERENCE, label, SYMBOL_LOCAL, true, true); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", reference, SYMBOL_REFERENCE, import_directive, SYMBOL_IMPORT, true, true); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", reference, SYMBOL_REFERENCE, export_directive, SYMBOL_EXPORT, true, true); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", label, SYMBOL_LOCAL, export_directive, SYMBOL_EXPORT, true, true); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // identity upgrades | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", reference, SYMBOL_REFERENCE, reference, SYMBOL_REFERENCE, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", label, SYMBOL_LOCAL, label, SYMBOL_LOCAL, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", import_directive, SYMBOL_IMPORT, import_directive, SYMBOL_IMPORT, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", export_directive, SYMBOL_EXPORT, export_directive, SYMBOL_EXPORT, true, false); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // downgrades that are allowed and ignored | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", label, SYMBOL_LOCAL, reference, SYMBOL_REFERENCE, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", import_directive, SYMBOL_IMPORT, reference, SYMBOL_REFERENCE, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", export_directive, SYMBOL_EXPORT, reference, SYMBOL_REFERENCE, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", export_directive, SYMBOL_EXPORT, label, SYMBOL_LOCAL, true, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", import_directive, SYMBOL_IMPORT, label, SYMBOL_LOCAL, true, false); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     ast_node_free(root); | 
		
	
		
			
				|  |  |  |  |     tokenlist_free(list); | 
		
	
		
			
				|  |  |  |  |     return MUNIT_OK; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | MunitResult test_symbol_upgrade_invalid(const MunitParameter params[], void *data) { | 
		
	
		
			
				|  |  |  |  |     ast_node_t *root; | 
		
	
		
			
				|  |  |  |  |     tokenlist_t *list; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     symbols_setup_test(&root, &list, "tests/input/symbols.asm"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     ast_node_t *reference = root->children[3]->children[1]->children[0]->children[0]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *label = root->children[2]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *import_directive = root->children[0]->children[1]; | 
		
	
		
			
				|  |  |  |  |     ast_node_t *export_directive = root->children[1]->children[1]; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // invalid upgrades | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", label, SYMBOL_LOCAL, import_directive, SYMBOL_IMPORT, false, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", export_directive, SYMBOL_EXPORT, import_directive, SYMBOL_IMPORT, false, false); | 
		
	
		
			
				|  |  |  |  |     test_symbol_update("test", import_directive, SYMBOL_IMPORT, export_directive, SYMBOL_EXPORT, false, false); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     ast_node_free(root); | 
		
	
		
			
				|  |  |  |  |     tokenlist_free(list); | 
		
	
		
			
				|  |  |  |  |     return MUNIT_OK; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | MunitResult test_symbol_add_export(const MunitParameter params[], void *data) { | 
		
	
		
			
				|  |  |  |  |     (void)params; | 
		
	
		
			
				|  |  |  |  |     (void)data; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -171,5 +266,7 @@ MunitTest symbols_tests[] = { | 
		
	
		
			
				|  |  |  |  |     {"/add_label",          test_symbol_add_label,          nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, | 
		
	
		
			
				|  |  |  |  |     {"/add_import",         test_symbol_add_import,         nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, | 
		
	
		
			
				|  |  |  |  |     {"/add_export",         test_symbol_add_export,         nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, | 
		
	
		
			
				|  |  |  |  |     {"/upgrade_valid",      test_symbol_upgrade_valid,      nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, | 
		
	
		
			
				|  |  |  |  |     {"/upgrade_invalid",    test_symbol_upgrade_invalid,    nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, | 
		
	
		
			
				|  |  |  |  |     {nullptr,               nullptr,                        nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr} | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
	
		
			
				
					
					| 
							
							
							
						 |  |  |   |