// Kyler Olsen // YREA SLS // Lexer Tests // October 2025 #include #include #include #include #include #include "sls/sls_errors.h" #include "sls/lexer.h" #include "sls/string.h" #include "tests/lexer_test_helpers.h" #include "tests/tests.h" static const size_t NUM_OF_TESTS = 14; // Test cases static TestResult test_empty_statement() { LexerTest test = start_up_test("test_empty_statement", ""); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_hello_world_statement() { LexerTest test = start_up_test("test_hello_world_statement", "\"Hello, World!\" print"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_string_value(&test, result, i++, &(TestStringValue){13, "Hello, World!"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 5, "print"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_add_statement() { LexerTest test = start_up_test("test_add_statement", "3 4 +"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 3})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 4})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "+"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_sub_statement() { LexerTest test = start_up_test("test_sub_statement", "10 3 -"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 10})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 3})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "-"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_mult_statement() { LexerTest test = start_up_test("test_mult_statement", "5 6 *"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 5})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 6})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "*"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_div_statement() { LexerTest test = start_up_test("test_div_statement", "20 4 /"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 20})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 4})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "/"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_add_and_mult_statement() { LexerTest test = start_up_test("test_add_and_mult_statement", "2 3 + 4 *"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 2})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 3})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "+"})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 4})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "*"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_dup_and_mult_statement() { LexerTest test = start_up_test("test_dup_and_mult_statement", "10 dup *"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 10})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "dup"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 1, "*"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_square_fn() { LexerTest test = start_up_test("test_dup_statement", "(Number -- Number) { dup * } ::square fn"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_type_tuple_value(&test, result, i++, &(TestTypeTupleValue){1, (TestIdentifierValue[]){(TestIdentifierValue){TRUE, 6, "Number"}}, 1, (TestIdentifierValue[]){(TestIdentifierValue){TRUE, 6, "Number"}}})) return test.result; if (test_token_string_value(&test, result, i++, &(TestTokenStringValue){3, (TestTokenStringToken[]){ (TestTokenStringToken){(Boolean (*)(LexerTest *, LexerResult, size_t, void *))test_identifier_value, &(TestIdentifierValue){FALSE, 3, "dup"}}, (TestTokenStringToken){(Boolean (*)(LexerTest *, LexerResult, size_t, void *))test_identifier_value, &(TestIdentifierValue){FALSE, 1, "*"}} }})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){TRUE, 6, "square"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 2, "fn"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_dup_statement() { LexerTest test = start_up_test("test_dup_statement", "5 dup"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 5})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "dup"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_swap_statement() { LexerTest test = start_up_test("test_swap_statement", "5 10 swap"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 5})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 10})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "swap"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_over_statement() { LexerTest test = start_up_test("test_over_statement", "5 10 over"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 5})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 10})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "over"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_rot_statement() { LexerTest test = start_up_test("test_rot_statement", "1 2 3 rot"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 1})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 2})) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 3})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "rot"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } static TestResult test_swap_and_rot_statement() { LexerTest test = start_up_test("test_swap_and_rot_statement", "swap rot rot"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); size_t i = 0; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "swap"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "rot"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 3, "rot"})) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result; return pass_test(&test, result); } // Lexer Tests Runner TestsReport run_lexer_tests() { TestsReport test_report = (TestsReport) { .section = "lexer_tests", .count = NUM_OF_TESTS, .tests = (TestResult *)malloc(sizeof(TestResult) * NUM_OF_TESTS), }; size_t i = 0; test_report.tests[i++] = test_empty_statement(); test_report.tests[i++] = test_hello_world_statement(); test_report.tests[i++] = test_add_statement(); test_report.tests[i++] = test_sub_statement(); test_report.tests[i++] = test_mult_statement(); test_report.tests[i++] = test_div_statement(); test_report.tests[i++] = test_add_and_mult_statement(); test_report.tests[i++] = test_dup_and_mult_statement(); test_report.tests[i++] = test_square_fn(); test_report.tests[i++] = test_dup_statement(); test_report.tests[i++] = test_swap_statement(); test_report.tests[i++] = test_over_statement(); test_report.tests[i++] = test_rot_statement(); test_report.tests[i++] = test_swap_and_rot_statement(); return test_report; }