diff --git a/tests/input/symbols.asm b/tests/input/symbols.asm new file mode 100644 index 0000000..921d90a --- /dev/null +++ b/tests/input/symbols.asm @@ -0,0 +1,12 @@ +.import test +.export test +test: + call test +.import more +.export more +more: + call more +.import other +.export other +other: + call other diff --git a/tests/main.c b/tests/main.c index d8a79ea..6f168fe 100644 --- a/tests/main.c +++ b/tests/main.c @@ -2,12 +2,14 @@ extern MunitTest ast_tests[]; extern MunitTest lexer_tests[]; +extern MunitTest symbols_tests[]; int main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)]) { MunitSuite suites[] = { - {"/ast", ast_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE}, - {"/lexer", lexer_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE}, - {nullptr, nullptr, nullptr, 0, MUNIT_SUITE_OPTION_NONE}, + {"/ast", ast_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE}, + {"/lexer", lexer_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE}, + {"/symbols", symbols_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE}, + {nullptr, nullptr, nullptr, 0, MUNIT_SUITE_OPTION_NONE}, }; MunitSuite master_suite = {"/oas", nullptr, suites, 1, MUNIT_SUITE_OPTION_NONE}; diff --git a/tests/symbols.c b/tests/symbols.c new file mode 100644 index 0000000..ae1d9b5 --- /dev/null +++ b/tests/symbols.c @@ -0,0 +1,81 @@ +#include "../src/encoder/symbols.h" +#include "../src/ast.h" +#include "../src/error.h" +#include "../src/lexer.h" +#include "../src/parser/parser.h" +#include "munit.h" +#include + +void symbols_setup_test(ast_node_t **node, tokenlist_t **list, char *path) { + lexer_t *lex = &(lexer_t){}; + lexer_open(lex, path); + tokenlist_alloc(list); + tokenlist_fill(*list, lex); + parse_result_t result = parse((*list)->head); + lexer_close(lex); + + *node = result.node; +} + +MunitResult test_symbol_table_alloc(const MunitParameter params[], void *data) { + (void)params; + (void)data; + + symbol_table_t *table = nullptr; + error_t *err = symbol_table_alloc(&table); + + munit_assert_ptr_not_null(table); + munit_assert_ptr_null(err); + munit_assert_size(table->cap, ==, 64); // Default capacity + munit_assert_size(table->len, ==, 0); + munit_assert_ptr_not_null(table->symbols); + + symbol_table_free(table); + return MUNIT_OK; +} + +MunitResult test_symbol_table_lookup_empty(const MunitParameter params[], void *data) { + (void)params; + (void)data; + + symbol_table_t *table = nullptr; + symbol_table_alloc(&table); + + symbol_t *symbol = symbol_table_lookup(table, "nonexistent"); + munit_assert_ptr_null(symbol); + + symbol_table_free(table); + return MUNIT_OK; +} + +MunitResult test_symbol_add_reference(const MunitParameter params[], void *data) { + (void)params; + (void)data; + ast_node_t *root; + tokenlist_t *list; + symbol_table_t *table = nullptr; + symbols_setup_test(&root, &list, "tests/input/symbols.asm"); + symbol_table_alloc(&table); + + ast_node_t *reference = root->children[3]->children[1]->children[0]->children[0]; + munit_assert_size(table->len, ==, 0); + error_t *err = symbol_table_update(table, reference); + munit_assert_null(err); + symbol_t *symbol = symbol_table_lookup(table, "test"); + munit_assert_size(table->len, ==, 1); + munit_assert_not_null(symbol); + munit_assert_int(SYMBOL_REFERENCE, ==, symbol->kind); + munit_assert_ptr_equal(reference, symbol->node); + munit_assert_string_equal(symbol->name, "test"); + + ast_node_free(root); + tokenlist_free(list); + return MUNIT_OK; +} + +MunitTest symbols_tests[] = { + {"/table_alloc", test_symbol_table_alloc, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, + {"/table_lookup_empty", test_symbol_table_lookup_empty, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, + {"/add_reference", test_symbol_add_reference, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, + {nullptr, nullptr, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr} +};