update stuff

This commit is contained in:
2026-02-05 19:14:31 +11:00
parent 4333c42305
commit 755e7f9606
8 changed files with 175 additions and 52 deletions

View File

@@ -1,11 +1,15 @@
#if 0 #if 0
set -eou set -e
if [[ ! -v OUTPUT ]]; then if [[ ! -v OUTPUT ]]; then
OUTPUT=solstice OUTPUT=solstice
fi fi
if [[ ! -v CFLAGS ]]; then
CFLAGS=""
fi
gcc "$0" -o "$OUTPUT" gcc "$0" -o "$OUTPUT"
if not [ $# -lt 1 ]; then if not [ $# -lt 1 ]; then
@@ -30,6 +34,8 @@ exit
// -- LEXER -- // -- LEXER --
#include "src/lexer/SolsType.c" #include "src/lexer/SolsType.c"
#include "src/lexer/SolsToken.c"
#include "src/lexer/SolsLiteral.c"
#include "src/lexer/lexer.c" #include "src/lexer/lexer.c"
// -- PARSER -- // -- PARSER --

48
src/lexer/SolsLiteral.c Normal file
View File

@@ -0,0 +1,48 @@
#include "SolsLiteral.h"
#include <stdarg.h>
#include <string.h>
ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) {
va_list args;
va_start(args, type);
SolsLiteral literal = {
.type = type
};
switch (type) {
case SLT_INT: {
literal.as.intv = va_arg(args, int64_t);
break;
}
case SLT_DOUBLE: {
literal.as.doublev = va_arg(args, double);
break;
}
case SLT_BOOL: {
literal.as.boolv = (bool) va_arg(args, int);
break;
}
case SLT_CHAR: {
literal.as.charv = (char) va_arg(args, int);
break;
}
case SLT_STRING: {
char* input = va_arg(args, char*);
if (input == NULL) {
return Error(SolsLiteral, charptr, "Unexpected NULL value (in createSolsLiteral() function)");
}
literal.as.stringv = malloc(strlen(input) + 1);
if (literal.as.stringv == NULL) {
return Error(SolsLiteral, charptr, "Couldn't allocate memory (in createSolsLiteral() function)");
}
strcpy(literal.as.stringv, input);
}
}
return Success(SolsLiteral, charptr, literal);
va_end(args);
}
void freeSolsLiteral(SolsLiteral* lit) {
if (lit->type == SLT_STRING && lit->as.stringv != NULL) {
free(lit->as.stringv);
}
}

44
src/lexer/SolsLiteral.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef SOLSLITERAL_H
#define SOLSLITERAL_H
#include <inttypes.h>
#include <stdarg.h>
#include "../include/error.h"
typedef char* charptr;
typedef enum SolsLiteralType {
SLT_INT, SLT_STRING, SLT_DOUBLE, SLT_BOOL, SLT_CHAR
} SolsLiteralType;
// Stores literal values which will be added to the Ground code.
// Not much explaining needed here.
typedef struct SolsLiteral {
SolsLiteralType type;
union {
int64_t intv;
char* stringv;
double doublev;
bool boolv;
char charv;
} as;
} SolsLiteral;
Result(SolsLiteral, charptr);
// Creates a SolsLiteral, based on the type provided.
// SolsLiteralType -> C type:
// SLT_INT -> int64_t
// SLT_STRING -> char*
// SLT_DOUBLE -> double
// SLT_BOOL -> bool
// SL_CHAR -> char
// An error will only be returned if there is an issue copying a provided char*.
// There is no way to detect incorrectly provided types, so ensure that the right type
// is provided!!!!
ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...);
// Frees a SolsLiteral. Primarily concerned with freeing .as.stringv
void freeSolsLiteral(SolsLiteral* lit);
#endif

0
src/lexer/SolsToken.c Normal file
View File

