Got token_string tests converting to C
This commit is contained in:
parent
6d586852d4
commit
ad26c41463
|
|
@ -16,7 +16,7 @@
|
||||||
#include "tests/tests.h"
|
#include "tests/tests.h"
|
||||||
|
|
||||||
|
|
||||||
static const size_t NUM_OF_TESTS = 344;
|
static const size_t NUM_OF_TESTS = 389;
|
||||||
|
|
||||||
static TestResult test_Empty_Statement() {
|
static TestResult test_Empty_Statement() {
|
||||||
LexerTest test = start_up_test(SLS_STR("Empty_Statement"), SLS_STR(""));
|
LexerTest test = start_up_test(SLS_STR("Empty_Statement"), SLS_STR(""));
|
||||||
|
|
@ -2073,6 +2073,16 @@ static TestResult test_Char_Right_Brace() {
|
||||||
return pass_test(&test, result);
|
return pass_test(&test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TestResult test_Char_Escape_Tab() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'"));
|
||||||
|
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_character_value(&test, result, i++, &(uint8_t){9})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Null_character() {
|
static TestResult test_Char_Escape_Null_character() {
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Null character"), SLS_STR("'\\0'"));
|
LexerTest test = start_up_test(SLS_STR("Char Escape Null character"), SLS_STR("'\\0'"));
|
||||||
LexerResult result = lexical_analysis(&test.lexer_info);
|
LexerResult result = lexical_analysis(&test.lexer_info);
|
||||||
|
|
@ -2083,16 +2093,6 @@ static TestResult test_Char_Escape_Null_character() {
|
||||||
return pass_test(&test, result);
|
return pass_test(&test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Backslash() {
|
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'"));
|
|
||||||
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_character_value(&test, result, i++, &(uint8_t){92})) return test.result;
|
|
||||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
|
||||||
return pass_test(&test, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Carriage_return() {
|
static TestResult test_Char_Escape_Carriage_return() {
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Carriage return"), SLS_STR("'\\r'"));
|
LexerTest test = start_up_test(SLS_STR("Char Escape Carriage return"), SLS_STR("'\\r'"));
|
||||||
LexerResult result = lexical_analysis(&test.lexer_info);
|
LexerResult result = lexical_analysis(&test.lexer_info);
|
||||||
|
|
@ -2103,26 +2103,6 @@ static TestResult test_Char_Escape_Carriage_return() {
|
||||||
return pass_test(&test, result);
|
return pass_test(&test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Single_quote() {
|
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''"));
|
|
||||||
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_character_value(&test, result, i++, &(uint8_t){39})) return test.result;
|
|
||||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
|
||||||
return pass_test(&test, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Tab() {
|
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'"));
|
|
||||||
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_character_value(&test, result, i++, &(uint8_t){9})) return test.result;
|
|
||||||
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
|
||||||
return pass_test(&test, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TestResult test_Char_Escape_Newline() {
|
static TestResult test_Char_Escape_Newline() {
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Escape Newline"), SLS_STR("'\\n'"));
|
LexerTest test = start_up_test(SLS_STR("Char Escape Newline"), SLS_STR("'\\n'"));
|
||||||
LexerResult result = lexical_analysis(&test.lexer_info);
|
LexerResult result = lexical_analysis(&test.lexer_info);
|
||||||
|
|
@ -2133,6 +2113,26 @@ static TestResult test_Char_Escape_Newline() {
|
||||||
return pass_test(&test, result);
|
return pass_test(&test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TestResult test_Char_Escape_Backslash() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'"));
|
||||||
|
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_character_value(&test, result, i++, &(uint8_t){92})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_Char_Escape_Single_quote() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''"));
|
||||||
|
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_character_value(&test, result, i++, &(uint8_t){39})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
static TestResult test_Char_Hex_Lowercase_A() {
|
static TestResult test_Char_Hex_Lowercase_A() {
|
||||||
LexerTest test = start_up_test(SLS_STR("Char Hex Lowercase A"), SLS_STR("'\\x61'"));
|
LexerTest test = start_up_test(SLS_STR("Char Hex Lowercase A"), SLS_STR("'\\x61'"));
|
||||||
LexerResult result = lexical_analysis(&test.lexer_info);
|
LexerResult result = lexical_analysis(&test.lexer_info);
|
||||||
|
|
@ -3425,6 +3425,453 @@ static TestResult test_Bool_Three_Values() {
|
||||||
return pass_test(&test, result);
|
return pass_test(&test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Empty() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Empty"), SLS_STR("{ }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){0, NULL})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Single_Integer() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Single Integer"), SLS_STR("{ 42 }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 42}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Single_Identifier() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Single Identifier"), SLS_STR("{ 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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Two_Integers() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Two Integers"), SLS_STR("{ 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Simple_Expression() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Simple Expression"), SLS_STR("{ 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Stack_Ops() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Stack Ops"), SLS_STR("{ 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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Integer_Literals() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Integer Literals"), SLS_STR("{ 0 42 -10 1000 }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){4, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 0}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 42}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, -10}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 1000}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Float_Literals() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Float Literals"), SLS_STR("{ 3.14 -2.5 0.0 }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_double_value, .value = &(double){3.14}}, {.token_handler = test_double_value, .value = &(double){-2.5}}, {.token_handler = test_double_value, .value = &(double){0.0}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Char_Literal() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Char Literal"), SLS_STR("{ 'A' }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_character_value, .value = &(uint8_t){65}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Boolean_Literals() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Boolean Literals"), SLS_STR("{ true false }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_boolean_value, .value = &(Boolean){TRUE}}, {.token_handler = test_boolean_value, .value = &(Boolean){FALSE}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiple_Identifiers() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiple Identifiers"), SLS_STR("{ dup swap 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("swap")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("over")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Identifier_Literals() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Identifier Literals"), SLS_STR("{ ::x ::y }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){TRUE, SLS_STR("x")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){TRUE, SLS_STR("y")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Mixed_Identifiers() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Mixed Identifiers"), SLS_STR("{ ::Point get x 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_token_string_value(&test, result, i, &(TestTokenStringValue){4, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){TRUE, SLS_STR("Point")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("get")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("x")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("swap")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Nested_Single() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Nested Single"), SLS_STR("{ { 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Nested_With_Others() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Nested With Others"), SLS_STR("{ x { 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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("x")}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiple_Nested() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiple Nested"), SLS_STR("{ { 2 3 + } { 4 5 * } }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 4}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 5}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Double_Nested() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Double Nested"), SLS_STR("{ { { 42 } } }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_token_string_value, .value = &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_token_string_value, .value = &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 42}}}}}}}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Complex_Nesting() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Complex Nesting"), SLS_STR("{ 1 { 2 { 3 } 4 } 5 }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 1}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}}}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 4}}}}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 5}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_No_Whitespace() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString No Whitespace"), SLS_STR("{2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Extra_Whitespace() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Extra Whitespace"), SLS_STR("{ 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Leading_Whitespace_Outside() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Leading Whitespace Outside"), SLS_STR(" { 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Trailing_Whitespace_Outside() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Trailing Whitespace Outside"), SLS_STR("{ 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_With_Tabs() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString With Tabs"), SLS_STR("{\t2\t3\t+\t}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiline_Simple() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiline Simple"), SLS_STR("{\n 2 3 +\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiline_Multiple() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiline Multiple"), SLS_STR("{\n dup\n *\n 2\n +\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){4, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Mixed_Line_Breaks() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Mixed Line Breaks"), SLS_STR("{ 1 2\n3 4\n\n5 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_token_string_value(&test, result, i, &(TestTokenStringValue){6, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 1}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 4}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 5}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 6}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Indented_Multiline() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Indented Multiline"), SLS_STR("{\n dup 0 >\n { }\n { 0 swap - }\n if\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){6, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 0}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR(">")}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){0, NULL}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 0}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("swap")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("-")}}}}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("if")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Comment_End_Of_Line() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Comment End Of Line"), SLS_STR("{ 2 3 + // add them\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiple_Comments() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiple Comments"), SLS_STR("{ 2 // first\n3 // second\n+ // add\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Comment_Own_Line() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Comment Own Line"), SLS_STR("{\n // This is a comment\n 2 3 +\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Comment_At_Start() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Comment At Start"), SLS_STR("{ // comment\n2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Multiple_Comment_Lines() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Multiple Comment Lines"), SLS_STR("{\n // First comment\n // Second comment\n 2 3 +\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Comments_Nested() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Comments Nested"), SLS_STR("{ { 2 3 + // inner comment\n} // outer comment\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_token_string_value, .value = &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Unclosed() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Unclosed"), SLS_STR("{ 2 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_for_error(&test, result, i++, SLS_STR("Unclosed token string: missing closing brace '}'."))) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Unclosed_Nested() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Unclosed Nested"), SLS_STR("{ { 2 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_for_error(&test, result, i++, SLS_STR("Unclosed token string: missing closing brace '}'."))) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Extra_Closing_Brace() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Extra Closing Brace"), SLS_STR("{ 2 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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 3}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_for_error(&test, result, i++, SLS_STR("Unexpected closing brace '}' without matching opening brace."))) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Only_Closing_Brace() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Only Closing Brace"), SLS_STR("}"));
|
||||||
|
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_for_error(&test, result, i++, SLS_STR("Unexpected closing brace '}' without matching opening brace."))) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Error_Inside() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Error Inside"), SLS_STR("{ 2 3a + }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){3, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_for_error, .value = SLS_STR("Invalid decimal literal: unexpected 'a' in decimal integer.")}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Unclosed_String_Inside() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Unclosed String Inside"), SLS_STR("{ \"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_token_string_value(&test, result, i, &(TestTokenStringValue){1, (TestTokenValue[]){{.token_handler = test_for_error, .value = SLS_STR("Invalid string literal: unclosed string literal.")}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Function_Body() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Function Body"), SLS_STR("{ 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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Loop_Body() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Loop Body"), SLS_STR("{ dup print 1 + }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){4, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("print")}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 1}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("+")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Struct_Fields() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Struct Fields"), SLS_STR("{ x: y: }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){4, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("x")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR(":")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("y")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR(":")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Lambda() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Lambda"), SLS_STR("{ 2 * }"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 2}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Array_Map() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Array Map"), SLS_STR("{ 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_token_string_value(&test, result, i, &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TestResult test_TokenString_Conditional_Complex() {
|
||||||
|
LexerTest test = start_up_test(SLS_STR("TokenString Conditional Complex"), SLS_STR("{\n dup 0 >\n { dup * }\n { drop 0 }\n if\n}"));
|
||||||
|
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_token_string_value(&test, result, i, &(TestTokenStringValue){6, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 0}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR(">")}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("dup")}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("*")}}}}}, {.token_handler = test_token_string_value, .value = &(TestTokenStringValue){2, (TestTokenValue[]){{.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("drop")}}, {.token_handler = test_integer_value, .value = &(TestIntegerValue){INTEGER_I64, 0}}}}}, {.token_handler = test_identifier_value, .value = &(TestIdentifierValue){FALSE, SLS_STR("if")}}}})) return test.result;
|
||||||
|
if (test_eof_value(&test, result, i++, 0)) return test.result;
|
||||||
|
return pass_test(&test, result);
|
||||||
|
}
|
||||||
|
|
||||||
TestsReport run_lexer_tests() {
|
TestsReport run_lexer_tests() {
|
||||||
TestsReport test_report = (TestsReport) {
|
TestsReport test_report = (TestsReport) {
|
||||||
.section = SLS_STR("lexer_tests"),
|
.section = SLS_STR("lexer_tests"),
|
||||||
|
|
@ -3642,12 +4089,12 @@ TestsReport run_lexer_tests() {
|
||||||
test_report.tests[i++] = test_Char_Right_Bracket();
|
test_report.tests[i++] = test_Char_Right_Bracket();
|
||||||
test_report.tests[i++] = test_Char_Left_Brace();
|
test_report.tests[i++] = test_Char_Left_Brace();
|
||||||
test_report.tests[i++] = test_Char_Right_Brace();
|
test_report.tests[i++] = test_Char_Right_Brace();
|
||||||
test_report.tests[i++] = test_Char_Escape_Null_character();
|
|
||||||
test_report.tests[i++] = test_Char_Escape_Backslash();
|
|
||||||
test_report.tests[i++] = test_Char_Escape_Carriage_return();
|
|
||||||
test_report.tests[i++] = test_Char_Escape_Single_quote();
|
|
||||||
test_report.tests[i++] = test_Char_Escape_Tab();
|
test_report.tests[i++] = test_Char_Escape_Tab();
|
||||||
|
test_report.tests[i++] = test_Char_Escape_Null_character();
|
||||||
|
test_report.tests[i++] = test_Char_Escape_Carriage_return();
|
||||||
test_report.tests[i++] = test_Char_Escape_Newline();
|
test_report.tests[i++] = test_Char_Escape_Newline();
|
||||||
|
test_report.tests[i++] = test_Char_Escape_Backslash();
|
||||||
|
test_report.tests[i++] = test_Char_Escape_Single_quote();
|
||||||
test_report.tests[i++] = test_Char_Hex_Lowercase_A();
|
test_report.tests[i++] = test_Char_Hex_Lowercase_A();
|
||||||
test_report.tests[i++] = test_Char_Hex_Uppercase_A();
|
test_report.tests[i++] = test_Char_Hex_Uppercase_A();
|
||||||
test_report.tests[i++] = test_Char_Hex_Space();
|
test_report.tests[i++] = test_Char_Hex_Space();
|
||||||
|
|
@ -3778,6 +4225,51 @@ TestsReport run_lexer_tests() {
|
||||||
test_report.tests[i++] = test_Bool_Multiple_True_False();
|
test_report.tests[i++] = test_Bool_Multiple_True_False();
|
||||||
test_report.tests[i++] = test_Bool_Multiple_Same();
|
test_report.tests[i++] = test_Bool_Multiple_Same();
|
||||||
test_report.tests[i++] = test_Bool_Three_Values();
|
test_report.tests[i++] = test_Bool_Three_Values();
|
||||||
|
test_report.tests[i++] = test_TokenString_Empty();
|
||||||
|
test_report.tests[i++] = test_TokenString_Single_Integer();
|
||||||
|
test_report.tests[i++] = test_TokenString_Single_Identifier();
|
||||||
|
test_report.tests[i++] = test_TokenString_Two_Integers();
|
||||||
|
test_report.tests[i++] = test_TokenString_Simple_Expression();
|
||||||
|
test_report.tests[i++] = test_TokenString_Stack_Ops();
|
||||||
|
test_report.tests[i++] = test_TokenString_Integer_Literals();
|
||||||
|
test_report.tests[i++] = test_TokenString_Float_Literals();
|
||||||
|
test_report.tests[i++] = test_TokenString_Char_Literal();
|
||||||
|
test_report.tests[i++] = test_TokenString_Boolean_Literals();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiple_Identifiers();
|
||||||
|
test_report.tests[i++] = test_TokenString_Identifier_Literals();
|
||||||
|
test_report.tests[i++] = test_TokenString_Mixed_Identifiers();
|
||||||
|
test_report.tests[i++] = test_TokenString_Nested_Single();
|
||||||
|
test_report.tests[i++] = test_TokenString_Nested_With_Others();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiple_Nested();
|
||||||
|
test_report.tests[i++] = test_TokenString_Double_Nested();
|
||||||
|
test_report.tests[i++] = test_TokenString_Complex_Nesting();
|
||||||
|
test_report.tests[i++] = test_TokenString_No_Whitespace();
|
||||||
|
test_report.tests[i++] = test_TokenString_Extra_Whitespace();
|
||||||
|
test_report.tests[i++] = test_TokenString_Leading_Whitespace_Outside();
|
||||||
|
test_report.tests[i++] = test_TokenString_Trailing_Whitespace_Outside();
|
||||||
|
test_report.tests[i++] = test_TokenString_With_Tabs();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiline_Simple();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiline_Multiple();
|
||||||
|
test_report.tests[i++] = test_TokenString_Mixed_Line_Breaks();
|
||||||
|
test_report.tests[i++] = test_TokenString_Indented_Multiline();
|
||||||
|
test_report.tests[i++] = test_TokenString_Comment_End_Of_Line();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiple_Comments();
|
||||||
|
test_report.tests[i++] = test_TokenString_Comment_Own_Line();
|
||||||
|
test_report.tests[i++] = test_TokenString_Comment_At_Start();
|
||||||
|
test_report.tests[i++] = test_TokenString_Multiple_Comment_Lines();
|
||||||
|
test_report.tests[i++] = test_TokenString_Comments_Nested();
|
||||||
|
test_report.tests[i++] = test_TokenString_Unclosed();
|
||||||
|
test_report.tests[i++] = test_TokenString_Unclosed_Nested();
|
||||||
|
test_report.tests[i++] = test_TokenString_Extra_Closing_Brace();
|
||||||
|
test_report.tests[i++] = test_TokenString_Only_Closing_Brace();
|
||||||
|
test_report.tests[i++] = test_TokenString_Error_Inside();
|
||||||
|
test_report.tests[i++] = test_TokenString_Unclosed_String_Inside();
|
||||||
|
test_report.tests[i++] = test_TokenString_Function_Body();
|
||||||
|
test_report.tests[i++] = test_TokenString_Loop_Body();
|
||||||
|
test_report.tests[i++] = test_TokenString_Struct_Fields();
|
||||||
|
test_report.tests[i++] = test_TokenString_Lambda();
|
||||||
|
test_report.tests[i++] = test_TokenString_Array_Map();
|
||||||
|
test_report.tests[i++] = test_TokenString_Conditional_Complex();
|
||||||
|
|
||||||
return test_report;
|
return test_report;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1526
SLS_Tests/cases.yaml
1526
SLS_Tests/cases.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -3,7 +3,7 @@ from .general_tests import GeneralTestGenerator
|
||||||
from .integer_tests import IntegerTestGenerator
|
from .integer_tests import IntegerTestGenerator
|
||||||
from .float_tests import FloatTestGenerator
|
from .float_tests import FloatTestGenerator
|
||||||
from .char_tests import CharTestGenerator
|
from .char_tests import CharTestGenerator
|
||||||
# from .string_tests import StringTestGenerator
|
from .string_tests import StringTestGenerator
|
||||||
from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator
|
from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator
|
||||||
from .token_strings import TokenStringTestGenerator
|
from .token_strings import TokenStringTestGenerator
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ __all__ = [
|
||||||
"IntegerTestGenerator",
|
"IntegerTestGenerator",
|
||||||
"FloatTestGenerator",
|
"FloatTestGenerator",
|
||||||
"CharTestGenerator",
|
"CharTestGenerator",
|
||||||
# "StringTestGenerator",
|
"StringTestGenerator",
|
||||||
"IdentifierTestGenerator",
|
"IdentifierTestGenerator",
|
||||||
"BooleanTestGenerator",
|
"BooleanTestGenerator",
|
||||||
"TokenStringTestGenerator",
|
"TokenStringTestGenerator",
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ class BaseTestGenerator(ABC):
|
||||||
|
|
||||||
ENABLE_UNICODE = False
|
ENABLE_UNICODE = False
|
||||||
ENABLE_EXPONENTIAL_LITERALS = False
|
ENABLE_EXPONENTIAL_LITERALS = False
|
||||||
|
ENABLE_STRINGS = False
|
||||||
|
|
||||||
__generators: "ClassVar[List[Type[BaseTestGenerator]]]" = []
|
__generators: "ClassVar[List[Type[BaseTestGenerator]]]" = []
|
||||||
|
|
||||||
|
|
@ -365,3 +366,39 @@ class BaseTestGenerator(ABC):
|
||||||
if not self.validate_test_names_unique():
|
if not self.validate_test_names_unique():
|
||||||
duplicates = self.get_duplicate_test_names()
|
duplicates = self.get_duplicate_test_names()
|
||||||
print(f" WARNING: Duplicate test names found: {duplicates}")
|
print(f" WARNING: Duplicate test names found: {duplicates}")
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Token String Helpers
|
||||||
|
# =========================================================================
|
||||||
|
|
||||||
|
def make_token_string_token(self, inner_tokens: List[Token]) -> Token:
|
||||||
|
"""
|
||||||
|
Create a token string token containing inner tokens.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
inner_tokens: List of tokens inside the token string
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Token with type "token_string" and tokens array
|
||||||
|
"""
|
||||||
|
return Token(type="token_string", value=[t.__dict__ for t in inner_tokens])
|
||||||
|
|
||||||
|
def make_token_string_test(self, name: str, code: str, inner_tokens: List[Token]):
|
||||||
|
"""
|
||||||
|
Create a successful token string test.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: Test name
|
||||||
|
code: Source code
|
||||||
|
inner_tokens: Tokens inside the token string
|
||||||
|
"""
|
||||||
|
token = self.make_token_string_token(inner_tokens)
|
||||||
|
|
||||||
|
# For operations, we push the token string as a value
|
||||||
|
op_value = {"tokens": [t.__dict__ for t in inner_tokens]}
|
||||||
|
op = self.make_push_op("token_string", op_value)
|
||||||
|
|
||||||
|
# On the stack, it's a token_string value
|
||||||
|
stack = self.make_stack_item("token_string", op_value)
|
||||||
|
|
||||||
|
self.add_test(name, code, [token], [op], [stack])
|
||||||
|
|
|
||||||
|
|
@ -436,6 +436,10 @@ class StringTestGenerator(BaseTestGenerator):
|
||||||
|
|
||||||
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||||
"""Generate all string literal test cases."""
|
"""Generate all string literal test cases."""
|
||||||
|
|
||||||
|
if not self.ENABLE_STRINGS:
|
||||||
|
return []
|
||||||
|
|
||||||
# Basic tests
|
# Basic tests
|
||||||
self.generate_basic_tests()
|
self.generate_basic_tests()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,38 +5,6 @@ from .base_tests import BaseTestGenerator, Token
|
||||||
class TokenStringTestGenerator(BaseTestGenerator):
|
class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
"""Generate test cases for token strings (unparsed code blocks in braces)."""
|
"""Generate test cases for token strings (unparsed code blocks in braces)."""
|
||||||
|
|
||||||
def make_token_string_token(self, inner_tokens: List[Token]) -> Token:
|
|
||||||
"""
|
|
||||||
Create a token string token containing inner tokens.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
inner_tokens: List of tokens inside the token string
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Token with type "token_string" and tokens array
|
|
||||||
"""
|
|
||||||
return Token(type="token_string", value=[t.__dict__ for t in inner_tokens])
|
|
||||||
|
|
||||||
def make_token_string_test(self, name: str, code: str, inner_tokens: List[Token]):
|
|
||||||
"""
|
|
||||||
Create a successful token string test.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name: Test name
|
|
||||||
code: Source code
|
|
||||||
inner_tokens: Tokens inside the token string
|
|
||||||
"""
|
|
||||||
token = self.make_token_string_token(inner_tokens)
|
|
||||||
|
|
||||||
# For operations, we push the token string as a value
|
|
||||||
op_value = {"tokens": [t.__dict__ for t in inner_tokens]}
|
|
||||||
op = self.make_push_op("token_string", op_value)
|
|
||||||
|
|
||||||
# On the stack, it's a token_string value
|
|
||||||
stack = self.make_stack_item("token_string", op_value)
|
|
||||||
|
|
||||||
self.add_test(name, code, [token], [op], [stack])
|
|
||||||
|
|
||||||
def generate_basic_tests(self):
|
def generate_basic_tests(self):
|
||||||
"""Generate basic token string tests."""
|
"""Generate basic token string tests."""
|
||||||
# Empty token string
|
# Empty token string
|
||||||
|
|
@ -116,20 +84,21 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
)
|
)
|
||||||
|
|
||||||
# String literals
|
# String literals
|
||||||
self.make_token_string_test(
|
if self.ENABLE_STRINGS:
|
||||||
"TokenString String Literal",
|
self.make_token_string_test(
|
||||||
'{ "hello" }',
|
"TokenString String Literal",
|
||||||
[Token(type="String", value="hello")]
|
'{ "hello" }',
|
||||||
)
|
[Token(type="String", value="hello")]
|
||||||
|
)
|
||||||
|
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Multiple Strings",
|
"TokenString Multiple Strings",
|
||||||
'{ "hello" "world" }',
|
'{ "hello" "world" }',
|
||||||
[
|
[
|
||||||
Token(type="String", value="hello"),
|
Token(type="String", value="hello"),
|
||||||
Token(type="String", value="world")
|
Token(type="String", value="world")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Character literals
|
# Character literals
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
|
|
@ -149,17 +118,18 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mixed literals
|
# Mixed literals
|
||||||
self.make_token_string_test(
|
if self.ENABLE_STRINGS:
|
||||||
"TokenString Mixed Literals",
|
self.make_token_string_test(
|
||||||
'{ 42 3.14 "hello" true \'A\' }',
|
"TokenString Mixed Literals",
|
||||||
[
|
'{ 42 3.14 "hello" true \'A\' }',
|
||||||
Token(type="i64", value=42),
|
[
|
||||||
Token(type="f64", value=3.14),
|
Token(type="i64", value=42),
|
||||||
Token(type="String", value="hello"),
|
Token(type="f64", value=3.14),
|
||||||
Token(type="bool", value=True),
|
Token(type="String", value="hello"),
|
||||||
Token(type="char", value='A')
|
Token(type="bool", value=True),
|
||||||
]
|
Token(type="char", value='A')
|
||||||
)
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def generate_identifier_tests(self):
|
def generate_identifier_tests(self):
|
||||||
"""Generate tests with various identifiers inside token strings."""
|
"""Generate tests with various identifiers inside token strings."""
|
||||||
|
|
@ -319,7 +289,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Tabs
|
# Tabs
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString With Tabs",
|
"TokenString With Tabs",
|
||||||
"{\t2\t3\t+\t}",
|
"{\\t2\\t3\\t+\\t}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -332,7 +302,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Simple multiline
|
# Simple multiline
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Multiline Simple",
|
"TokenString Multiline Simple",
|
||||||
"{\n 2 3 +\n}",
|
"{\\n 2 3 +\\n}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -343,7 +313,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Multiple lines with tokens
|
# Multiple lines with tokens
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Multiline Multiple",
|
"TokenString Multiline Multiple",
|
||||||
"{\n dup\n *\n 2\n +\n}",
|
"{\\n dup\\n *\\n 2\\n +\\n}",
|
||||||
[
|
[
|
||||||
Token(type="identifier", value="dup"),
|
Token(type="identifier", value="dup"),
|
||||||
Token(type="identifier", value="*"),
|
Token(type="identifier", value="*"),
|
||||||
|
|
@ -355,7 +325,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Mixed line breaks
|
# Mixed line breaks
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Mixed Line Breaks",
|
"TokenString Mixed Line Breaks",
|
||||||
"{ 1 2\n3 4\n\n5 6 }",
|
"{ 1 2\\n3 4\\n\\n5 6 }",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=1),
|
Token(type="i64", value=1),
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
|
|
@ -369,7 +339,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Indented multiline
|
# Indented multiline
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Indented Multiline",
|
"TokenString Indented Multiline",
|
||||||
"{\n dup 0 >\n { }\n { 0 swap - }\n if\n}",
|
"{\\n dup 0 >\\n { }\\n { 0 swap - }\\n if\\n}",
|
||||||
[
|
[
|
||||||
Token(type="identifier", value="dup"),
|
Token(type="identifier", value="dup"),
|
||||||
Token(type="i64", value=0),
|
Token(type="i64", value=0),
|
||||||
|
|
@ -389,7 +359,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Comment at end of line inside token string
|
# Comment at end of line inside token string
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Comment End Of Line",
|
"TokenString Comment End Of Line",
|
||||||
"{ 2 3 + // add them\n}",
|
"{ 2 3 + // add them\\n}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -400,7 +370,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Multiple comments
|
# Multiple comments
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Multiple Comments",
|
"TokenString Multiple Comments",
|
||||||
"{ 2 // first\n3 // second\n+ // add\n}",
|
"{ 2 // first\\n3 // second\\n+ // add\\n}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -411,7 +381,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Comment on its own line
|
# Comment on its own line
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Comment Own Line",
|
"TokenString Comment Own Line",
|
||||||
"{\n // This is a comment\n 2 3 +\n}",
|
"{\\n // This is a comment\\n 2 3 +\\n}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -422,7 +392,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Comment at start
|
# Comment at start
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Comment At Start",
|
"TokenString Comment At Start",
|
||||||
"{ // comment\n2 3 + }",
|
"{ // comment\\n2 3 + }",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -433,7 +403,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Multiple comment lines
|
# Multiple comment lines
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Multiple Comment Lines",
|
"TokenString Multiple Comment Lines",
|
||||||
"{\n // First comment\n // Second comment\n 2 3 +\n}",
|
"{\\n // First comment\\n // Second comment\\n 2 3 +\\n}",
|
||||||
[
|
[
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
Token(type="i64", value=3),
|
Token(type="i64", value=3),
|
||||||
|
|
@ -444,7 +414,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Comments in nested token strings
|
# Comments in nested token strings
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Comments Nested",
|
"TokenString Comments Nested",
|
||||||
"{ { 2 3 + // inner comment\n} // outer comment\n}",
|
"{ { 2 3 + // inner comment\\n} // outer comment\\n}",
|
||||||
[
|
[
|
||||||
self.make_token_string_token([
|
self.make_token_string_token([
|
||||||
Token(type="i64", value=2),
|
Token(type="i64", value=2),
|
||||||
|
|
@ -545,14 +515,15 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
)
|
)
|
||||||
|
|
||||||
# If statement branches
|
# If statement branches
|
||||||
self.make_token_string_test(
|
if self.ENABLE_STRINGS:
|
||||||
"TokenString If Branches",
|
self.make_token_string_test(
|
||||||
'{ "positive" print }',
|
"TokenString If Branches",
|
||||||
[
|
'{ "positive" print }',
|
||||||
Token(type="String", value="positive"),
|
[
|
||||||
Token(type="identifier", value="print")
|
Token(type="String", value="positive"),
|
||||||
]
|
Token(type="identifier", value="print")
|
||||||
)
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Loop body
|
# Loop body
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
|
|
@ -601,7 +572,7 @@ class TokenStringTestGenerator(BaseTestGenerator):
|
||||||
# Conditional with nested token strings
|
# Conditional with nested token strings
|
||||||
self.make_token_string_test(
|
self.make_token_string_test(
|
||||||
"TokenString Conditional Complex",
|
"TokenString Conditional Complex",
|
||||||
"{\n dup 0 >\n { dup * }\n { drop 0 }\n if\n}",
|
"{\\n dup 0 >\\n { dup * }\\n { drop 0 }\\n if\\n}",
|
||||||
[
|
[
|
||||||
Token(type="identifier", value="dup"),
|
Token(type="identifier", value="dup"),
|
||||||
Token(type="i64", value=0),
|
Token(type="i64", value=0),
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,162 @@ def _token_to_c_call(token: dict, idx_var="i") -> str:
|
||||||
return f'test_boolean_value(&test, result, {idx_var}++, &(Boolean){{{"TRUE" if value else "FALSE"}}})' # type: ignore
|
return f'test_boolean_value(&test, result, {idx_var}++, &(Boolean){{{"TRUE" if value else "FALSE"}}})' # type: ignore
|
||||||
elif ttype == "error":
|
elif ttype == "error":
|
||||||
return f'test_for_error(&test, result, i++, SLS_STR("{c_string_literal(value)}"))' # type: ignore
|
return f'test_for_error(&test, result, i++, SLS_STR("{c_string_literal(value)}"))' # type: ignore
|
||||||
|
elif ttype == "token_string":
|
||||||
|
return _token_string_c_call(token, idx_var, value) # type: ignore
|
||||||
else:
|
else:
|
||||||
raise ValueError(f' Unhandled token type: {ttype}')
|
raise ValueError(f' Unhandled token type: {ttype}')
|
||||||
|
|
||||||
|
def _token_string_c_call(token: dict, idx_var: str, value: list[dict]) -> str:
|
||||||
|
"""Generate C code for testing a token string value."""
|
||||||
|
# Build the array of TestTokenValue structures
|
||||||
|
token_values = []
|
||||||
|
for inner_token in value:
|
||||||
|
inner_type = inner_token.get("type")
|
||||||
|
inner_value = inner_token.get("value")
|
||||||
|
|
||||||
|
# Map token types to their C test handler and value structure
|
||||||
|
if inner_type == "i64":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I64, {inner_value}}}"
|
||||||
|
elif inner_type == "i32":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I32, {inner_value}}}"
|
||||||
|
elif inner_type == "i16":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I16, {inner_value}}}"
|
||||||
|
elif inner_type == "i8":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I8, {inner_value}}}"
|
||||||
|
elif inner_type == "u64":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U64, {inner_value}}}"
|
||||||
|
elif inner_type == "u32":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U32, {inner_value}}}"
|
||||||
|
elif inner_type == "u16":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U16, {inner_value}}}"
|
||||||
|
elif inner_type == "u8":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U8, {inner_value}}}"
|
||||||
|
elif inner_type == "f64":
|
||||||
|
handler = "test_double_value"
|
||||||
|
value_struct = f"&(double){{{inner_value}}}"
|
||||||
|
elif inner_type == "f32":
|
||||||
|
handler = "test_float_value"
|
||||||
|
value_struct = f"&(float){{{inner_value}}}"
|
||||||
|
elif inner_type == "char":
|
||||||
|
handler = "test_character_value"
|
||||||
|
value_struct = f"&(uint8_t){{{ord(inner_value)}}}" # type: ignore
|
||||||
|
elif inner_type == "string":
|
||||||
|
handler = "test_string_value"
|
||||||
|
value_struct = f'&SLS_STR("{c_string_literal(inner_value)}")' # type: ignore
|
||||||
|
elif inner_type == "identifier":
|
||||||
|
handler = "test_identifier_value"
|
||||||
|
value_struct = f'&(TestIdentifierValue){{FALSE, SLS_STR("{inner_value}")}}'
|
||||||
|
elif inner_type == "identifier_literal":
|
||||||
|
handler = "test_identifier_value"
|
||||||
|
value_struct = f'&(TestIdentifierValue){{TRUE, SLS_STR("{inner_value}")}}'
|
||||||
|
elif inner_type == "bool":
|
||||||
|
handler = "test_boolean_value"
|
||||||
|
bool_str = "TRUE" if inner_value else "FALSE"
|
||||||
|
value_struct = f"&(Boolean){{{bool_str}}}"
|
||||||
|
elif inner_type == "error":
|
||||||
|
handler = "test_for_error"
|
||||||
|
value_struct = f'SLS_STR("{c_string_literal(inner_value)}")' # type: ignore
|
||||||
|
elif inner_type == "token_string":
|
||||||
|
# Recursive case: nested token string
|
||||||
|
handler = "test_token_string_value"
|
||||||
|
nested_tokens = inner_value if isinstance(inner_value, list) else []
|
||||||
|
value_struct = _build_token_string_value_struct(nested_tokens)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unhandled inner token type in token_string: {inner_type}')
|
||||||
|
|
||||||
|
token_values.append(f"{{.token_handler = {handler}, .value = {value_struct}}}")
|
||||||
|
|
||||||
|
# Generate the TestTokenStringValue initialization
|
||||||
|
num_tokens = len(value)
|
||||||
|
if num_tokens == 0:
|
||||||
|
# Empty token string
|
||||||
|
return f'test_token_string_value(&test, result, {idx_var}, &(TestTokenStringValue){{0, NULL}})'
|
||||||
|
else:
|
||||||
|
# Token string with values
|
||||||
|
values_array = f"(TestTokenValue[]){{{', '.join(token_values)}}}"
|
||||||
|
return f'test_token_string_value(&test, result, {idx_var}, &(TestTokenStringValue){{{num_tokens}, {values_array}}})'
|
||||||
|
|
||||||
|
|
||||||
|
def _build_token_string_value_struct(nested_tokens: list[dict]) -> str:
|
||||||
|
"""Helper to build a TestTokenStringValue structure for nested token strings."""
|
||||||
|
if not nested_tokens:
|
||||||
|
return "&(TestTokenStringValue){0, NULL}"
|
||||||
|
|
||||||
|
token_values = []
|
||||||
|
for inner_token in nested_tokens:
|
||||||
|
inner_type = inner_token.get("type")
|
||||||
|
inner_value = inner_token.get("value")
|
||||||
|
|
||||||
|
if inner_type == "i64":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I64, {inner_value}}}"
|
||||||
|
elif inner_type == "i32":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I32, {inner_value}}}"
|
||||||
|
elif inner_type == "i16":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I16, {inner_value}}}"
|
||||||
|
elif inner_type == "i8":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_I8, {inner_value}}}"
|
||||||
|
elif inner_type == "u64":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U64, {inner_value}}}"
|
||||||
|
elif inner_type == "u32":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U32, {inner_value}}}"
|
||||||
|
elif inner_type == "u16":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U16, {inner_value}}}"
|
||||||
|
elif inner_type == "u8":
|
||||||
|
handler = "test_integer_value"
|
||||||
|
value_struct = f"&(TestIntegerValue){{INTEGER_U8, {inner_value}}}"
|
||||||
|
elif inner_type == "f64":
|
||||||
|
handler = "test_double_value"
|
||||||
|
value_struct = f"&(double){{{inner_value}}}"
|
||||||
|
elif inner_type == "f32":
|
||||||
|
handler = "test_float_value"
|
||||||
|
value_struct = f"&(float){{{inner_value}}}"
|
||||||
|
elif inner_type == "char":
|
||||||
|
handler = "test_character_value"
|
||||||
|
value_struct = f"&(uint8_t){{{ord(inner_value)}}}" # type: ignore
|
||||||
|
elif inner_type == "string":
|
||||||
|
handler = "test_string_value"
|
||||||
|
value_struct = f'&SLS_STR("{c_string_literal(inner_value)}")' # type: ignore
|
||||||
|
elif inner_type == "identifier":
|
||||||
|
handler = "test_identifier_value"
|
||||||
|
value_struct = f'&(TestIdentifierValue){{FALSE, SLS_STR("{inner_value}")}}'
|
||||||
|
elif inner_type == "identifier_literal":
|
||||||
|
handler = "test_identifier_value"
|
||||||
|
value_struct = f'&(TestIdentifierValue){{TRUE, SLS_STR("{inner_value}")}}'
|
||||||
|
elif inner_type == "bool":
|
||||||
|
handler = "test_boolean_value"
|
||||||
|
bool_str = "TRUE" if inner_value else "FALSE"
|
||||||
|
value_struct = f"&(Boolean){{{bool_str}}}"
|
||||||
|
elif inner_type == "error":
|
||||||
|
handler = "test_for_error"
|
||||||
|
value_struct = f'SLS_STR("{c_string_literal(inner_value)}")' # type: ignore
|
||||||
|
elif inner_type == "token_string":
|
||||||
|
# Recursive case
|
||||||
|
handler = "test_token_string_value"
|
||||||
|
value_struct = _build_token_string_value_struct(inner_value if isinstance(inner_value, list) else [])
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unhandled nested token type in token_string: {inner_type}')
|
||||||
|
|
||||||
|
token_values.append(f"{{.token_handler = {handler}, .value = {value_struct}}}")
|
||||||
|
|
||||||
|
num_tokens = len(nested_tokens)
|
||||||
|
values_array = f"(TestTokenValue[]){{{', '.join(token_values)}}}"
|
||||||
|
return f"&(TestTokenStringValue){{{num_tokens}, {values_array}}}"
|
||||||
|
|
||||||
def token_to_c_call(token: dict, idx_var="i") -> str:
|
def token_to_c_call(token: dict, idx_var="i") -> str:
|
||||||
"""Generate a C 'test_*_value' call based on token type."""
|
"""Generate a C 'test_*_value' call based on token type."""
|
||||||
return f"if ({_token_to_c_call(token, idx_var)}) return test.result;"
|
return f"if ({_token_to_c_call(token, idx_var)}) return test.result;"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue