|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include "../ir/ir.h"
|
|
#include "../runtime/labeltable.h"
|
|
|
|
static int tests_passed = 0;
|
|
|
|
#define TEST(name) static void test_##name(void)
|
|
#define RUN_TEST(name) do { \
|
|
printf("Running %s... ", #name); \
|
|
test_##name(); \
|
|
printf("PASSED\n"); \
|
|
tests_passed++; \
|
|
} while(0)
|
|
|
|
TEST(create_empty) {
|
|
RavaInstructionList_t* list = rava_instruction_list_create();
|
|
LabelTable_t* table = rava_labeltable_create(list);
|
|
assert(table != NULL);
|
|
rava_labeltable_destroy(table);
|
|
rava_instruction_list_destroy(list);
|
|
}
|
|
|
|
TEST(create_null) {
|
|
LabelTable_t* table = rava_labeltable_create(NULL);
|
|
assert(table == NULL);
|
|
}
|
|
|
|
TEST(single_label) {
|
|
RavaInstructionList_t* list = rava_instruction_list_create();
|
|
|
|
RavaInstruction_t instr1 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 10};
|
|
RavaInstruction_t instr2 = {.opcode = RAVA_OP_LABEL, .operand.label_id = 0};
|
|
RavaInstruction_t instr3 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 20};
|
|
|
|
rava_instruction_list_add(list, instr1);
|
|
rava_instruction_list_add(list, instr2);
|
|
rava_instruction_list_add(list, instr3);
|
|
|
|
LabelTable_t* table = rava_labeltable_create(list);
|
|
assert(table != NULL);
|
|
|
|
size_t pc = rava_labeltable_lookup(table, 0);
|
|
assert(pc == 2);
|
|
|
|
rava_labeltable_destroy(table);
|
|
rava_instruction_list_destroy(list);
|
|
}
|
|
|
|
TEST(multiple_labels) {
|
|
RavaInstructionList_t* list = rava_instruction_list_create();
|
|
|
|
RavaInstruction_t instr0 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 0};
|
|
RavaInstruction_t label0 = {.opcode = RAVA_OP_LABEL, .operand.label_id = 0};
|
|
RavaInstruction_t instr1 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 1};
|
|
RavaInstruction_t label1 = {.opcode = RAVA_OP_LABEL, .operand.label_id = 1};
|
|
RavaInstruction_t instr2 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 2};
|
|
RavaInstruction_t label2 = {.opcode = RAVA_OP_LABEL, .operand.label_id = 2};
|
|
|
|
rava_instruction_list_add(list, instr0);
|
|
rava_instruction_list_add(list, label0);
|
|
rava_instruction_list_add(list, instr1);
|
|
rava_instruction_list_add(list, label1);
|
|
rava_instruction_list_add(list, instr2);
|
|
rava_instruction_list_add(list, label2);
|
|
|
|
LabelTable_t* table = rava_labeltable_create(list);
|
|
assert(table != NULL);
|
|
|
|
assert(rava_labeltable_lookup(table, 0) == 2);
|
|
assert(rava_labeltable_lookup(table, 1) == 4);
|
|
assert(rava_labeltable_lookup(table, 2) == 6);
|
|
|
|
rava_labeltable_destroy(table);
|
|
rava_instruction_list_destroy(list);
|
|
}
|
|
|
|
TEST(missing_label) {
|
|
RavaInstructionList_t* list = rava_instruction_list_create();
|
|
|
|
RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 5};
|
|
rava_instruction_list_add(list, label);
|
|
|
|
LabelTable_t* table = rava_labeltable_create(list);
|
|
assert(table != NULL);
|
|
|
|
assert(rava_labeltable_lookup(table, 0) == 0);
|
|
assert(rava_labeltable_lookup(table, 1) == 0);
|
|
assert(rava_labeltable_lookup(table, 5) == 1);
|
|
|
|
rava_labeltable_destroy(table);
|
|
rava_instruction_list_destroy(list);
|
|
}
|
|
|
|
TEST(out_of_range) {
|
|
RavaInstructionList_t* list = rava_instruction_list_create();
|
|
|
|
RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 2};
|
|
rava_instruction_list_add(list, label);
|
|
|
|
LabelTable_t* table = rava_labeltable_create(list);
|
|
assert(table != NULL);
|
|
|
|
assert(rava_labeltable_lookup(table, 100) == 0);
|
|
assert(rava_labeltable_lookup(table, -1) == 0);
|
|
|
|
rava_labeltable_destroy(table);
|
|
rava_instruction_list_destroy(list);
|
|
}
|
|
|
|
int main(void) {
|
|
printf("=== Label Table Unit Tests ===\n\n");
|
|
|
|
RUN_TEST(create_empty);
|
|
RUN_TEST(create_null);
|
|
RUN_TEST(single_label);
|
|
RUN_TEST(multiple_labels);
|
|
RUN_TEST(missing_label);
|
|
RUN_TEST(out_of_range);
|
|
|
|
printf("\n=== Results: %d tests passed ===\n", tests_passed);
|
|
return 0;
|
|
}
|