diff --git a/src/lexer/SolsLiteral.c b/src/lexer/SolsLiteral.c index 372c141..afddf09 100644 --- a/src/lexer/SolsLiteral.c +++ b/src/lexer/SolsLiteral.c @@ -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); diff --git a/src/lexer/SolsToken.c b/src/lexer/SolsToken.c index 2c805f0..c667d3f 100644 --- a/src/lexer/SolsToken.c +++ b/src/lexer/SolsToken.c @@ -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); diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 28a48b6..468f6e7 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -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) {