Compare commits
5 Commits
b38b5d220a
...
347512e599
Author | SHA1 | Date | |
---|---|---|---|
347512e599 | |||
abf5e3063a | |||
ac45c1ea84 | |||
b514f5d78b | |||
2710784872 |
@ -1,5 +1,6 @@
|
|||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -59,12 +60,19 @@ error_t *symbol_table_get_node_info(ast_node_t *node, symbol_kind_t *kind,
|
|||||||
case NODE_LABEL:
|
case NODE_LABEL:
|
||||||
*kind = SYMBOL_LOCAL;
|
*kind = SYMBOL_LOCAL;
|
||||||
*name = node->children[0]->token_entry->token.value;
|
*name = node->children[0]->token_entry->token.value;
|
||||||
break;
|
return nullptr;
|
||||||
case NODE_LABEL_REFERENCE:
|
case NODE_LABEL_REFERENCE:
|
||||||
*kind = SYMBOL_REFERENCE;
|
*kind = SYMBOL_REFERENCE;
|
||||||
*name = node->token_entry->token.value;
|
*name = node->token_entry->token.value;
|
||||||
break;
|
return nullptr;
|
||||||
// TODO: when .import and .export directives are created add them here
|
case NODE_IMPORT_DIRECTIVE:
|
||||||
|
*kind = SYMBOL_IMPORT;
|
||||||
|
*name = node->children[1]->token_entry->token.value;
|
||||||
|
return nullptr;
|
||||||
|
case NODE_EXPORT_DIRECTIVE:
|
||||||
|
*kind = SYMBOL_EXPORT;
|
||||||
|
*name = node->children[1]->token_entry->token.value;
|
||||||
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
return err_symbol_table_invalid_node;
|
return err_symbol_table_invalid_node;
|
||||||
}
|
}
|
||||||
@ -117,6 +125,8 @@ error_t *symbol_table_add(symbol_table_t *table, char *name, symbol_kind_t kind,
|
|||||||
.node = node,
|
.node = node,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
table->len += 1;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ parse_result_t parse_register_expression(tokenlist_entry_t *current) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parse_result_t parse_immediate(tokenlist_entry_t *current) {
|
parse_result_t parse_immediate(tokenlist_entry_t *current) {
|
||||||
parser_t parsers[] = {parse_number, parse_identifier, nullptr};
|
parser_t parsers[] = {parse_number, parse_label_reference, nullptr};
|
||||||
parse_result_t result = parse_any(current, parsers);
|
parse_result_t result = parse_any(current, parsers);
|
||||||
return parse_result_wrap(NODE_IMMEDIATE, result);
|
return parse_result_wrap(NODE_IMMEDIATE, result);
|
||||||
}
|
}
|
||||||
|
12
tests/input/symbols.asm
Normal file
12
tests/input/symbols.asm
Normal file
@ -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
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
extern MunitTest ast_tests[];
|
extern MunitTest ast_tests[];
|
||||||
extern MunitTest lexer_tests[];
|
extern MunitTest lexer_tests[];
|
||||||
|
extern MunitTest symbols_tests[];
|
||||||
|
|
||||||
int main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
int main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||||
MunitSuite suites[] = {
|
MunitSuite suites[] = {
|
||||||
{"/ast", ast_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE},
|
{"/ast", ast_tests, nullptr, 1, MUNIT_SUITE_OPTION_NONE},
|
||||||
{"/lexer", lexer_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},
|
{nullptr, nullptr, nullptr, 0, MUNIT_SUITE_OPTION_NONE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
175
tests/symbols.c
Normal file
175
tests/symbols.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#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 <string.h>
|
||||||
|
|
||||||
|
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_int(reference->id, ==, NODE_LABEL_REFERENCE);
|
||||||
|
munit_assert_size(table->len, ==, 0);
|
||||||
|
|
||||||
|
error_t *err = symbol_table_update(table, reference);
|
||||||
|
munit_assert_null(err);
|
||||||
|
munit_assert_size(table->len, ==, 1);
|
||||||
|
|
||||||
|
symbol_t *symbol = symbol_table_lookup(table, "test");
|
||||||
|
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");
|
||||||
|
|
||||||
|
symbol_table_free(table);
|
||||||
|
ast_node_free(root);
|
||||||
|
tokenlist_free(list);
|
||||||
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
MunitResult test_symbol_add_label(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 *label = root->children[2];
|
||||||
|
munit_assert_int(label->id, ==, NODE_LABEL);
|
||||||
|
munit_assert_size(table->len, ==, 0);
|
||||||
|
|
||||||
|
error_t *err = symbol_table_update(table, label);
|
||||||
|
munit_assert_null(err);
|
||||||
|
munit_assert_size(table->len, ==, 1);
|
||||||
|
|
||||||
|
symbol_t *symbol = symbol_table_lookup(table, "test");
|
||||||
|
munit_assert_not_null(symbol);
|
||||||
|
munit_assert_int(SYMBOL_LOCAL, ==, symbol->kind);
|
||||||
|
munit_assert_ptr_equal(label, symbol->node);
|
||||||
|
munit_assert_string_equal(symbol->name, "test");
|
||||||
|
|
||||||
|
symbol_table_free(table);
|
||||||
|
ast_node_free(root);
|
||||||
|
tokenlist_free(list);
|
||||||
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
MunitResult test_symbol_add_import(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 *import_directive = root->children[0]->children[1];
|
||||||
|
munit_assert_int(import_directive->id, ==, NODE_IMPORT_DIRECTIVE);
|
||||||
|
munit_assert_size(table->len, ==, 0);
|
||||||
|
|
||||||
|
error_t *err = symbol_table_update(table, import_directive);
|
||||||
|
munit_assert_null(err);
|
||||||
|
munit_assert_size(table->len, ==, 1);
|
||||||
|
|
||||||
|
symbol_t *symbol = symbol_table_lookup(table, "test");
|
||||||
|
munit_assert_not_null(symbol);
|
||||||
|
munit_assert_int(SYMBOL_IMPORT, ==, symbol->kind);
|
||||||
|
munit_assert_ptr_equal(import_directive, symbol->node);
|
||||||
|
munit_assert_string_equal(symbol->name, "test");
|
||||||
|
|
||||||
|
symbol_table_free(table);
|
||||||
|
ast_node_free(root);
|
||||||
|
tokenlist_free(list);
|
||||||
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
MunitResult test_symbol_add_export(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 *export_directive = root->children[1]->children[1];
|
||||||
|
munit_assert_int(export_directive->id, ==, NODE_EXPORT_DIRECTIVE);
|
||||||
|
munit_assert_size(table->len, ==, 0);
|
||||||
|
|
||||||
|
error_t *err = symbol_table_update(table, export_directive);
|
||||||
|
munit_assert_null(err);
|
||||||
|
munit_assert_size(table->len, ==, 1);
|
||||||
|
|
||||||
|
symbol_t *symbol = symbol_table_lookup(table, "test");
|
||||||
|
munit_assert_not_null(symbol);
|
||||||
|
munit_assert_int(SYMBOL_EXPORT, ==, symbol->kind);
|
||||||
|
munit_assert_ptr_equal(export_directive, symbol->node);
|
||||||
|
munit_assert_string_equal(symbol->name, "test");
|
||||||
|
|
||||||
|
symbol_table_free(table);
|
||||||
|
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},
|
||||||
|
{"/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},
|
||||||
|
{nullptr, nullptr, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user