Reworked how tests are defined
This commit is contained in:
parent
bc2247481b
commit
98922385e8
|
|
@ -15,12 +15,10 @@
|
|||
#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", "");
|
||||
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;
|
||||
|
|
@ -28,169 +26,137 @@ static TestResult test_empty_statement() {
|
|||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_hello_world_statement() {
|
||||
LexerTest test = start_up_test("test_hello_world_statement", "\"Hello, World!\" print");
|
||||
static TestResult test_Identifier_Hello() {
|
||||
LexerTest test = start_up_test("test_Identifier_Hello", "Hello");
|
||||
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_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 5, "Hello"})) 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 +");
|
||||
static TestResult test_Identifier_Plus() {
|
||||
LexerTest test = start_up_test("test_Identifier_Plus", "+");
|
||||
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 -");
|
||||
static TestResult test_Identifier_Rotate() {
|
||||
LexerTest test = start_up_test("test_Identifier_Rotate", "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, 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_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_mult_statement() {
|
||||
LexerTest test = start_up_test("test_mult_statement", "5 6 *");
|
||||
static TestResult test_Identifier_Swap_and_Duplicate() {
|
||||
LexerTest test = start_up_test("test_Identifier_Swap_and_Duplicate", "swap 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_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, 4, "swap"})) 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");
|
||||
static TestResult test_Identifier_Depth() {
|
||||
LexerTest test = start_up_test("test_Identifier_Depth", "depth");
|
||||
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, 5, "depth"})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Identifier_Literal_Point() {
|
||||
LexerTest test = start_up_test("test_Identifier_Literal_Point", "::Point");
|
||||
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){TRUE, 5, "Point"})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Identifier_Literal_Multiply() {
|
||||
LexerTest test = start_up_test("test_Identifier_Literal_Multiply", "::*");
|
||||
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){TRUE, 1, "*"})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Identifier_Literal_Name() {
|
||||
LexerTest test = start_up_test("test_Identifier_Literal_Name", "::name");
|
||||
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){TRUE, 4, "name"})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Integer_Default_Decimal_15() {
|
||||
LexerTest test = start_up_test("test_Integer_Default_Decimal_15", "15");
|
||||
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, 15})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Integer_Default_Hex_E1() {
|
||||
LexerTest test = start_up_test("test_Integer_Default_Hex_E1", "0xE1");
|
||||
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, 225})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Integer_Default_Hex_b2() {
|
||||
LexerTest test = start_up_test("test_Integer_Default_Hex_b2", "0xb2");
|
||||
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, 178})) return test.result;
|
||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||
return pass_test(&test, result);
|
||||
}
|
||||
|
||||
static TestResult test_Integer_Default_Binary_1010() {
|
||||
LexerTest test = start_up_test("test_Integer_Default_Binary_1010", "0b1010");
|
||||
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");
|
||||
static TestResult test_Integer_Default_Decimal_2_001_650() {
|
||||
LexerTest test = start_up_test("test_Integer_Default_Decimal_2_001_650", "2_001_650");
|
||||
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_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 2001650})) 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",
|
||||
|
|
@ -200,20 +166,20 @@ TestsReport run_lexer_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();
|
||||
test_report.tests[i++] = test_Empty_Statement();
|
||||
test_report.tests[i++] = test_Identifier_Hello();
|
||||
test_report.tests[i++] = test_Identifier_Plus();
|
||||
test_report.tests[i++] = test_Identifier_Rotate();
|
||||
test_report.tests[i++] = test_Identifier_Swap_and_Duplicate();
|
||||
test_report.tests[i++] = test_Identifier_Depth();
|
||||
test_report.tests[i++] = test_Identifier_Literal_Point();
|
||||
test_report.tests[i++] = test_Identifier_Literal_Multiply();
|
||||
test_report.tests[i++] = test_Identifier_Literal_Name();
|
||||
test_report.tests[i++] = test_Integer_Default_Decimal_15();
|
||||
test_report.tests[i++] = test_Integer_Default_Hex_E1();
|
||||
test_report.tests[i++] = test_Integer_Default_Hex_b2();
|
||||
test_report.tests[i++] = test_Integer_Default_Binary_1010();
|
||||
test_report.tests[i++] = test_Integer_Default_Decimal_2_001_650();
|
||||
|
||||
return test_report;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@
|
|||
# runtime_error:
|
||||
# message: Error message.
|
||||
|
||||
- name: Empty_Statement
|
||||
code: ""
|
||||
tokens: []
|
||||
operations: []
|
||||
stack_final: []
|
||||
|
||||
# Basic Identifiers
|
||||
|
||||
- name: Identifier Hello
|
||||
|
|
@ -188,9 +194,9 @@
|
|||
- type: i64
|
||||
value: 2001650
|
||||
|
||||
- name: Integer i64 Decimal 5
|
||||
- name: Integer i64 Hex 5f
|
||||
- name: Integer i64 Binary 10110
|
||||
# - name: Integer i64 Decimal 5
|
||||
# - name: Integer i64 Hex 5f
|
||||
# - name: Integer i64 Binary 10110
|
||||
|
||||
# Basic Floats
|
||||
# Basic Strings
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
import yaml
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# python3 SLS_Tests/yaml_to_c_tests.py SLS_Tests/cases.yaml SLS_C/tests/lexer_tests.c
|
||||
|
||||
file_headers = """\
|
||||
// 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"
|
||||
|
||||
"""
|
||||
|
||||
main_header = """\
|
||||
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;
|
||||
"""
|
||||
|
||||
# === Helper functions ===
|
||||
|
||||
def sanitize_name(name: str) -> str:
|
||||
"""Convert test name into a valid C function name."""
|
||||
name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
|
||||
name = re.sub(r"_+", "_", name)
|
||||
return f"test_{name}"
|
||||
|
||||
def c_string_literal(s: str) -> str:
|
||||
"""Escape quotes for embedding in C string literals."""
|
||||
return s.replace('"', '\\"')
|
||||
|
||||
def token_to_c_call(token: dict, idx_var="i") -> str:
|
||||
"""Generate a C 'test_*_value' call based on token type."""
|
||||
ttype = token.get("type")
|
||||
value = token.get("value")
|
||||
|
||||
if ttype == "i64":
|
||||
return f'if (test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_I64, {value}}})) return test.result;'
|
||||
elif ttype == "identifier":
|
||||
return f'if (test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})) return test.result;' # type: ignore
|
||||
elif ttype == "identifier_literal":
|
||||
return f'if (test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{TRUE, {len(value)}, "{value}"}})) return test.result;' # type: ignore
|
||||
else:
|
||||
return f'// Unhandled token type: {ttype}'
|
||||
|
||||
def generate_c_test(test: dict) -> str:
|
||||
"""Convert a single YAML test entry to a C test function."""
|
||||
name = sanitize_name(test["name"])
|
||||
code = c_string_literal(test["code"])
|
||||
tokens = test.get("tokens", [])
|
||||
|
||||
# Function header
|
||||
c_code = [f"static TestResult {name}() " "{",
|
||||
f' LexerTest test = start_up_test("{name}", "{code}");',
|
||||
" LexerResult result = lexical_analysis(&test.lexer_info);",
|
||||
" if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);",
|
||||
" size_t i = 0;"]
|
||||
|
||||
# Token checks
|
||||
for token in tokens:
|
||||
c_code.append(" " + token_to_c_call(token))
|
||||
|
||||
# EOF check and return
|
||||
c_code.append(" if (test_eof_value(&test, result, i++, 0)) return test.result;")
|
||||
c_code.append(" return pass_test(&test, result);")
|
||||
c_code.append("}\n")
|
||||
|
||||
return "\n".join(c_code)
|
||||
|
||||
def yaml_to_c_tests(yaml_path: str, output_path: str):
|
||||
"""Convert YAML test cases into C test code."""
|
||||
with open(yaml_path, "r", encoding="utf-8") as f:
|
||||
tests = yaml.safe_load(f)
|
||||
|
||||
# Ensure we have a list of tests
|
||||
if not isinstance(tests, list):
|
||||
raise ValueError("Expected a YAML list of test cases.")
|
||||
|
||||
c_tests = []
|
||||
for test in tests:
|
||||
c_tests.append(generate_c_test(test))
|
||||
|
||||
program = [
|
||||
file_headers,
|
||||
f"static const size_t NUM_OF_TESTS = {len(tests)};",
|
||||
"\n".join(c_tests),
|
||||
main_header,
|
||||
] + [f" test_report.tests[i++] = {sanitize_name(test['name'])}();" for test in tests]
|
||||
program.append("\n return test_report;\n}\n")
|
||||
|
||||
output_code = "\n".join(program)
|
||||
Path(output_path).write_text(output_code, encoding="utf-8")
|
||||
print(f" Generated {len(c_tests)} C tests -> {output_path}")
|
||||
|
||||
# === Example usage ===
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Convert YAML SLS tests to C lexer tests.")
|
||||
parser.add_argument("input", help="Path to input YAML test file")
|
||||
parser.add_argument("output", help="Path to output C file")
|
||||
args = parser.parse_args()
|
||||
yaml_to_c_tests(args.input, args.output)
|
||||
Loading…
Reference in New Issue