summaryrefslogtreecommitdiffhomepage
path: root/include/CompilerKit/Utils
diff options
context:
space:
mode:
Diffstat (limited to 'include/CompilerKit/Utils')
-rw-r--r--include/CompilerKit/Utils/Assembler.h74
-rw-r--r--include/CompilerKit/Utils/Compiler.h118
-rw-r--r--include/CompilerKit/Utils/DLL.h81
3 files changed, 273 insertions, 0 deletions
diff --git a/include/CompilerKit/Utils/Assembler.h b/include/CompilerKit/Utils/Assembler.h
new file mode 100644
index 0000000..6beff60
--- /dev/null
+++ b/include/CompilerKit/Utils/Assembler.h
@@ -0,0 +1,74 @@
+// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
+// Licensed under the Apache License, Version 2.0 (See accompanying
+// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
+// Official repository: https://github.com/ne-foss-org/nectar
+
+#ifndef NECTAR_COMPILERKIT_UTILITIES_ASSEMBLER_H
+#define NECTAR_COMPILERKIT_UTILITIES_ASSEMBLER_H
+
+#include <CompilerKit/AST.h>
+#include <CompilerKit/CodeGenerator.h>
+#include <CompilerKit/Utils/Compiler.h>
+
+namespace CompilerKit {
+/// @brief Get Number from lineBuffer.
+/// @param lineBuffer the lineBuffer to fetch from.
+/// @param numberKey where to seek that number.
+/// @return A numbercast of 32-bit width.
+inline NumberCast32 GetNumber32(STLString lineBuffer, STLString numberKey) {
+ if (lineBuffer.empty()) return {};
+ if (lineBuffer.find(numberKey) == STLString::npos) return {};
+
+ auto pos = lineBuffer.find(numberKey) + numberKey.size();
+
+ if (pos > lineBuffer.size()) return {};
+ if ((pos + 1) > lineBuffer.size()) return {};
+
+ while (lineBuffer[pos] == ' ') ++pos;
+
+ switch (lineBuffer[pos + 1]) {
+ case 'x': {
+ auto res = strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 16);
+ NumberCast32 numOffset(strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 16));
+
+ if (kVerbose) {
+ kStdOut << "asm: found a base 16 number here: " << lineBuffer.substr(pos) << "\n";
+ }
+
+ return numOffset;
+ }
+ case 'b': {
+ auto res = strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 2);
+ NumberCast32 numOffset(strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 2));
+
+ if (kVerbose) {
+ kStdOut << "asm: found a base 2 number here:" << lineBuffer.substr(pos) << "\n";
+ }
+
+ return numOffset;
+ }
+ case 'o': {
+ auto res = strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 8);
+ NumberCast32 numOffset(strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 8));
+
+ if (kVerbose) {
+ kStdOut << "asm: found a base 8 number here:" << lineBuffer.substr(pos) << "\n";
+ }
+
+ return numOffset;
+ }
+ default: {
+ auto res = strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 10);
+ NumberCast32 numOffset(strtol(lineBuffer.substr(pos + 2).c_str(), nullptr, 10));
+
+ if (kVerbose) {
+ kStdOut << "asm: found a base 10 number here:" << lineBuffer.substr(pos) << kStdEndl;
+ }
+
+ return numOffset;
+ }
+ }
+}
+} // namespace CompilerKit
+
+#endif // NECTAR_COMPILERKIT_UTILITIES_ASSEMBLER_H
diff --git a/include/CompilerKit/Utils/Compiler.h b/include/CompilerKit/Utils/Compiler.h
new file mode 100644
index 0000000..094647b
--- /dev/null
+++ b/include/CompilerKit/Utils/Compiler.h
@@ -0,0 +1,118 @@
+// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
+// Licensed under the Apache License, Version 2.0 (See accompanying
+// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
+// Official repository: https://github.com/ne-foss-org/nectar
+
+#ifndef NECTAR_COMPILERKIT_UTILITIES_COMPILER_H
+#define NECTAR_COMPILERKIT_UTILITIES_COMPILER_H
+
+#include <CompilerKit/AST.h>
+#include <CompilerKit/CodeGenerator.h>
+#include <CompilerKit/Detail/Config.h>
+#include <CompilerKit/ErrorID.h>
+#include <ThirdParty/Dialogs/Dialogs.h>
+#include <iostream>
+
+#define kZero64Section ".zero64"
+#define kCode64Section ".code64"
+#define kData64Section ".data64"
+
+#define kZero128Section ".zero128"
+#define kCode128Section ".code128"
+#define kData128Section ".data128"
+
+#define kBlank "\e[0;0m"
+#define kRed "\e[0;31m"
+#define kWhite "\e[0;97m"
+#define kYellow "\e[0;33m"
+#define kReset kBlank
+
+#define kStdOut (std::cout << kRed << "nectar: " << kReset)
+#define kStdErr (std::cerr << kRed << "nectar: " << kReset)
+#define kStdEndl std::endl
+#define kPrintF kStdOut
+#define kPrintErr kStdErr
+
+inline static UInt32 kErrorLimit = 0;
+inline static UInt32 kAcceptableErrors = 0;
+inline static bool kVerbose = false;
+inline static bool kOutputAsBinary = false;
+inline static bool kNasmOutput = false;
+
+namespace CompilerKit::Detail {
+/// @brief Blob structure
+struct Blob final {
+ std::vector<char> mBlob{}; // PEF code/bss/data blob.
+ UIntPtr mOffset{0UL}; // the offset of the PEF container header...
+
+ explicit operator bool() { return mBlob.empty() && mOffset > 0UL; }
+};
+
+inline void print_error(STLString reason, STLString file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
+
+ kStdErr << file << ": " << reason << kBlank << std::endl;
+
+ ++kAcceptableErrors;
+ if (kAcceptableErrors > kErrorLimit) std::exit(NECTAR_EXEC_ERROR);
+}
+
+inline void print_warning(STLString reason, STLString file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
+
+ kStdOut << file << ": " << kYellow << reason << kBlank << std::endl;
+}
+
+/// @internal
+/// @brief Handler for SIGSEGV signal.
+inline void drvi_crash_handler(std::int32_t id) {
+ CompilerKit::STLString verbose_header = "NECTAR CRASH REPORT - ";
+ verbose_header += kDistVersion;
+ verbose_header += " - ";
+ verbose_header += CompilerKit::current_date();
+
+ for (auto& ch : verbose_header) {
+ std::cout << '=';
+ }
+
+ kStdOut << kStdEndl;
+ kStdOut << verbose_header << kStdEndl;
+
+ for (auto& ch : verbose_header) {
+ std::cout << '=';
+ }
+
+ kStdOut << kStdEndl;
+
+ kStdOut << "DATE: " << CompilerKit::current_date() << kStdEndl;
+ kStdOut << "VERSION: " << kDistVersion << kStdEndl;
+ kStdOut << "ERRNO: " << errno << kStdEndl;
+
+ switch (id) {
+ default: {
+ kStdOut << "SIGNAL: (" << id << ")." << kBlank << kStdEndl;
+ break;
+ }
+ }
+
+ std::cout << kWhite;
+
+ for (auto& ch : verbose_header) {
+ std::cout << '=';
+ }
+
+ std::cout << std::endl;
+
+ std::cout << verbose_header << std::endl;
+
+ for (auto& ch : verbose_header) {
+ std::cout << '=';
+ }
+
+ std::cout << std::endl;
+
+ std::exit(NECTAR_EXEC_ERROR);
+}
+} // namespace CompilerKit::Detail
+
+#endif // NECTAR_COMPILERKIT_UTILITIES_COMPILER_H
diff --git a/include/CompilerKit/Utils/DLL.h b/include/CompilerKit/Utils/DLL.h
new file mode 100644
index 0000000..6d12538
--- /dev/null
+++ b/include/CompilerKit/Utils/DLL.h
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org)
+// Licensed under the Apache License, Version 2.0 (See accompanying
+// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
+// Official repository: https://github.com/ne-foss-org/nectar
+
+#ifndef NECTAR_COMPILERKIT_UTILITIES_DLL_H
+#define NECTAR_COMPILERKIT_UTILITIES_DLL_H
+
+#include <CompilerKit/Detail/Config.h>
+#include <CompilerKit/Ref.h>
+#include <dlfcn.h>
+#include <mutex>
+
+namespace CompilerKit {
+
+#ifdef CK_POSIX
+class ModuleLoader final {
+ public:
+ using EntryT = Int32 (*)(Int32 argc, char const* argv[]);
+ using HandleT = VoidPtr;
+ using MutexT = std::mutex;
+
+ EntryT fEntrypoint{nullptr};
+
+ private:
+ HandleT mDLL{nullptr};
+ MutexT mMutex;
+
+ public:
+ explicit operator bool() { return this->mDLL != nullptr; }
+
+ ModuleLoader& operator()(const std::string& path, const std::string& entrypoint) {
+ if (path.empty() || entrypoint.empty()) return *this;
+
+ std::lock_guard<MutexT> lock(this->mMutex);
+
+ if (this->mDLL) {
+ this->Reset();
+ }
+
+ this->mDLL = ::dlopen(path.data(), RTLD_LAZY);
+
+ if (!this->mDLL) {
+ return *this;
+ }
+
+ this->fEntrypoint = reinterpret_cast<EntryT>(::dlsym(this->mDLL, entrypoint.data()));
+
+ if (!this->fEntrypoint) {
+ this->Reset();
+ return *this;
+ }
+
+ return *this;
+ }
+
+ NECTAR_COPY_DELETE(ModuleLoader)
+
+ ModuleLoader() = default;
+ ~ModuleLoader() { this->Reset(); }
+
+ void Reset() noexcept {
+ if (this->mDLL) {
+ ::dlclose(this->mDLL);
+ this->mDLL = nullptr;
+ }
+
+ this->fEntrypoint = nullptr;
+ }
+};
+
+using StrongDLLRef = StrongRef<ModuleLoader>;
+using WeakDLLRef = WeakRef<ModuleLoader>;
+#else
+#error No ModuleLoader defined.
+#endif
+
+} // namespace CompilerKit
+
+#endif // NECTAR_COMPILERKIT_UTILITIES_DLL_H