From 5edf6ed382d2a69b0f84b15e5ca720e3cac307c5 Mon Sep 17 00:00:00 2001 From: mmichlol Date: Sat, 7 Feb 2026 15:53:25 +0100 Subject: [PATCH] added Random Int Generator --- PCCcompiler/codegen.cpp | 69 +++++++++++++++++++++++++++++++----- PCCcompiler/compiler_types.h | 2 ++ PCCcompiler/parser.cpp | 16 +++++++-- push.bat | 28 +++++++++++++++ 4 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 push.bat diff --git a/PCCcompiler/codegen.cpp b/PCCcompiler/codegen.cpp index 0e4fa6e..6198a47 100644 --- a/PCCcompiler/codegen.cpp +++ b/PCCcompiler/codegen.cpp @@ -41,19 +41,18 @@ std::string generateAssembly(const CompilerState& state) { result += "global main\n"; result += "extern printf\n"; result += "extern getchar\n"; - result += "extern _getch\n"; // ZMIANA: Dodajemy _getch (zamiast lub obok getchar) + result += "extern _getch\n"; + result += "extern rand\n"; + result += "extern srand\n"; + result += "extern time\n"; result += "section .data\n"; result += " fmt db '%d', 10, 0\n"; result += "section .data\n"; result += " fmt_int db '%d', 10, 0\n"; // Format dla liczb - result += " fmt_str db '%s', 10, 0\n"; // NOWOŒÆ: Format dla stringów + result += " fmt_str db '%s', 10, 0\n"; // Format dla stringów // --- WYPISYWANIE STRINGÓW --- - for (const auto& pair : state.stringLiterals) { - // Nazwa etykiety: db 'Tresc', 0 - // Uwaga: ASM nie lubi pewnych znaków, ale zak³adamy proste litery - result += " " + pair.second + " db '" + pair.first + "', 0\n"; - } + for (const auto& pair : state.stringLiterals) { result += " " + pair.second + " db '" + pair.first + "', 0\n"; } result += "section .text\n\n"; for (const auto& pair : state.functions) { @@ -88,7 +87,9 @@ std::string generateAssembly(const CompilerState& state) { instr.type == OpType::ADD || instr.type == OpType::EQ || instr.type == OpType::SUB || - instr.type == OpType::MUL); + instr.type == OpType::MUL || + instr.type == OpType::DIV || + instr.type == OpType::MOD); if (isWriteOp && stackMap.find(instr.arg1) == stackMap.end() && instr.arg1 != "RAX") { stackMap[instr.arg1] = currentStack; @@ -264,9 +265,59 @@ std::string generateAssembly(const CompilerState& state) { } } + // ... wewn¹trz case OpType::CALL ... + if (instr.arg1 == "sys_seed") { + result += " mov rcx, 0\n"; + result += " call time\n"; // Pobierz czas + result += " mov rcx, rax\n"; // Czas jako argument dla srand + result += " call srand\n"; // Inicjuj generator + break; + } + if (instr.arg1 == "sys_rand") { + result += " call rand\n"; // Wynik w EAX + break; + } + result += " call " + instr.arg1 + "\n"; break; } + case OpType::DIV: { + std::string op1 = getVarLocation(instr.arg2, stackMap); + std::string op2 = getVarLocation(instr.arg3, stackMap); + std::string dst = getVarLocation(instr.arg1, stackMap); + + result += " mov eax, " + op1 + "\n"; + result += " cdq\n"; // Rozszerza EAX na EDX:EAX (konieczne przed dzieleniem) + + // IDIV nie przyjmuje sta³ej (np. 10), musi byæ rejestr + if (isdigit(op2[0]) || op2[0] == '-') { + result += " mov ecx, " + op2 + "\n"; + result += " idiv ecx\n"; + } + else { + result += " idiv dword " + op2 + "\n"; + } + result += " mov " + dst + ", eax\n"; // Wynik dzielenia + break; + } + case OpType::MOD: { + std::string op1 = getVarLocation(instr.arg2, stackMap); + std::string op2 = getVarLocation(instr.arg3, stackMap); + std::string dst = getVarLocation(instr.arg1, stackMap); + + result += " mov eax, " + op1 + "\n"; + result += " cdq\n"; // Rozszerza EAX + + if (isdigit(op2[0]) || op2[0] == '-') { + result += " mov ecx, " + op2 + "\n"; + result += " idiv ecx\n"; + } + else { + result += " idiv dword " + op2 + "\n"; + } + result += " mov " + dst + ", edx\n"; // EDX to reszta z dzielenia! + break; + } } } @@ -277,4 +328,4 @@ std::string generateAssembly(const CompilerState& state) { } return result; -} +} \ No newline at end of file diff --git a/PCCcompiler/compiler_types.h b/PCCcompiler/compiler_types.h index ebb235c..c211d0b 100644 --- a/PCCcompiler/compiler_types.h +++ b/PCCcompiler/compiler_types.h @@ -19,6 +19,8 @@ enum class OpType { LABEL, // miejsce skoku CALL, // wywo³anie funkcji RETURN, // return x + DIV, // dzielenie + MOD, // Reszta z dzelenia (%) NOP // pusta instrukcja }; diff --git a/PCCcompiler/parser.cpp b/PCCcompiler/parser.cpp index 4c38f48..10a0e9a 100644 --- a/PCCcompiler/parser.cpp +++ b/PCCcompiler/parser.cpp @@ -37,7 +37,6 @@ void processSource(const std::string& src, CompilerState& state) { // --- 1. DEFINICJA FUNKCJI --- // Warunki: zaczyna siÄ™ od typu, ma '(', ma '{' i NIE ma '=' (żeby nie mylić ze zmiennÄ…) bool startsWithType = (line.rfind("int ", 0) == 0 || line.rfind("void ", 0) == 0 || line.rfind("bool ", 0) == 0); - if (startsWithType && line.find("(") != std::string::npos && line.find("{") != std::string::npos && line.find("=") == std::string::npos) { size_t openParen = line.find('('); @@ -56,7 +55,6 @@ void processSource(const std::string& src, CompilerState& state) { std::cout << "[PARSER] New Function: " << funcName << "\n"; continue; } - // --- 2. ZAMYKANIE BLOKU '}' --- if (line == "}") { // Najpierw sprawdzamy, czy zamykamy IF-a (czy jest coÅ› na stosie bloków) @@ -75,7 +73,6 @@ void processSource(const std::string& src, CompilerState& state) { } continue; } - // --- JESTEÅšMY W ÅšRODKU FUNKCJI --- if (state.currentFunction) { Function& f = *state.currentFunction; @@ -188,6 +185,19 @@ void processSource(const std::string& src, CompilerState& state) { std::string b = trim(rightSide.substr(opPos + 1)); f.instructions.push_back({ OpType::MUL, varName, a, b }); // <--- Używamy MUL } + else if (rightSide.find("/") != std::string::npos) { + size_t opPos = rightSide.find("/"); + std::string a = trim(rightSide.substr(0, opPos)); + std::string b = trim(rightSide.substr(opPos + 1)); + f.instructions.push_back({ OpType::DIV, varName, a, b }); + } + // MODULO: a % b + else if (rightSide.find("%") != std::string::npos) { + size_t opPos = rightSide.find("%"); + std::string a = trim(rightSide.substr(0, opPos)); + std::string b = trim(rightSide.substr(opPos + 1)); + f.instructions.push_back({ OpType::MOD, varName, a, b }); + } // 3. Czy to porównanie? a == b (Ważne: == może być w IFie, ale tu jesteÅ›my w linii z '=') // UWAGA: To rzadkie w C++ (bool x = a == b), ale obsÅ‚użmy proste przypisanie wartoÅ›ci logicznej else if (rightSide.find("==") != std::string::npos) { diff --git a/push.bat b/push.bat new file mode 100644 index 0000000..551557c --- /dev/null +++ b/push.bat @@ -0,0 +1,28 @@ +@echo off +echo --- AUTO GIT PUSHER --- +echo. + +:: 1. Dodajemy wszystkie pliki +echo [1/3] Adding files... +git add . + +:: 2. Pytamy o nazwÄ™ commita +echo. +set /p commit_msg="Enter commit message: " + +:: Sprawdzamy czy wpisano wiadomość, jak nie to dajemy domyÅ›lnÄ… +if "%commit_msg%"=="" set commit_msg="Auto update" + +:: 3. Robimy commit +echo. +echo [2/3] Committing with message: "%commit_msg%"... +git commit -m "%commit_msg%" + +:: 4. WysyÅ‚amy (zakÅ‚adajÄ…c, że masz już ustawiony 'origin') +echo. +echo [3/3] Pushing to repository... +git push + +echo. +echo DONE! +pause