First test finished

This commit is contained in:
Kyler Olsen 2025-10-29 16:57:02 -06:00
parent 4287ebc648
commit ecbc562dd5
4 changed files with 87 additions and 38 deletions

View File

@ -34,7 +34,7 @@ typedef enum {
typedef struct { typedef struct {
const char *name; const char *name;
size_t length; size_t length;
uint8_t is_literal; Boolean is_literal;
} Identifier; } Identifier;
typedef enum { typedef enum {
@ -61,15 +61,15 @@ typedef struct {
typedef struct { typedef struct {
TokenType type; TokenType type;
union { union {
Identifier *identifiers; Identifier *identifiers; // type == TOKEN_IDENTIFIER
IntegerLiteral *integer_literals; IntegerLiteral *integer_literals; // type == TOKEN_INTEGER
float *float_literals; float *float_literals; // type == TOKEN_FLOAT
double *double_literals; double *double_literals; // type == TOKEN_DOUBLE
StringLiteral *string_literals; StringLiteral *string_literals; // type == TOKEN_STRING
uint8_t *boolean_literals; uint8_t *boolean_literals; // type == TOKEN_BOOLEAN
ArrayLiteral *array_literals; ArrayLiteral *array_literals; // type == TOKEN_ARRAY
TokenString *token_strings; TokenString *token_strings; // type == TOKEN_TOKEN_STRING
TypeTuple *type_tuples; TypeTuple *type_tuples; // type == TOKEN_TYPE_TUPLE
}; };
size_t length; size_t length;
} ArrayLiteral; } ArrayLiteral;
@ -89,23 +89,23 @@ typedef struct {
typedef struct { typedef struct {
TokenType type; TokenType type;
union { union {
Identifier identifier; Identifier identifier; // type == TOKEN_IDENTIFIER
IntegerLiteral integer_literal; IntegerLiteral integer_literal; // type == TOKEN_INTEGER
float float_literal; float float_literal; // type == TOKEN_FLOAT
double double_literal; double double_literal; // type == TOKEN_DOUBLE
StringLiteral string_literal; StringLiteral string_literal; // type == TOKEN_STRING
uint8_t boolean_literal; uint8_t boolean_literal; // type == TOKEN_BOOLEAN
ArrayLiteral array_literal; ArrayLiteral array_literal; // type == TOKEN_ARRAY
TokenString token_string; TokenString token_string; // type == TOKEN_TOKEN_STRING
TypeTuple type_tuple; TypeTuple type_tuple; // type == TOKEN_TYPE_TUPLE
}; };
} Token; } Token;
typedef struct LexerTokenResult { typedef struct LexerTokenResult {
SlsResultType type; SlsResultType type;
union { union {
Token result; Token result; // type == SLS_RESULT
SlsError error; SlsError error; // type == SLS_ERROR
}; };
FileInfo file_info; FileInfo file_info;
struct LexerTokenResult *next; struct LexerTokenResult *next;
@ -114,8 +114,8 @@ typedef struct LexerTokenResult {
typedef struct { typedef struct {
SlsResultType type; SlsResultType type;
union { union {
LexerTokenResult *result; LexerTokenResult *result; // type == SLS_RESULT
SlsError error; SlsError error; // type == SLS_ERROR
}; };
} LexerResult; } LexerResult;

View File

@ -6,6 +6,11 @@
#ifndef SLS_ERROR_H #ifndef SLS_ERROR_H
#define SLS_ERROR_H #define SLS_ERROR_H
typedef enum {
FALSE,
TRUE,
} Boolean;
typedef struct { typedef struct {
const char *message; const char *message;
int code; int code;

View File

@ -13,17 +13,18 @@ const char *TEST_FILE_NAME = "TEST_FILE.SLS";
typedef enum { typedef enum {
TEST_ERROR, TEST_ERROR,
TEST_LOGIC_FAILED, TEST_LOGIC_FAIL,
TEST_ERROR_FAILED, TEST_ERROR_FAIL,
TEST_SUCCESS, TEST_PASS,
TEST_NOT_IMPLEMENTED,
} TestResultType; } TestResultType;
typedef struct { typedef struct {
const char *name; const char *name;
uint8_t success; TestResultType status;
union { union {
const char *message; const char *message; // status in { TEST_LOGIC_FAIL, }
SlsError error; SlsError error; // status in { TEST_ERROR, TEST_ERROR_FAIL, }
}; };
} TestResult; } TestResult;

View File

@ -5,6 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "sls/sls_errors.h" #include "sls/sls_errors.h"
#include "sls/lexer.h" #include "sls/lexer.h"
@ -19,7 +20,7 @@ typedef struct {
static LexerTest start_up_test(const char *test_name, const char *test_code) { static LexerTest start_up_test(const char *test_name, const char *test_code) {
LexerTest test = (LexerTest) { LexerTest test = (LexerTest) {
.result = (TestResult) { .name = test_name, .success = 0 } }; .result = (TestResult) { .name = test_name, .status = TEST_NOT_IMPLEMENTED } };
lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code); lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code);
return test; return test;
} }
@ -31,21 +32,27 @@ static void clean_up_test(LexerResult result) {
static TestResult logic_fail_test(LexerTest test, LexerResult result, const char *message) { static TestResult logic_fail_test(LexerTest test, LexerResult result, const char *message) {
clean_up_test(result); clean_up_test(result);
test.result.success = 0; test.result.status = TEST_LOGIC_FAIL;
test.result.message = message; test.result.message = message;
return test.result; return test.result;
} }
static TestResult error_fail_test(LexerTest test, LexerResult result, SlsError error) { static TestResult error_fail_test(LexerTest test, LexerResult result, SlsError error) {
clean_up_test(result); clean_up_test(result);
test.result.success = 0; test.result.status = TEST_ERROR_FAIL;
test.result.error = error; test.result.error = error;
return test.result; return test.result;
} }
static TestResult skip_test(LexerTest test, LexerResult result) {
clean_up_test(result);
test.result.status = TEST_NOT_IMPLEMENTED;
return test.result;
}
static TestResult pass_test(LexerTest test, LexerResult result) { static TestResult pass_test(LexerTest test, LexerResult result) {
clean_up_test(result); clean_up_test(result);
test.result.success = 1; test.result.status = TEST_PASS;
return test.result; return test.result;
} }
@ -55,18 +62,54 @@ static TestResult test_add_statement() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) if (result.type == SLS_ERROR)
return fail_test(test, result, result.error.message); return error_fail_test(test, result, result.error);
LexerTokenResult *head = result.result; LexerTokenResult *head = result.result;
if (head == 0)
return logic_fail_test(test, result, "Unexpected end of token stream (0 tokens found)");
if (head->type == SLS_ERROR) if (head->type == SLS_ERROR)
return fail_test(test, result, result.error.message); return error_fail_test(test, result, result.error);
if (head->result.type != TOKEN_INTEGER) if (head->result.type != TOKEN_INTEGER)
return fail_test(test, result); return logic_fail_test(test, result, "First token should be an integer");
if (head->result.integer_literal.type != INTEGER_I64) if (head->result.integer_literal.type != INTEGER_I64)
return fail_test(test, result); return logic_fail_test(test, result, "First integer type should be i64");
if (head->result.integer_literal.value != 3) if (head->result.integer_literal.value != 3)
return fail_test(test, result); return logic_fail_test(test, result, "First integer value should be 3");
head = head->next;
if (head == 0)
return logic_fail_test(test, result, "Unexpected end of token stream (1 token found)");
if (head->type == SLS_ERROR)
return error_fail_test(test, result, result.error);
if (head->result.type != TOKEN_INTEGER)
return logic_fail_test(test, result, "Second token should be an integer");
if (head->result.integer_literal.type != INTEGER_I64)
return logic_fail_test(test, result, "Second integer type should be `i64`");
if (head->result.integer_literal.value != 4)
return logic_fail_test(test, result, "Second integer value should be `4`");
head = head->next;
if (head == 0)
return logic_fail_test(test, result, "Unexpected end of token stream (2 tokens found)");
if (head->type == SLS_ERROR)
return error_fail_test(test, result, result.error);
if (head->result.type != TOKEN_IDENTIFIER)
return logic_fail_test(test, result, "Third token should be an identifier");
if (head->result.identifier.is_literal == TRUE)
return logic_fail_test(test, result, "Identifier should not be a literal identifier");
if (head->result.identifier.length == 1)
return logic_fail_test(test, result, "Identifier length should be `1`");
if (strcmp(head->result.identifier.name, "+") != 0)
return logic_fail_test(test, result, "Identifier name should be `+`");
head = head->next;
if (head == 0)
return logic_fail_test(test, result, "Unexpected end of token stream (3 tokens found)");
if (head->type == SLS_ERROR)
return error_fail_test(test, result, result.error);
if (head->result.type != TOKEN_EOF)
return logic_fail_test(test, result, "Fourth token should be EOF");
return pass_test(test, result); return pass_test(test, result);
} }