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

View File

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

View File

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

View File

@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "sls/sls_errors.h"
#include "sls/lexer.h"
@ -19,7 +20,7 @@ typedef struct {
static LexerTest start_up_test(const char *test_name, const char *test_code) {
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);
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) {
clean_up_test(result);
test.result.success = 0;
test.result.status = TEST_LOGIC_FAIL;
test.result.message = message;
return test.result;
}
static TestResult error_fail_test(LexerTest test, LexerResult result, SlsError error) {
clean_up_test(result);
test.result.success = 0;
test.result.status = TEST_ERROR_FAIL;
test.result.error = error;
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) {
clean_up_test(result);
test.result.success = 1;
test.result.status = TEST_PASS;
return test.result;
}
@ -55,18 +62,54 @@ static TestResult test_add_statement() {
LexerResult result = lexical_analysis(&test.lexer_info);
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;
if (head == 0)
return logic_fail_test(test, result, "Unexpected end of token stream (0 tokens found)");
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)
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)
return fail_test(test, result);
return logic_fail_test(test, result, "First integer type should be i64");
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);
}