From 906a632fef5670db51b91daa8641881e4e63e38e Mon Sep 17 00:00:00 2001 From: Kyler Date: Tue, 4 Nov 2025 23:16:00 -0700 Subject: [PATCH] Lexer tests working --- SLS_C/Makefile | 7 +- SLS_C/include/sls/lexer.h | 47 +------- SLS_C/include/sls/sls_errors.h | 4 +- SLS_C/include/sls/string.h | 14 +++ SLS_C/include/tests/tests.h | 7 +- SLS_C/src/lexer.c | 46 +++++++ SLS_C/src/string.c | 17 +++ SLS_C/tests/lexer_tests.c | 212 ++++++++++++++++++--------------- SLS_C/tests/tests.c | 12 +- 9 files changed, 220 insertions(+), 146 deletions(-) create mode 100644 SLS_C/include/sls/string.h create mode 100644 SLS_C/src/string.c diff --git a/SLS_C/Makefile b/SLS_C/Makefile index 9d048a4..097a683 100644 --- a/SLS_C/Makefile +++ b/SLS_C/Makefile @@ -3,6 +3,7 @@ CC ?= gcc CFLAGS ?= -std=c11 -Wall -Wextra -g -Iinclude -MMD -MP LDFLAGS ?= +CTESTFLAGS ?= -std=c11 -Wall -Wextra -Wno-unused-function -g -Iinclude -MMD -MP SRCDIR := src OBJDIR := obj @@ -34,11 +35,11 @@ $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/%.o: $(TESTDIR)/%.c | $(OBJDIR) - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CTESTFLAGS) -c $< -o $@ # Link main program $(TARGET): $(OBJECTS) | $(BINDIR) - $(CC) $(LDFLAGS) $^ -o $@ + $(CC) $(LDFLAGS) $^ -o $@ -lm # Run main program run: $(TARGET) @@ -47,7 +48,7 @@ run: $(TARGET) # Build test runner executable $(TEST_TARGET): $(TEST_OBJECTS) $(OBJECTS) | $(BINDIR) - $(CC) $(LDFLAGS) $^ -o $@ + $(CC) $(LDFLAGS) $^ -o $@ -lm # Run tests test: $(TEST_TARGET) diff --git a/SLS_C/include/sls/lexer.h b/SLS_C/include/sls/lexer.h index c1dce9b..ab3b3f3 100644 --- a/SLS_C/include/sls/lexer.h +++ b/SLS_C/include/sls/lexer.h @@ -6,11 +6,11 @@ #ifndef SLS_LEXER_H #define SLS_LEXER_H -#include +#include #include "sls_errors.h" -const size_t TYPE_NAMES_SAFE_LENGTH = 20; +extern const size_t TYPE_NAMES_SAFE_LENGTH; typedef struct { const char *filename; @@ -33,18 +33,7 @@ typedef enum { TOKEN_TYPE_TUPLE, } TokenType; -const char *TOKEN_TYPES_NAMES[] = { - "End of File", - "Identifier", - "Integer", - "Float", - "Double", - "String", - "Boolean", - "Array", - "Token String", - "Type Tuple", -}; +extern const char *TOKEN_TYPES_NAMES[]; typedef enum { ARRAY_IDENTIFIER, @@ -63,22 +52,7 @@ typedef enum { ARRAY_STRUCT_INLINE, } ArrayType; -const char *ARRAY_TYPES_NAMES[] = { - "Identifier", - "i64", - "i32", - "i16", - "i8", - "u64", - "u32", - "u16", - "u8", - "Float", - "Double", - "String", - "Boolean", - "Inline Struct", -}; +extern const char *ARRAY_TYPES_NAMES[]; typedef struct { const char *name; @@ -97,16 +71,7 @@ typedef enum { INTEGER_U8, } IntegerBuiltInType; -const char *INTEGER_TYPES_NAMES[] = { - "i64", - "i32", - "i16", - "i8", - "u64", - "u32", - "u16", - "u8", -}; +extern const char *INTEGER_TYPES_NAMES[]; typedef struct { uint64_t value; @@ -188,8 +153,8 @@ typedef struct { } LexerResult; void init_lexer(LexerInfo *lexer_info, const char *filename, const char *source_code); -LexerResult lexical_analysis(LexerInfo *lexer_info); LexerTokenResult *get_token(LexerTokenResult *head, size_t i); void clean_token_result(LexerTokenResult *head); +LexerResult lexical_analysis(LexerInfo *lexer_info); #endif // SLS_LEXER_H diff --git a/SLS_C/include/sls/sls_errors.h b/SLS_C/include/sls/sls_errors.h index c7d91df..73d768f 100644 --- a/SLS_C/include/sls/sls_errors.h +++ b/SLS_C/include/sls/sls_errors.h @@ -6,6 +6,8 @@ #ifndef SLS_ERROR_H #define SLS_ERROR_H +#include + typedef enum { FALSE, TRUE, @@ -13,7 +15,7 @@ typedef enum { typedef struct { const char *message; - int code; + int32_t code; } SlsError; typedef enum { diff --git a/SLS_C/include/sls/string.h b/SLS_C/include/sls/string.h new file mode 100644 index 0000000..5362332 --- /dev/null +++ b/SLS_C/include/sls/string.h @@ -0,0 +1,14 @@ +// Kyler Olsen +// YREA SLS +// Strings Header +// November 2025 + +#ifndef SLS_STRING_H +#define SLS_STRING_H + +#include + +int isascii(unsigned char c); +size_t strnlen(const char *s, size_t maxlen); + +#endif // SLS_STRING_H diff --git a/SLS_C/include/tests/tests.h b/SLS_C/include/tests/tests.h index a59749f..1034264 100644 --- a/SLS_C/include/tests/tests.h +++ b/SLS_C/include/tests/tests.h @@ -6,10 +6,11 @@ #ifndef SLS_TESTS_H #define SLS_TESTS_H -#include +#include + #include "../sls/sls_errors.h" -const char *TEST_FILE_NAME = "TEST_FILE.SLS"; +extern const char *TEST_FILE_NAME; typedef enum { TEST_ERROR, @@ -23,7 +24,7 @@ typedef struct { const char *name; TestResultType status; union { - const char *message; // status in { TEST_LOGIC_FAIL, } + char *message; // status in { TEST_LOGIC_FAIL, } SlsError error; // status in { TEST_ERROR, TEST_ERROR_FAIL, } }; } TestResult; diff --git a/SLS_C/src/lexer.c b/SLS_C/src/lexer.c index f917f1b..63fc4b5 100644 --- a/SLS_C/src/lexer.c +++ b/SLS_C/src/lexer.c @@ -6,9 +6,55 @@ #include #include #include +#include +#include #include "sls/sls_errors.h" #include "sls/lexer.h" +#include "sls/string.h" + +const size_t TYPE_NAMES_SAFE_LENGTH = 20; + +const char *TOKEN_TYPES_NAMES[] = { + "End of File", + "Identifier", + "Integer", + "Float", + "Double", + "String", + "Boolean", + "Array", + "Token String", + "Type Tuple", +}; + +const char *ARRAY_TYPES_NAMES[] = { + "Identifier", + "i64", + "i32", + "i16", + "i8", + "u64", + "u32", + "u16", + "u8", + "Float", + "Double", + "String", + "Boolean", + "Inline Struct", +}; + +const char *INTEGER_TYPES_NAMES[] = { + "i64", + "i32", + "i16", + "i8", + "u64", + "u32", + "u16", + "u8", +}; void init_lexer(LexerInfo *lexer_info, const char *filename, const char *source_code) { lexer_info->filename = filename; diff --git a/SLS_C/src/string.c b/SLS_C/src/string.c new file mode 100644 index 0000000..0c195a1 --- /dev/null +++ b/SLS_C/src/string.c @@ -0,0 +1,17 @@ +// Kyler Olsen +// YREA SLS +// String Helpers +// November 2025 + +#include + +int isascii(unsigned char c) { + return c < 128; +} + +size_t strnlen(const char *s, size_t maxlen) { + size_t i; + for (i = 0; i < maxlen; i++) + if (s[i] == '\0') break; + return i; +} diff --git a/SLS_C/tests/lexer_tests.c b/SLS_C/tests/lexer_tests.c index 3d08aba..bf2eb9c 100644 --- a/SLS_C/tests/lexer_tests.c +++ b/SLS_C/tests/lexer_tests.c @@ -11,9 +11,10 @@ #include "sls/sls_errors.h" #include "sls/lexer.h" +#include "sls/string.h" #include "tests/tests.h" -static const size_t NUM_OF_TESTS = 12; +static const size_t NUM_OF_TESTS = 14; static const double FLOAT_TEST_PRECISION = 0.01; @@ -28,7 +29,7 @@ static LexerTest start_up_test(const char *test_name, const char *test_code) { LexerTest test = (LexerTest) { .result = (TestResult) { .name = test_name, .status = TEST_NOT_IMPLEMENTED } }; - lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code); + init_lexer(&test.lexer_info, TEST_FILE_NAME, test_code); return test; } @@ -44,9 +45,9 @@ static TestResult error_test(LexerTest *test, LexerResult result, SlsError error return test->result; } -static TestResult logic_fail_test(LexerTest *test, LexerResult result, const char *message) { +static TestResult logic_fail_test(LexerTest *test, LexerResult result, char *message) { if (message == 0) return error_test(test, result, (SlsError) { - .message = "Out of Memory Error!", .code = 3458, }); + .message = "Out of Memory Error!", .code = 1, }); clean_up_test(result); test->result.status = TEST_LOGIC_FAIL; test->result.message = message; @@ -66,6 +67,11 @@ static TestResult skip_test(LexerTest *test, LexerResult result) { return test->result; } +static TestResult skip_test_no_result(LexerTest *test) { + test->result.status = TEST_NOT_IMPLEMENTED; + return test->result; +} + static TestResult pass_test(LexerTest *test, LexerResult result) { clean_up_test(result); test->result.status = TEST_PASS; @@ -76,172 +82,172 @@ static TestResult pass_test(LexerTest *test, LexerResult result) { static char *unexpected_end_of_token_stream(size_t i) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Unexpected end of token stream (%zu tokens found)", i - 1); return string; } static char *expected_end_of_token_stream(size_t i) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Expected end of token stream (more than %zu tokens found)", i - 1); return string; } static char *token_should_be(size_t i, TokenType should, TokenType found) { 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]); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu should be a %s, but found a %s", i, TOKEN_TYPES_NAMES[should], TOKEN_TYPES_NAMES[found]); return string; } -static char *integer_type_should_be(size_t i, TokenType should, TokenType found) { +static char *integer_type_should_be(size_t i, IntegerBuiltInType should, IntegerBuiltInType found) { 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]); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu integer type should be a %s, but found a %s", i, TOKEN_TYPES_NAMES[should], TOKEN_TYPES_NAMES[found]); return string; } static char *integer_value_should_be(size_t i, uint64_t should, uint64_t found) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu integer value should be %lu, but found %lu", i, should, found); return string; } static char *float_value_should_be(size_t i, double should, double found) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu float value should be %.2f, but found %.2f", i, should, found); return string; } static char *identifier_should_be_literal(size_t i) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu identifier should be an identifier literal", i); return string; } static char *identifier_should_not_be_literal(size_t i) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu identifier should not be an identifier literal", i); return string; } static char *token_length_should_be(size_t i, TokenType type, uint64_t should, uint64_t found) { 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu of type %s length should be %lu, but found %lu", i, TOKEN_TYPES_NAMES[type], should, found); return string; } 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu of type %s string value should be %s, but found %s", i, TOKEN_TYPES_NAMES[type], should, found); return string; } static char *boolean_should_be(size_t i, Boolean value) { 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); - else snprintf(string, length, "Token #%d boolean should be false, but is true", i); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + if (value) snprintf(string, length, "Token #%zu boolean should be true, but is false", i); + else snprintf(string, length, "Token #%zu boolean should be false, but is true", i); 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]); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu array dimensions should be %zu, but found %zu", 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu dimension %zu of array type %s should be shape %lu, but found %lu", 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu element %zu of array type %s should be %lu, but found %lu", 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu element %zu 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu element %zu 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]); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + if (value) snprintf(string, length, "Token #%zu element %zu of array type %s should be true, but found false", i, j, TOKEN_TYPES_NAMES[type]); + else snprintf(string, length, "Token #%zu element %zu 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu element %zu of type tuple should be %lu, but found %lu", 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + snprintf(string, length, "Token #%zu element %zu 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); + char *string = (char *)malloc(sizeof(char) * length); + if (string == 0) return string; + if (value) snprintf(string, length, "Token #%zu element %zu of type tuple should be true, but found false", i, j); + else snprintf(string, length, "Token #%zu element %zu of type tuple should be false, but found true", i, j); return string; } @@ -253,7 +259,7 @@ static Boolean test_token_type(LexerTest *test, LexerResult result, size_t i, To logic_fail_test(test, result, unexpected_end_of_token_stream(i + 1)); return TRUE; } if (head->type == SLS_ERROR) { - error_fail_test(test, result, result.error); + error_fail_test(test, result, head->error); return TRUE; } if (head->result.type != token_type) { logic_fail_test(test, result, token_should_be(i + 1, token_type, head->result.type)); @@ -273,7 +279,7 @@ static Boolean test_array_type(LexerTest *test, LexerResult result, size_t i, Ar 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++) { + for (size_t 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; @@ -283,6 +289,7 @@ static Boolean test_array_type(LexerTest *test, LexerResult result, size_t i, Ar } static Boolean test_eof_value(LexerTest *test, LexerResult result, size_t i, void *_) { + (void)_; // We don't use this anywhere in this function static const TokenType token_type = TOKEN_EOF; LexerTokenResult *head = get_token(result.result, i); if (test_token_type(test, result, i, token_type)) { @@ -407,8 +414,8 @@ static Boolean test_array_identifier_value(LexerTest *test, LexerResult result, return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (head->result.array_literal.identifiers[j].length == values->values[j].length) { logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values->values[j].length, head->result.array_literal.identifiers[j].length)); return TRUE; @@ -436,8 +443,8 @@ static Boolean test_array_integer_value(LexerTest *test, LexerResult result, siz return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (head->result.array_literal.integer_literals[j] == values->values[j].value) { logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values->values[j].value, head->result.array_literal.integer_literals[j])); return TRUE; @@ -459,8 +466,8 @@ static Boolean test_array_float_value(LexerTest *test, LexerResult result, size_ return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (fabsf(head->result.array_literal.float_literals[j] - values->values[j]) >= FLOAT_TEST_PRECISION) { logic_fail_test(test, result, array_element_float_should_be(i + 1, j, array_type, values->values[j], head->result.array_literal.float_literals[j])); return TRUE; @@ -482,8 +489,8 @@ static Boolean test_array_double_value(LexerTest *test, LexerResult result, size return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (fabs(head->result.array_literal.float_literals[j] - values->values[j]) >= FLOAT_TEST_PRECISION) { logic_fail_test(test, result, array_element_float_should_be(i + 1, j, array_type, values->values[j], head->result.array_literal.float_literals[j])); return TRUE; @@ -505,8 +512,8 @@ static Boolean test_array_string_value(LexerTest *test, LexerResult result, size return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (head->result.array_literal.string_literals[j].length == values->values[j].length) { logic_fail_test(test, result, array_element_integer_should_be(i + 1, j, array_type, values->values[j].length, head->result.array_literal.string_literals[j].length)); return TRUE; @@ -531,8 +538,8 @@ static Boolean test_array_boolean_value(LexerTest *test, LexerResult result, siz return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (head->result.array_literal.boolean_literals[j] == values->values[j]) { logic_fail_test(test, result, array_element_boolean_should_be(i + 1, j, array_type, values->values[j])); return TRUE; @@ -556,12 +563,12 @@ static Boolean test_array_struct_inline_value(LexerTest *test, LexerResult resul if (test_array_type(test, result, i, array_type, values->shape, values->dimensions)) { return TRUE; } if (strncmp(head->result.array_literal.struct_inline.name, values->struct_name, values->struct_name_length)) { - logic_fail_test(test, result, token_value_string_should_be(i + 1, ARRAY_STRUCT_INLINE, values->struct_name_length, values->struct_name, head->result.array_literal.struct_inline.name)); + logic_fail_test(test, result, token_value_string_should_be(i + 1, TOKEN_IDENTIFIER, values->struct_name_length, values->struct_name, head->result.array_literal.struct_inline.name)); return TRUE; } size_t length = 1; - for (int j = 0; j < values->dimensions; j++) length *= values->shape[j]; - for (int j = 0; j < length; j++) { + for (size_t j = 0; j < values->dimensions; j++) length *= values->shape[j]; + for (size_t j = 0; j < length; j++) { if (values->struct_handler(test, result, i, j, head->result.array_literal.struct_inline.values[j], values->values[j])) { return TRUE; } @@ -582,10 +589,10 @@ typedef struct { static LexerResult token_string_to_lexer_result(TokenString token_string, FileInfo file_info) { LexerTokenResult *new, *head; head = 0; - // head = malloc(sizeof(LexerTokenResult)); + // head = (LexerTokenResult *)malloc(sizeof(LexerTokenResult)); // *head = (LexerTokenResult) { .type = SLS_RESULT, .result = (Token) { .type = TOKEN_EOF }, .file_info = file_info, .next = 0 }; - for (int i = 0; i> token_string.length; i++) { - new = malloc(sizeof(LexerTokenResult)); + for (size_t i = 0; i> token_string.length; i++) { + new = (LexerTokenResult *)malloc(sizeof(LexerTokenResult)); *new = (LexerTokenResult) { .type = SLS_RESULT, .result = token_string.tokens[i], .file_info = file_info, .next = head }; head = new; } @@ -601,7 +608,7 @@ static Boolean test_token_string_value(LexerTest *test, LexerResult result, size logic_fail_test(test, result, integer_value_should_be(i + 1, values->tokens, head->result.token_string.length)); return TRUE; } - for (int j = 0; j < values->tokens; j++) { + for (size_t j = 0; j < values->tokens; j++) { LexerResult token_string_result = token_string_to_lexer_result(head->result.token_string, head->file_info); if (values->values[j].token_handler(test, token_string_result, j, values->values[j].value)) { clean_token_result(token_string_result.result); @@ -630,7 +637,7 @@ static Boolean test_type_tuple_value(LexerTest *test, LexerResult result, size_t } if (head->result.type_tuple.output_length != values->output_length) { logic_fail_test(test, result, token_length_should_be(i + 1, token_type, values->output_length, head->result.type_tuple.output_length)); return TRUE; - } for (int j = 0; j < values->input_length; j++) { + } for (size_t j = 0; j < values->input_length; j++) { if (head->result.type_tuple.input_identifiers[j].length == values->input_values[j].length) { logic_fail_test(test, result, type_tuple_element_integer_should_be(i + 1, j, values->input_values[j].length, head->result.type_tuple.input_identifiers[j].length)); return TRUE; @@ -641,7 +648,7 @@ static Boolean test_type_tuple_value(LexerTest *test, LexerResult result, size_t logic_fail_test(test, result, type_tuple_element_boolean_should_be(i + 1, j, TRUE)); return TRUE; } - } for (int j = 0; j < values->output_length; j++) { + } for (size_t j = 0; j < values->output_length; j++) { if (head->result.type_tuple.output_identifiers[j].length == values->output_values[j].length) { logic_fail_test(test, result, type_tuple_element_integer_should_be(i + 1, j, values->output_values[j].length, head->result.type_tuple.output_identifiers[j].length)); return TRUE; @@ -658,6 +665,15 @@ static Boolean test_type_tuple_value(LexerTest *test, LexerResult result, size_t // Test cases +static TestResult test_empty_statement() { + LexerTest test = start_up_test("test_empty_statement", ""); + LexerResult result = lexical_analysis(&test.lexer_info); + if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); + size_t i = 0; + if (test_eof_value(&test, result, i++, 0)) return test.result; + return pass_test(&test, result); +} + static TestResult test_hello_world_statement() { LexerTest test = start_up_test("test_hello_world_statement", "\"Hello, World!\" print"); LexerResult result = lexical_analysis(&test.lexer_info); @@ -750,8 +766,8 @@ static TestResult test_square_fn() { size_t i = 0; if (test_type_tuple_value(&test, result, i++, &(TestTypeTupleValue){1, (TestIdentifierValue[]){(TestIdentifierValue){TRUE, 6, "Number"}}, 1, (TestIdentifierValue[]){(TestIdentifierValue){TRUE, 6, "Number"}}})) return test.result; if (test_token_string_value(&test, result, i++, &(TestTokenStringValue){3, (TestTokenStringToken[]){ - (TestTokenStringToken){test_identifier_value, &(TestIdentifierValue){FALSE, 3, "dup"}}, - (TestTokenStringToken){test_identifier_value, &(TestIdentifierValue){FALSE, 1, "*"}} + (TestTokenStringToken){(Boolean (*)(LexerTest *, LexerResult, size_t, void *))test_identifier_value, &(TestIdentifierValue){FALSE, 3, "dup"}}, + (TestTokenStringToken){(Boolean (*)(LexerTest *, LexerResult, size_t, void *))test_identifier_value, &(TestIdentifierValue){FALSE, 1, "*"}} }})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){TRUE, 6, "square"})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, 2, "fn"})) return test.result; @@ -825,11 +841,12 @@ TestsReport run_lexer_tests() { TestsReport test_report = (TestsReport) { .section = "lexer_tests", .count = NUM_OF_TESTS, - .tests = malloc(sizeof(TestResult) * NUM_OF_TESTS), + .tests = (TestResult *)malloc(sizeof(TestResult) * NUM_OF_TESTS), }; size_t i = 0; + test_report.tests[i++] = test_empty_statement(); test_report.tests[i++] = test_hello_world_statement(); test_report.tests[i++] = test_add_statement(); test_report.tests[i++] = test_sub_statement(); @@ -837,6 +854,7 @@ TestsReport run_lexer_tests() { test_report.tests[i++] = test_div_statement(); test_report.tests[i++] = test_add_and_mult_statement(); test_report.tests[i++] = test_dup_and_mult_statement(); + test_report.tests[i++] = test_square_fn(); test_report.tests[i++] = test_dup_statement(); test_report.tests[i++] = test_swap_statement(); test_report.tests[i++] = test_over_statement(); diff --git a/SLS_C/tests/tests.c b/SLS_C/tests/tests.c index 25468b2..ff35d37 100644 --- a/SLS_C/tests/tests.c +++ b/SLS_C/tests/tests.c @@ -4,27 +4,37 @@ // November 2025 #include +#include +#include #include "tests/tests.h" +const char *TEST_FILE_NAME = "TEST_FILE.SLS"; + int main(void) { TestsReport lexer_reports = run_lexer_tests(); - for (int i = 0; i < lexer_reports.count; i++) { + for (size_t i = 0; i < lexer_reports.count; i++) { switch (lexer_reports.tests[i].status) { case TEST_ERROR: + // Bright Red printf("\x1b[91mTest errored: %s\n\t%s\n\x1b[0m", lexer_reports.tests[i].name, lexer_reports.tests[i].error.message); break; case TEST_ERROR_FAIL: + // Magenta printf("\x1b[35mTest failed (errored): %s\n\t%s\n\x1b[0m", lexer_reports.tests[i].name, lexer_reports.tests[i].error.message); break; case TEST_LOGIC_FAIL: + // Red printf("\x1b[31mTest failed: %s\n\t%s\n\x1b[0m", lexer_reports.tests[i].name, lexer_reports.tests[i].message); + free(lexer_reports.tests[i].message); break; case TEST_PASS: + // Green printf("\x1b[32mTest passed: %s\n\x1b[0m", lexer_reports.tests[i].name); break; case TEST_NOT_IMPLEMENTED: + // Blue printf("\x1b[34mTest not implemented: %s\n\x1b[0m", lexer_reports.tests[i].name); break; }