This commit is contained in:
2026-02-21 17:18:38 +11:00
parent 437023fe65
commit 929482d7d4
3 changed files with 110 additions and 61 deletions

View File

@@ -28,13 +28,16 @@ ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) {
case SLT_STRING: {
char* input = va_arg(args, char*);
if (input == NULL) {
va_end(args);
return Error(SolsLiteral, charptr, "Unexpected NULL value (in createSolsLiteral() function)");
}
literal.as.stringv = malloc(strlen(input) + 1);
if (literal.as.stringv == NULL) {
va_end(args);
return Error(SolsLiteral, charptr, "Couldn't allocate memory (in createSolsLiteral() function)");
}
strcpy(literal.as.stringv, input);
break;
}
}
va_end(args);

View File

@@ -14,10 +14,12 @@ ResultType(SolsToken, charptr) createSolsToken(SolsTokenType type, ...) {
if (type == STT_IDENTIFIER) {
char* name = va_arg(args, char*);
if (name == NULL) {
va_end(args);
return Error(SolsToken, charptr, "String passed is NULL (in createSolsToken() function)");
}
token.as.idName = malloc(strlen(name) + 1);
if (token.as.idName == NULL) {
va_end(args);
return Error(SolsToken, charptr, "Couldn't allocate memory (in createSolsToken() function)");
}
strcpy(token.as.idName, name);
@@ -26,10 +28,12 @@ ResultType(SolsToken, charptr) createSolsToken(SolsTokenType type, ...) {
if (type == STT_KW_GROUND) {
char* ground = va_arg(args, char*);
if (ground == NULL) {
va_end(args);
return Error(SolsToken, charptr, "String passed is NULL (in createSolsToken() function)");
}
token.as.inlineGround = malloc(strlen(ground) + 1);
if (token.as.inlineGround == NULL) {
va_end(args);
return Error(SolsToken, charptr, "Couldn't allocate memory (in createSolsToken() function)");
}
strcpy(token.as.inlineGround, ground);

View File

@@ -105,7 +105,7 @@ ResultType(char, Nothing) lexerPeek(SolsLexer* lexer, size_t ahead) {
if (lexer->input == NULL) {
return Error(char, Nothing, {});
}
if (lexer->current + ahead > lexer->inputsize) {
if (lexer->current + ahead >= lexer->inputsize) {
return Error(char, Nothing, {});
}
@@ -180,7 +180,7 @@ ResultType(SolsToken, charptr) identifyToken(const char* token) {
}
// Process integers and floats
if (isdigit(token[0]) || token[0] == '-') {
if (isdigit(token[0]) || (token[0] == '-' && strlen(token) > 1 && (isdigit(token[1]) || token[1] == '.'))) {
size_t len = strlen(token);
bool isInt = true;
bool isDouble = false;
@@ -365,16 +365,6 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
return Error(Nothing, charptr, "Lexer is not initialised");
}
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
if (tokens.error) {
Estr e = CREATE_ESTR(tokens.as.error);
APPEND_ESTR(e, " (in createSolsTokens() function)");
return Error(Nothing, charptr, e.str);
}
lexer->output = tokens.as.success;
lexer->current = 0;
Estr buf = CREATE_ESTR("");
bool inString = false;
@@ -400,49 +390,63 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (chr.as.success == '/' && !inString) {
ResultType(char, Nothing) peek = lexerPeek(lexer, 1);
if (!peek.error && peek.as.success == '/') {
chr = lexerConsume(lexer);
for (;;) {
chr = lexerConsume(lexer);
if (chr.error) return Success(Nothing, charptr, {});
if (chr.as.success == '\n') {
chr = lexerConsume(lexer);
break;
}
// Consume characters until \n or EOF
while (true) {
ResultType(char, Nothing) next = lexerPeek(lexer, 1);
if (next.error || next.as.success == '\n') break;
lexerConsume(lexer);
}
continue;
} else if (!peek.error && peek.as.success == '*') {
for (;;) {
chr = lexerConsume(lexer);
if (chr.error) return Success(Nothing, charptr, {});
if (chr.as.success == '*') {
peek = lexerPeek(lexer, 1);
if (!peek.error && peek.as.success == '/') {
chr = lexerConsume(lexer);
// Skip the *
lexerConsume(lexer);
// Consume characters until */ or EOF
while (true) {
ResultType(char, Nothing) next = lexerConsume(lexer);
if (next.error) break;
if (next.as.success == '\n') {
lineNum++;
DESTROY_ESTR(currentLine);
currentLine = CREATE_ESTR("");
lineStart = lexer->current;
for (size_t i = lineStart; i < lexer->inputsize; i++) {
if (lexer->input[i] == '\n') break;
char tmp[] = {lexer->input[i], '\0'};
APPEND_ESTR(currentLine, tmp);
}
}
if (next.as.success == '*') {
ResultType(char, Nothing) peek2 = lexerPeek(lexer, 1);
if (!peek2.error && peek2.as.success == '/') {
lexerConsume(lexer); // skip /
break;
}
}
}
continue;
}
}
if (chr.as.success == '#' && !inString) {
for (;;) {
chr = lexerConsume(lexer);
if (chr.error) return Success(Nothing, charptr, {});
if (chr.as.success == '\n') {
chr = lexerConsume(lexer);
break;
}
while (true) {
ResultType(char, Nothing) next = lexerPeek(lexer, 1);
if (next.error || next.as.success == '\n') break;
lexerConsume(lexer);
}
continue;
}
if (chr.as.success == '\n') {
for (; lineStart < lexer->inputsize; lineStart++) {
if (lexer->input[lineStart] == '\n') {
lineNum++;
DESTROY_ESTR(currentLine);
currentLine = CREATE_ESTR("");
lineStart = lexer->current;
for (size_t i = lineStart; i < lexer->inputsize; i++) {
if (lexer->input[i] == '\n') {
break;
}
char buf[] = {lexer->input[lineStart], '\0'};
APPEND_ESTR(currentLine, buf);
char buf_tmp[] = {lexer->input[i], '\0'};
APPEND_ESTR(currentLine, buf_tmp);
}
lineNum ++;
}
if (inString) {
@@ -472,7 +476,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
DESTROY_ESTR(buf);
@@ -481,8 +488,12 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
break;
}
@@ -493,7 +504,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
DESTROY_ESTR(buf);
@@ -504,7 +518,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
}
@@ -512,7 +529,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, '=', '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
lexerConsume(lexer);
@@ -521,7 +541,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, chr.as.success, '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
lexerConsume(lexer);
@@ -539,7 +562,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
DESTROY_ESTR(buf);
@@ -550,7 +576,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
}
@@ -558,7 +587,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
char tmp[] = {chr.as.success, '=', '\0'};
ResultType(SolsToken, charptr) result = identifyToken(tmp);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
lexerConsume(lexer);
@@ -570,18 +602,17 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
// '.' requires checking whether it's a number or an identifier after
case '.': {
ResultType(char, Nothing) peek = lexerPeek(lexer, 1);
if (peek.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, "Expecting token after '.'"));
}
if (isdigit(peek.as.success)) {
char tmp[] = {peek.as.success, '\0'};
APPEND_ESTR(buf, tmp);
lexerConsume(lexer);
// If the next character is a digit, then this is a literal, not a member access dot.
if (!peek.error && isdigit(peek.as.success)) {
APPEND_ESTR(buf, ".");
} else {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
DESTROY_ESTR(buf);
@@ -598,7 +629,10 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
addTokenToSolsTokens(&lexer->output, result.as.success);
DESTROY_ESTR(buf);
@@ -636,16 +670,24 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
if (strcmp(buf.str, "") != 0) {
ResultType(SolsToken, charptr) result = identifyToken(buf.str);
if (result.error) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, result.as.error));
char* err = createParsingError(lineNum, currentLine.str, result.as.error);
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
DESTROY_ESTR(buf);
addTokenToSolsTokens(&lexer->output, result.as.success);
}
if (inString) {
return Error(Nothing, charptr, createParsingError(lineNum, currentLine.str, "Unterminated string"));
char* err = createParsingError(lineNum, currentLine.str, "Unterminated string");
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err);
}
return Success(Nothing, charptr, {});
DESTROY_ESTR(buf);
DESTROY_ESTR(currentLine);
return Success(Nothing, charptr, (Nothing){});
}
ResultType(Nothing, charptr) processTypeSignature(SolsLexer* lexer) {