From 3658cb8407814603aceaf2970a5c1016b6c9fdc8 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 6 Aug 2025 16:41:31 +0100 Subject: feat! breaking API changes before NeKernel.org 0.0.4. Signed-off-by: Amlal El Mahrouss --- dev/CompilerKit/src/AssemblyFactory.cc | 52 ++ dev/CompilerKit/src/Backend/Assembler32x0.cc | 2 +- dev/CompilerKit/src/Backend/Assembler64x0.cc | 2 +- dev/CompilerKit/src/Backend/AssemblerARM64.cc | 2 +- dev/CompilerKit/src/Backend/AssemblerPowerPC.cc | 2 +- dev/CompilerKit/src/BasicString.cc | 178 ---- dev/CompilerKit/src/CodeGen.cc | 52 -- dev/CompilerKit/src/Frontend.cc | 51 -- dev/CompilerKit/src/Frontend/CCompiler64x0.cc | 2 +- dev/CompilerKit/src/Frontend/CCompilerARM64.cc | 2 +- dev/CompilerKit/src/Frontend/CCompilerPower64.cc | 2 +- dev/CompilerKit/src/FrontendHelpers.cc | 51 ++ dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc | 5 +- .../src/Macro/CPlusPlusCompilerPreProcessor.cc | 893 --------------------- dev/CompilerKit/src/Macro/CPlusPlusPreprocessor.cc | 893 +++++++++++++++++++++ dev/CompilerKit/src/StringKit.cc | 179 +++++ 16 files changed, 1184 insertions(+), 1184 deletions(-) create mode 100644 dev/CompilerKit/src/AssemblyFactory.cc delete mode 100644 dev/CompilerKit/src/BasicString.cc delete mode 100644 dev/CompilerKit/src/CodeGen.cc delete mode 100644 dev/CompilerKit/src/Frontend.cc create mode 100644 dev/CompilerKit/src/FrontendHelpers.cc delete mode 100644 dev/CompilerKit/src/Macro/CPlusPlusCompilerPreProcessor.cc create mode 100644 dev/CompilerKit/src/Macro/CPlusPlusPreprocessor.cc create mode 100644 dev/CompilerKit/src/StringKit.cc (limited to 'dev/CompilerKit/src') diff --git a/dev/CompilerKit/src/AssemblyFactory.cc b/dev/CompilerKit/src/AssemblyFactory.cc new file mode 100644 index 0000000..1f08b32 --- /dev/null +++ b/dev/CompilerKit/src/AssemblyFactory.cc @@ -0,0 +1,52 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved + +------------------------------------------- */ + +#include +#include + +/** + * @file AssemblyFactory.cc + * @author Amlal El Mahrouss (amlal@nekernel.org) + * @brief Compiler API of NeCTI + * @version 0.0.2 + * + * @copyright Copyright (c) 2024-2025 Amlal El Mahrouss + * + */ + +namespace CompilerKit { +///! @brief Compile for specific format (ELF, PEF, ZBIN) +Int32 AssemblyFactory::Compile(STLString sourceFile, const Int32& arch) noexcept { + if (sourceFile.length() < 1) return NECTI_UNIMPLEMENTED; + + if (!fMounted) return NECTI_UNIMPLEMENTED; + if (arch != fMounted->Arch()) return NECTI_INVALID_ARCH; + + try { + return this->fMounted->CompileToFormat(sourceFile, arch); + } catch (std::exception& e) { + return NECTI_EXEC_ERROR; + } +} + +///! @brief mount assembly backend. +void AssemblyFactory::Mount(AssemblyInterface* mountPtr) noexcept { + if (mountPtr) { + fMounted = mountPtr; + } +} + +///! @brief Unmount assembler. +AssemblyInterface* AssemblyFactory::Unmount() noexcept { + auto mount_prev = fMounted; + + if (fMounted) { + fMounted = nullptr; + } + + return mount_prev; +} +} // namespace CompilerKit diff --git a/dev/CompilerKit/src/Backend/Assembler32x0.cc b/dev/CompilerKit/src/Backend/Assembler32x0.cc index bc52d25..a7cb022 100644 --- a/dev/CompilerKit/src/Backend/Assembler32x0.cc +++ b/dev/CompilerKit/src/Backend/Assembler32x0.cc @@ -8,7 +8,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// -// @file 32asm.cxx +// @file 32asm.cc // @author EL Mahrouss Amlal // @brief 32x0 Assembler. diff --git a/dev/CompilerKit/src/Backend/Assembler64x0.cc b/dev/CompilerKit/src/Backend/Assembler64x0.cc index 511c64d..6bc8842 100644 --- a/dev/CompilerKit/src/Backend/Assembler64x0.cc +++ b/dev/CompilerKit/src/Backend/Assembler64x0.cc @@ -8,7 +8,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// -// @file Assembler64x0.cxx +// @file Assembler64x0.cc // @author EL Mahrouss Amlal // @brief 64x000 Assembler. diff --git a/dev/CompilerKit/src/Backend/AssemblerARM64.cc b/dev/CompilerKit/src/Backend/AssemblerARM64.cc index 6890b2c..331e708 100644 --- a/dev/CompilerKit/src/Backend/AssemblerARM64.cc +++ b/dev/CompilerKit/src/Backend/AssemblerARM64.cc @@ -6,7 +6,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// -/// @file AssemblerARM64.cxx +/// @file AssemblerARM64.cc /// @author EL Mahrouss Amlal /// @brief 'ACORN' Assembler. diff --git a/dev/CompilerKit/src/Backend/AssemblerPowerPC.cc b/dev/CompilerKit/src/Backend/AssemblerPowerPC.cc index b02a112..bbb5a8b 100644 --- a/dev/CompilerKit/src/Backend/AssemblerPowerPC.cc +++ b/dev/CompilerKit/src/Backend/AssemblerPowerPC.cc @@ -6,7 +6,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// -/// @file AssemblerPower.cxx +/// @file AssemblerPower.cc /// @author EL Mahrouss Amlal /// @brief POWER Assembler. diff --git a/dev/CompilerKit/src/BasicString.cc b/dev/CompilerKit/src/BasicString.cc deleted file mode 100644 index dc263aa..0000000 --- a/dev/CompilerKit/src/BasicString.cc +++ /dev/null @@ -1,178 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved. - * - * ======================================================== - */ - -/** - * @file BasicString.cc - * @author Amlal (amlal@nekernel.org) - * @brief C++ string manipulation API. - * @version 0.2 - * @date 2024-01-23 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#include - -namespace CompilerKit { - -Char* BasicString::Data() { - return m_Data; -} - -const Char* BasicString::CData() const { - return m_Data; -} - -SizeType BasicString::Length() const { - return strlen(m_Data); -} - -bool BasicString::operator==(const BasicString& rhs) const { - const SizeType len = Length(); - if (rhs.Length() != len) return false; - return memcmp(m_Data, rhs.m_Data, len) == 0; -} - -bool BasicString::operator==(const Char* rhs) const { - const SizeType rhs_len = string_length(rhs); - const SizeType len = Length(); - if (rhs_len != len) return false; - return memcmp(m_Data, rhs, len) == 0; -} - -bool BasicString::operator!=(const BasicString& rhs) const { - return !(*this == rhs); -} - -bool BasicString::operator!=(const Char* rhs) const { - return !(*this == rhs); -} - -BasicString StringBuilder::Construct(const Char* data) { - if (!data || *data == 0) return BasicString(0); - - BasicString view(strlen(data)); - view += data; - - return view; -} - -BasicString StringBuilder::FromInt(const char* fmt, int i) { - if (!fmt) return BasicString(0); - - Char result[sizeof(int64_t)] = {0}; - if (!to_str(result, sizeof(int64_t), i)) return BasicString(0); - - const SizeType fmt_len = string_length(fmt); - const SizeType res_len = string_length(result); - - BasicString output(fmt_len + res_len); - bool inserted = false; - - for (SizeType idx = 0; idx < fmt_len; ++idx) { - if (!inserted && fmt[idx] == '%') { - output += result; - inserted = true; - continue; - } - output += Char{fmt[idx]}; - } - - return output; -} - -BasicString StringBuilder::FromBool(const char* fmt, bool val) { - if (!fmt) return BasicString(0); - - const Char* boolean_expr = val ? "true" : "false"; - const SizeType fmt_len = string_length(fmt); - const SizeType res_len = string_length(boolean_expr); - - BasicString output(fmt_len + res_len); - bool inserted = false; - - for (SizeType idx = 0; idx < fmt_len; ++idx) { - if (!inserted && fmt[idx] == '%') { - output += boolean_expr; - inserted = true; - continue; - } - output += Char{fmt[idx]}; - } - - return output; -} - -bool StringBuilder::Equals(const char* lhs, const char* rhs) { - const SizeType lhs_len = string_length(lhs); - const SizeType rhs_len = string_length(rhs); - - if (lhs_len != rhs_len) return false; - return memcmp(lhs, rhs, lhs_len) == 0; -} - -BasicString StringBuilder::Format(const char* fmt, const char* fmtRight) { - if (!fmt || !fmtRight) return BasicString(0); - - const SizeType fmt_len = string_length(fmt); - const SizeType rhs_len = string_length(fmtRight); - - BasicString output(fmt_len + rhs_len); - bool inserted = false; - - for (SizeType idx = 0; idx < fmt_len; ++idx) { - if (!inserted && fmt[idx] == '%') { - output += fmtRight; - inserted = true; - continue; - } - output += Char{fmt[idx]}; - } - - return output; -} - -BasicString& BasicString::operator+=(const Char* rhs) { - const SizeType rhs_len = strlen(rhs); - if (this->m_Cur + rhs_len >= this->m_Sz) { - throw std::runtime_error("out_of_bounds: BasicString"); - } - - memcpy(this->m_Data + this->m_Cur, rhs, rhs_len); - this->m_Cur += rhs_len; - this->m_Data[this->m_Cur] = '\0'; - - return *this; -} - -BasicString& BasicString::operator+=(const BasicString& rhs) { - if (this->m_Cur + rhs.m_Cur >= this->m_Sz) { - throw std::runtime_error("out_of_bounds: BasicString"); - } - - memcpy(this->m_Data + this->m_Cur, rhs.CData(), rhs.m_Cur); - this->m_Cur += rhs.m_Cur; - this->m_Data[this->m_Cur] = '\0'; - - return *this; -} - -BasicString& BasicString::operator+=(Char ch) { - if (this->m_Cur + 1 >= this->m_Sz) { - throw std::runtime_error("out_of_bounds.."); - } - - this->m_Data[this->m_Cur++] = ch; - this->m_Data[this->m_Cur] = '\0'; - - return *this; -} - -} // namespace CompilerKit diff --git a/dev/CompilerKit/src/CodeGen.cc b/dev/CompilerKit/src/CodeGen.cc deleted file mode 100644 index 693d7a5..0000000 --- a/dev/CompilerKit/src/CodeGen.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved - -------------------------------------------- */ - -#include -#include - -/** - * @file CodeGen.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief CodeGen API of NeCTI - * @version 0.0.2 - * - * @copyright Copyright (c) 2024-2025 Amlal El Mahrouss - * - */ - -namespace CompilerKit { -///! @brief Compile for specific format (ELF, PEF, ZBIN) -Int32 AssemblyFactory::Compile(STLString sourceFile, const Int32& arch) noexcept { - if (sourceFile.length() < 1) return NECTI_UNIMPLEMENTED; - - if (!fMounted) return NECTI_UNIMPLEMENTED; - if (arch != fMounted->Arch()) return NECTI_INVALID_ARCH; - - try { - return this->fMounted->CompileToFormat(sourceFile, arch); - } catch (std::exception& e) { - return NECTI_EXEC_ERROR; - } -} - -///! @brief mount assembly backend. -void AssemblyFactory::Mount(AssemblyInterface* mountPtr) noexcept { - if (mountPtr) { - fMounted = mountPtr; - } -} - -///! @brief Unmount assembler. -AssemblyInterface* AssemblyFactory::Unmount() noexcept { - auto mount_prev = fMounted; - - if (fMounted) { - fMounted = nullptr; - } - - return mount_prev; -} -} // namespace CompilerKit diff --git a/dev/CompilerKit/src/Frontend.cc b/dev/CompilerKit/src/Frontend.cc deleted file mode 100644 index 37b36f7..0000000 --- a/dev/CompilerKit/src/Frontend.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025 Amlal EL Mahrouss, all rights reserved - -------------------------------------------- */ - -#include - -namespace CompilerKit { -/// find the perfect matching word in a haystack. -/// \param haystack base string -/// \param needle the string we search for. -/// \return if we found it or not. -BOOL find_word(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - // declare lambda - auto not_part_of_word = [&](int index) { - if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) return true; - - if (index <= 0 || index >= haystack.size()) return true; - - return false; - }; - - return not_part_of_word(index - 1) && not_part_of_word(index + needle.size()); -} - -/// find a word within strict conditions and returns a range of it. -/// \param haystack -/// \param needle -/// \return position of needle. -SizeType find_word_range(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - if (!isalnum((haystack[index + needle.size() + 1])) && - !isdigit(haystack[index + needle.size() + 1]) && - !isalnum((haystack[index - needle.size() - 1])) && - !isdigit(haystack[index - needle.size() - 1])) { - return index; - } - - return STLString::npos; -} -} // namespace CompilerKit \ No newline at end of file diff --git a/dev/CompilerKit/src/Frontend/CCompiler64x0.cc b/dev/CompilerKit/src/Frontend/CCompiler64x0.cc index 6ee7e32..1221521 100644 --- a/dev/CompilerKit/src/Frontend/CCompiler64x0.cc +++ b/dev/CompilerKit/src/Frontend/CCompiler64x0.cc @@ -28,7 +28,7 @@ /* (c) Amlal El Mahrouss */ /// @author EL Mahrouss Amlal (amlel) -/// @file 64x0-cc.cxx +/// @file 64x0-cc.cc /// @brief 64x0 C Compiler. /// TODO: support structures, else if, else, . and -> diff --git a/dev/CompilerKit/src/Frontend/CCompilerARM64.cc b/dev/CompilerKit/src/Frontend/CCompilerARM64.cc index 1c1582f..6795c67 100644 --- a/dev/CompilerKit/src/Frontend/CCompilerARM64.cc +++ b/dev/CompilerKit/src/Frontend/CCompilerARM64.cc @@ -29,7 +29,7 @@ /* (c) Amlal El Mahrouss */ /// @author EL Mahrouss Amlal (amlel) -/// @file ARM64-cc.cxx +/// @file ARM64-cc.cc /// @brief ARM64 C Compiler. /// TODO: support structures, else if, else, . and -> diff --git a/dev/CompilerKit/src/Frontend/CCompilerPower64.cc b/dev/CompilerKit/src/Frontend/CCompilerPower64.cc index 40598c9..1999f48 100644 --- a/dev/CompilerKit/src/Frontend/CCompilerPower64.cc +++ b/dev/CompilerKit/src/Frontend/CCompilerPower64.cc @@ -23,7 +23,7 @@ #define kExitOK 0 /// @author EL Mahrouss Amlal (amlal@nekernel.org) -/// @file cc.cxx +/// @file cc.cc /// @brief POWER64 C Compiler. ///////////////////// diff --git a/dev/CompilerKit/src/FrontendHelpers.cc b/dev/CompilerKit/src/FrontendHelpers.cc new file mode 100644 index 0000000..37b36f7 --- /dev/null +++ b/dev/CompilerKit/src/FrontendHelpers.cc @@ -0,0 +1,51 @@ +/* ------------------------------------------- + + Copyright (C) 2025 Amlal EL Mahrouss, all rights reserved + +------------------------------------------- */ + +#include + +namespace CompilerKit { +/// find the perfect matching word in a haystack. +/// \param haystack base string +/// \param needle the string we search for. +/// \return if we found it or not. +BOOL find_word(STLString haystack, STLString needle) noexcept { + auto index = haystack.find(needle); + + // check for needle validity. + if (index == STLString::npos) return false; + + // declare lambda + auto not_part_of_word = [&](int index) { + if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) return true; + + if (index <= 0 || index >= haystack.size()) return true; + + return false; + }; + + return not_part_of_word(index - 1) && not_part_of_word(index + needle.size()); +} + +/// find a word within strict conditions and returns a range of it. +/// \param haystack +/// \param needle +/// \return position of needle. +SizeType find_word_range(STLString haystack, STLString needle) noexcept { + auto index = haystack.find(needle); + + // check for needle validity. + if (index == STLString::npos) return false; + + if (!isalnum((haystack[index + needle.size() + 1])) && + !isdigit(haystack[index + needle.size() + 1]) && + !isalnum((haystack[index - needle.size() - 1])) && + !isdigit(haystack[index - needle.size() - 1])) { + return index; + } + + return STLString::npos; +} +} // namespace CompilerKit \ No newline at end of file diff --git a/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc b/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc index 0aa2b78..394014c 100644 --- a/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc +++ b/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -317,7 +317,6 @@ NECTI_MODULE(DynamicLinker64PEF) { if (kVerbose) { kConsoleOut << "Record: " << ae_records[ae_record_index].fName << " is marked.\n"; - kConsoleOut << "Offset: " << command_header.Offset << "\n"; } @@ -660,7 +659,7 @@ NECTI_MODULE(DynamicLinker64PEF) { if ((!kStartFound || kDuplicateSymbols) && (std::filesystem::exists(kOutput) || !unreferenced_symbols.empty())) { if (kVerbose) { - kConsoleOut << "File: " << kOutput << ", is corrupt, removing file...\n"; + kConsoleOut << "File: " << kOutput << " is corrupt now...\n"; } return NECTI_EXEC_ERROR; diff --git a/dev/CompilerKit/src/Macro/CPlusPlusCompilerPreProcessor.cc b/dev/CompilerKit/src/Macro/CPlusPlusCompilerPreProcessor.cc deleted file mode 100644 index 9845967..0000000 --- a/dev/CompilerKit/src/Macro/CPlusPlusCompilerPreProcessor.cc +++ /dev/null @@ -1,893 +0,0 @@ -/* - * ======================================================== - * - * C++ Preprocessor Driver - * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved. - * - * ======================================================== - */ - -/// BUGS: 0 - -#include -#include -#include -#include -#include -#include -#include -#include - -#define kMacroPrefix '#' - -/// @author EL Mahrouss Amlal (amlel) -/// @file bpp.cxx -/// @brief Preprocessor. - -typedef Int32 (*bpp_parser_fn_t)(CompilerKit::STLString& line, std::ifstream& hdr_file, - std::ofstream& pp_out); - -///////////////////////////////////////////////////////////////////////////////////////// - -// @brief Preprocessor internal types. - -///////////////////////////////////////////////////////////////////////////////////////// - -namespace Detail { -enum { - kInvalid = 0, - kEqual = 100, - kGreaterEqThan, - kLesserEqThan, - kGreaterThan, - kLesserThan, - kNotEqual, - kCount = 6, -}; - -struct bpp_macro_condition final { - int32_t fType; - CompilerKit::STLString fTypeName; - - void Print() { - std::cout << "type: " << fType << "\n"; - std::cout << "type_name: " << fTypeName << "\n"; - } -}; - -struct bpp_macro final { - std::vector fArgs; - CompilerKit::STLString fName; - CompilerKit::STLString fValue; - - void Print() { - std::cout << "name: " << fName << "\n"; - std::cout << "value: " << fValue << "\n"; - - for (auto& arg : fArgs) { - std::cout << "arg: " << arg << "\n"; - } - } -}; -} // namespace Detail - -static std::vector kFiles; -static std::vector kMacros; -static std::vector kIncludes; - -static CompilerKit::STLString kWorkingDir = ""; - -///////////////////////////////////////////////////////////////////////////////////////// - -// @name bpp_parse_if_condition -// @brief parse #if condition - -///////////////////////////////////////////////////////////////////////////////////////// - -int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_macro& macro, - bool& inactive_code, bool& defined, - CompilerKit::STLString& macro_str) { - if (cond.fType == Detail::kEqual) { - auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); - - if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) { - if (macro.fValue == "0") { - defined = false; - inactive_code = true; - - return 1; - } - - defined = true; - inactive_code = false; - - return 1; - } - } else if (cond.fType == Detail::kNotEqual) { - auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); - - if (substr_macro.find(macro.fName) != CompilerKit::STLString::npos) { - if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) { - defined = false; - inactive_code = true; - - return 1; - } - - defined = true; - inactive_code = false; - - return 1; - } - - return 0; - } - - auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); - - CompilerKit::STLString number; - - for (auto& macro_num : kMacros) { - if (substr_macro.find(macro_num.fName) != CompilerKit::STLString::npos) { - for (size_t i = 0; i < macro_num.fName.size(); ++i) { - if (isdigit(macro_num.fValue[i])) { - number += macro_num.fValue[i]; - } else { - number.clear(); - break; - } - } - - break; - } - } - - size_t y = 2; - - /* last try */ - for (; y < macro_str.size(); y++) { - if (isdigit(macro_str[y])) { - for (size_t x = y; x < macro_str.size(); x++) { - if (macro_str[x] == ' ') break; - - number += macro_str[x]; - } - - break; - } - } - - size_t rhs = atol(macro.fValue.c_str()); - size_t lhs = atol(number.c_str()); - - if (lhs == 0) { - number.clear(); - ++y; - - for (; y < macro_str.size(); y++) { - if (isdigit(macro_str[y])) { - for (size_t x = y; x < macro_str.size(); x++) { - if (macro_str[x] == ' ') break; - - number += macro_str[x]; - } - - break; - } - } - - lhs = atol(number.c_str()); - } - - if (cond.fType == Detail::kGreaterThan) { - if (lhs < rhs) { - defined = true; - inactive_code = false; - - return 1; - } - - return 0; - } - - if (cond.fType == Detail::kGreaterEqThan) { - if (lhs <= rhs) { - defined = true; - inactive_code = false; - - return 1; - } - - return 0; - } - - if (cond.fType == Detail::kLesserEqThan) { - if (lhs >= rhs) { - defined = true; - inactive_code = false; - - return 1; - } - - return 0; - } - - if (cond.fType == Detail::kLesserThan) { - if (lhs > rhs) { - defined = true; - inactive_code = false; - - return 1; - } - - return 0; - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -// @brief stores every included file here. - -///////////////////////////////////////////////////////////////////////////////////////// - -std::vector kAllIncludes; - -///////////////////////////////////////////////////////////////////////////////////////// - -// @name bpp_parse_file -// @brief parse file to preprocess it. - -///////////////////////////////////////////////////////////////////////////////////////// - -void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) { - CompilerKit::STLString hdr_line; - CompilerKit::STLString line_after_include; - - bool inactive_code = false; - bool defined = false; - - try { - while (std::getline(hdr_file, hdr_line)) { - if (inactive_code) { - if (hdr_line.find("#endif") == CompilerKit::STLString::npos) { - continue; - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("#endif") != CompilerKit::STLString::npos) { - inactive_code = false; - } - } - - if (hdr_line.find("*/") != CompilerKit::STLString::npos) { - hdr_line.erase(hdr_line.find("*/"), strlen("*/")); - } - - if (hdr_line.find("/*") != CompilerKit::STLString::npos) { - inactive_code = true; - - // get rid of comment. - hdr_line.erase(hdr_line.find("/*")); - } - - if (hdr_line[0] == kMacroPrefix && hdr_line.find("endif") != CompilerKit::STLString::npos) { - if (!defined && inactive_code) { - inactive_code = false; - defined = false; - - continue; - } - - continue; - } - - if (!defined && inactive_code) { - continue; - } - - if (defined && inactive_code) { - continue; - } - - for (auto macro : kMacros) { - if (CompilerKit::find_word(hdr_line, macro.fName)) { - if (hdr_line.substr(hdr_line.find(macro.fName)).find(macro.fName + '(') != - CompilerKit::STLString::npos) { - if (!macro.fArgs.empty()) { - CompilerKit::STLString symbol_val = macro.fValue; - std::vector args; - - size_t x_arg_indx = 0; - - CompilerKit::STLString line_after_define = hdr_line; - CompilerKit::STLString str_arg; - - if (line_after_define.find("(") != CompilerKit::STLString::npos) { - line_after_define.erase(0, line_after_define.find("(") + 1); - - for (auto& subc : line_after_define) { - if (subc == ' ' || subc == '\t') continue; - - if (subc == ',' || subc == ')') { - if (str_arg.empty()) continue; - - args.push_back(str_arg); - - str_arg.clear(); - - continue; - } - - str_arg.push_back(subc); - } - } - - for (auto arg : macro.fArgs) { - if (symbol_val.find(macro.fArgs[x_arg_indx]) != CompilerKit::STLString::npos) { - symbol_val.replace(symbol_val.find(macro.fArgs[x_arg_indx]), - macro.fArgs[x_arg_indx].size(), args[x_arg_indx]); - ++x_arg_indx; - } else { - throw std::runtime_error("cppdrv: Internal error."); - } - } - - auto len = macro.fName.size(); - len += symbol_val.size(); - len += 2; // ( and ) - - hdr_line.erase(hdr_line.find(")"), 1); - - hdr_line.replace(hdr_line.find(hdr_line.substr(hdr_line.find(macro.fName + '('))), - len, symbol_val); - } else { - auto value = macro.fValue; - - hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), value); - } - } - } - } - - if (hdr_line[0] == kMacroPrefix && hdr_line.find("define ") != CompilerKit::STLString::npos) { - auto line_after_define = hdr_line.substr(hdr_line.find("define ") + strlen("define ")); - - CompilerKit::STLString macro_value; - CompilerKit::STLString macro_key; - - std::size_t pos = 0UL; - - std::vector args; - bool on_args = false; - - for (auto& ch : line_after_define) { - ++pos; - - if (ch == '(') { - on_args = true; - continue; - } - - if (ch == ')') { - on_args = false; - continue; - } - - if (ch == '\\') continue; - - if (on_args) continue; - - if (ch == ' ') { - for (size_t i = pos; i < line_after_define.size(); i++) { - macro_value += line_after_define[i]; - } - - break; - } - - macro_key += ch; - } - - CompilerKit::STLString str; - - if (line_after_define.find("(") != CompilerKit::STLString::npos) { - line_after_define.erase(0, line_after_define.find("(") + 1); - - for (auto& subc : line_after_define) { - if (subc == ',' || subc == ')') { - if (str.empty()) continue; - - args.push_back(str); - - str.clear(); - - continue; - } - - str.push_back(subc); - } - } - - Detail::bpp_macro macro; - - macro.fArgs = args; - macro.fName = macro_key; - macro.fValue = macro_value; - - kMacros.emplace_back(macro); - - continue; - } - - if (hdr_line[0] != kMacroPrefix) { - if (inactive_code) { - continue; - } - - pp_out << hdr_line << std::endl; - - continue; - } - - if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != CompilerKit::STLString::npos) { - auto line_after_ifndef = hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1); - CompilerKit::STLString macro; - - for (auto& ch : line_after_ifndef) { - if (ch == ' ') { - break; - } - - macro += ch; - } - - if (macro == "0") { - defined = true; - inactive_code = false; - continue; - } - - if (macro == "1") { - defined = false; - inactive_code = true; - - continue; - } - - bool found = false; - - defined = true; - inactive_code = false; - - for (auto& macro_ref : kMacros) { - if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) { - found = true; - break; - } - } - - if (found) { - defined = false; - inactive_code = true; - - continue; - } - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("else") != CompilerKit::STLString::npos) { - if (!defined && inactive_code) { - inactive_code = false; - defined = true; - - continue; - } else { - defined = false; - inactive_code = true; - - continue; - } - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("ifdef") != CompilerKit::STLString::npos) { - auto line_after_ifdef = hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1); - CompilerKit::STLString macro; - - for (auto& ch : line_after_ifdef) { - if (ch == ' ') { - break; - } - - macro += ch; - } - - if (macro == "0") { - defined = false; - inactive_code = true; - - continue; - } - - if (macro == "1") { - defined = true; - inactive_code = false; - - continue; - } - - defined = false; - inactive_code = true; - - for (auto& macro_ref : kMacros) { - if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) { - defined = true; - inactive_code = false; - - break; - } - } - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("if") != CompilerKit::STLString::npos) { - inactive_code = true; - - std::vector bpp_macro_condition_list = { - { - .fType = Detail::kEqual, - .fTypeName = "==", - }, - { - .fType = Detail::kNotEqual, - .fTypeName = "!=", - }, - { - .fType = Detail::kLesserThan, - .fTypeName = "<", - }, - { - .fType = Detail::kGreaterThan, - .fTypeName = ">", - }, - { - .fType = Detail::kLesserEqThan, - .fTypeName = "<=", - }, - { - .fType = Detail::kGreaterEqThan, - .fTypeName = ">=", - }, - }; - - int32_t good_to_go = 0; - - for (auto& macro_condition : bpp_macro_condition_list) { - if (hdr_line.find(macro_condition.fTypeName) != CompilerKit::STLString::npos) { - for (auto& found_macro : kMacros) { - if (hdr_line.find(found_macro.fName) != CompilerKit::STLString::npos) { - good_to_go = bpp_parse_if_condition(macro_condition, found_macro, inactive_code, - defined, hdr_line); - - break; - } - } - } - } - - if (good_to_go) continue; - - auto line_after_if = hdr_line.substr(hdr_line.find("if") + strlen("if") + 1); - CompilerKit::STLString macro; - - for (auto& ch : line_after_if) { - if (ch == ' ') { - break; - } - - macro += ch; - } - - if (macro == "0") { - defined = false; - inactive_code = true; - continue; - } - - if (macro == "1") { - defined = true; - inactive_code = false; - - continue; - } - - // last try, is it defined to be one? - for (auto& macro_ref : kMacros) { - if (macro_ref.fName.find(macro) != CompilerKit::STLString::npos && - macro_ref.fValue == "1") { - inactive_code = false; - defined = true; - - break; - } - } - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("warning") != CompilerKit::STLString::npos) { - auto line_after_warning = hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1); - CompilerKit::STLString message; - - for (auto& ch : line_after_warning) { - if (ch == '\r' || ch == '\n') { - break; - } - - message += ch; - } - - std::cout << "warn: " << message << std::endl; - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("error") != CompilerKit::STLString::npos) { - auto line_after_warning = hdr_line.substr(hdr_line.find("error") + strlen("error") + 1); - CompilerKit::STLString message; - - for (auto& ch : line_after_warning) { - if (ch == '\r' || ch == '\n') { - break; - } - - message += ch; - } - - throw std::runtime_error("error: " + message); - } else if (hdr_line[0] == kMacroPrefix && - hdr_line.find("include ") != CompilerKit::STLString::npos) { - line_after_include = hdr_line.substr(hdr_line.find("include ") + strlen("include ")); - - kIncludeFile: - auto it = std::find(kAllIncludes.cbegin(), kAllIncludes.cend(), line_after_include); - - if (it != kAllIncludes.cend()) { - continue; - } - - CompilerKit::STLString path; - - kAllIncludes.push_back(line_after_include); - - bool enable = false; - bool not_local = false; - - for (auto& ch : line_after_include) { - if (ch == ' ') continue; - - if (ch == '<') { - not_local = true; - enable = true; - - continue; - } - - if (ch == '\"') { - not_local = false; - enable = true; - continue; - } - - if (enable) { - path += ch; - } - } - - if (not_local) { - bool open = false; - - if (path.ends_with('>')) { - path.erase(path.find('>')); - } - - if (path.ends_with('"')) { - path.erase(path.find('"')); - } - - for (auto& include : kIncludes) { - CompilerKit::STLString header_path = include; - header_path.push_back('/'); - header_path += path; - - std::ifstream header(header_path); - - if (!header.is_open()) continue; - - open = true; - - bpp_parse_file(header, pp_out); - - break; - } - - if (!open) { - throw std::runtime_error("cppdrv: no such include file: " + path); - } - } else { - std::ifstream header(path); - - if (!header.is_open()) throw std::runtime_error("cppdrv: no such include file: " + path); - - bpp_parse_file(header, pp_out); - } - } else { - std::cerr << ("cppdrv: unknown pre-processor directive, " + hdr_line) << "\n"; - continue; - } - } - } catch (std::out_of_range& oor) { - return; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -// @brief main entrypoint of app. - -///////////////////////////////////////////////////////////////////////////////////////// - -NECTI_MODULE(CPlusPlusPreprocessorMain) { - try { - bool skip = false; - bool double_skip = false; - - Detail::bpp_macro macro_1; - - macro_1.fName = "__true"; - macro_1.fValue = "1"; - - kMacros.push_back(macro_1); - - Detail::bpp_macro macro_unreachable; - - macro_unreachable.fName = "__unreachable"; - macro_unreachable.fValue = "__libcompiler_unreachable"; - - kMacros.push_back(macro_unreachable); - - Detail::bpp_macro macro_unused; - - macro_unreachable.fName = "__unused"; - macro_unreachable.fValue = "__libcompiler_unused"; - - kMacros.push_back(macro_unused); - - Detail::bpp_macro macro_0; - - macro_0.fName = "__false"; - macro_0.fValue = "0"; - - kMacros.push_back(macro_0); - - Detail::bpp_macro macro_zka; - - macro_zka.fName = "__NECTI__"; - macro_zka.fValue = "1"; - - kMacros.push_back(macro_zka); - - Detail::bpp_macro macro_cxx; - - macro_cxx.fName = "__cplusplus"; - macro_cxx.fValue = "202302L"; - - kMacros.push_back(macro_cxx); - - Detail::bpp_macro macro_size_t; - macro_size_t.fName = "__SIZE_TYPE__"; - macro_size_t.fValue = "unsigned long long int"; - - kMacros.push_back(macro_size_t); - - macro_size_t.fName = "__UINT32_TYPE__"; - macro_size_t.fValue = "unsigned int"; - - kMacros.push_back(macro_size_t); - - macro_size_t.fName = "__UINTPTR_TYPE__"; - macro_size_t.fValue = "unsigned long long int"; - - kMacros.push_back(macro_size_t); - - for (auto index = 1UL; index < argc; ++index) { - if (skip) { - skip = false; - continue; - } - - if (double_skip) { - ++index; - double_skip = false; - continue; - } - - if (argv[index][0] == '-') { - if (strcmp(argv[index], "-cpp-ver") == 0) { - printf("%s\n", - "NeKernel Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2025 all rights " - "reserved."); - - return NECTI_SUCCESS; - } - - if (strcmp(argv[index], "-cpp-help") == 0) { - printf("%s\n", - "NeKernel Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2025 all rights " - "reserved."); - printf("%s\n", "-cpp-working-dir : set directory to working path."); - printf("%s\n", "-cpp-include-dir : add directory to include path."); - printf("%s\n", "-cpp-def : define a macro."); - printf("%s\n", "-cpp-ver: print the version."); - printf("%s\n", "-cpp-help: show help (this current command)."); - - return NECTI_SUCCESS; - } - - if (strcmp(argv[index], "-cpp-include-dir") == 0) { - CompilerKit::STLString inc = argv[index + 1]; - - skip = true; - - kIncludes.push_back(inc); - } - - if (strcmp(argv[index], "-cpp-working-dir") == 0) { - CompilerKit::STLString inc = argv[index + 1]; - skip = true; - kWorkingDir = inc; - } - - if (strcmp(argv[index], "-cpp-def") == 0 && argv[index + 1] != nullptr && - argv[index + 2] != nullptr) { - CompilerKit::STLString macro_key = argv[index + 1]; - - CompilerKit::STLString macro_value; - bool is_string = false; - - for (int argv_find_len = 0; argv_find_len < strlen(argv[index]); ++argv_find_len) { - if (!isdigit(argv[index][argv_find_len])) { - is_string = true; - macro_value += "\""; - - break; - } - } - - macro_value += argv[index + 2]; - - if (is_string) macro_value += "\""; - - Detail::bpp_macro macro; - macro.fName = macro_key; - macro.fValue = macro_value; - - kMacros.push_back(macro); - - double_skip = true; - } - - continue; - } - - kFiles.emplace_back(argv[index]); - } - - if (kFiles.empty()) return NECTI_EXEC_ERROR; - - for (auto& file : kFiles) { - if (!std::filesystem::exists(file)) continue; - - std::ifstream file_descriptor(file); - std::ofstream file_descriptor_pp(file + ".pp"); - - bpp_parse_file(file_descriptor, file_descriptor_pp); - } - - return NECTI_SUCCESS; - } catch (const std::runtime_error& e) { - std::cout << e.what() << '\n'; - } - - return NECTI_EXEC_ERROR; -} - -// Last rev 8-1-24 diff --git a/dev/CompilerKit/src/Macro/CPlusPlusPreprocessor.cc b/dev/CompilerKit/src/Macro/CPlusPlusPreprocessor.cc new file mode 100644 index 0000000..aaa5793 --- /dev/null +++ b/dev/CompilerKit/src/Macro/CPlusPlusPreprocessor.cc @@ -0,0 +1,893 @@ +/* + * ======================================================== + * + * C++ Preprocessor Driver + * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved. + * + * ======================================================== + */ + +/// BUGS: 0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define kMacroPrefix '#' + +/// @author EL Mahrouss Amlal (amlel) +/// @file CPlusPlusPreprocessor.cc +/// @brief Preprocessor. + +typedef Int32 (*bpp_parser_fn_t)(CompilerKit::STLString& line, std::ifstream& hdr_file, + std::ofstream& pp_out); + +///////////////////////////////////////////////////////////////////////////////////////// + +// @brief Preprocessor internal types. + +///////////////////////////////////////////////////////////////////////////////////////// + +namespace Detail { +enum { + kInvalid = 0, + kEqual = 100, + kGreaterEqThan, + kLesserEqThan, + kGreaterThan, + kLesserThan, + kNotEqual, + kCount = 6, +}; + +struct bpp_macro_condition final { + int32_t fType; + CompilerKit::STLString fTypeName; + + void Print() { + std::cout << "type: " << fType << "\n"; + std::cout << "type_name: " << fTypeName << "\n"; + } +}; + +struct bpp_macro final { + std::vector fArgs; + CompilerKit::STLString fName; + CompilerKit::STLString fValue; + + void Print() { + std::cout << "name: " << fName << "\n"; + std::cout << "value: " << fValue << "\n"; + + for (auto& arg : fArgs) { + std::cout << "arg: " << arg << "\n"; + } + } +}; +} // namespace Detail + +static std::vector kFiles; +static std::vector kMacros; +static std::vector kIncludes; + +static CompilerKit::STLString kWorkingDir = ""; + +///////////////////////////////////////////////////////////////////////////////////////// + +// @name bpp_parse_if_condition +// @brief parse #if condition + +///////////////////////////////////////////////////////////////////////////////////////// + +int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_macro& macro, + bool& inactive_code, bool& defined, + CompilerKit::STLString& macro_str) { + if (cond.fType == Detail::kEqual) { + auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); + + if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) { + if (macro.fValue == "0") { + defined = false; + inactive_code = true; + + return 1; + } + + defined = true; + inactive_code = false; + + return 1; + } + } else if (cond.fType == Detail::kNotEqual) { + auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); + + if (substr_macro.find(macro.fName) != CompilerKit::STLString::npos) { + if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) { + defined = false; + inactive_code = true; + + return 1; + } + + defined = true; + inactive_code = false; + + return 1; + } + + return 0; + } + + auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size()); + + CompilerKit::STLString number; + + for (auto& macro_num : kMacros) { + if (substr_macro.find(macro_num.fName) != CompilerKit::STLString::npos) { + for (size_t i = 0; i < macro_num.fName.size(); ++i) { + if (isdigit(macro_num.fValue[i])) { + number += macro_num.fValue[i]; + } else { + number.clear(); + break; + } + } + + break; + } + } + + size_t y = 2; + + /* last try */ + for (; y < macro_str.size(); y++) { + if (isdigit(macro_str[y])) { + for (size_t x = y; x < macro_str.size(); x++) { + if (macro_str[x] == ' ') break; + + number += macro_str[x]; + } + + break; + } + } + + size_t rhs = atol(macro.fValue.c_str()); + size_t lhs = atol(number.c_str()); + + if (lhs == 0) { + number.clear(); + ++y; + + for (; y < macro_str.size(); y++) { + if (isdigit(macro_str[y])) { + for (size_t x = y; x < macro_str.size(); x++) { + if (macro_str[x] == ' ') break; + + number += macro_str[x]; + } + + break; + } + } + + lhs = atol(number.c_str()); + } + + if (cond.fType == Detail::kGreaterThan) { + if (lhs < rhs) { + defined = true; + inactive_code = false; + + return 1; + } + + return 0; + } + + if (cond.fType == Detail::kGreaterEqThan) { + if (lhs <= rhs) { + defined = true; + inactive_code = false; + + return 1; + } + + return 0; + } + + if (cond.fType == Detail::kLesserEqThan) { + if (lhs >= rhs) { + defined = true; + inactive_code = false; + + return 1; + } + + return 0; + } + + if (cond.fType == Detail::kLesserThan) { + if (lhs > rhs) { + defined = true; + inactive_code = false; + + return 1; + } + + return 0; + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +// @brief stores every included file here. + +///////////////////////////////////////////////////////////////////////////////////////// + +std::vector kAllIncludes; + +///////////////////////////////////////////////////////////////////////////////////////// + +// @name bpp_parse_file +// @brief parse file to preprocess it. + +///////////////////////////////////////////////////////////////////////////////////////// + +void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) { + CompilerKit::STLString hdr_line; + CompilerKit::STLString line_after_include; + + bool inactive_code = false; + bool defined = false; + + try { + while (std::getline(hdr_file, hdr_line)) { + if (inactive_code) { + if (hdr_line.find("#endif") == CompilerKit::STLString::npos) { + continue; + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("#endif") != CompilerKit::STLString::npos) { + inactive_code = false; + } + } + + if (hdr_line.find("*/") != CompilerKit::STLString::npos) { + hdr_line.erase(hdr_line.find("*/"), strlen("*/")); + } + + if (hdr_line.find("/*") != CompilerKit::STLString::npos) { + inactive_code = true; + + // get rid of comment. + hdr_line.erase(hdr_line.find("/*")); + } + + if (hdr_line[0] == kMacroPrefix && hdr_line.find("endif") != CompilerKit::STLString::npos) { + if (!defined && inactive_code) { + inactive_code = false; + defined = false; + + continue; + } + + continue; + } + + if (!defined && inactive_code) { + continue; + } + + if (defined && inactive_code) { + continue; + } + + for (auto macro : kMacros) { + if (CompilerKit::find_word(hdr_line, macro.fName)) { + if (hdr_line.substr(hdr_line.find(macro.fName)).find(macro.fName + '(') != + CompilerKit::STLString::npos) { + if (!macro.fArgs.empty()) { + CompilerKit::STLString symbol_val = macro.fValue; + std::vector args; + + size_t x_arg_indx = 0; + + CompilerKit::STLString line_after_define = hdr_line; + CompilerKit::STLString str_arg; + + if (line_after_define.find("(") != CompilerKit::STLString::npos) { + line_after_define.erase(0, line_after_define.find("(") + 1); + + for (auto& subc : line_after_define) { + if (subc == ' ' || subc == '\t') continue; + + if (subc == ',' || subc == ')') { + if (str_arg.empty()) continue; + + args.push_back(str_arg); + + str_arg.clear(); + + continue; + } + + str_arg.push_back(subc); + } + } + + for (auto arg : macro.fArgs) { + if (symbol_val.find(macro.fArgs[x_arg_indx]) != CompilerKit::STLString::npos) { + symbol_val.replace(symbol_val.find(macro.fArgs[x_arg_indx]), + macro.fArgs[x_arg_indx].size(), args[x_arg_indx]); + ++x_arg_indx; + } else { + throw std::runtime_error("cppdrv: Internal error."); + } + } + + auto len = macro.fName.size(); + len += symbol_val.size(); + len += 2; // ( and ) + + hdr_line.erase(hdr_line.find(")"), 1); + + hdr_line.replace(hdr_line.find(hdr_line.substr(hdr_line.find(macro.fName + '('))), + len, symbol_val); + } else { + auto value = macro.fValue; + + hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), value); + } + } + } + } + + if (hdr_line[0] == kMacroPrefix && hdr_line.find("define ") != CompilerKit::STLString::npos) { + auto line_after_define = hdr_line.substr(hdr_line.find("define ") + strlen("define ")); + + CompilerKit::STLString macro_value; + CompilerKit::STLString macro_key; + + std::size_t pos = 0UL; + + std::vector args; + bool on_args = false; + + for (auto& ch : line_after_define) { + ++pos; + + if (ch == '(') { + on_args = true; + continue; + } + + if (ch == ')') { + on_args = false; + continue; + } + + if (ch == '\\') continue; + + if (on_args) continue; + + if (ch == ' ') { + for (size_t i = pos; i < line_after_define.size(); i++) { + macro_value += line_after_define[i]; + } + + break; + } + + macro_key += ch; + } + + CompilerKit::STLString str; + + if (line_after_define.find("(") != CompilerKit::STLString::npos) { + line_after_define.erase(0, line_after_define.find("(") + 1); + + for (auto& subc : line_after_define) { + if (subc == ',' || subc == ')') { + if (str.empty()) continue; + + args.push_back(str); + + str.clear(); + + continue; + } + + str.push_back(subc); + } + } + + Detail::bpp_macro macro; + + macro.fArgs = args; + macro.fName = macro_key; + macro.fValue = macro_value; + + kMacros.emplace_back(macro); + + continue; + } + + if (hdr_line[0] != kMacroPrefix) { + if (inactive_code) { + continue; + } + + pp_out << hdr_line << std::endl; + + continue; + } + + if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != CompilerKit::STLString::npos) { + auto line_after_ifndef = hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1); + CompilerKit::STLString macro; + + for (auto& ch : line_after_ifndef) { + if (ch == ' ') { + break; + } + + macro += ch; + } + + if (macro == "0") { + defined = true; + inactive_code = false; + continue; + } + + if (macro == "1") { + defined = false; + inactive_code = true; + + continue; + } + + bool found = false; + + defined = true; + inactive_code = false; + + for (auto& macro_ref : kMacros) { + if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) { + found = true; + break; + } + } + + if (found) { + defined = false; + inactive_code = true; + + continue; + } + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("else") != CompilerKit::STLString::npos) { + if (!defined && inactive_code) { + inactive_code = false; + defined = true; + + continue; + } else { + defined = false; + inactive_code = true; + + continue; + } + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("ifdef") != CompilerKit::STLString::npos) { + auto line_after_ifdef = hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1); + CompilerKit::STLString macro; + + for (auto& ch : line_after_ifdef) { + if (ch == ' ') { + break; + } + + macro += ch; + } + + if (macro == "0") { + defined = false; + inactive_code = true; + + continue; + } + + if (macro == "1") { + defined = true; + inactive_code = false; + + continue; + } + + defined = false; + inactive_code = true; + + for (auto& macro_ref : kMacros) { + if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) { + defined = true; + inactive_code = false; + + break; + } + } + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("if") != CompilerKit::STLString::npos) { + inactive_code = true; + + std::vector bpp_macro_condition_list = { + { + .fType = Detail::kEqual, + .fTypeName = "==", + }, + { + .fType = Detail::kNotEqual, + .fTypeName = "!=", + }, + { + .fType = Detail::kLesserThan, + .fTypeName = "<", + }, + { + .fType = Detail::kGreaterThan, + .fTypeName = ">", + }, + { + .fType = Detail::kLesserEqThan, + .fTypeName = "<=", + }, + { + .fType = Detail::kGreaterEqThan, + .fTypeName = ">=", + }, + }; + + int32_t good_to_go = 0; + + for (auto& macro_condition : bpp_macro_condition_list) { + if (hdr_line.find(macro_condition.fTypeName) != CompilerKit::STLString::npos) { + for (auto& found_macro : kMacros) { + if (hdr_line.find(found_macro.fName) != CompilerKit::STLString::npos) { + good_to_go = bpp_parse_if_condition(macro_condition, found_macro, inactive_code, + defined, hdr_line); + + break; + } + } + } + } + + if (good_to_go) continue; + + auto line_after_if = hdr_line.substr(hdr_line.find("if") + strlen("if") + 1); + CompilerKit::STLString macro; + + for (auto& ch : line_after_if) { + if (ch == ' ') { + break; + } + + macro += ch; + } + + if (macro == "0") { + defined = false; + inactive_code = true; + continue; + } + + if (macro == "1") { + defined = true; + inactive_code = false; + + continue; + } + + // last try, is it defined to be one? + for (auto& macro_ref : kMacros) { + if (macro_ref.fName.find(macro) != CompilerKit::STLString::npos && + macro_ref.fValue == "1") { + inactive_code = false; + defined = true; + + break; + } + } + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("warning") != CompilerKit::STLString::npos) { + auto line_after_warning = hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1); + CompilerKit::STLString message; + + for (auto& ch : line_after_warning) { + if (ch == '\r' || ch == '\n') { + break; + } + + message += ch; + } + + std::cout << "warn: " << message << std::endl; + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("error") != CompilerKit::STLString::npos) { + auto line_after_warning = hdr_line.substr(hdr_line.find("error") + strlen("error") + 1); + CompilerKit::STLString message; + + for (auto& ch : line_after_warning) { + if (ch == '\r' || ch == '\n') { + break; + } + + message += ch; + } + + throw std::runtime_error("error: " + message); + } else if (hdr_line[0] == kMacroPrefix && + hdr_line.find("include ") != CompilerKit::STLString::npos) { + line_after_include = hdr_line.substr(hdr_line.find("include ") + strlen("include ")); + + kIncludeFile: + auto it = std::find(kAllIncludes.cbegin(), kAllIncludes.cend(), line_after_include); + + if (it != kAllIncludes.cend()) { + continue; + } + + CompilerKit::STLString path; + + kAllIncludes.push_back(line_after_include); + + bool enable = false; + bool not_local = false; + + for (auto& ch : line_after_include) { + if (ch == ' ') continue; + + if (ch == '<') { + not_local = true; + enable = true; + + continue; + } + + if (ch == '\"') { + not_local = false; + enable = true; + continue; + } + + if (enable) { + path += ch; + } + } + + if (not_local) { + bool open = false; + + if (path.ends_with('>')) { + path.erase(path.find('>')); + } + + if (path.ends_with('"')) { + path.erase(path.find('"')); + } + + for (auto& include : kIncludes) { + CompilerKit::STLString header_path = include; + header_path.push_back('/'); + header_path += path; + + std::ifstream header(header_path); + + if (!header.is_open()) continue; + + open = true; + + bpp_parse_file(header, pp_out); + + break; + } + + if (!open) { + throw std::runtime_error("cppdrv: no such include file: " + path); + } + } else { + std::ifstream header(path); + + if (!header.is_open()) throw std::runtime_error("cppdrv: no such include file: " + path); + + bpp_parse_file(header, pp_out); + } + } else { + std::cerr << ("cppdrv: unknown pre-processor directive, " + hdr_line) << "\n"; + continue; + } + } + } catch (std::out_of_range& oor) { + return; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +// @brief main entrypoint of app. + +///////////////////////////////////////////////////////////////////////////////////////// + +NECTI_MODULE(CPlusPlusPreprocessorMain) { + try { + bool skip = false; + bool double_skip = false; + + Detail::bpp_macro macro_1; + + macro_1.fName = "__true"; + macro_1.fValue = "1"; + + kMacros.push_back(macro_1); + + Detail::bpp_macro macro_unreachable; + + macro_unreachable.fName = "__unreachable"; + macro_unreachable.fValue = "__libcompiler_unreachable"; + + kMacros.push_back(macro_unreachable); + + Detail::bpp_macro macro_unused; + + macro_unreachable.fName = "__unused"; + macro_unreachable.fValue = "__libcompiler_unused"; + + kMacros.push_back(macro_unused); + + Detail::bpp_macro macro_0; + + macro_0.fName = "__false"; + macro_0.fValue = "0"; + + kMacros.push_back(macro_0); + + Detail::bpp_macro macro_zka; + + macro_zka.fName = "__NECTI__"; + macro_zka.fValue = "1"; + + kMacros.push_back(macro_zka); + + Detail::bpp_macro macro_cxx; + + macro_cxx.fName = "__cplusplus"; + macro_cxx.fValue = "202302L"; + + kMacros.push_back(macro_cxx); + + Detail::bpp_macro macro_size_t; + macro_size_t.fName = "__SIZE_TYPE__"; + macro_size_t.fValue = "unsigned long long int"; + + kMacros.push_back(macro_size_t); + + macro_size_t.fName = "__UINT32_TYPE__"; + macro_size_t.fValue = "unsigned int"; + + kMacros.push_back(macro_size_t); + + macro_size_t.fName = "__UINTPTR_TYPE__"; + macro_size_t.fValue = "unsigned long long int"; + + kMacros.push_back(macro_size_t); + + for (auto index = 1UL; index < argc; ++index) { + if (skip) { + skip = false; + continue; + } + + if (double_skip) { + ++index; + double_skip = false; + continue; + } + + if (argv[index][0] == '-') { + if (strcmp(argv[index], "-cpp-ver") == 0) { + printf("%s\n", + "NeKernel Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2025 all rights " + "reserved."); + + return NECTI_SUCCESS; + } + + if (strcmp(argv[index], "-cpp-help") == 0) { + printf("%s\n", + "NeKernel Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2025 all rights " + "reserved."); + printf("%s\n", "-cpp-working-dir : set directory to working path."); + printf("%s\n", "-cpp-include-dir : add directory to include path."); + printf("%s\n", "-cpp-def : define a macro."); + printf("%s\n", "-cpp-ver: print the version."); + printf("%s\n", "-cpp-help: show help (this current command)."); + + return NECTI_SUCCESS; + } + + if (strcmp(argv[index], "-cpp-include-dir") == 0) { + CompilerKit::STLString inc = argv[index + 1]; + + skip = true; + + kIncludes.push_back(inc); + } + + if (strcmp(argv[index], "-cpp-working-dir") == 0) { + CompilerKit::STLString inc = argv[index + 1]; + skip = true; + kWorkingDir = inc; + } + + if (strcmp(argv[index], "-cpp-def") == 0 && argv[index + 1] != nullptr && + argv[index + 2] != nullptr) { + CompilerKit::STLString macro_key = argv[index + 1]; + + CompilerKit::STLString macro_value; + bool is_string = false; + + for (int argv_find_len = 0; argv_find_len < strlen(argv[index]); ++argv_find_len) { + if (!isdigit(argv[index][argv_find_len])) { + is_string = true; + macro_value += "\""; + + break; + } + } + + macro_value += argv[index + 2]; + + if (is_string) macro_value += "\""; + + Detail::bpp_macro macro; + macro.fName = macro_key; + macro.fValue = macro_value; + + kMacros.push_back(macro); + + double_skip = true; + } + + continue; + } + + kFiles.emplace_back(argv[index]); + } + + if (kFiles.empty()) return NECTI_EXEC_ERROR; + + for (auto& file : kFiles) { + if (!std::filesystem::exists(file)) continue; + + std::ifstream file_descriptor(file); + std::ofstream file_descriptor_pp(file + ".pp"); + + bpp_parse_file(file_descriptor, file_descriptor_pp); + } + + return NECTI_SUCCESS; + } catch (const std::runtime_error& e) { + std::cout << e.what() << '\n'; + } + + return NECTI_EXEC_ERROR; +} + +// Last rev 8-1-24 diff --git a/dev/CompilerKit/src/StringKit.cc b/dev/CompilerKit/src/StringKit.cc new file mode 100644 index 0000000..13142a6 --- /dev/null +++ b/dev/CompilerKit/src/StringKit.cc @@ -0,0 +1,179 @@ +/* + * ======================================================== + * + * CompilerKit + * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved. + * + * ======================================================== + */ + +/** + * @file BasicString.cc + * @author Amlal (amlal@nekernel.org) + * @brief C++ string manipulation API. + * @version 0.2 + * @date 2024-01-23 + * + * @copyright Copyright (c) Amlal El Mahrouss + * + */ + +#include + +namespace CompilerKit { + +Char* BasicString::Data() { + return m_Data; +} + +const Char* BasicString::CData() const { + return m_Data; +} + +SizeType BasicString::Length() const { + return strlen(m_Data); +} + +bool BasicString::operator==(const BasicString& rhs) const { + const SizeType len = Length(); + if (rhs.Length() != len) return false; + return memcmp(m_Data, rhs.m_Data, len) == 0; +} + +bool BasicString::operator==(const Char* rhs) const { + const SizeType rhs_len = string_length(rhs); + const SizeType len = Length(); + if (rhs_len != len) return false; + return memcmp(m_Data, rhs, len) == 0; +} + +bool BasicString::operator!=(const BasicString& rhs) const { + return !(*this == rhs); +} + +bool BasicString::operator!=(const Char* rhs) const { + return !(*this == rhs); +} + +BasicString StringBuilder::Construct(const Char* data) { + if (!data || *data == 0) return BasicString(0); + + BasicString view(strlen(data)); + view += data; + + return view; +} + +BasicString StringBuilder::FromInt(const char* fmt, int i) { + if (!fmt) return BasicString(0); + + Char result[sizeof(int64_t)] = {0}; + if (!to_str(result, sizeof(int64_t), i)) return BasicString(0); + + const SizeType fmt_len = string_length(fmt); + const SizeType res_len = string_length(result); + + BasicString output(fmt_len + res_len); + bool inserted = false; + + for (SizeType idx = 0; idx < fmt_len; ++idx) { + if (!inserted && fmt[idx] == '%') { + output += result; + inserted = true; + continue; + } + output += Char{fmt[idx]}; + } + + return output; +} + +BasicString StringBuilder::FromBool(const char* fmt, bool val) { + if (!fmt) return BasicString(0); + + const Char* boolean_expr = val ? "true" : "false"; + const SizeType fmt_len = string_length(fmt); + const SizeType res_len = string_length(boolean_expr); + + BasicString output(fmt_len + res_len); + bool inserted = false; + + for (SizeType idx = 0; idx < fmt_len; ++idx) { + if (!inserted && fmt[idx] == '%') { + output += boolean_expr; + inserted = true; + continue; + } + output += Char{fmt[idx]}; + } + + return output; +} + +bool StringBuilder::Equals(const char* lhs, const char* rhs) { + const SizeType lhs_len = string_length(lhs); + const SizeType rhs_len = string_length(rhs); + + if (lhs_len != rhs_len) return false; + return memcmp(lhs, rhs, lhs_len) == 0; +} + +BasicString StringBuilder::Format(const char* fmt, const char* fmtRight) { + if (!fmt || !fmtRight) return BasicString(0); + + const SizeType fmt_len = string_length(fmt); + const SizeType rhs_len = string_length(fmtRight); + + BasicString output(fmt_len + rhs_len); + bool inserted = false; + + for (SizeType idx = 0; idx < fmt_len; ++idx) { + if (!inserted && fmt[idx] == '%') { + output += fmtRight; + inserted = true; + continue; + } + output += Char{fmt[idx]}; + } + + return output; +} + +BasicString& BasicString::operator+=(const Char* rhs) { + const SizeType rhs_len = strlen(rhs); + if (this->m_Cur + rhs_len >= this->m_Sz) { + throw std::runtime_error("out_of_bounds: BasicString"); + } + + memcpy(this->m_Data + this->m_Cur, rhs, rhs_len); + + this->m_Cur += rhs_len; + this->m_Data[this->m_Cur] = '\0'; + + return *this; +} + +BasicString& BasicString::operator+=(const BasicString& rhs) { + if (this->m_Cur + rhs.m_Cur >= this->m_Sz) { + throw std::runtime_error("out_of_bounds: BasicString"); + } + + memcpy(this->m_Data + this->m_Cur, rhs.CData(), rhs.m_Cur); + this->m_Cur += rhs.m_Cur; + this->m_Data[this->m_Cur] = '\0'; + + return *this; +} + +BasicString& BasicString::operator+=(const Char ch) { + if (this->m_Cur + 1 >= this->m_Sz) { + throw std::runtime_error("out_of_bounds.."); + } + + this->m_Data[this->m_Cur++] = ch; + this->m_Data[this->m_Cur] = '\0'; + + return *this; +} + +} // namespace CompilerKit -- cgit v1.2.3