220 lines
12 KiB
C
220 lines
12 KiB
C
// Kyler Olsen
|
|
// YREA SLS
|
|
// Lexer Tests
|
|
// October 2025
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#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;
|
|
}
|