#include #include #include #include #include #include #include #include "compiler_types.h" #include "parser.h" #include "codegen.h" #include "preprocessor.h" std::string getExecutablePath() { char buffer[MAX_PATH]; GetModuleFileNameA(NULL, buffer, MAX_PATH); std::string::size_type pos = std::string(buffer).find_last_of("\\/"); return std::string(buffer).substr(0, pos); } int main(int argc, char* argv[]) { std::string inputFile, outputName; std::string Version = "v0.0.5-beta"; bool showHelp = false, showVersion = false, showCredits = false; // --- PARSOWANIE ARGUMENTÓW --- for (int i = 1; i < argc; i++) { std::string arg = argv[i]; if (arg == "--help" || arg == "-h") { showHelp = true; } else if (arg == "--version" || arg == "-v") { showVersion = true; } else if (arg == "--credits" || arg == "-c") { showCredits = true; } else if (arg.substr(0, 2) == "-o") { if (arg.size() > 2) { outputName = arg.substr(2); } else if (i + 1 < argc) { outputName = argv[++i]; } } else { inputFile = arg; } } // --- OBSŁUGA INFORMACYJNA --- if (showVersion) { std::cout << "PCC Compiler " << Version << " (x64, Modular structure)\n"; return 0; } if (showCredits) { std::cout << "Created by: Michal Lewandowski\n"; std::cout << "Contact : slawek.1q2w3e4r@gmail.com\n"; // Twój email z oryginału std::cout << "Docs: https://nodrop.xyz/PCC_docs.html\n"; return 0; } if (showHelp || inputFile.empty()) { std::cout << "PCC Compiler " << Version << "\n"; std::cout << "Usage: PCC [Options] File.pcc\n\n"; std::cout << "Options:\n"; std::cout << " -h, --help Show Help\n"; std::cout << " -v, --version Show Version\n"; std::cout << " -o Name Exe Name (output\\Name.exe)\n"; return 0; } // --- WCZYTYWANIE PLIKU --- std::ifstream in(inputFile); if (!in) { std::cerr << "Error: Cannot open file " << inputFile << "\n"; return 1; } // ... wczytywanie pliku (to co miałeś) ... std::string src((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); // --- PREPROCESSOR START --- std::cout << "[INFO] Preprocessing...\n"; // 1. Ścieżka projektu (tam gdzie plik wejściowy) std::filesystem::path p(inputFile); std::string projectDir = p.parent_path().string(); // 2. Ścieżka kompilatora (tam gdzie PCC.exe i folder std) std::string compilerDir = getExecutablePath(); // Uruchamiamy z obiema ścieżkami src = preprocessSource(src, projectDir, compilerDir); CompilerState state; std::cout << "[INFO] Parsing code...\n"; // 1. Parsowanie tekstu do struktur processSource(src, state); std::cout << "[INFO] Calculating expressions...\n"; // 2. Obliczanie matematyki calculateExpressions(state); std::cout << "[INFO] Generating Assembly...\n"; // 3. Generowanie kodu ASM std::string asmCode = generateAssembly(state); // --- ZAPIS I KOMPILACJA ZEWNĘTRZNA --- std::system("if not exist output mkdir output"); // 1. Ustal bazową nazwę (bez rozszerzenia) std::string baseName; if (outputName.empty()) { // Jeśli nie podano -o, weź nazwę pliku wejściowego i utnij .pcc size_t lastDot = inputFile.find_last_of("."); if (lastDot != std::string::npos) baseName = inputFile.substr(0, lastDot); else baseName = inputFile; } else { // Jeśli podano -o, sprawdź czy ma .exe i ewentualnie utnij // (żebyśmy mogli dodać .asm i .obj bez bałaganu) size_t exePos = outputName.find(".exe"); if (exePos != std::string::npos) baseName = outputName.substr(0, exePos); else baseName = outputName; } // Teraz budujemy ścieżki - czysto i ładnie std::string asmPath = "output\\" + baseName + ".asm"; std::string objPath = "output\\" + baseName + ".obj"; std::string exePath = "output\\" + baseName + ".exe"; // Zapisz ASM std::ofstream asmOut(asmPath); asmOut << asmCode; asmOut.close(); std::cout << "ASM saved to: " << asmPath << "\n"; // Uruchom NASM std::string nasmCmd = "nasm -f win64 \"" + asmPath + "\" -o \"" + objPath + "\""; if (std::system(nasmCmd.c_str()) != 0) { std::cerr << "NASM Error! Check if NASM is in PATH.\n"; return 1; } // Uruchom GoLink std::string linkCmd = "go-link.exe /console /entry:main \"" + objPath + "\" msvcrt.dll kernel32.dll user32.dll \"" + exePath + "\""; if (std::system(linkCmd.c_str()) != 0) { std::cerr << "GoLink Error! Check if go-link.exe is in PATH.\n"; return 1; } std::cout << "SUCCESS! Executable created: " << exePath << "\n"; return 0; }