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: { case SLT_STRING: {
char* input = va_arg(args, char*); char* input = va_arg(args, char*);
if (input == NULL) { if (input == NULL) {
va_end(args);
return Error(SolsLiteral, charptr, "Unexpected NULL value (in createSolsLiteral() function)"); return Error(SolsLiteral, charptr, "Unexpected NULL value (in createSolsLiteral() function)");
} }
literal.as.stringv = malloc(strlen(input) + 1); literal.as.stringv = malloc(strlen(input) + 1);
if (literal.as.stringv == NULL) { if (literal.as.stringv == NULL) {
va_end(args);
return Error(SolsLiteral, charptr, "Couldn't allocate memory (in createSolsLiteral() function)"); return Error(SolsLiteral, charptr, "Couldn't allocate memory (in createSolsLiteral() function)");
} }
strcpy(literal.as.stringv, input); strcpy(literal.as.stringv, input);
break;
} }
} }
va_end(args); va_end(args);

View File

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

View File

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