#include "parser.h" #include "utils.h" #include #include #include "compiler_types.h" void processSource(const std::string& src, CompilerState& state) { std::istringstream iss(src); std::string line; std::cout << "Parsuje kod:\n"; while (std::getline(iss, line)) { line = trim(line); if (line.empty()) continue; // FUNKCJE if (line.length() > 4 && line.substr(0, 4) == "void") { size_t openParen = line.find("(", 4); size_t closeParen = line.find(")", openParen); if (openParen != std::string::npos && closeParen != std::string::npos) { size_t nameStart = 4; while (nameStart < openParen && (line[nameStart] == ' ' || line[nameStart] == '\t')) nameStart++; size_t nameEnd = openParen; while (nameEnd > nameStart && (line[nameEnd - 1] == ' ' || line[nameEnd - 1] == '\t')) nameEnd--; // ZMIANA: używamy 'state' zamiast 'compilerState' state.currentFunction = line.substr(nameStart, nameEnd - nameStart); state.functions[state.currentFunction] = std::vector(); state.inFunction = true; std::cout << " FUNC " << state.currentFunction << "\n"; state.braceStack.push(true); continue; } } // } ZAMYKANIE KLAMRY else if (line.find("}") != std::string::npos) { if (!state.braceStack.empty()) { // Sprawdzamy co zamykamy PRZED zdjęciem ze stosu bool wasFunction = state.braceStack.top(); state.braceStack.pop(); // Jeśli zdjęliśmy 'true' (czyli znacznik funkcji) ORAZ stos jest pusty // to znaczy, że zamknęliśmy funkcję główną. if (wasFunction && state.braceStack.empty()) { state.inFunction = false; state.currentFunction.clear(); std::cout << " END FUNC\n"; } else { // Zamknęliśmy IF-a (lub inny blok wewnętrzny) std::cout << " END BLOCK (IF)\n"; } } continue; } // INT if (line.length() > 3 && line.substr(0, 3) == "int") { size_t eqPos = line.find("=", 4); if (eqPos != std::string::npos) { size_t semiPos = line.find(";", eqPos); if (semiPos != std::string::npos) { std::string name = trim(line.substr(4, eqPos - 4)); std::string rightSide = trim(line.substr(eqPos + 1, semiPos - eqPos - 1)); std::string op; size_t opPos; size_t eqPos2 = rightSide.find("=="); if (eqPos2 != std::string::npos && (eqPos2 + 1 < rightSide.length()) && rightSide[eqPos2 + 2] != '=') { op = "=="; opPos = eqPos2; } else { opPos = rightSide.find('+'); if (opPos == std::string::npos) opPos = rightSide.find('-'); if (opPos != std::string::npos) op = rightSide.substr(opPos, 1); } if (opPos != std::string::npos && !op.empty()) { std::string leftVar = trim(rightSide.substr(0, opPos)); std::string rightVar = trim(rightSide.substr(opPos + op.length())); // ZMIANA: używamy 'state' Expression expr{ leftVar, op, rightVar, name }; state.expressions.push_back(expr); state.variables[name] = 0; std::cout << " " << op << " EXPR " << name << " = " << leftVar << " " << op << " " << rightVar << "\n"; } else { try { int value = std::stoi(rightSide); state.variables[name] = value; std::cout << " VAR " << name << " = " << value << "\n"; } catch (...) { // Usunięto '❌' żeby uniknąć warningów o kodowaniu (C4566) std::cout << " [X] BLAD: '" << rightSide << "'\n"; } } } } } // BOOL else if (!state.inFunction && line.length() > 4 && line.substr(0, 4) == "bool") { size_t eqPos = line.find("=", 5); if (eqPos != std::string::npos) { size_t semiPos = line.find(";", eqPos); if (semiPos != std::string::npos) { std::string nameRaw = line.substr(5, eqPos - 5); size_t nameStart = nameRaw.find_first_not_of(" \t"); size_t nameEnd = nameRaw.find_last_not_of(" \t"); std::string name = nameRaw.substr(nameStart, nameEnd - nameStart + 1); std::string valueRaw = line.substr(eqPos + 1, semiPos - eqPos - 1); size_t valStart = valueRaw.find_first_not_of(" \t"); size_t valEnd = valueRaw.find_last_not_of(" \t"); std::string valueStr = valueRaw.substr(valStart, valEnd - valStart + 1); bool value = (valueStr == "true" || valueStr == "1"); state.variables[name] = value ? 1 : 0; std::cout << " BOOL '" << name << "' = " << (value ? "true" : "false") << "\n"; } } } // IF else if (line.length() > 3 && line.substr(0, 2) == "if") { size_t openParen = line.find("("); size_t closeParen = line.find(")"); if (openParen != std::string::npos && closeParen > openParen) { std::string condition = trim(line.substr(openParen + 1, closeParen - openParen - 1)); IfBlock newIf; newIf.conditionVar = condition; state.ifBlocks.push_back(newIf); // WAŻNE: Dodajemy instrukcję "IF:numer" do listy rozkazów funkcji if (state.inFunction) { int ifIndex = state.ifBlocks.size() - 1; state.functions[state.currentFunction].push_back("IF:" + std::to_string(ifIndex)); } std::cout << " IF [" << condition << "] { <- blok #" << state.ifBlocks.size() - 1 << "\n"; state.braceStack.push(false); // false oznacza, że to klamra IFa (a nie funkcji) continue; } } // PRINT else if (line.length() > 5 && line.substr(0, 5) == "print") { size_t openParen = line.find("(", 5); size_t closeParen = line.rfind(")"); if (openParen != std::string::npos && closeParen > openParen) { std::string varName = line.substr(openParen + 1, closeParen - openParen - 1); size_t varStart = varName.find_first_not_of(" \t"); size_t varEnd = varName.find_last_not_of(" \t"); if (varStart != std::string::npos) { varName = varName.substr(varStart, varEnd - varStart + 1); if (state.inFunction && !state.currentFunction.empty()) { // SPRAWDZAMY CZY JESTEŚMY W IFIE // (sprawdzamy szczyt stosu klamerek: false = IF, true = FUNC) if (!state.braceStack.empty() && state.braceStack.top() == false) { // Jesteśmy w IFie -> dodaj TYLKO do ifBlocks if (!state.ifBlocks.empty()) { state.ifBlocks.back().prints.push_back(varName); std::cout << " IF PRINT: " << varName << "\n"; } } else { // Jesteśmy w normalnej funkcji (poza ifem) -> dodaj jako rozkaz PRINT: state.functions[state.currentFunction].push_back("PRINT:" + varName); std::cout << " FUNC PRINT " << state.currentFunction << ": " << varName << "\n"; } } else { // Print globalny (poza funkcjami) state.globalPrints.push_back(varName); std::cout << " PRINT " << varName << "\n"; } } } } // WYWOLYWANIE FUNKCJI; else if (line.length() > 3 && line.find("();") != std::string::npos) { size_t openParen = line.find("("); if (openParen != std::string::npos) { std::string funcName = line.substr(0, openParen); size_t nameStart = funcName.find_first_not_of(" \t"); size_t nameEnd = funcName.find_last_not_of(" \t"); funcName = funcName.substr(nameStart, nameEnd - nameStart + 1); state.printCalls.push_back("CALL_" + funcName); // ZMIANA: state std::cout << " CALL FUNC " << funcName << "\n"; } } } } void calculateExpressions(CompilerState& state) { for (const auto& expr : state.expressions) { if (state.variables.count(expr.leftVar) && state.variables.count(expr.rightVar)) { int left = state.variables[expr.leftVar]; int right = state.variables[expr.rightVar]; int result = 0; if (expr.op == "+") result = left + right; else if (expr.op == "==") result = (left == right); state.variables[expr.resultVar] = result; } } }