/* 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 . */ #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> 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 Parser::getTokens() { return tokens; }