Initial commit
This commit is contained in:
192
src/Parser.cpp
Normal file
192
src/Parser.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
Iodine
|
||||
Copyright (C) 2025 Maxwell Jeffress
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Parser.h"
|
||||
|
||||
bool Parser::canInt(string in) {
|
||||
try {
|
||||
stoi(in);
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::canDec(string in) {
|
||||
try {
|
||||
stod(in);
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseLines(string in, Logger log) {
|
||||
log.debug("Parsing lines...");
|
||||
buffer.clear();
|
||||
termBuffer.clear();
|
||||
terms.clear();
|
||||
bool isString = false;
|
||||
bool isEscaped = false;
|
||||
|
||||
for (size_t i = 0; i < in.size(); i++) {
|
||||
char c = in[i];
|
||||
|
||||
if (isEscaped) {
|
||||
buffer += c;
|
||||
isEscaped = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\\') {
|
||||
isEscaped = true;
|
||||
buffer += c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '"') {
|
||||
buffer += c;
|
||||
isString = !isString;
|
||||
} else if (c == '\n' && !isString) {
|
||||
// Skip newlines outside strings
|
||||
continue;
|
||||
} else if (c == ';' && !isString) {
|
||||
if (!buffer.empty()) {
|
||||
termBuffer.push_back(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
terms.push_back(termBuffer);
|
||||
termBuffer.clear();
|
||||
} else if ((c == ',' || c == '{' || c == '}' || c == '(' || c == ')') && !isString) {
|
||||
if (!buffer.empty()) {
|
||||
termBuffer.push_back(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
termBuffer.push_back(string(1, c));
|
||||
} else if (c == ' ' && !isString) {
|
||||
if (!buffer.empty()) {
|
||||
termBuffer.push_back(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
} else {
|
||||
buffer += c;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle any remaining buffer content
|
||||
if (!buffer.empty()) {
|
||||
termBuffer.push_back(buffer);
|
||||
}
|
||||
if (!termBuffer.empty()) {
|
||||
terms.push_back(termBuffer);
|
||||
}
|
||||
|
||||
// Debug output
|
||||
string debugString;
|
||||
log.debug("Lines have been parsed.");
|
||||
for (const auto& term : terms) {
|
||||
for (const auto& t : term) {
|
||||
debugString += t + ", ";
|
||||
}
|
||||
debugString += "\n";
|
||||
}
|
||||
log.debug(debugString);
|
||||
}
|
||||
|
||||
void Parser::processLines() {
|
||||
// Process vector<vector<string>> terms
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
for (int j = 0; j < terms[i].size(); j++) {
|
||||
Token token;
|
||||
string ct = terms[i][j];
|
||||
if (ct == " ") continue;
|
||||
// Oh boy here we go
|
||||
else if (ct == "fun") token.keyword = keywords::FUN;
|
||||
else if (ct == "let") token.keyword = keywords::LET;
|
||||
else if (ct == "print") token.keyword = keywords::PRINT;
|
||||
else if (ct == "println") token.keyword = keywords::PRINTLN;
|
||||
else if (ct == "input") token.keyword = keywords::INPUT;
|
||||
else if (ct == "return") token.keyword = keywords::RETURN;
|
||||
else if (ct == "exit") token.keyword = keywords::EXIT;
|
||||
else if (ct == "int") token.keyword = keywords::INT;
|
||||
else if (ct == "dec") token.keyword = keywords::DEC;
|
||||
else if (ct == "str") token.keyword = keywords::STR;
|
||||
else if (ct == "bool") token.keyword = keywords::BOOL;
|
||||
else if (ct == "if") token.keyword = keywords::IF;
|
||||
else if (ct == "while") token.keyword = keywords::WHILE;
|
||||
else if (ct == "{") token.keyword = keywords::OBRAC;
|
||||
else if (ct == "}") token.keyword = keywords::CBRAC;
|
||||
else if (ct == "(") token.keyword = keywords::OPARE;
|
||||
else if (ct == ")") token.keyword = keywords::CPARE;
|
||||
else if (ct == "+") token.keyword = keywords::ADD;
|
||||
else if (ct == "-") token.keyword = keywords::SUBTRACT;
|
||||
else if (ct == "*") token.keyword = keywords::MULTIPLY;
|
||||
else if (ct == "/") token.keyword = keywords::DIVIDE;
|
||||
else if (ct == "=") token.keyword = keywords::SET;
|
||||
else if (ct == "++") token.keyword = keywords::INCREMENT;
|
||||
else if (ct == "--") token.keyword = keywords::DECREMENT;
|
||||
else if (ct == "+=") token.keyword = keywords::ADDTO;
|
||||
else if (ct == "-=") token.keyword = keywords::SUBTRACTFROM;
|
||||
else if (ct == "*=") token.keyword = keywords::MULTIPLYTO;
|
||||
else if (ct == "/=") token.keyword = keywords::DIVIDEFROM;
|
||||
else if (ct == "==") token.keyword = keywords::EQUAL;
|
||||
else if (ct == "!=") token.keyword = keywords::INEQUAL;
|
||||
else if (ct == "<") token.keyword = keywords::LESS;
|
||||
else if (ct == ">") token.keyword = keywords::GREATER;
|
||||
else if (ct == "//") token.keyword = keywords::COMMENT;
|
||||
else if (ct == "[") token.keyword = keywords::OSQUA;
|
||||
else if (ct == "]") token.keyword = keywords::CSQUA;
|
||||
else {
|
||||
token.keyword = keywords::VALUE;
|
||||
// Convert the value based on its type
|
||||
if (canInt(ct)) {
|
||||
token.type = valtype::INT;
|
||||
token.value.type = valtype::INT;
|
||||
token.value.value = stoi(ct);
|
||||
}else if (canDec(ct)) {
|
||||
token.type = valtype::DEC;
|
||||
token.value.type = valtype::DEC;
|
||||
token.value.value = stod(ct);
|
||||
} else if (ct == "true" || ct == "false") {
|
||||
token.type = valtype::BOOL;
|
||||
token.value.type = valtype::BOOL;
|
||||
token.value.value = (ct == "true");
|
||||
}
|
||||
else {
|
||||
// Handle strings - remove quotes if present
|
||||
token.type = valtype::STR;
|
||||
token.value.type = valtype::STR;
|
||||
if (ct.size() >= 2 && ct.front() == '"' && ct.back() == '"') {
|
||||
// Remove the quotes
|
||||
token.value.value = ct.substr(1, ct.size() - 2);
|
||||
} else {
|
||||
token.value.value = ct;
|
||||
}
|
||||
}
|
||||
}
|
||||
tokens.push_back(token);
|
||||
}
|
||||
Token semi;
|
||||
semi.keyword = keywords::SEMICOLON;
|
||||
tokens.push_back(semi);
|
||||
}
|
||||
}
|
||||
|
||||
vector<Token> Parser::getTokens() {
|
||||
return tokens;
|
||||
}
|
Reference in New Issue
Block a user