summaryrefslogtreecommitdiffhomepage
path: root/Private/CompilerKit
diff options
context:
space:
mode:
Diffstat (limited to 'Private/CompilerKit')
-rw-r--r--Private/CompilerKit/AsmKit/Arch/32x0.hpp65
-rw-r--r--Private/CompilerKit/AsmKit/Arch/64x0.hpp74
-rw-r--r--Private/CompilerKit/AsmKit/Arch/amd64.hpp84
-rw-r--r--Private/CompilerKit/AsmKit/AsmKit.cc62
-rw-r--r--Private/CompilerKit/AsmKit/AsmKit.hpp283
-rw-r--r--Private/CompilerKit/Compiler.hpp31
-rw-r--r--Private/CompilerKit/Defines.hpp128
-rw-r--r--Private/CompilerKit/ParserKit.hpp180
-rw-r--r--Private/CompilerKit/StdKit/AE.hpp200
-rw-r--r--Private/CompilerKit/StdKit/ErrorID.hpp2
-rw-r--r--Private/CompilerKit/StdKit/ErrorOr.hpp63
-rw-r--r--Private/CompilerKit/StdKit/PEF.hpp144
-rw-r--r--Private/CompilerKit/StdKit/Ref.hpp129
-rw-r--r--Private/CompilerKit/StdKit/String.cc302
-rw-r--r--Private/CompilerKit/StdKit/String.hpp141
15 files changed, 854 insertions, 1034 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/32x0.hpp b/Private/CompilerKit/AsmKit/Arch/32x0.hpp
index f9be82b..bf4b4c1 100644
--- a/Private/CompilerKit/AsmKit/Arch/32x0.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/32x0.hpp
@@ -15,43 +15,44 @@
// @file Arch/32x0.hpp
#define kAsmOpcodeDecl(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \
- { .fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7 },
-
-
-
+ {.fName = __NAME, \
+ .fOpcode = __OPCODE, \
+ .fFunct3 = __FUNCT3, \
+ .fFunct7 = __FUNCT7},
#define kAsmImmediate 0x01
#define kAsmSyscall 0x02
#define kAsmJump 0x03
#define kAsmNoArgs 0x04
-#define kAsmByte 0
+#define kAsmByte 0
#define kAsmHWord 1
-#define kAsmWord 2
-
-struct CpuCode32x0
-{
- const char fName[32];
- char fOpcode;
- char fSize;
- char fFunct3;
- char fFunct7;
+#define kAsmWord 2
+
+struct CpuCode32x0 {
+ const char fName[32];
+ char fOpcode;
+ char fSize;
+ char fFunct3;
+ char fFunct7;
};
-#define kAsmDWordStr ".dword" /* 64 bit */
-#define kAsmWordStr ".word" /* 32-bit */
-#define kAsmHWordStr ".half" /* 16-bit */
-#define kAsmByteStr ".byte" /* 8-bit */
+#define kAsmDWordStr ".dword" /* 64 bit */
+#define kAsmWordStr ".word" /* 32-bit */
+#define kAsmHWordStr ".half" /* 16-bit */
+#define kAsmByteStr ".byte" /* 8-bit */
inline std::vector<CpuCode32x0> kOpcodes32x0 = {
- kAsmOpcodeDecl("nop", 0b0100011, 0b000, kAsmNoArgs) // nothing to do.
- kAsmOpcodeDecl("jmp", 0b1110011, 0b001, kAsmJump) // jump to branch
- kAsmOpcodeDecl("move", 0b0100011, 0b101, kAsmImmediate) // move registers
- kAsmOpcodeDecl("push", 0b0111011, 0b000, kAsmImmediate) // push to sp
- kAsmOpcodeDecl("pop", 0b0111011, 0b001, kAsmImmediate) // pop from sp.
- kAsmOpcodeDecl("cls", 0b0111011, 0b010, kAsmImmediate) // setup stack and call, store address to CR.
- kAsmOpcodeDecl("rts", 0b0111011, 0b110, kAsmImmediate) // pull stack and return form CR.
- kAsmOpcodeDecl("int", 0b0111111, 0b000, kAsmSyscall) // raise interrupt
+ kAsmOpcodeDecl("nop", 0b0100011, 0b000, kAsmNoArgs) // nothing to do.
+ kAsmOpcodeDecl("jmp", 0b1110011, 0b001, kAsmJump) // jump to branch
+ kAsmOpcodeDecl("move", 0b0100011, 0b101, kAsmImmediate) // move registers
+ kAsmOpcodeDecl("push", 0b0111011, 0b000, kAsmImmediate) // push to sp
+ kAsmOpcodeDecl("pop", 0b0111011, 0b001, kAsmImmediate) // pop from sp.
+ kAsmOpcodeDecl("cls", 0b0111011, 0b010,
+ kAsmImmediate) // setup stack and call, store address to CR.
+ kAsmOpcodeDecl("rts", 0b0111011, 0b110,
+ kAsmImmediate) // pull stack and return form CR.
+ kAsmOpcodeDecl("int", 0b0111111, 0b000, kAsmSyscall) // raise interrupt
};
// \brief 64x0 register prefix
@@ -60,13 +61,13 @@ inline std::vector<CpuCode32x0> kOpcodes32x0 = {
// r0 -> hw zero
#define kAsmRegisterPrefix "r"
-#define kAsmRegisterLimit 16
-#define kAsmPcRegister 17
-#define kAsmCrRegister 18
-#define kAsmSpRegister 5
+#define kAsmRegisterLimit 16
+#define kAsmPcRegister 17
+#define kAsmCrRegister 18
+#define kAsmSpRegister 5
/* return address register */
-#define kAsmRetRegister 19
+#define kAsmRetRegister 19
/////////////////////////////////////////////////////////////////////////////
@@ -93,4 +94,4 @@ inline std::vector<CpuCode32x0> kOpcodes32x0 = {
// PROCESS INTERRUPT
// ENABLE INTERRUPTS
-//////////////////////////////// \ No newline at end of file
+////////////////////////////////
diff --git a/Private/CompilerKit/AsmKit/Arch/64x0.hpp b/Private/CompilerKit/AsmKit/Arch/64x0.hpp
index 3052021..c00b0c9 100644
--- a/Private/CompilerKit/AsmKit/Arch/64x0.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/64x0.hpp
@@ -15,9 +15,10 @@
// @file Arch/64x0.hpp
#define kAsmOpcodeDecl(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \
- { .fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7 },
-
-
+ {.fName = __NAME, \
+ .fOpcode = __OPCODE, \
+ .fFunct3 = __FUNCT3, \
+ .fFunct7 = __FUNCT7},
#define kAsmImmediate 0x01
#define kAsmRegToReg 0x02
@@ -28,40 +29,41 @@
typedef char e64k_character_t;
typedef uint8_t e64k_num_t;
-struct CpuCode64x0
-{
- const e64k_character_t fName[32];
- e64k_num_t fOpcode;
- e64k_num_t fFunct3;
- e64k_num_t fFunct7;
+struct CpuCode64x0 {
+ const e64k_character_t fName[32];
+ e64k_num_t fOpcode;
+ e64k_num_t fFunct3;
+ e64k_num_t fFunct7;
};
inline std::vector<CpuCode64x0> kOpcodes64x0 = {
- kAsmOpcodeDecl("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
- kAsmOpcodeDecl("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
- kAsmOpcodeDecl("jlr", 0b1110011, 0b0000111, kAsmJump) // jump to linked return register
- kAsmOpcodeDecl("jrl", 0b1110011, 0b0001111, kAsmJump) // jump from return register.
- kAsmOpcodeDecl("mv", 0b0100011, 0b101, kAsmRegToReg)
- kAsmOpcodeDecl("bg", 0b1100111, 0b111, kAsmRegToReg)
- kAsmOpcodeDecl("bl", 0b1100111, 0b011, kAsmRegToReg)
- kAsmOpcodeDecl("beq", 0b1100111, 0b000, kAsmRegToReg)
- kAsmOpcodeDecl("bne", 0b1100111, 0b001, kAsmRegToReg)
- kAsmOpcodeDecl("bge", 0b1100111, 0b101, kAsmRegToReg)
- kAsmOpcodeDecl("ble", 0b1100111, 0b100, kAsmRegToReg)
- kAsmOpcodeDecl("stw", 0b0001111, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("ldw", 0b0001111, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("lda", 0b0001111, 0b101, kAsmImmediate)
- kAsmOpcodeDecl("sta", 0b0001111, 0b001, kAsmImmediate)
+ kAsmOpcodeDecl("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
+ kAsmOpcodeDecl("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
+ kAsmOpcodeDecl("jlr", 0b1110011, 0b0000111,
+ kAsmJump) // jump to linked return register
+ kAsmOpcodeDecl("jrl", 0b1110011, 0b0001111,
+ kAsmJump) // jump from return register.
+ kAsmOpcodeDecl("mv", 0b0100011, 0b101, kAsmRegToReg) kAsmOpcodeDecl(
+ "bg", 0b1100111, 0b111,
+ kAsmRegToReg) kAsmOpcodeDecl("bl", 0b1100111, 0b011, kAsmRegToReg)
+ kAsmOpcodeDecl("beq", 0b1100111, 0b000, kAsmRegToReg) kAsmOpcodeDecl(
+ "bne", 0b1100111, 0b001,
+ kAsmRegToReg) kAsmOpcodeDecl("bge", 0b1100111, 0b101, kAsmRegToReg)
+ kAsmOpcodeDecl("ble", 0b1100111, 0b100, kAsmRegToReg)
+ kAsmOpcodeDecl("stw", 0b0001111, 0b100, kAsmImmediate)
+ kAsmOpcodeDecl("ldw", 0b0001111, 0b100, kAsmImmediate)
+ kAsmOpcodeDecl("lda", 0b0001111, 0b101, kAsmImmediate)
+ kAsmOpcodeDecl("sta", 0b0001111, 0b001,
+ kAsmImmediate)
// add/sub without carry flag
kAsmOpcodeDecl("add", 0b0101011, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("dec", 0b0101011, 0b101, kAsmImmediate)
+ kAsmOpcodeDecl("dec", 0b0101011, 0b101, kAsmImmediate)
// add/sub with carry flag
kAsmOpcodeDecl("addc", 0b0101011, 0b110, kAsmImmediate)
- kAsmOpcodeDecl("decc", 0b0101011, 0b111, kAsmImmediate)
- kAsmOpcodeDecl("int", 0b1110011, 0b00, kAsmSyscall)
- kAsmOpcodeDecl("pha", 0b1110011, 0b00, kAsmNoArgs)
- kAsmOpcodeDecl("pla", 0b1110011, 0b01, kAsmNoArgs)
-};
+ kAsmOpcodeDecl("decc", 0b0101011, 0b111, kAsmImmediate)
+ kAsmOpcodeDecl("int", 0b1110011, 0b00, kAsmSyscall)
+ kAsmOpcodeDecl("pha", 0b1110011, 0b00, kAsmNoArgs)
+ kAsmOpcodeDecl("pla", 0b1110011, 0b01, kAsmNoArgs)};
// \brief 64x0 register prefix
// example: r32, r0
@@ -72,13 +74,13 @@ inline std::vector<CpuCode64x0> kOpcodes64x0 = {
#define kAsmZeroRegister 0
#define kAsmRegisterPrefix "r"
-#define kAsmRegisterLimit 30
-#define kAsmPcRegister 17
-#define kAsmCrRegister 18
-#define kAsmSpRegister 5
+#define kAsmRegisterLimit 30
+#define kAsmPcRegister 17
+#define kAsmCrRegister 18
+#define kAsmSpRegister 5
/* return address register */
-#define kAsmRetRegister 19
+#define kAsmRetRegister 19
/////////////////////////////////////////////////////////////////////////////
@@ -105,4 +107,4 @@ inline std::vector<CpuCode64x0> kOpcodes64x0 = {
// PROCESS INTERRUPT
// ENABLE INTERRUPTS
-//////////////////////////////// \ No newline at end of file
+////////////////////////////////
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
index ac92c9b..f7845e2 100644
--- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
@@ -14,63 +14,51 @@
// @brief 64x0 support.
// @file Arch/64x0.hpp
-#define kAsmOpcodeDecl(__NAME, __OPCODE) \
- { .fName = __NAME, .fOpcode = __OPCODE },
-
-
-
+#define kAsmOpcodeDecl(__NAME, __OPCODE) {.fName = __NAME, .fOpcode = __OPCODE},
typedef char e64k_character_t;
typedef uint8_t e64_byte_t;
typedef uint16_t e64_hword_t;
typedef uint32_t e64k_word_t;
-struct CpuCodeAMD64
-{
- std::string fName;
- e64_byte_t fPrefixBytes[4];
- e64_hword_t fOpcode;
- e64_hword_t fModReg;
- e64k_word_t fDisplacment;
- e64k_word_t fImmediate;
+struct CpuCodeAMD64 {
+ std::string fName;
+ e64_byte_t fPrefixBytes[4];
+ e64_hword_t fOpcode;
+ e64_hword_t fModReg;
+ e64k_word_t fDisplacment;
+ e64k_word_t fImmediate;
};
/// these two are edge cases
#define kAsmIntOpcode 0xCC
#define kasmIntOpcodeAlt 0xCD
-#define kAsmJumpOpcode 0x0F80
-#define kJumpLimit 30
-#define kJumpLimitStandard 0xE3
+#define kAsmJumpOpcode 0x0F80
+#define kJumpLimit 30
+#define kJumpLimitStandard 0xE3
#define kJumpLimitStandardLimit 0xEB
inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = {
- kAsmOpcodeDecl("int", 0xCD)
- kAsmOpcodeDecl("into", 0xCE)
- kAsmOpcodeDecl("intd", 0xF1)
- kAsmOpcodeDecl("int3", 0xC3)
-
- kAsmOpcodeDecl("iret", 0xCF)
- kAsmOpcodeDecl("retf", 0xCB)
- kAsmOpcodeDecl("retn", 0xC3)
- kAsmOpcodeDecl("sti", 0xfb)
- kAsmOpcodeDecl("cli", 0xfa)
-
- kAsmOpcodeDecl("nop", 0x90)
-
- kAsmOpcodeDecl("mov eax", 0xb8)
- kAsmOpcodeDecl("mov ecx", 0xb9)
- kAsmOpcodeDecl("mov edx", 0xba)
- kAsmOpcodeDecl("mov ebx", 0xbb)
- kAsmOpcodeDecl("mov esp", 0xbc)
- kAsmOpcodeDecl("mov ebp", 0xbd)
- kAsmOpcodeDecl("mov esi", 0xbe)
-
- kAsmOpcodeDecl("jmp", 0xE9)
- kAsmOpcodeDecl("call", 0xE9)
-
- kAsmOpcodeDecl("mov", 0x00)
-};
+ kAsmOpcodeDecl("int", 0xCD) kAsmOpcodeDecl("into", 0xCE) kAsmOpcodeDecl(
+ "intd", 0xF1) kAsmOpcodeDecl("int3", 0xC3)
+
+ kAsmOpcodeDecl("iret", 0xCF) kAsmOpcodeDecl("retf", 0xCB)
+ kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("sti", 0xfb)
+ kAsmOpcodeDecl("cli", 0xfa)
+
+ kAsmOpcodeDecl("nop", 0x90)
+
+ kAsmOpcodeDecl("mov eax", 0xb8) kAsmOpcodeDecl(
+ "mov ecx", 0xb9) kAsmOpcodeDecl("mov edx", 0xba)
+ kAsmOpcodeDecl("mov ebx", 0xbb) kAsmOpcodeDecl(
+ "mov esp", 0xbc) kAsmOpcodeDecl("mov ebp", 0xbd)
+ kAsmOpcodeDecl("mov esi", 0xbe)
+
+ kAsmOpcodeDecl("jmp", 0xE9)
+ kAsmOpcodeDecl("call", 0xE9)
+
+ kAsmOpcodeDecl("mov", 0x00)};
// \brief 64x0 register prefix
// example: r32, r0
@@ -78,13 +66,13 @@ inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = {
// r0 -> hw zero
#define kAsmFloatZeroRegister -1
-#define kAsmZeroRegister -1
+#define kAsmZeroRegister -1
#define kAsmRegisterPrefix "r"
-#define kAsmRegisterLimit 16
-#define kAsmPcRegister 8
-#define kAsmCrRegister -1
-#define kAsmSpRegister 9
+#define kAsmRegisterLimit 16
+#define kAsmPcRegister 8
+#define kAsmCrRegister -1
+#define kAsmSpRegister 9
/* return address register */
-#define kAsmRetRegister 0
+#define kAsmRetRegister 0
diff --git a/Private/CompilerKit/AsmKit/AsmKit.cc b/Private/CompilerKit/AsmKit/AsmKit.cc
index 1eea5cc..7cd1360 100644
--- a/Private/CompilerKit/AsmKit/AsmKit.cc
+++ b/Private/CompilerKit/AsmKit/AsmKit.cc
@@ -16,9 +16,9 @@
* @brief Assembler Kit
* @version 0.1
* @date 2024-01-27
- *
+ *
* @copyright Copyright (c) 2024, Mahrouss Logic
- *
+ *
*/
#include <iostream>
@@ -26,37 +26,29 @@
//! @file AsmKit.cpp
//! @brief AssemblyKit source implementation.
-namespace CompilerKit
-{
- //! @brief Compile for specific format (ELF, PEF, ZBIN)
- Int32 AssemblyFactory::Compile(StringView& sourceFile,
- const Int32& arch) noexcept
- {
- if (sourceFile.Length() < 1 ||
- !fMounted)
- return CXXKIT_UNIMPLEMENTED;
-
- return fMounted->CompileToFormat(sourceFile, arch);
- }
-
- //! @brief mount assembly backend.
- void AssemblyFactory::Mount(AssemblyMountpoint* mountPtr) noexcept
- {
- if (mountPtr)
- {
- fMounted = mountPtr;
- }
- }
-
- AssemblyMountpoint* AssemblyFactory::Unmount() noexcept
- {
- auto mount_prev = fMounted;
-
- if (mount_prev)
- {
- fMounted = nullptr;
- }
-
- return mount_prev;
- }
+namespace CompilerKit {
+//! @brief Compile for specific format (ELF, PEF, ZBIN)
+Int32 AssemblyFactory::Compile(StringView& sourceFile,
+ const Int32& arch) noexcept {
+ if (sourceFile.Length() < 1 || !fMounted) return CXXKIT_UNIMPLEMENTED;
+
+ return fMounted->CompileToFormat(sourceFile, arch);
+}
+
+//! @brief mount assembly backend.
+void AssemblyFactory::Mount(AssemblyMountpoint* mountPtr) noexcept {
+ if (mountPtr) {
+ fMounted = mountPtr;
+ }
+}
+
+AssemblyMountpoint* AssemblyFactory::Unmount() noexcept {
+ auto mount_prev = fMounted;
+
+ if (mount_prev) {
+ fMounted = nullptr;
+ }
+
+ return mount_prev;
}
+} // namespace CompilerKit
diff --git a/Private/CompilerKit/AsmKit/AsmKit.hpp b/Private/CompilerKit/AsmKit/AsmKit.hpp
index a561aad..c838221 100644
--- a/Private/CompilerKit/AsmKit/AsmKit.hpp
+++ b/Private/CompilerKit/AsmKit/AsmKit.hpp
@@ -13,171 +13,156 @@
#include <CompilerKit/Defines.hpp>
#include <CompilerKit/StdKit/String.hpp>
-namespace CompilerKit
-{
- //
- // @brief Frontend to Assembly mountpoint.
- //
- class AssemblyMountpoint
- {
- public:
- explicit AssemblyMountpoint() = default;
- virtual ~AssemblyMountpoint() = default;
-
- CXXKIT_COPY_DEFAULT(AssemblyMountpoint);
-
- //@ brief compile to object file.
- // Example C++ -> MASM -> AE object.
- virtual Int32 CompileToFormat(StringView& src, Int32 arch) = 0;
-
- };
-
- /// @brief Simple assembly factory
- class AssemblyFactory final
- {
- public:
- explicit AssemblyFactory() = default;
- ~AssemblyFactory() = default;
-
- CXXKIT_COPY_DEFAULT(AssemblyFactory);
-
- public:
- enum
- {
- kArchAMD64,
- kArch32x0,
- kArch64x0,
- kArchRISCV,
- kArchUnknown,
- };
-
- Int32 Compile(StringView& sourceFile, const Int32& arch) noexcept;
-
- void Mount(AssemblyMountpoint* mountPtr) noexcept;
- AssemblyMountpoint* Unmount() noexcept;
-
- private:
- AssemblyMountpoint* fMounted{ nullptr };
-
- };
-
- union NumberCastBase
- {
- NumberCastBase() = default;
- ~NumberCastBase() = default;
-
- };
-
- union NumberCast64 final
- {
- NumberCast64() = default;
- explicit NumberCast64(UInt64 raw) : raw(raw) {}
- ~NumberCast64() { raw = 0; }
-
- CharType number[8];
- UInt64 raw;
- };
-
- union NumberCast32 final
- {
- NumberCast32() = default;
- explicit NumberCast32(UInt32 raw) : raw(raw) {}
- ~NumberCast32() { raw = 0; }
-
- CharType number[4];
- UInt32 raw;
- };
-
- union NumberCast16 final
- {
- NumberCast16() = default;
- explicit NumberCast16(UInt16 raw) : raw(raw) {}
- ~NumberCast16() { raw = 0; }
-
- CharType number[2];
- UInt16 raw;
- };
-
- union NumberCast8 final
- {
- NumberCast8() = default;
- explicit NumberCast8(UInt8 raw) : raw(raw) {}
- ~NumberCast8() { raw = 0; }
-
- CharType number;
- UInt8 raw;
- };
-
- class PlatformAssembler
- {
- public:
- explicit PlatformAssembler() = default;
- ~PlatformAssembler() = default;
-
- CXXKIT_COPY_DEFAULT(PlatformAssembler);
-
- virtual std::string CheckLine(std::string &line, const std::string &file) = 0;
- virtual bool WriteLine(std::string &line, const std::string &file) = 0;
- virtual bool WriteNumber(const std::size_t &pos, std::string &from_what) = 0;
-
- };
+namespace CompilerKit {
+//
+// @brief Frontend to Assembly mountpoint.
+//
+class AssemblyMountpoint {
+ public:
+ explicit AssemblyMountpoint() = default;
+ virtual ~AssemblyMountpoint() = default;
+
+ CXXKIT_COPY_DEFAULT(AssemblyMountpoint);
+
+ //@ brief compile to object file.
+ // Example C++ -> MASM -> AE object.
+ virtual Int32 CompileToFormat(StringView& src, Int32 arch) = 0;
+};
+
+/// @brief Simple assembly factory
+class AssemblyFactory final {
+ public:
+ explicit AssemblyFactory() = default;
+ ~AssemblyFactory() = default;
+
+ CXXKIT_COPY_DEFAULT(AssemblyFactory);
+
+ public:
+ enum {
+ kArchAMD64,
+ kArch32x0,
+ kArch64x0,
+ kArchRISCV,
+ kArchUnknown,
+ };
+
+ Int32 Compile(StringView& sourceFile, const Int32& arch) noexcept;
+
+ void Mount(AssemblyMountpoint* mountPtr) noexcept;
+ AssemblyMountpoint* Unmount() noexcept;
+
+ private:
+ AssemblyMountpoint* fMounted{nullptr};
+};
+
+union NumberCastBase {
+ NumberCastBase() = default;
+ ~NumberCastBase() = default;
+};
+
+union NumberCast64 final {
+ NumberCast64() = default;
+ explicit NumberCast64(UInt64 raw) : raw(raw) {}
+ ~NumberCast64() { raw = 0; }
+
+ CharType number[8];
+ UInt64 raw;
+};
+
+union NumberCast32 final {
+ NumberCast32() = default;
+ explicit NumberCast32(UInt32 raw) : raw(raw) {}
+ ~NumberCast32() { raw = 0; }
+
+ CharType number[4];
+ UInt32 raw;
+};
+
+union NumberCast16 final {
+ NumberCast16() = default;
+ explicit NumberCast16(UInt16 raw) : raw(raw) {}
+ ~NumberCast16() { raw = 0; }
+
+ CharType number[2];
+ UInt16 raw;
+};
+
+union NumberCast8 final {
+ NumberCast8() = default;
+ explicit NumberCast8(UInt8 raw) : raw(raw) {}
+ ~NumberCast8() { raw = 0; }
+
+ CharType number;
+ UInt8 raw;
+};
+
+class PlatformAssembler {
+ public:
+ explicit PlatformAssembler() = default;
+ ~PlatformAssembler() = default;
+
+ CXXKIT_COPY_DEFAULT(PlatformAssembler);
+
+ virtual std::string CheckLine(std::string& line, const std::string& file) = 0;
+ virtual bool WriteLine(std::string& line, const std::string& file) = 0;
+ virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) = 0;
+};
#ifdef __ASM_NEED_AMD64__
- class PlatformAssemblerAMD64 final : public PlatformAssembler
- {
- public:
- explicit PlatformAssemblerAMD64() = default;
- ~PlatformAssemblerAMD64() = default;
+class PlatformAssemblerAMD64 final : public PlatformAssembler {
+ public:
+ explicit PlatformAssemblerAMD64() = default;
+ ~PlatformAssemblerAMD64() = default;
- CXXKIT_COPY_DEFAULT(PlatformAssemblerAMD64);
+ CXXKIT_COPY_DEFAULT(PlatformAssemblerAMD64);
- virtual std::string CheckLine(std::string &line, const std::string &file) override;
- virtual bool WriteLine(std::string &line, const std::string &file) override;
- virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override;
+ virtual std::string CheckLine(std::string& line,
+ const std::string& file) override;
+ virtual bool WriteLine(std::string& line, const std::string& file) override;
+ virtual bool WriteNumber(const std::size_t& pos,
+ std::string& from_what) override;
- virtual bool WriteNumber16(const std::size_t& pos, std::string& from_what);
- virtual bool WriteNumber32(const std::size_t& pos, std::string& from_what);
- virtual bool WriteNumber8(const std::size_t& pos, std::string& from_what);
+ virtual bool WriteNumber16(const std::size_t& pos, std::string& from_what);
+ virtual bool WriteNumber32(const std::size_t& pos, std::string& from_what);
+ virtual bool WriteNumber8(const std::size_t& pos, std::string& from_what);
+};
- };
-
-#endif // __ASM_NEED_AMD64__
+#endif // __ASM_NEED_AMD64__
#ifdef __ASM_NEED_64x0__
- class PlatformAssembler64x0 final : public PlatformAssembler
- {
- public:
- explicit PlatformAssembler64x0() = default;
- ~PlatformAssembler64x0() = default;
-
- CXXKIT_COPY_DEFAULT(PlatformAssembler64x0);
+class PlatformAssembler64x0 final : public PlatformAssembler {
+ public:
+ explicit PlatformAssembler64x0() = default;
+ ~PlatformAssembler64x0() = default;
- virtual std::string CheckLine(std::string &line, const std::string &file) override;
- virtual bool WriteLine(std::string &line, const std::string &file) override;
- virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override;
+ CXXKIT_COPY_DEFAULT(PlatformAssembler64x0);
- };
+ virtual std::string CheckLine(std::string& line,
+ const std::string& file) override;
+ virtual bool WriteLine(std::string& line, const std::string& file) override;
+ virtual bool WriteNumber(const std::size_t& pos,
+ std::string& from_what) override;
+};
-#endif // __ASM_NEED_64x0__
+#endif // __ASM_NEED_64x0__
#ifdef __ASM_NEED_32x0__
- class PlatformAssembler32x0 final : public PlatformAssembler
- {
- public:
- explicit PlatformAssembler32x0() = default;
- ~PlatformAssembler32x0() = default;
-
- CXXKIT_COPY_DEFAULT(PlatformAssembler32x0);
-
- virtual std::string CheckLine(std::string &line, const std::string &file) override;
- virtual bool WriteLine(std::string &line, const std::string &file) override;
- virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override;
+class PlatformAssembler32x0 final : public PlatformAssembler {
+ public:
+ explicit PlatformAssembler32x0() = default;
+ ~PlatformAssembler32x0() = default;
- };
+ CXXKIT_COPY_DEFAULT(PlatformAssembler32x0);
-#endif // __ASM_NEED_32x0__
-}
+ virtual std::string CheckLine(std::string& line,
+ const std::string& file) override;
+ virtual bool WriteLine(std::string& line, const std::string& file) override;
+ virtual bool WriteNumber(const std::size_t& pos,
+ std::string& from_what) override;
+};
+#endif // __ASM_NEED_32x0__
+} // namespace CompilerKit
diff --git a/Private/CompilerKit/Compiler.hpp b/Private/CompilerKit/Compiler.hpp
index 810652f..d3d32bb 100644
--- a/Private/CompilerKit/Compiler.hpp
+++ b/Private/CompilerKit/Compiler.hpp
@@ -12,25 +12,20 @@
#ifndef _CK_CL_HPP
#define _CK_CL_HPP
-#define CXXKIT_COPY_DELETE(KLASS) \
- KLASS &operator=(const KLASS &) = delete; \
- KLASS(const KLASS &) = delete;
+#define CXXKIT_COPY_DELETE(KLASS) \
+ KLASS &operator=(const KLASS &) = delete; \
+ KLASS(const KLASS &) = delete;
+#define CXXKIT_COPY_DEFAULT(KLASS) \
+ KLASS &operator=(const KLASS &) = default; \
+ KLASS(const KLASS &) = default;
-#define CXXKIT_COPY_DEFAULT(KLASS) \
- KLASS &operator=(const KLASS &) = default; \
- KLASS(const KLASS &) = default;
+#define CXXKIT_MOVE_DELETE(KLASS) \
+ KLASS &operator=(KLASS &&) = delete; \
+ KLASS(KLASS &&) = delete;
+#define CXXKIT_MOVE_DEFAULT(KLASS) \
+ KLASS &operator=(KLASS &&) = default; \
+ KLASS(KLASS &&) = default;
-#define CXXKIT_MOVE_DELETE(KLASS) \
- KLASS &operator=(KLASS &&) = delete; \
- KLASS(KLASS &&) = delete;
-
-
-#define CXXKIT_MOVE_DEFAULT(KLASS) \
- KLASS &operator=(KLASS &&) = default; \
- KLASS(KLASS &&) = default;
-
-
-
-#endif /* ifndef _CK_CL_HPP */ \ No newline at end of file
+#endif /* ifndef _CK_CL_HPP */
diff --git a/Private/CompilerKit/Defines.hpp b/Private/CompilerKit/Defines.hpp
index 568e024..42c7d2a 100644
--- a/Private/CompilerKit/Defines.hpp
+++ b/Private/CompilerKit/Defines.hpp
@@ -12,17 +12,17 @@
#ifndef Yes
#define Yes true
-#endif // ifndef Yes
+#endif // ifndef Yes
#ifndef No
#define No false
-#endif // ifndef No
+#endif // ifndef No
#include <stdint.h>
#define SizeType size_t
-#define VoidPtr void*
+#define VoidPtr void *
#define voidPtr VoidPtr
#define UIntPtr uintptr_t
@@ -44,103 +44,93 @@
#define CharType char
#define Boolean bool
-#include <new>
-#include <cstring>
#include <cassert>
+#include <cstring>
+#include <new>
#define nullPtr std::nullptr_t
#define MUST_PASS(E) assert(E)
#ifndef __FORCE_STRLEN
-# define __FORCE_STRLEN 1
+#define __FORCE_STRLEN 1
-# define string_length(len) strlen(len)
+#define string_length(len) strlen(len)
#endif
#ifndef __FORCE_MEMCPY
-# define __FORCE_MEMCPY 1
+#define __FORCE_MEMCPY 1
-# define rt_copy_memory(dst, src, len) memcpy(dst, src, len)
+#define rt_copy_memory(dst, src, len) memcpy(dst, src, len)
#endif
-#define CXXKIT_COPY_DELETE(KLASS) \
- KLASS &operator=(const KLASS &) = delete; \
- KLASS(const KLASS &) = delete;
+#define CXXKIT_COPY_DELETE(KLASS) \
+ KLASS &operator=(const KLASS &) = delete; \
+ KLASS(const KLASS &) = delete;
+#define CXXKIT_COPY_DEFAULT(KLASS) \
+ KLASS &operator=(const KLASS &) = default; \
+ KLASS(const KLASS &) = default;
-#define CXXKIT_COPY_DEFAULT(KLASS) \
- KLASS &operator=(const KLASS &) = default; \
- KLASS(const KLASS &) = default;
+#define CXXKIT_MOVE_DELETE(KLASS) \
+ KLASS &operator=(KLASS &&) = delete; \
+ KLASS(KLASS &&) = delete;
+#define CXXKIT_MOVE_DEFAULT(KLASS) \
+ KLASS &operator=(KLASS &&) = default; \
+ KLASS(KLASS &&) = default;
-#define CXXKIT_MOVE_DELETE(KLASS) \
- KLASS &operator=(KLASS &&) = delete; \
- KLASS(KLASS &&) = delete;
+#include <ctime>
+#include <fstream>
+#include <string>
+namespace CompilerKit {
+inline constexpr int BASE_YEAR = 1900;
-#define CXXKIT_MOVE_DEFAULT(KLASS) \
- KLASS &operator=(KLASS &&) = default; \
- KLASS(KLASS &&) = default;
+inline std::string current_date() {
+ auto time_data = time(nullptr);
+ auto time_struct = gmtime(&time_data);
+ std::string fmt = std::to_string(BASE_YEAR + time_struct->tm_year);
+ fmt += "-";
+ fmt += std::to_string(time_struct->tm_mon + 1);
+ fmt += "-";
+ fmt += std::to_string(time_struct->tm_mday);
+ return fmt;
+}
-#include <ctime>
-#include <string>
-#include <fstream>
+inline bool to_str(CharType *str, Int32 limit, Int32 base) {
+ if (limit == 0) return false;
+
+ Int32 copy_limit = limit;
+ Int32 cnt = 0;
+ Int32 ret = base;
-namespace CompilerKit
-{
- inline constexpr int BASE_YEAR = 1900;
-
- inline std::string current_date()
- {
- auto time_data = time(nullptr);
- auto time_struct = gmtime(&time_data);
-
- std::string fmt = std::to_string(BASE_YEAR + time_struct->tm_year);
- fmt += "-";
- fmt += std::to_string(time_struct->tm_mon + 1);
- fmt += "-";
- fmt += std::to_string(time_struct->tm_mday);
-
- return fmt;
- }
-
- inline bool to_str(CharType *str, Int32 limit, Int32 base)
- {
- if (limit == 0)
- return false;
-
- Int32 copy_limit = limit;
- Int32 cnt = 0;
- Int32 ret = base;
-
- while (limit != 1)
- {
- ret = ret % 10;
- str[cnt] = ret;
-
- ++cnt;
- --limit;
- --ret;
- }
-
- str[copy_limit] = '\0';
- return true;
- }
+ while (limit != 1) {
+ ret = ret % 10;
+ str[cnt] = ret;
+
+ ++cnt;
+ --limit;
+ --ret;
+ }
+
+ str[copy_limit] = '\0';
+ return true;
}
+} // namespace CompilerKit
typedef char char_type;
-#define kObjectFileExt ".o"
-#define kAsmFileExts { ".64x", ".32x", ".masm", ".s", ".S" }
+#define kObjectFileExt ".o"
+#define kAsmFileExts \
+ { ".64x", ".32x", ".masm", ".s", ".S" }
#ifdef __MODULE_NEED__
-# define MPCC_MODULE(name) int name(int argc, char** argv)
+#define MPCC_MODULE(name) int name(int argc, char **argv)
#else
-# define MPCC_MODULE(name) int main(int argc, char** argv)
+#define MPCC_MODULE(name) int main(int argc, char **argv)
#endif /* ifdef __MODULE_NEED__ */
#endif /* ifndef __CXXKIT_DEFINES_HPP__ */
-
diff --git a/Private/CompilerKit/ParserKit.hpp b/Private/CompilerKit/ParserKit.hpp
index 49907e5..614e56c 100644
--- a/Private/CompilerKit/ParserKit.hpp
+++ b/Private/CompilerKit/ParserKit.hpp
@@ -11,101 +11,89 @@
#include <CompilerKit/AsmKit/AsmKit.hpp>
-namespace ParserKit
-{
- using namespace CompilerKit;
-
- class CompilerBackend
- {
- public:
- explicit CompilerBackend() = default;
- virtual ~CompilerBackend() = default;
-
- CXXKIT_COPY_DEFAULT(CompilerBackend);
-
- // NOTE: cast this to your user defined ast.
- typedef void* AstType;
-
- //! @brief Compile a syntax tree ouf of the text.
- //! Also takes the source file name for metadata.
-
- virtual bool Compile(const std::string& text, const char* file) = 0;
-
- //! @brief What language are we dealing with?
- virtual const char* Language() { return "Generic Language"; }
-
- };
-
- struct SyntaxLeafList;
- struct SyntaxLeafList;
-
- struct SyntaxLeafList final
- {
- struct SyntaxLeaf final
- {
- Int32 fUserType;
- std::string fUserData;
- std::string fUserValue;
- struct SyntaxLeaf* fNext;
- };
-
- std::vector<SyntaxLeaf> fLeafList;
- SizeType fNumLeafs;
-
- size_t SizeOf() { return fNumLeafs; }
- std::vector<SyntaxLeaf>& Get() { return fLeafList; }
- SyntaxLeaf& At(size_t index) { return fLeafList[index]; }
-
- };
-
- /// 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.
- inline bool find_word(const std::string& haystack,const std::string& needle) noexcept
- {
- auto index = haystack.find(needle);
-
- // check for needle validity.
- if (index == std::string::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.
- inline std::size_t find_word_range(const std::string& haystack, const std::string& needle) noexcept
- {
- auto index = haystack.find(needle);
-
- // check for needle validity.
- if (index == std::string::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 false;
- }
+namespace ParserKit {
+using namespace CompilerKit;
+
+class CompilerBackend {
+ public:
+ explicit CompilerBackend() = default;
+ virtual ~CompilerBackend() = default;
+
+ CXXKIT_COPY_DEFAULT(CompilerBackend);
+
+ // NOTE: cast this to your user defined ast.
+ typedef void* AstType;
+
+ //! @brief Compile a syntax tree ouf of the text.
+ //! Also takes the source file name for metadata.
+
+ virtual bool Compile(const std::string& text, const char* file) = 0;
+
+ //! @brief What language are we dealing with?
+ virtual const char* Language() { return "Generic Language"; }
+};
+
+struct SyntaxLeafList;
+struct SyntaxLeafList;
+
+struct SyntaxLeafList final {
+ struct SyntaxLeaf final {
+ Int32 fUserType;
+ std::string fUserData;
+ std::string fUserValue;
+ struct SyntaxLeaf* fNext;
+ };
+
+ std::vector<SyntaxLeaf> fLeafList;
+ SizeType fNumLeafs;
+
+ size_t SizeOf() { return fNumLeafs; }
+ std::vector<SyntaxLeaf>& Get() { return fLeafList; }
+ SyntaxLeaf& At(size_t index) { return fLeafList[index]; }
+};
+
+/// 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.
+inline bool find_word(const std::string& haystack,
+ const std::string& needle) noexcept {
+ auto index = haystack.find(needle);
+
+ // check for needle validity.
+ if (index == std::string::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.
+inline std::size_t find_word_range(const std::string& haystack,
+ const std::string& needle) noexcept {
+ auto index = haystack.find(needle);
+
+ // check for needle validity.
+ if (index == std::string::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 false;
+}
+} // namespace ParserKit
diff --git a/Private/CompilerKit/StdKit/AE.hpp b/Private/CompilerKit/StdKit/AE.hpp
index 77358fb..4144252 100644
--- a/Private/CompilerKit/StdKit/AE.hpp
+++ b/Private/CompilerKit/StdKit/AE.hpp
@@ -15,127 +15,115 @@
#define kAEMag1 'E'
#define kAESymbolLen 64
-#define kAEPad 8
+#define kAEPad 8
#define kAEMagLen 2
#define kAEInvalidOpcode 0x00
// Advanced Executable File Format for MetroLink.
// Reloctable by offset is the default strategy.
-// You can also relocate at runtime but that's up to the operating system loader.
-
-namespace CompilerKit
-{
- // @brief Advanced Executable Header
- // One thing to keep in mind.
- // This object format, is reloctable.
- typedef struct AEHeader final
- {
- CharType fMagic[kAEMagLen];
- CharType fArch;
- SizeType fCount;
- CharType fSize;
- SizeType fStartCode;
- SizeType fCodeSize;
- CharType fPad[kAEPad];
- } __attribute__((packed)) AEHeader, *AEHeaderPtr;
-
- // @brief Advanced Executable Record.
- // Could be data, code or bss.
- // fKind must be filled with PEF fields.
-
- typedef struct AERecordHeader final
- {
- CharType fName[kAESymbolLen];
- SizeType fKind;
- SizeType fSize;
- SizeType fFlags;
- UIntPtr fOffset;
- CharType fPad[kAEPad];
- } __attribute__((packed)) AERecordHeader, *AERecordHeaderPtr;
-
- enum
- {
- kKindRelocationByOffset = 0x23f,
- kKindRelocationAtRuntime = 0x34f,
- };
-}
-
+// You can also relocate at runtime but that's up to the operating system
+// loader.
+
+namespace CompilerKit {
+// @brief Advanced Executable Header
+// One thing to keep in mind.
+// This object format, is reloctable.
+typedef struct AEHeader final {
+ CharType fMagic[kAEMagLen];
+ CharType fArch;
+ SizeType fCount;
+ CharType fSize;
+ SizeType fStartCode;
+ SizeType fCodeSize;
+ CharType fPad[kAEPad];
+} __attribute__((packed)) AEHeader, *AEHeaderPtr;
+
+// @brief Advanced Executable Record.
+// Could be data, code or bss.
+// fKind must be filled with PEF fields.
+
+typedef struct AERecordHeader final {
+ CharType fName[kAESymbolLen];
+ SizeType fKind;
+ SizeType fSize;
+ SizeType fFlags;
+ UIntPtr fOffset;
+ CharType fPad[kAEPad];
+} __attribute__((packed)) AERecordHeader, *AERecordHeaderPtr;
+
+enum {
+ kKindRelocationByOffset = 0x23f,
+ kKindRelocationAtRuntime = 0x34f,
+};
+} // namespace CompilerKit
// provide operator<< for AE
-std::ofstream &operator<<(std::ofstream &fp, CompilerKit::AEHeader &container)
-{
- fp.write((char *)&container, sizeof(CompilerKit::AEHeader));
+std::ofstream &operator<<(std::ofstream &fp, CompilerKit::AEHeader &container) {
+ fp.write((char *)&container, sizeof(CompilerKit::AEHeader));
- return fp;
+ return fp;
}
-std::ofstream &operator<<(std::ofstream &fp, CompilerKit::AERecordHeader &container)
-{
- fp.write((char *)&container, sizeof(CompilerKit::AERecordHeader));
+std::ofstream &operator<<(std::ofstream &fp,
+ CompilerKit::AERecordHeader &container) {
+ fp.write((char *)&container, sizeof(CompilerKit::AERecordHeader));
- return fp;
+ return fp;
}
-std::ifstream &operator>>(std::ifstream& fp, CompilerKit::AEHeader& container)
-{
- fp.read((char*)&container, sizeof(CompilerKit::AEHeader));
- return fp;
+std::ifstream &operator>>(std::ifstream &fp, CompilerKit::AEHeader &container) {
+ fp.read((char *)&container, sizeof(CompilerKit::AEHeader));
+ return fp;
}
-std::ifstream &operator>>(std::ifstream& fp, CompilerKit::AERecordHeader& container)
-{
- fp.read((char*)&container, sizeof(CompilerKit::AERecordHeader));
- return fp;
+std::ifstream &operator>>(std::ifstream &fp,
+ CompilerKit::AERecordHeader &container) {
+ fp.read((char *)&container, sizeof(CompilerKit::AERecordHeader));
+ return fp;
}
-namespace CompilerKit::Utils
-{
- /**
- * @brief AE Reader protocol
- *
- */
- class AEReadableProtocol final
- {
- public:
- std::ifstream FP;
-
- public:
- explicit AEReadableProtocol() = default;
- ~AEReadableProtocol() = default;
-
- CXXKIT_COPY_DELETE(AEReadableProtocol);
-
- /**
- * @brief Read AE record
- *
- * @param raw the containing buffer
- * @param sz it's size (without sizeof(AERecordHeader) added to it.)
- * @return AERecordHeaderPtr
- */
- AERecordHeaderPtr Read(char* raw, std::size_t sz)
- {
- if (!raw)
- return nullptr;
-
- return this->_Read<AERecordHeader>(raw, sz * sizeof(AERecordHeader));
- }
-
- private:
- /**
- * @brief Implementation of Read for raw classes.
- *
- * @tparam TypeClass The class to read.
- * @param raw the buffer
- * @param sz the size
- * @return TypeClass* the returning class.
- */
- template <typename TypeClass>
- TypeClass* _Read(char* raw, std::size_t sz)
- {
- FP.read(raw, std::streamsize(sz));
- return reinterpret_cast<TypeClass*>(raw);
- }
-
- };
-} // namespace CompilerKit::Utils \ No newline at end of file
+namespace CompilerKit::Utils {
+/**
+ * @brief AE Reader protocol
+ *
+ */
+class AEReadableProtocol final {
+ public:
+ std::ifstream FP;
+
+ public:
+ explicit AEReadableProtocol() = default;
+ ~AEReadableProtocol() = default;
+
+ CXXKIT_COPY_DELETE(AEReadableProtocol);
+
+ /**
+ * @brief Read AE record
+ *
+ * @param raw the containing buffer
+ * @param sz it's size (without sizeof(AERecordHeader) added to it.)
+ * @return AERecordHeaderPtr
+ */
+ AERecordHeaderPtr Read(char *raw, std::size_t sz) {
+ if (!raw) return nullptr;
+
+ return this->_Read<AERecordHeader>(raw, sz * sizeof(AERecordHeader));
+ }
+
+ private:
+ /**
+ * @brief Implementation of Read for raw classes.
+ *
+ * @tparam TypeClass The class to read.
+ * @param raw the buffer
+ * @param sz the size
+ * @return TypeClass* the returning class.
+ */
+ template <typename TypeClass>
+ TypeClass *_Read(char *raw, std::size_t sz) {
+ FP.read(raw, std::streamsize(sz));
+ return reinterpret_cast<TypeClass *>(raw);
+ }
+};
+} // namespace CompilerKit::Utils
diff --git a/Private/CompilerKit/StdKit/ErrorID.hpp b/Private/CompilerKit/StdKit/ErrorID.hpp
index e7bc7de..5577197 100644
--- a/Private/CompilerKit/StdKit/ErrorID.hpp
+++ b/Private/CompilerKit/StdKit/ErrorID.hpp
@@ -9,8 +9,8 @@
#pragma once
-#include <StdKit/ErrorOr.hpp>
#include <Defines.hpp>
+#include <StdKit/ErrorOr.hpp>
#define CXXKIT_EXEC_ERROR -30
#define CXXKIT_FILE_NOT_FOUND -31
diff --git a/Private/CompilerKit/StdKit/ErrorOr.hpp b/Private/CompilerKit/StdKit/ErrorOr.hpp
index 97aeaa2..7da6135 100644
--- a/Private/CompilerKit/StdKit/ErrorOr.hpp
+++ b/Private/CompilerKit/StdKit/ErrorOr.hpp
@@ -12,47 +12,34 @@
#include <CompilerKit/Defines.hpp>
#include <CompilerKit/StdKit/Ref.hpp>
-namespace CompilerKit
-{
+namespace CompilerKit {
using ErrorT = UInt32;
-template <typename T>
-class ErrorOr final
-{
- public:
- ErrorOr() = default;
- ~ErrorOr() = default;
-
- public:
- explicit ErrorOr(Int32 err)
- : mId(err)
- {}
-
- explicit ErrorOr(nullPtr Null)
- {}
-
- explicit ErrorOr(T Class)
- : mRef(Class)
- {}
-
- ErrorOr &operator=(const ErrorOr &) = default;
- ErrorOr(const ErrorOr &) = default;
-
- Ref<T> Leak()
- {
- return mRef;
- }
-
- operator bool()
- {
- return mRef;
- }
-
- private:
- Ref<T> mRef;
- Int32 mId{0};
+template <typename T>
+class ErrorOr final {
+ public:
+ ErrorOr() = default;
+ ~ErrorOr() = default;
+
+ public:
+ explicit ErrorOr(Int32 err) : mId(err) {}
+
+ explicit ErrorOr(nullPtr Null) {}
+
+ explicit ErrorOr(T Class) : mRef(Class) {}
+
+ ErrorOr &operator=(const ErrorOr &) = default;
+ ErrorOr(const ErrorOr &) = default;
+
+ Ref<T> Leak() { return mRef; }
+
+ operator bool() { return mRef; }
+
+ private:
+ Ref<T> mRef;
+ Int32 mId{0};
};
using ErrorOrAny = ErrorOr<voidPtr>;
-} // namespace CompilerKit
+} // namespace CompilerKit
diff --git a/Private/CompilerKit/StdKit/PEF.hpp b/Private/CompilerKit/StdKit/PEF.hpp
index a26af9e..dbc98ca 100644
--- a/Private/CompilerKit/StdKit/PEF.hpp
+++ b/Private/CompilerKit/StdKit/PEF.hpp
@@ -14,7 +14,7 @@
// @file PEF.hpp
// @brief Preferred Executable Format
-#define kPefMagic "PEF"
+#define kPefMagic "PEF"
#define kPefMagicFat "FEP"
#define kPefExt ".out"
@@ -29,84 +29,78 @@
#define kPefBaseOrigin 0x1000
-namespace CompilerKit
-{
- enum
- {
- kPefArchIntel86S = 100,
- kPefArchAMD64,
- kPefArchRISCV,
- kPefArch64000, /* 64x0 RISC architecture. */
- kPefArch32000,
- kPefArchInvalid = 0xFF,
- };
-
- enum
- {
- kPefKindExec = 1, /* .o/.pef/<none> */
- kPefKindSharedObject = 2, /* .lib */
- kPefKindObject = 4, /* .obj */
- kPefKindDwarf = 5, /* .dsym */
- };
-
- /* PEF container */
- typedef struct PEFContainer final
- {
- CharType Magic[kPefMagicLen];
- UInt32 Linker;
- UInt32 Version;
- UInt32 Kind;
- UInt32 Abi;
- UInt32 Cpu;
- UInt32 SubCpu; /* Cpu specific information */
- UIntPtr Start; /* Origin of code */
- SizeType HdrSz; /* Size of header */
- SizeType Count; /* container header count */
- } __attribute__((packed)) PEFContainer;
-
- /* First PEFCommandHeader starts after PEFContainer */
- /* Last container is __exec_end */
-
- /* PEF executable section and commands. */
-
- typedef struct PEFCommandHeader final
- {
- CharType Name[kPefNameLen]; /* container name */
- UInt32 Flags; /* container flags */
- UInt16 Kind; /* container kind */
- UIntPtr Offset; /* file offset */
- SizeType Size; /* file size */
- } __attribute__((packed)) PEFCommandHeader;
-
- enum
- {
- kPefCode = 0xC,
- kPefData = 0xD,
- kPefZero = 0xE,
- kPefLinkerID = 0x1,
- };
-} // namespace CompilerKit
-
-inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFContainer& container)
-{
- fp.write((char*)&container, sizeof(CompilerKit::PEFContainer));
- return fp;
+namespace CompilerKit {
+enum {
+ kPefArchIntel86S = 100,
+ kPefArchAMD64,
+ kPefArchRISCV,
+ kPefArch64000, /* 64x0 RISC architecture. */
+ kPefArch32000,
+ kPefArchInvalid = 0xFF,
+};
+
+enum {
+ kPefKindExec = 1, /* .o/.pef/<none> */
+ kPefKindSharedObject = 2, /* .lib */
+ kPefKindObject = 4, /* .obj */
+ kPefKindDwarf = 5, /* .dsym */
+};
+
+/* PEF container */
+typedef struct PEFContainer final {
+ CharType Magic[kPefMagicLen];
+ UInt32 Linker;
+ UInt32 Version;
+ UInt32 Kind;
+ UInt32 Abi;
+ UInt32 Cpu;
+ UInt32 SubCpu; /* Cpu specific information */
+ UIntPtr Start; /* Origin of code */
+ SizeType HdrSz; /* Size of header */
+ SizeType Count; /* container header count */
+} __attribute__((packed)) PEFContainer;
+
+/* First PEFCommandHeader starts after PEFContainer */
+/* Last container is __exec_end */
+
+/* PEF executable section and commands. */
+
+typedef struct PEFCommandHeader final {
+ CharType Name[kPefNameLen]; /* container name */
+ UInt32 Flags; /* container flags */
+ UInt16 Kind; /* container kind */
+ UIntPtr Offset; /* file offset */
+ SizeType Size; /* file size */
+} __attribute__((packed)) PEFCommandHeader;
+
+enum {
+ kPefCode = 0xC,
+ kPefData = 0xD,
+ kPefZero = 0xE,
+ kPefLinkerID = 0x1,
+};
+} // namespace CompilerKit
+
+inline std::ofstream& operator<<(std::ofstream& fp,
+ CompilerKit::PEFContainer& container) {
+ fp.write((char*)&container, sizeof(CompilerKit::PEFContainer));
+ return fp;
}
-inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFCommandHeader& container)
-{
- fp.write((char*)&container, sizeof(CompilerKit::PEFCommandHeader));
- return fp;
+inline std::ofstream& operator<<(std::ofstream& fp,
+ CompilerKit::PEFCommandHeader& container) {
+ fp.write((char*)&container, sizeof(CompilerKit::PEFCommandHeader));
+ return fp;
}
-std::ifstream &operator>>(std::ifstream& fp, CompilerKit::PEFContainer& container)
-{
- fp.read((char*)&container, sizeof(CompilerKit::PEFContainer));
- return fp;
+std::ifstream& operator>>(std::ifstream& fp,
+ CompilerKit::PEFContainer& container) {
+ fp.read((char*)&container, sizeof(CompilerKit::PEFContainer));
+ return fp;
}
-std::ifstream &operator>>(std::ifstream& fp, CompilerKit::PEFCommandHeader& container)
-{
- fp.read((char*)&container, sizeof(CompilerKit::PEFCommandHeader));
- return fp;
+std::ifstream& operator>>(std::ifstream& fp,
+ CompilerKit::PEFCommandHeader& container) {
+ fp.read((char*)&container, sizeof(CompilerKit::PEFCommandHeader));
+ return fp;
}
diff --git a/Private/CompilerKit/StdKit/Ref.hpp b/Private/CompilerKit/StdKit/Ref.hpp
index 9b79ca9..d7ef957 100644
--- a/Private/CompilerKit/StdKit/Ref.hpp
+++ b/Private/CompilerKit/StdKit/Ref.hpp
@@ -10,78 +10,57 @@
#pragma once
-namespace CompilerKit
-{
- // @author Amlal EL Mahrouss
- // @brief Reference class, refers to a pointer of data in static memory.
- template <typename T>
- class Ref final
- {
- public:
- explicit Ref() = default;
- ~Ref() = default;
-
- public:
- explicit Ref(T cls, const bool &strong = false) : m_Class(cls), m_Strong(strong) {}
-
- Ref& operator=(T ref)
- {
- m_Class = ref;
- return *this;
- }
-
- public:
- T operator->() const
- {
- return m_Class;
- }
-
- T &Leak()
- {
- return m_Class;
- }
-
- T operator*()
- {
- return m_Class;
- }
-
- bool IsStrong() const
- {
- return m_Strong;
- }
-
- operator bool()
- {
- return m_Class;
- }
-
- private:
- T m_Class;
- bool m_Strong{ false };
-
- };
-
- template <typename T>
- class NonNullRef final
- {
- public:
- NonNullRef() = delete;
- NonNullRef(nullPtr) = delete;
-
- explicit NonNullRef(T *ref) : m_Ref(ref, true) {}
-
- Ref<T> &operator->()
- {
- MUST_PASS(m_Ref);
- return m_Ref;
- }
-
- NonNullRef &operator=(const NonNullRef<T> &ref) = delete;
- NonNullRef(const NonNullRef<T> &ref) = default;
-
- private:
- Ref<T> m_Ref{ nullptr };
-
- };
-} // namespace CompilerKit
+namespace CompilerKit {
+// @author Amlal EL Mahrouss
+// @brief Reference class, refers to a pointer of data in static memory.
+template <typename T>
+class Ref final {
+ public:
+ explicit Ref() = default;
+ ~Ref() = default;
+
+ public:
+ explicit Ref(T cls, const bool &strong = false)
+ : m_Class(cls), m_Strong(strong) {}
+
+ Ref &operator=(T ref) {
+ m_Class = ref;
+ return *this;
+ }
+
+ public:
+ T operator->() const { return m_Class; }
+
+ T &Leak() { return m_Class; }
+
+ T operator*() { return m_Class; }
+
+ bool IsStrong() const { return m_Strong; }
+
+ operator bool() { return m_Class; }
+
+ private:
+ T m_Class;
+ bool m_Strong{false};
+};
+
+template <typename T>
+class NonNullRef final {
+ public:
+ NonNullRef() = delete;
+ NonNullRef(nullPtr) = delete;
+
+ explicit NonNullRef(T *ref) : m_Ref(ref, true) {}
+
+ Ref<T> &operator->() {
+ MUST_PASS(m_Ref);
+ return m_Ref;
+ }
+
+ NonNullRef &operator=(const NonNullRef<T> &ref) = delete;
+ NonNullRef(const NonNullRef<T> &ref) = default;
+
+ private:
+ Ref<T> m_Ref{nullptr};
+};
+} // namespace CompilerKit
diff --git a/Private/CompilerKit/StdKit/String.cc b/Private/CompilerKit/StdKit/String.cc
index 519ccff..958638d 100644
--- a/Private/CompilerKit/StdKit/String.cc
+++ b/Private/CompilerKit/StdKit/String.cc
@@ -13,241 +13,187 @@
* @brief C++ String Manip API.
* @version 0.2
* @date 2024-01-23
- *
+ *
* @copyright Copyright (c) 2024 Mahrouss Logic
- *
+ *
*/
#include "String.hpp"
+
#include <utility>
-namespace CompilerKit
-{
- CharType* StringView::Data()
- {
- return m_Data;
- }
+namespace CompilerKit {
+CharType *StringView::Data() { return m_Data; }
- const CharType* StringView::CData() const
- {
- return m_Data;
- }
+const CharType *StringView::CData() const { return m_Data; }
- SizeType StringView::Length() const
- {
- return strlen(m_Data);
- }
+SizeType StringView::Length() const { return strlen(m_Data); }
- bool StringView::operator==(const StringView &rhs) const
- {
- if (rhs.Length() != Length())
- return false;
+bool StringView::operator==(const StringView &rhs) const {
+ if (rhs.Length() != Length()) return false;
- for (SizeType index = 0; index < Length(); ++index)
- {
- if (rhs.m_Data[index] != m_Data[index])
- return false;
- }
+ for (SizeType index = 0; index < Length(); ++index) {
+ if (rhs.m_Data[index] != m_Data[index]) return false;
+ }
- return true;
- }
+ return true;
+}
- bool StringView::operator==(const CharType *rhs) const
- {
- if (string_length(rhs) != Length())
- return false;
+bool StringView::operator==(const CharType *rhs) const {
+ if (string_length(rhs) != Length()) return false;
- for (SizeType index = 0; index < string_length(rhs); ++index)
- {
- if (rhs[index] != m_Data[index])
- return false;
- }
+ for (SizeType index = 0; index < string_length(rhs); ++index) {
+ if (rhs[index] != m_Data[index]) return false;
+ }
- return true;
- }
+ return true;
+}
- bool StringView::operator!=(const StringView &rhs) const
- {
- if (rhs.Length() != Length())
- return false;
+bool StringView::operator!=(const StringView &rhs) const {
+ if (rhs.Length() != Length()) return false;
- for (SizeType index = 0; index < rhs.Length(); ++index)
- {
- if (rhs.m_Data[index] == m_Data[index])
- return false;
- }
+ for (SizeType index = 0; index < rhs.Length(); ++index) {
+ if (rhs.m_Data[index] == m_Data[index]) return false;
+ }
- return true;
- }
+ return true;
+}
- bool StringView::operator!=(const CharType *rhs) const
- {
- if (string_length(rhs) != Length())
- return false;
+bool StringView::operator!=(const CharType *rhs) const {
+ if (string_length(rhs) != Length()) return false;
- for (SizeType index = 0; index < string_length(rhs); ++index)
- {
- if (rhs[index] == m_Data[index])
- return false;
- }
+ for (SizeType index = 0; index < string_length(rhs); ++index) {
+ if (rhs[index] == m_Data[index]) return false;
+ }
- return true;
- }
-
- StringView StringBuilder::Construct(const CharType *data)
- {
- if (!data ||
- *data == 0)
- return StringView(0);
+ return true;
+}
- StringView view(strlen(data));
- view += data;
-
- return view;
- }
+StringView StringBuilder::Construct(const CharType *data) {
+ if (!data || *data == 0) return StringView(0);
- const char* StringBuilder::FromInt(const char *fmt, int i)
- {
- if (!fmt)
- return ("-1");
+ StringView view(strlen(data));
+ view += data;
- char *ret = new char[8 + string_length(fmt)];
+ return view;
+}
- if (!ret)
- return ("-1");
+const char *StringBuilder::FromInt(const char *fmt, int i) {
+ if (!fmt) return ("-1");
- CharType result[8];
- if (!to_str(result, sizeof(int), i))
- {
- delete[] ret;
- return ("-1");
- }
+ char *ret = new char[8 + string_length(fmt)];
- const auto fmt_len = string_length(fmt);
- const auto res_len = string_length(result);
+ if (!ret) return ("-1");
- for (SizeType idx = 0; idx < fmt_len; ++idx)
- {
- if (fmt[idx] == '%') {
- SizeType result_cnt = idx;
+ CharType result[8];
+ if (!to_str(result, sizeof(int), i)) {
+ delete[] ret;
+ return ("-1");
+ }
- for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
- ret[result_cnt] = result[y_idx];
- ++result_cnt;
- }
+ const auto fmt_len = string_length(fmt);
+ const auto res_len = string_length(result);
- break;
- }
+ for (SizeType idx = 0; idx < fmt_len; ++idx) {
+ if (fmt[idx] == '%') {
+ SizeType result_cnt = idx;
- ret[idx] = fmt[idx];
- }
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
+ ret[result_cnt] = result[y_idx];
+ ++result_cnt;
+ }
- return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */
+ break;
}
- const char* StringBuilder::FromBool(const char *fmt, bool i)
- {
- if (!fmt)
- return ("?");
+ ret[idx] = fmt[idx];
+ }
- const char *boolean_expr = i ? "true" : "false";
- char *ret = new char[i ? 4 : 5 + string_length(fmt)];
+ return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */
+}
- if (!ret)
- return ("?");
+const char *StringBuilder::FromBool(const char *fmt, bool i) {
+ if (!fmt) return ("?");
- const auto fmt_len = string_length(fmt);
- const auto res_len = string_length(boolean_expr);
+ const char *boolean_expr = i ? "true" : "false";
+ char *ret = new char[i ? 4 : 5 + string_length(fmt)];
- for (SizeType idx = 0; idx < fmt_len; ++idx)
- {
- if (fmt[idx] == '%')
- {
- SizeType result_cnt = idx;
+ if (!ret) return ("?");
- for (auto y_idx = idx; y_idx < res_len; ++y_idx)
- {
- ret[result_cnt] = boolean_expr[y_idx];
- ++result_cnt;
- }
+ const auto fmt_len = string_length(fmt);
+ const auto res_len = string_length(boolean_expr);
- break;
- }
+ for (SizeType idx = 0; idx < fmt_len; ++idx) {
+ if (fmt[idx] == '%') {
+ SizeType result_cnt = idx;
- ret[idx] = fmt[idx];
- }
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
+ ret[result_cnt] = boolean_expr[y_idx];
+ ++result_cnt;
+ }
- return ret;
+ break;
}
- bool StringBuilder::Equals(const char *lhs, const char *rhs)
- {
- if (string_length(rhs) != string_length(lhs))
- return false;
+ ret[idx] = fmt[idx];
+ }
- for (SizeType index = 0; index < string_length(rhs); ++index)
- {
- if (rhs[index] != lhs[index])
- return false;
- }
+ return ret;
+}
- return true;
- }
+bool StringBuilder::Equals(const char *lhs, const char *rhs) {
+ if (string_length(rhs) != string_length(lhs)) return false;
- const char *StringBuilder::Format(const char *fmt, const char *fmt2)
- {
- if (!fmt || !fmt2)
- return ("?");
+ for (SizeType index = 0; index < string_length(rhs); ++index) {
+ if (rhs[index] != lhs[index]) return false;
+ }
- char *ret = new char[string_length(fmt2) + string_length(fmt2)];
- if (!ret)
- return ("?");
+ return true;
+}
- for (SizeType idx = 0; idx < string_length(fmt); ++idx)
- {
- if (fmt[idx] == '%')
- {
- SizeType result_cnt = idx;
+const char *StringBuilder::Format(const char *fmt, const char *fmt2) {
+ if (!fmt || !fmt2) return ("?");
- for (SizeType y_idx = 0; y_idx < string_length(fmt2); ++y_idx)
- {
- ret[result_cnt] = fmt2[y_idx];
- ++result_cnt;
- }
+ char *ret = new char[string_length(fmt2) + string_length(fmt2)];
+ if (!ret) return ("?");
- break;
- }
+ for (SizeType idx = 0; idx < string_length(fmt); ++idx) {
+ if (fmt[idx] == '%') {
+ SizeType result_cnt = idx;
- ret[idx] = fmt[idx];
- }
+ for (SizeType y_idx = 0; y_idx < string_length(fmt2); ++y_idx) {
+ ret[result_cnt] = fmt2[y_idx];
+ ++result_cnt;
+ }
- return ret;
+ break;
}
- StringView &StringView::operator+=(const CharType *rhs)
- {
- if (strlen(rhs) > this->m_Sz)
- {
- throw std::runtime_error("out_of_bounds: StringView");
- }
+ ret[idx] = fmt[idx];
+ }
+ return ret;
+}
- memcpy(this->m_Data + this->m_Cur, rhs, strlen(rhs));
- this->m_Cur += strlen(rhs);
+StringView &StringView::operator+=(const CharType *rhs) {
+ if (strlen(rhs) > this->m_Sz) {
+ throw std::runtime_error("out_of_bounds: StringView");
+ }
- return *this;
- }
+ memcpy(this->m_Data + this->m_Cur, rhs, strlen(rhs));
+ this->m_Cur += strlen(rhs);
- StringView &StringView::operator+=(const StringView &rhs)
- {
- if (rhs.m_Cur > this->m_Sz)
- {
- throw std::runtime_error("out_of_bounds: StringView");
- }
+ return *this;
+}
- memcpy(this->m_Data + this->m_Cur, rhs.CData(), strlen(rhs.CData()));
- this->m_Cur += strlen(rhs.CData());
+StringView &StringView::operator+=(const StringView &rhs) {
+ if (rhs.m_Cur > this->m_Sz) {
+ throw std::runtime_error("out_of_bounds: StringView");
+ }
- return *this;
- }
-} // namespace CompilerKit
+ memcpy(this->m_Data + this->m_Cur, rhs.CData(), strlen(rhs.CData()));
+ this->m_Cur += strlen(rhs.CData());
+
+ return *this;
+}
+} // namespace CompilerKit
diff --git a/Private/CompilerKit/StdKit/String.hpp b/Private/CompilerKit/StdKit/String.hpp
index eada24d..1e4b34c 100644
--- a/Private/CompilerKit/StdKit/String.hpp
+++ b/Private/CompilerKit/StdKit/String.hpp
@@ -12,81 +12,66 @@
#include <CompilerKit/Defines.hpp>
#include <CompilerKit/StdKit/ErrorOr.hpp>
-namespace CompilerKit
-{
- /**
- * @brief StringView class, contains a C string and manages it.
- * @note No need to manage it it's getting deleted by default.
- */
-
- class StringView final
- {
- public:
- explicit StringView() = delete;
-
- explicit StringView(SizeType Sz) noexcept
- : m_Sz(Sz)
- {
- m_Data = new char[Sz];
- assert(m_Data);
- }
-
- ~StringView() noexcept
- {
- if (m_Data)
- {
- memset(m_Data, 0, m_Sz);
- delete[] m_Data;
-
- m_Data = nullptr;
- }
- }
-
- CXXKIT_COPY_DEFAULT(StringView);
-
- CharType *Data();
- const CharType *CData() const;
- SizeType Length() const;
-
- bool operator==(const CharType *rhs) const;
- bool operator!=(const CharType *rhs) const;
-
- bool operator==(const StringView &rhs) const;
- bool operator!=(const StringView &rhs) const;
-
- StringView &operator+=(const CharType *rhs);
- StringView &operator+=(const StringView &rhs);
-
- operator bool()
- {
- return m_Data && m_Data[0] != 0;
- }
-
- bool operator!()
- {
- return !m_Data || m_Data[0] == 0;
- }
-
- private:
- char* m_Data{ nullptr };
- SizeType m_Sz{ 0 };
- SizeType m_Cur{ 0 };
-
- friend class StringBuilder;
-
- };
-
- /**
- * @brief StringBuilder class
- * @note These results shall call delete[] after they're used.
- */
- struct StringBuilder final
- {
- static StringView Construct(const CharType *data);
- static const char* FromInt(const char *fmt, int n);
- static const char* FromBool(const char *fmt, bool n);
- static const char* Format(const char *fmt, const char* from);
- static bool Equals(const char *lhs, const char *rhs);
-
- };
-} // namespace CompilerKit
+namespace CompilerKit {
+/**
+ * @brief StringView class, contains a C string and manages it.
+ * @note No need to manage it it's getting deleted by default.
+ */
+
+class StringView final {
+ public:
+ explicit StringView() = delete;
+
+ explicit StringView(SizeType Sz) noexcept : m_Sz(Sz) {
+ m_Data = new char[Sz];
+ assert(m_Data);
+ }
+
+ ~StringView() noexcept {
+ if (m_Data) {
+ memset(m_Data, 0, m_Sz);
+ delete[] m_Data;
+
+ m_Data = nullptr;
+ }
+ }
+
+ CXXKIT_COPY_DEFAULT(StringView);
+
+ CharType *Data();
+ const CharType *CData() const;
+ SizeType Length() const;
+
+ bool operator==(const CharType *rhs) const;
+ bool operator!=(const CharType *rhs) const;
+
+ bool operator==(const StringView &rhs) const;
+ bool operator!=(const StringView &rhs) const;
+
+ StringView &operator+=(const CharType *rhs);
+ StringView &operator+=(const StringView &rhs);
+
+ operator bool() { return m_Data && m_Data[0] != 0; }
+
+ bool operator!() { return !m_Data || m_Data[0] == 0; }
+
+ private:
+ char *m_Data{nullptr};
+ SizeType m_Sz{0};
+ SizeType m_Cur{0};
+
+ friend class StringBuilder;
+};
+
+/**
+ * @brief StringBuilder class
+ * @note These results shall call delete[] after they're used.
+ */
+struct StringBuilder final {
+ static StringView Construct(const CharType *data);
+ static const char *FromInt(const char *fmt, int n);
+ static const char *FromBool(const char *fmt, bool n);
+ static const char *Format(const char *fmt, const char *from);
+ static bool Equals(const char *lhs, const char *rhs);
+};
+} // namespace CompilerKit