Files
PCCCompiler/PCCcompiler/preprocessor.cpp
2026-02-07 11:33:50 +01:00

90 lines
3.5 KiB
C++

#include "preprocessor.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <filesystem>
#include <regex>
namespace fs = std::filesystem;
// Funkcja pomocnicza do wczytania pliku
std::string loadFileContent(const std::string& path) {
std::ifstream in(path);
if (!in) {
std::cerr << "[PREPROCESSOR] Error: Could not open included file: " << path << "\n";
return "";
}
return std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
}
std::string preprocessSource(const std::string& src, const std::string& basePath) {
std::istringstream iss(src);
std::string line;
std::stringstream output;
while (std::getline(iss, line)) {
// Szukamy: #include "..." lub #include <...>
// U¿ywamy prostego find, ¿eby by³o szybko
std::string trimLine = line;
// Usuwamy bia³e znaki z pocz¹tku
size_t first = trimLine.find_first_not_of(" \t");
if (first != std::string::npos) trimLine = trimLine.substr(first);
if (trimLine.rfind("#include", 0) == 0) {
// Mamy include!
size_t openQuote = trimLine.find('"');
size_t closeQuote = trimLine.rfind('"');
size_t openAngle = trimLine.find('<');
size_t closeAngle = trimLine.rfind('>');
std::string includePath;
bool isStdLib = false;
// Wersja: #include "plik.pcc"
if (openQuote != std::string::npos && closeQuote > openQuote) {
includePath = trimLine.substr(openQuote + 1, closeQuote - openQuote - 1);
}
// Wersja: #include <plik.pcc>
else if (openAngle != std::string::npos && closeAngle > openAngle) {
includePath = trimLine.substr(openAngle + 1, closeAngle - openAngle - 1);
isStdLib = true;
}
if (!includePath.empty()) {
std::string fullPath;
if (isStdLib) {
// Biblioteka standardowa: szukamy w folderze "std" obok exe/projektu
// U¿ywamy current_path() + "std"
fullPath = "std/" + includePath;
std::cout << "[PREPROCESSOR] Including STD lib: " << fullPath << "\n";
}
else {
// Plik lokalny: szukamy w tym samym folderze co plik Ÿród³owy
// Jeœli basePath jest pusty, szukamy lokalnie
if (basePath.empty()) fullPath = includePath;
else fullPath = basePath + "/" + includePath;
std::cout << "[PREPROCESSOR] Including local file: " << fullPath << "\n";
}
// Wczytujemy plik i REKURENCYJNIE go przetwarzamy
// (bo plik do³¹czany mo¿e mieæ swoje include!)
std::string content = loadFileContent(fullPath);
// Dla uproszczenia rekurencji w include'ach lokalnych, przekazujemy ten sam basePath
// W idealnym œwiecie powinniœmy braæ folder nowego pliku.
std::string processedContent = preprocessSource(content, basePath);
output << "\n// --- BEGIN INCLUDE: " << includePath << " ---\n";
output << processedContent;
output << "\n// --- END INCLUDE ---\n";
}
}
else {
// Zwyk³a linia kodu - przepisujemy bez zmian
output << line << "\n";
}
}
return output.str();
}