diff --git a/SLS_C/include/tests/tests.h b/SLS_C/include/tests/tests.h index 445a8b4..a59749f 100644 --- a/SLS_C/include/tests/tests.h +++ b/SLS_C/include/tests/tests.h @@ -34,4 +34,6 @@ typedef struct { TestResult* tests; } TestsReport; +TestsReport run_lexer_tests(); + #endif // SLS_TESTS_H diff --git a/SLS_C/tests/lexer_tests.c b/SLS_C/tests/lexer_tests.c index ad67a6e..c2157bd 100644 --- a/SLS_C/tests/lexer_tests.c +++ b/SLS_C/tests/lexer_tests.c @@ -14,6 +14,8 @@ static const size_t NUM_OF_TESTS = 6; +static const double FLOAT_TEST_PRECISION = 0.01; + typedef struct { TestResult result; LexerInfo lexer_info; @@ -77,7 +79,7 @@ static TestResult pass_test(LexerTest *test, LexerResult result) { // Test messages static char *unexpected_end_of_token_stream(size_t i) { - size_t length = floor(log10(i)) + 47; + size_t length = ceil(log10(i)) + 47; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Unexpected end of token stream (%d tokens found)", i-1); @@ -85,7 +87,7 @@ static char *unexpected_end_of_token_stream(size_t i) { } static char *expected_end_of_token_stream(size_t i) { - size_t length = floor(log10(i)) + 47; + size_t length = ceil(log10(i)) + 47; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Expected end of token stream (more than %d tokens found)", i-1); @@ -93,7 +95,7 @@ static char *expected_end_of_token_stream(size_t i) { } static char *token_should_be(size_t i, TokenType should, TokenType found) { - size_t length = floor(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[should], 13) + strnlen(TOKEN_TYPES_NAMES[found], 13) + 35; + size_t length = ceil(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[should], TYPE_NAMES_SAFE_LENGTH) + strnlen(TOKEN_TYPES_NAMES[found], TYPE_NAMES_SAFE_LENGTH) + 35; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d should be a %s, but found a %s", i, TOKEN_TYPES_NAMES[should], TOKEN_TYPES_NAMES[found]); @@ -101,7 +103,7 @@ static char *token_should_be(size_t i, TokenType should, TokenType found) { } static char *integer_type_should_be(size_t i, TokenType should, TokenType found) { - size_t length = floor(log10(i + 1)) + strnlen(INTEGER_TYPES_NAMES[should], 5) + strnlen(INTEGER_TYPES_NAMES[found], 5) + 48; + size_t length = ceil(log10(i + 1)) + strnlen(INTEGER_TYPES_NAMES[should], 5) + strnlen(INTEGER_TYPES_NAMES[found], 5) + 48; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d integer type should be a %s, but found a %s", i, TOKEN_TYPES_NAMES[should], TOKEN_TYPES_NAMES[found]); @@ -109,7 +111,7 @@ static char *integer_type_should_be(size_t i, TokenType should, TokenType found) } static char *integer_value_should_be(size_t i, uint64_t should, uint64_t found) { - size_t length = floor(log10(i + 1)) + floor(log10(should + 1)) + floor(log10(found + 1)) + 45; + size_t length = ceil(log10(i + 1)) + ceil(log10(should + 1)) + ceil(log10(found + 1)) + 45; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d integer value should be %d, but found %d", i, should, found); @@ -117,7 +119,7 @@ static char *integer_value_should_be(size_t i, uint64_t should, uint64_t found) } static char *float_value_should_be(size_t i, double should, double found) { - size_t length = floor(log10(i + 1)) + floor(log10(should + 1) + 3) + floor(log10(found + 1) + 3) + 43; + size_t length = ceil(log10(i + 1)) + ceil(log10(should + 1) + 3) + ceil(log10(found + 1) + 3) + 43; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d float value should be %.2f, but found %.2f", i, should, found); @@ -125,7 +127,7 @@ static char *float_value_should_be(size_t i, double should, double found) { } static char *identifier_should_be_literal(size_t i) { - size_t length = floor(log10(i + 1)) + 51; + size_t length = ceil(log10(i + 1)) + 51; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d identifier should be an identifier literal", i); @@ -133,7 +135,7 @@ static char *identifier_should_be_literal(size_t i) { } static char *identifier_should_not_be_literal(size_t i) { - size_t length = floor(log10(i + 1)) + 55; + size_t length = ceil(log10(i + 1)) + 55; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d identifier should not be an identifier literal", i); @@ -141,15 +143,15 @@ static char *identifier_should_not_be_literal(size_t i) { } static char *token_length_should_be(size_t i, TokenType type, uint64_t should, uint64_t found) { - size_t length = floor(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[type], 13) + floor(log10(should + 1)) + floor(log10(found + 1)) + 47; + size_t length = ceil(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + ceil(log10(should + 1)) + ceil(log10(found + 1)) + 47; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d of type %s length should be %d, but found %d", i, TOKEN_TYPES_NAMES[type], should, found); return string; } -static char *token_value_string_should_be(size_t i, TokenType type, size_t length, const char *should, const char *found) { - size_t length = floor(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[type], 13) + strnlen(should, length) + strnlen(found, length) + 53; +static char *token_value_string_should_be(size_t i, TokenType type, size_t value_length, const char *should, const char *found) { + size_t length = ceil(log10(i + 1)) + strnlen(TOKEN_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + strnlen(should, value_length) + strnlen(found, value_length) + 53; char *string = malloc(sizeof(char) * length); if (string = 0) return string; snprintf(string, length, "Token #%d of type %s string value should be %s, but found %s", i, TOKEN_TYPES_NAMES[type], should, found); @@ -157,7 +159,7 @@ static char *token_value_string_should_be(size_t i, TokenType type, size_t lengt } static char *boolean_should_be(size_t i, Boolean value) { - size_t length = floor(log10(i + 1)) + 45; + size_t length = ceil(log10(i + 1)) + 45; char *string = malloc(sizeof(char) * length); if (string = 0) return string; if (value) snprintf(string, length, "Token #%d boolean should be true, but is false", i); @@ -165,6 +167,88 @@ static char *boolean_should_be(size_t i, Boolean value) { return string; } +static char *array_type_should_be(size_t i, ArrayType should, ArrayType found) { + size_t length = ceil(log10(i + 1)) + strnlen(ARRAY_TYPES_NAMES[should], TYPE_NAMES_SAFE_LENGTH) + strnlen(ARRAY_TYPES_NAMES[found], TYPE_NAMES_SAFE_LENGTH) + 35; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d should be a %s, but found a %s", i, ARRAY_TYPES_NAMES[should], ARRAY_TYPES_NAMES[found]); + return string; +} + +static char *array_dimensions_should_be(size_t i, size_t should, size_t found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(should + 1)) + ceil(log10(found + 1)) + 48; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d array dimensions should be %s, but found %s", i, should, found); + return string; +} + +static char *array_element_shape_should_be(size_t i, size_t j, ArrayType type, uint64_t should, uint64_t found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(ARRAY_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + ceil(log10(should + 1) + 3) + ceil(log10(found + 1) + 3) + 63; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d dimension %d of array type %s should be shape %d, but found %d", i, j, TOKEN_TYPES_NAMES[type], should, found); + return string; +} + +static char *array_element_integer_should_be(size_t i, size_t j, ArrayType type, uint64_t should, uint64_t found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(ARRAY_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + ceil(log10(should + 1) + 3) + ceil(log10(found + 1) + 3) + 55; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d element %d of array type %s should be %d, but found %d", i, j, TOKEN_TYPES_NAMES[type], should, found); + return string; +} + +static char *array_element_float_should_be(size_t i, size_t j, ArrayType type, double should, double found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(ARRAY_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + ceil(log10(should + 1)) + ceil(log10(found + 1)) + 55; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d element %d of array type %s should be %.2f, but found %.2f", i, j, TOKEN_TYPES_NAMES[type], should, found); + return string; +} + +static char *array_element_string_should_be(size_t i, size_t j, ArrayType type, size_t value_length, const char *should, const char *found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(ARRAY_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + strnlen(should, value_length) + strnlen(found, value_length) + 55; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d element %d of array type %s should be %s, but found %s", i, j, TOKEN_TYPES_NAMES[type], should, found); + return string; +} + +static char *array_element_boolean_should_be(size_t i, size_t j, ArrayType type, Boolean value) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(ARRAY_TYPES_NAMES[type], TYPE_NAMES_SAFE_LENGTH) + 64; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + if (value) snprintf(string, length, "Token #%d element %d of array type %s should be true, but found false", i, j, TOKEN_TYPES_NAMES[type]); + else snprintf(string, length, "Token #%d element %d of array type %s should be false, but found true", i, j, TOKEN_TYPES_NAMES[type]); + return string; +} + +static char *type_tuple_element_integer_should_be(size_t i, size_t j, uint64_t should, uint64_t found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + ceil(log10(should + 1) + 3) + ceil(log10(found + 1) + 3) + 54; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d element %d of type tuple should be %d, but found %d", i, j, should, found); + return string; +} + +static char *type_tuple_element_string_should_be(size_t i, size_t j, size_t value_length, const char *should, const char *found) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + strnlen(should, value_length) + strnlen(found, value_length) + 54; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + snprintf(string, length, "Token #%d element %d of type tuple should be %s, but found %s", i, j, should, found); + return string; +} + +static char *type_tuple_element_boolean_should_be(size_t i, size_t j, Boolean value) { + size_t length = ceil(log10(i + 1)) + ceil(log10(j + 1)) + 63; + char *string = malloc(sizeof(char) * length); + if (string = 0) return string; + if (value) snprintf(string, length, "Token #%d element %d of type tuple should be true, but found false", i, j); + else snprintf(string, length, "Token #%d element %d of type tuple should be false, but found true", i, j); + return string; +} + // Test parts static Boolean test_token_type(LexerTest *test, LexerResult result, size_t i, TokenType token_type) { @@ -183,8 +267,9 @@ static Boolean test_token_type(LexerTest *test, LexerResult result, size_t i, To } static Boolean test_eof_value(LexerTest *test, LexerResult result, size_t i) { + static const TokenType token_type = TOKEN_EOF; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_EOF)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; } if (head->next != 0) { logic_fail_test(test, result, expected_end_of_token_stream(i + 1)); @@ -194,25 +279,27 @@ static Boolean test_eof_value(LexerTest *test, LexerResult result, size_t i) { } static Boolean test_identifier_value(LexerTest *test, LexerResult result, size_t i, Boolean is_literal, size_t length, const char *name) { + static const TokenType token_type = TOKEN_IDENTIFIER; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_IDENTIFIER)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; } if (head->result.identifier.is_literal != is_literal) { logic_fail_test(test, result, is_literal ? identifier_should_be_literal(i + 1) : identifier_should_not_be_literal(i + 1)); return TRUE; } if (head->result.identifier.length == strnlen(name, length)) { - logic_fail_test(test, result, token_length_should_be(i + 1, TOKEN_IDENTIFIER, strnlen(name, length), head->result.identifier.length)); + logic_fail_test(test, result, token_length_should_be(i + 1, token_type, strnlen(name, length), head->result.identifier.length)); return TRUE; - } if (strcmp(head->result.identifier.name, name) != 0) { - logic_fail_test(test, result, token_value_string_should_be(i + 1, TOKEN_IDENTIFIER, strnlen(name, length), head->result.identifier.name, name)); + } if (strncmp(head->result.identifier.name, name, length) != 0) { + logic_fail_test(test, result, token_value_string_should_be(i + 1, token_type, strnlen(name, length), head->result.identifier.name, name)); return TRUE; } return FALSE; } static Boolean test_integer_value(LexerTest *test, LexerResult result, size_t i, IntegerBuiltInType type, uint64_t value) { + static const TokenType token_type = TOKEN_INTEGER; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_INTEGER)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; } if (head->result.integer_literal.type != type) { logic_fail_test(test, result, integer_type_should_be(i + 1, type, head->result.integer_literal.type)); @@ -225,10 +312,11 @@ static Boolean test_integer_value(LexerTest *test, LexerResult result, size_t i, } static Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float value) { + static const TokenType token_type = TOKEN_FLOAT; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_FLOAT)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; - } if (head->result.float_literal - value) { + } if (fabsf(head->result.float_literal - value) >= FLOAT_TEST_PRECISION) { logic_fail_test(test, result, float_value_should_be(i + 1, value, head->result.float_literal)); return TRUE; } @@ -236,10 +324,11 @@ static Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, f } static Boolean test_double_value(LexerTest *test, LexerResult result, size_t i, double value) { + static const TokenType token_type = TOKEN_DOUBLE; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_DOUBLE)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; - } if (head->result.float_literal - value) { + } if (fabs(head->result.float_literal - value) >= FLOAT_TEST_PRECISION) { logic_fail_test(test, result, float_value_should_be(i + 1, value, head->result.float_literal)); return TRUE; } @@ -247,22 +336,24 @@ static Boolean test_double_value(LexerTest *test, LexerResult result, size_t i, } static Boolean test_string_value(LexerTest *test, LexerResult result, size_t i, size_t length, const char *value) { + static const TokenType token_type = TOKEN_STRING; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_STRING)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; } if (head->result.string_literal.length == strnlen(value, length)) { - logic_fail_test(test, result, token_length_should_be(i + 1, TOKEN_STRING, strnlen(value, length), head->result.string_literal.length)); + logic_fail_test(test, result, token_length_should_be(i + 1, token_type, strnlen(value, length), head->result.string_literal.length)); return TRUE; - } if (strcmp(head->result.string_literal.value, value) != 0) { - logic_fail_test(test, result, token_value_string_should_be(i + 1, TOKEN_STRING, strnlen(value, length), head->result.string_literal.value, value)); + } if (strncmp(head->result.string_literal.value, value, length) != 0) { + logic_fail_test(test, result, token_value_string_should_be(i + 1, token_type, fmax(strnlen(value, length), strnlen(head->result.string_literal.value, length)), value, head->result.string_literal.value)); return TRUE; } return FALSE; } static Boolean test_boolean_value(LexerTest *test, LexerResult result, size_t i, Boolean value) { + static const TokenType token_type = TOKEN_BOOLEAN; LexerTokenResult *head = get_token(result.result, i); - if (test_token_type(test, result, i, TOKEN_BOOLEAN)) { + if (test_token_type(test, result, i, token_type)) { return TRUE; } if (head->result.boolean_literal != value) { logic_fail_test(test, result, boolean_should_be(i + 1, value)); @@ -271,76 +362,195 @@ static Boolean test_boolean_value(LexerTest *test, LexerResult result, size_t i, return FALSE; } -static Boolean test_array_identifier_value(LexerTest *test, LexerResult result, size_t i, ArrayStringValues *values, size_t length) { +static Boolean test_array_type(LexerTest *test, LexerResult result, size_t i, ArrayType array_type, size_t *shape, size_t dimensions) { + LexerTokenResult *head = get_token(result.result, i); + if (test_token_type(test, result, i, TOKEN_ARRAY)) { + return TRUE; + } if (head->result.array_literal.type != array_type) { + logic_fail_test(test, result, array_type_should_be(i + 1, array_type, head->result.array_literal.type)); + return TRUE; + } if (head->result.array_literal.dimensions != dimensions) { + logic_fail_test(test, result, array_dimensions_should_be(i + 1, dimensions, head->result.array_literal.dimensions)); + return TRUE; + } + for (int j = 0; j < dimensions; j++) { + if (head->result.array_literal.shape[j] != shape[j]) { + logic_fail_test(test, result, array_element_shape_should_be(i + 1, j, array_type, shape[j], head->result.array_literal.shape[j])); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_identifier_value(LexerTest *test, LexerResult result, size_t i, ArrayStringValues *values, size_t *shape, size_t dimensions) { + static const ArrayType array_type = ARRAY_IDENTIFIER; + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (head->result.array_literal.identifiers[j].length == values[j].length) { + logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values[j].length, head->result.array_literal.identifiers[j].length)); + return TRUE; + } if (strncmp(head->result.array_literal.identifiers[j].name, values[j].value, values[j].length)) { + logic_fail_test(test, result, array_element_string_should_be(i + 1, j, array_type, values[j].length, values[j].value, head->result.array_literal.identifiers[j].name)); + return TRUE; + } if (head->result.array_literal.identifiers[j].is_literal) { + logic_fail_test(test, result, array_element_boolean_should_be(i + 1, j, array_type, TRUE)); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_integer_value(LexerTest *test, LexerResult result, size_t i, IntegerBuiltInType array_type, uint64_t *values, size_t *shape, size_t dimensions) { + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (head->result.array_literal.integer_literals[j] == values[j]) { + logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values[j], head->result.array_literal.integer_literals[j])); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_float_value(LexerTest *test, LexerResult result, size_t i, float *values, size_t *shape, size_t dimensions) { + static const ArrayType array_type = ARRAY_FLOAT; + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (fabsf(head->result.array_literal.float_literals[j] - values[j]) >= FLOAT_TEST_PRECISION) { + logic_fail_test(test, result, array_element_float_should_be(i + 1, j, array_type, values[j], head->result.array_literal.float_literals[j])); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_double_value(LexerTest *test, LexerResult result, size_t i, double *values, size_t *shape, size_t dimensions) { + static const ArrayType array_type = ARRAY_DOUBLE; + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (fabs(head->result.array_literal.float_literals[j] - values[j]) >= FLOAT_TEST_PRECISION) { + logic_fail_test(test, result, array_element_float_should_be(i + 1, j, array_type, values[j], head->result.array_literal.float_literals[j])); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_string_value(LexerTest *test, LexerResult result, size_t i, ArrayStringValues *values, size_t *shape, size_t dimensions) { + static const ArrayType array_type = ARRAY_STRING; + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (head->result.array_literal.string_literals[j].length == values[j].length) { + logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values[j].length, head->result.array_literal.string_literals[j].length)); + return TRUE; + } if (strncmp(head->result.array_literal.string_literals[j].value, values[j].value, values[j].length)) { + logic_fail_test(test, result, array_element_string_should_be(i + 1, j, array_type, values[j].length, values[j].value, head->result.array_literal.string_literals[j].value)); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_boolean_value(LexerTest *test, LexerResult result, size_t i, Boolean *values, size_t *shape, size_t dimensions) { + static const ArrayType array_type = ARRAY_BOOLEAN; + LexerTokenResult *head = get_token(result.result, i); + if (test_array_type(test, result, i, array_type, shape, dimensions)) { + return TRUE; + } + size_t length = 1; + for (int j = 0; j < dimensions; j++) length *= shape[j]; + for (int j = 0; j < length; j++) { + if (head->result.array_literal.boolean_literals[j] == values[j]) { + logic_fail_test(test, result, array_element_boolean_should_be(i + 1, j, array_type, values[j])); + return TRUE; + } + } + return FALSE; +} + +static Boolean test_array_token_string_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t *shape, size_t dimensions) { error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); // TODO return TRUE; } -static Boolean test_array_integer_value(LexerTest *test, LexerResult result, size_t i, IntegerBuiltInType type, uint64_t *values, size_t length) { +static Boolean test_array_type_tuple_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t *shape, size_t dimensions) { error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); // TODO return TRUE; } -static Boolean test_array_float_value(LexerTest *test, LexerResult result, size_t i, float *values, size_t length) { +static Boolean test_array_struct_inline_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t *shape, size_t dimensions) { error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); // TODO return TRUE; } -static Boolean test_array_double_value(LexerTest *test, LexerResult result, size_t i, double *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_string_value(LexerTest *test, LexerResult result, size_t i, ArrayStringValues *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_boolean_value(LexerTest *test, LexerResult result, size_t i, Boolean *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_array_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_token_string_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_type_tuple_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_array_struct_inline_value(LexerTest *test, LexerResult result, size_t i, void *values, size_t length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; -} - -static Boolean test_token_string_value(LexerTest *test, LexerResult result, size_t i, void *value, size_t length) { +static Boolean test_token_string_value(LexerTest *test, LexerResult result, size_t i, void *value, size_t *shape, size_t dimensions) { error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); // TODO return TRUE; } static Boolean test_type_tuple_value(LexerTest *test, LexerResult result, size_t i, ArrayStringValues *input_values, size_t input_length, ArrayStringValues *output_values, size_t output_length) { - error_test(test, result, (SlsError) { .message = "Test case not implemented!", .code = 984, }); - // TODO - return TRUE; + static const TokenType token_type = TOKEN_TYPE_TUPLE; + LexerTokenResult *head = get_token(result.result, i); + if (test_token_type(test, result, i, token_type)) { + return TRUE; + } if (head->result.type_tuple.input_length != input_length) { + logic_fail_test(test, result, token_length_should_be(i + 1, token_type, input_length, head->result.type_tuple.input_length)); + return TRUE; + } if (head->result.type_tuple.output_length != output_length) { + logic_fail_test(test, result, token_length_should_be(i + 1, token_type, output_length, head->result.type_tuple.output_length)); + return TRUE; + } for (int j = 0; j < input_length; j++) { + if (head->result.type_tuple.input_identifiers[j].length == input_values[j].length) { + logic_fail_test(test, result, type_tuple_element_integer_should_be(i + 1, j, input_values[j].length, head->result.type_tuple.input_identifiers[j].length)); + return TRUE; + } if (strncmp(head->result.type_tuple.input_identifiers[j].name, input_values[j].value, input_values[j].length)) { + logic_fail_test(test, result, type_tuple_element_string_should_be(i + 1, j, input_values[j].length, input_values[j].value, head->result.type_tuple.input_identifiers[j].name)); + return TRUE; + } if (head->result.type_tuple.input_identifiers[j].is_literal) { + logic_fail_test(test, result, type_tuple_element_boolean_should_be(i + 1, j, TRUE)); + return TRUE; + } + } for (int j = 0; j < output_length; j++) { + if (head->result.type_tuple.output_identifiers[j].length == output_values[j].length) { + logic_fail_test(test, result, type_tuple_element_integer_should_be(i + 1, j, output_values[j].length, head->result.type_tuple.output_identifiers[j].length)); + return TRUE; + } if (strncmp(head->result.type_tuple.output_identifiers[j].name, output_values[j].value, input_values[j].length)) { + logic_fail_test(test, result, type_tuple_element_string_should_be(i + 1, j, output_values[j].length, output_values[j].value, head->result.type_tuple.output_identifiers[j].name)); + return TRUE; + } if (head->result.type_tuple.output_identifiers[j].is_literal) { + logic_fail_test(test, result, type_tuple_element_boolean_should_be(i + 1, j, TRUE)); + return TRUE; + } + } + return FALSE; } // Test cases