40
src/lexer/SolsToken.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef SOLSTOKEN_H
#define SOLSTOKEN_H
#include "SolsType.h"
#include "SolsLiteral.h"
typedef enum SolsTokenType {
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_GROUND
} SolsTokenType;
// Represents a token lexed by the lex() function.
// Most token types exclusively use the .type field, however some tokens require storing
// more data, inside the .as union.
// Those tokens are:
// STT_LITERAL: A literal value. Uses field .as.literal
// STT_TYPE: A type descriptor. Uses field .as.type
// STT_IDENTIFIER: An identifier. Uses field .as.idName
// STT_KW_GROUND: Ground code embedded inside Solstice. Uses field .as.inlineGround
typedef struct SolsToken {
SolsTokenType type;
union {
SolsLiteral literal;
SolsType type;
char* idName;
char* inlineGround;
} as;
} SolsToken;
// Represents a Solstice program, seperated into tokens.
// .at is a pointer to the tokens
// .count is how many tokens are currently being stored
// .capacity is how many tokens worth of memory is allocated
typedef struct SolsTokens {
SolsToken* at;
size_t count;
size_t capacity;
} SolsTokens;
#endif

View File

@@ -0,0 +1,25 @@
#include "lexer.h"
#include "../include/error.h"
ResultType(SolsLexer, charptr) createLexer(char* input) {
char* inputcopy = malloc(strlen(input) + 1);
if (inputcopy == NULL) {
return Error(SolsLexer, charptr, "Couldn't copy string into lexer (in createLexer() function)");
}
strcpy(inputcopy, input);
SolsLexer lexer = {
.input = inputcopy,
.current = 0,
};
return Success(SolsLexer, charptr, lexer);
}
ResultType(voidptr, charptr) lex(SolsLexer* lexer) {
if (lexer->input == NULL) {
return Error(voidptr, charptr, "Lexer is not initialised");
}
lexer->current = 0;
return Success(voidptr, charptr, NULL);
}

View File

@@ -8,55 +8,8 @@
#include "../include/error.h" #include "../include/error.h"
#include "SolsType.h" #include "SolsType.h"
#include "SolsToken.h"
typedef enum SolsTokenType { #include "SolsLiteral.h"
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_GROUND
} SolsTokenType;
typedef enum SolsLiteralType {
SLT_INT, SLT_STRING, SLT_DOUBLE, SLT_BOOL, SLT_CHAR
} SolsLiteralType;
// Stores literal values which will be added to the Ground code.
// Not much explaining needed here.
typedef struct SolsLiteral {
SolsLiteralType type;
union {
int64_t intv;
char* stringv;
double doublev;
bool boolv;
char charv;
} as;
} SolsLiteral;
// Represents a token lexed by the lex() function.
// Most token types exclusively use the .type field, however some tokens require storing
// more data, inside the .as union.
// Those tokens are:
// STT_LITERAL: A literal value. Uses field .as.literal
// STT_TYPE: A type descriptor. Uses field .as.type
// STT_IDENTIFIER: An identifier. Uses field .as.idName
// STT_KW_GROUND: Ground code embedded inside Solstice. Uses field .as.inlineGround
typedef struct SolsToken {
SolsTokenType type;
union {
SolsLiteral literal;
SolsType type;
char* idName;
char* inlineGround;
} as;
} SolsToken;
// Represents a Solstice program, seperated into tokens.
// .at is a pointer to the tokens
// .count is how many tokens are currently being stored
// .capacity is how many tokens worth of memory is allocated
typedef struct SolsTokens {
SolsToken* at;
size_t count;
size_t capacity;
} SolsTokens;
// Represents the current state of the lexer. // Represents the current state of the lexer.
// .input is the Solstice program as written by the user. // .input is the Solstice program as written by the user.
@@ -69,9 +22,10 @@ typedef struct SolsLexer {
} SolsLexer; } SolsLexer;
// Creates a lexer for use by the lex() function. // Creates a lexer for use by the lex() function.
SolsLexer createLexer(char* input); Result(SolsLexer, charptr);
ResultType(SolsLexer, charptr) createLexer(char* input);
// Uses the provided lexer to scan the code, and create tokens. // Uses the provided lexer to scan the code, and create tokens.
void lex(SolsLexer* lexer); ResultType(voidptr, charptr) lex(SolsLexer* lexer);
#endif #endif

View File

@@ -1,5 +1,11 @@
#include "lexer/lexer.h" #include "lexer/lexer.h"
#include <stdio.h>
int main() { int main() {
ResultType(SolsLexer, charptr) lexer = createLexer("puts \"dingus\"");
if (lexer.error) {
printf("Error while creating lexer: %s", lexer.as.error);
}
lex(&lexer.as.success);
return 0; return 0;
} }