Initial commit

This commit is contained in:
2025-05-10 21:28:56 +10:00
commit a782c09f91
24 changed files with 2129 additions and 0 deletions

192
src/Parser.cpp Normal file
View 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;
}