summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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
-rw-r--r--Private/Frontend/Compiler/compiler_command.d12
-rw-r--r--Private/Frontend/Compiler/compiler_macro_helpers.d2
-rw-r--r--Private/Frontend/Compiler/compiler_start.d4
-rw-r--r--Private/Toolchain/32asm.cc15
-rw-r--r--Private/Toolchain/64asm.cc1497
-rw-r--r--Private/Toolchain/bccl.cc2142
-rw-r--r--Private/Toolchain/bpp.cc1924
-rw-r--r--Private/Toolchain/ccplus.cc1058
-rw-r--r--Private/Toolchain/compile_flags.txt3
-rw-r--r--Private/Toolchain/i64asm.cc1725
-rw-r--r--Private/Toolchain/ld.cc814
-rw-r--r--Public/Documentation/325462-sdm-vol-1-2abcd-3abcd-4.pdf (renamed from Public/PDF/325462-sdm-vol-1-2abcd-3abcd-4.pdf)bin25301301 -> 25301301 bytes
-rw-r--r--Public/Documentation/ASM_SPECS.TXT (renamed from Public/PDF/ASM_SPECS.TXT)0
-rw-r--r--Public/Documentation/HAVP.TXT (renamed from Public/PDF/HAVP.TXT)0
-rw-r--r--Public/Documentation/Inside 64x0.pdf (renamed from Public/PDF/Inside 64x0.pdf)bin64675 -> 64675 bytes
-rw-r--r--Public/Documentation/NOTICE.TXT (renamed from Public/PDF/NOTICE.TXT)0
-rw-r--r--Public/Documentation/VNRP.TXT (renamed from Public/PDF/VNRP.TXT)0
32 files changed, 4975 insertions, 6109 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
diff --git a/Private/Frontend/Compiler/compiler_command.d b/Private/Frontend/Compiler/compiler_command.d
index 80d8673..7da7ff3 100644
--- a/Private/Frontend/Compiler/compiler_command.d
+++ b/Private/Frontend/Compiler/compiler_command.d
@@ -20,7 +20,7 @@ public void mpcc_summon_executable(string path)
{
import core.stdc.stdlib;
import std.string;
-
+
system(toStringz(path));
}
@@ -32,7 +32,7 @@ public class Platform
import std.string;
import std.conv;
import std.path;
-
+
string pathHome = expandTilde("~");
pathHome ~= "/mp-ux/libc/";
@@ -45,7 +45,7 @@ public class Platform
import std.string;
import std.conv;
import std.path;
-
+
string pathHome = expandTilde("~");
pathHome ~= "/mp-ux/mp-ux/";
@@ -59,7 +59,7 @@ public class CompileCommand
{
import std.string;
import std.algorithm;
-
+
foreach (file; files)
{
if (file.length == 0)
@@ -68,7 +68,7 @@ public class CompileCommand
import std.datetime;
string input = "/usr/local/bin/bin/cpp";
-
+
string[] arr_macros = CompilerMacroHelpers.getStandardMacros();
foreach (string macro_name; arr_macros)
@@ -149,4 +149,4 @@ public class CompileCommand
mpcc_summon_executable("/usr/local/bin/bin/ld " ~ obj ~ output_object);
}
-} \ No newline at end of file
+}
diff --git a/Private/Frontend/Compiler/compiler_macro_helpers.d b/Private/Frontend/Compiler/compiler_macro_helpers.d
index 4dfe65e..f567cb1 100644
--- a/Private/Frontend/Compiler/compiler_macro_helpers.d
+++ b/Private/Frontend/Compiler/compiler_macro_helpers.d
@@ -7,4 +7,4 @@ class CompilerMacroHelpers
string[] macros = [ "__64x0__", "__mpux__" ];
return macros;
}
-} \ No newline at end of file
+}
diff --git a/Private/Frontend/Compiler/compiler_start.d b/Private/Frontend/Compiler/compiler_start.d
index 44e17da..4b5c1cd 100644
--- a/Private/Frontend/Compiler/compiler_start.d
+++ b/Private/Frontend/Compiler/compiler_start.d
@@ -31,7 +31,7 @@ void mpcc_summon_manual(string path)
core.stdc.stdlib.system(toStringz(base ~ path ~ extension));
}
-void main(string[] args)
+void main(string[] args)
{
import std.range, std.stdio;
@@ -109,4 +109,4 @@ void main(string[] args)
compiler.compile(Platform.getKernelPath(), args_list, shared_library, output_file, compile_only);
else
compiler.compile(Platform.getIncludePath(), args_list, shared_library, output_file, compile_only);
-} \ No newline at end of file
+}
diff --git a/Private/Toolchain/32asm.cc b/Private/Toolchain/32asm.cc
index 6c28868..6114f4a 100644
--- a/Private/Toolchain/32asm.cc
+++ b/Private/Toolchain/32asm.cc
@@ -15,8 +15,8 @@
// @author Amlal El Mahrouss
// @brief 32x0 Assembler.
-// REMINDER: when dealing with an undefined symbol use (string size):LinkerFindSymbol:(string)
-// so that ld will look for it.
+// REMINDER: when dealing with an undefined symbol use (string
+// size):LinkerFindSymbol:(string) so that ld will look for it.
/////////////////////////////////////////////////////////////////////////////////////////
@@ -24,11 +24,11 @@
#include <CompilerKit/AsmKit/Arch/32x0.hpp>
#include <CompilerKit/ParserKit.hpp>
-#include <CompilerKit/StdKit/PEF.hpp>
#include <CompilerKit/StdKit/AE.hpp>
+#include <CompilerKit/StdKit/PEF.hpp>
#include <filesystem>
-#include <iostream>
#include <fstream>
+#include <iostream>
/////////////////////
@@ -47,9 +47,4 @@
/////////////////////////////////////////////////////////////////////////////////////////
-MPCC_MODULE(MPUXAssembler32000)
-{
-
-
- return 0;
-} \ No newline at end of file
+MPCC_MODULE(MPUXAssembler32000) { return 0; }
diff --git a/Private/Toolchain/64asm.cc b/Private/Toolchain/64asm.cc
index 2764bf0..c91eb74 100644
--- a/Private/Toolchain/64asm.cc
+++ b/Private/Toolchain/64asm.cc
@@ -15,8 +15,8 @@
// @author Amlal El Mahrouss
// @brief 64x0 Assembler.
-// REMINDER: when dealing with an undefined symbol use (string size):LinkerFindSymbol:(string)
-// so that ld will look for it.
+// REMINDER: when dealing with an undefined symbol use (string
+// size):LinkerFindSymbol:(string) so that ld will look for it.
/////////////////////////////////////////////////////////////////////////////////////////
@@ -24,11 +24,11 @@
#include <CompilerKit/AsmKit/Arch/64x0.hpp>
#include <CompilerKit/ParserKit.hpp>
-#include <CompilerKit/StdKit/PEF.hpp>
#include <CompilerKit/StdKit/AE.hpp>
+#include <CompilerKit/StdKit/PEF.hpp>
#include <filesystem>
-#include <iostream>
#include <fstream>
+#include <iostream>
/////////////////////
@@ -59,12 +59,8 @@ static bool kVerbose = false;
static std::vector<e64k_num_t> kBytes;
-static CompilerKit::AERecordHeader kCurrentRecord {
- .fName = "",
- .fKind = CompilerKit::kPefCode,
- .fSize = 0,
- .fOffset = 0
- };
+static CompilerKit::AERecordHeader kCurrentRecord{
+ .fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0};
static std::vector<CompilerKit::AERecordHeader> kRecords;
static std::vector<std::string> kUndefinedSymbols;
@@ -75,35 +71,31 @@ static const std::string kRelocSymbol = ":mld:";
// \brief forward decl.
static bool asm_read_attributes(std::string &line);
-namespace detail
-{
- void print_error(std::string reason, const std::string &file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
+namespace detail {
+void print_error(std::string reason, const std::string &file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- kStdErr << kRed << "[ 64asm ] " << kWhite << ((file == "64asm") ? "internal assembler error " : ("in file, " + file)) << kBlank << std::endl;
- kStdErr << kRed << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
+ kStdErr << kRed << "[ 64asm ] " << kWhite
+ << ((file == "64asm") ? "internal assembler error "
+ : ("in file, " + file))
+ << kBlank << std::endl;
+ kStdErr << kRed << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
- if (kAcceptableErrors > kErrorLimit)
- std::exit(3);
+ if (kAcceptableErrors > kErrorLimit) std::exit(3);
- ++kAcceptableErrors;
- }
+ ++kAcceptableErrors;
+}
- void print_warning(std::string reason, const std::string &file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
+void print_warning(std::string reason, const std::string &file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- if (!file.empty())
- {
- kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
- }
+ if (!file.empty()) {
+ kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
+ }
- kStdOut << kYellow << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
- }
+ kStdOut << kYellow << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
}
+} // namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
@@ -111,225 +103,192 @@ namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
-MPCC_MODULE(MPUXAssembler64000)
-{
- for (size_t i = 1; i < argc; ++i)
- {
- if (argv[i][0] == '-')
- {
- if (strcmp(argv[i], "-version") == 0 ||
- strcmp(argv[i], "-v") == 0)
- {
- kStdOut << "64asm: 64x0 Assembler.\n64asm: v1.10\n64asm: Copyright (c) 2024 Mahrouss Logic.\n";
- return 0;
- }
- else if (strcmp(argv[i], "-h") == 0)
- {
- kStdOut << "64asm: 64x0 Assembler.\n64asm: Copyright (c) 2024 Mahrouss Logic.\n";
- kStdOut << "-version: Print program version.\n";
- kStdOut << "-verbose: Print verbose output.\n";
- kStdOut << "-binary: Output as flat binary.\n";
- kStdOut << "-64xxx: Compile for a subset of the X64000.\n";
-
- return 0;
- }
- else if (strcmp(argv[i], "-binary") == 0)
- {
- kOutputAsBinary = true;
- continue;
- }
- else if (strcmp(argv[i], "-verbose") == 0)
- {
- kVerbose = true;
- continue;
- }
-
- kStdOut << "64asm: ignore " << argv[i] << "\n";
- continue;
- }
+MPCC_MODULE(MPUXAssembler64000) {
+ for (size_t i = 1; i < argc; ++i) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "-v") == 0) {
+ kStdOut << "64asm: 64x0 Assembler.\n64asm: v1.10\n64asm: Copyright (c) "
+ "2024 Mahrouss Logic.\n";
+ return 0;
+ } else if (strcmp(argv[i], "-h") == 0) {
+ kStdOut << "64asm: 64x0 Assembler.\n64asm: Copyright (c) 2024 Mahrouss "
+ "Logic.\n";
+ kStdOut << "-version: Print program version.\n";
+ kStdOut << "-verbose: Print verbose output.\n";
+ kStdOut << "-binary: Output as flat binary.\n";
+ kStdOut << "-64xxx: Compile for a subset of the X64000.\n";
- if (!std::filesystem::exists(argv[i]))
- {
- kStdOut << "64asm: can't open: " << argv[i] << std::endl;
- goto asm_fail_exit;
- }
+ return 0;
+ } else if (strcmp(argv[i], "-binary") == 0) {
+ kOutputAsBinary = true;
+ continue;
+ } else if (strcmp(argv[i], "-verbose") == 0) {
+ kVerbose = true;
+ continue;
+ }
+
+ kStdOut << "64asm: ignore " << argv[i] << "\n";
+ continue;
+ }
- std::string object_output(argv[i]);
+ if (!std::filesystem::exists(argv[i])) {
+ kStdOut << "64asm: can't open: " << argv[i] << std::endl;
+ goto asm_fail_exit;
+ }
- for (auto &ext : kAsmFileExts)
- {
- if (object_output.find(ext) != std::string::npos)
- {
- object_output.erase(object_output.find(ext), std::strlen(ext));
- }
- }
+ std::string object_output(argv[i]);
- object_output += kObjectFileExt;
+ for (auto &ext : kAsmFileExts) {
+ if (object_output.find(ext) != std::string::npos) {
+ object_output.erase(object_output.find(ext), std::strlen(ext));
+ }
+ }
- std::ifstream file_ptr(argv[i]);
- std::ofstream file_ptr_out(object_output,
- std::ofstream::binary);
+ object_output += kObjectFileExt;
- if (file_ptr_out.bad())
- {
- if (kVerbose)
- {
- kStdOut << "64asm: error: " << strerror(errno) << "\n";
- }
- }
+ std::ifstream file_ptr(argv[i]);
+ std::ofstream file_ptr_out(object_output, std::ofstream::binary);
- std::string line;
+ if (file_ptr_out.bad()) {
+ if (kVerbose) {
+ kStdOut << "64asm: error: " << strerror(errno) << "\n";
+ }
+ }
- CompilerKit::AEHeader hdr{0};
+ std::string line;
- memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
+ CompilerKit::AEHeader hdr{0};
- hdr.fMagic[0] = kAEMag0;
- hdr.fMagic[1] = kAEMag1;
- hdr.fSize = sizeof(CompilerKit::AEHeader);
- hdr.fArch = kOutputArch;
+ memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
- /////////////////////////////////////////////////////////////////////////////////////////
+ hdr.fMagic[0] = kAEMag0;
+ hdr.fMagic[1] = kAEMag1;
+ hdr.fSize = sizeof(CompilerKit::AEHeader);
+ hdr.fArch = kOutputArch;
- // COMPILATION LOOP
+ /////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
+ // COMPILATION LOOP
- CompilerKit::PlatformAssembler64x0 asm64;
+ /////////////////////////////////////////////////////////////////////////////////////////
- while (std::getline(file_ptr, line))
- {
- if (auto ln = asm64.CheckLine(line, argv[i]);
- !ln.empty())
- {
- detail::print_error(ln, argv[i]);
- continue;
- }
+ CompilerKit::PlatformAssembler64x0 asm64;
- try
- {
- asm_read_attributes(line);
- asm64.WriteLine(line, argv[i]);
- }
- catch (const std::exception &e)
- {
- if (kVerbose)
- {
- std::string what = e.what();
- detail::print_warning("exit because of: " + what, "64asm");
- }
+ while (std::getline(file_ptr, line)) {
+ if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) {
+ detail::print_error(ln, argv[i]);
+ continue;
+ }
- std::filesystem::remove(object_output);
- goto asm_fail_exit;
- }
+ try {
+ asm_read_attributes(line);
+ asm64.WriteLine(line, argv[i]);
+ } catch (const std::exception &e) {
+ if (kVerbose) {
+ std::string what = e.what();
+ detail::print_warning("exit because of: " + what, "64asm");
}
- if (!kOutputAsBinary)
- {
- if (kVerbose)
- {
- kStdOut << "64asm: Writing object file...\n";
- }
+ std::filesystem::remove(object_output);
+ goto asm_fail_exit;
+ }
+ }
- // this is the final step, write everything to the file.
+ if (!kOutputAsBinary) {
+ if (kVerbose) {
+ kStdOut << "64asm: Writing object file...\n";
+ }
- auto pos = file_ptr_out.tellp();
+ // this is the final step, write everything to the file.
- hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
+ auto pos = file_ptr_out.tellp();
- file_ptr_out << hdr;
+ hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
- if (kRecords.empty())
- {
- kStdErr << "64asm: At least one record is needed to write an object file.\n64asm: Make one using `export .text foo_bar`.\n";
+ file_ptr_out << hdr;
- std::filesystem::remove(object_output);
- return -1;
- }
+ if (kRecords.empty()) {
+ kStdErr << "64asm: At least one record is needed to write an object "
+ "file.\n64asm: Make one using `export .text foo_bar`.\n";
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ std::filesystem::remove(object_output);
+ return -1;
+ }
- std::size_t record_count = 0UL;
+ kRecords[kRecords.size() - 1].fSize = kBytes.size();
- for (auto &rec : kRecords)
- {
- if (kVerbose)
- kStdOut << "64asm: Wrote record " << rec.fName << " to file...\n";
+ std::size_t record_count = 0UL;
- rec.fFlags |= CompilerKit::kKindRelocationAtRuntime;
- rec.fOffset = record_count;
- ++record_count;
+ for (auto &rec : kRecords) {
+ if (kVerbose)
+ kStdOut << "64asm: Wrote record " << rec.fName << " to file...\n";
- file_ptr_out << rec;
- }
+ rec.fFlags |= CompilerKit::kKindRelocationAtRuntime;
+ rec.fOffset = record_count;
+ ++record_count;
- // increment once again, so that we won't lie about the kUndefinedSymbols.
- ++record_count;
+ file_ptr_out << rec;
+ }
- for (auto &sym : kUndefinedSymbols)
- {
- CompilerKit::AERecordHeader _record_hdr{0};
+ // increment once again, so that we won't lie about the kUndefinedSymbols.
+ ++record_count;
- if (kVerbose)
- kStdOut << "64asm: Wrote symbol " << sym << " to file...\n";
+ for (auto &sym : kUndefinedSymbols) {
+ CompilerKit::AERecordHeader _record_hdr{0};
- _record_hdr.fKind = kAEInvalidOpcode;
- _record_hdr.fSize = sym.size();
- _record_hdr.fOffset = record_count;
+ if (kVerbose)
+ kStdOut << "64asm: Wrote symbol " << sym << " to file...\n";
- ++record_count;
+ _record_hdr.fKind = kAEInvalidOpcode;
+ _record_hdr.fSize = sym.size();
+ _record_hdr.fOffset = record_count;
- memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
- memcpy(_record_hdr.fName, sym.c_str(), sym.size());
+ ++record_count;
- file_ptr_out << _record_hdr;
+ memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
+ memcpy(_record_hdr.fName, sym.c_str(), sym.size());
- ++kCounter;
- }
+ file_ptr_out << _record_hdr;
- auto pos_end = file_ptr_out.tellp();
+ ++kCounter;
+ }
- file_ptr_out.seekp(pos);
+ auto pos_end = file_ptr_out.tellp();
- hdr.fStartCode = pos_end;
- hdr.fCodeSize = kBytes.size();
+ file_ptr_out.seekp(pos);
- file_ptr_out << hdr;
+ hdr.fStartCode = pos_end;
+ hdr.fCodeSize = kBytes.size();
- file_ptr_out.seekp(pos_end);
- }
- else
- {
- if (kVerbose)
- {
- kStdOut << "64asm: Write raw binary...\n";
- }
- }
+ file_ptr_out << hdr;
- // byte from byte, we write this.
- for (auto& byte : kBytes)
- {
- file_ptr_out.write(reinterpret_cast<const char*>(&byte), sizeof(byte));
- }
+ file_ptr_out.seekp(pos_end);
+ } else {
+ if (kVerbose) {
+ kStdOut << "64asm: Write raw binary...\n";
+ }
+ }
- if (kVerbose)
- kStdOut << "64asm: Wrote file with program in it.\n";
+ // byte from byte, we write this.
+ for (auto &byte : kBytes) {
+ file_ptr_out.write(reinterpret_cast<const char *>(&byte), sizeof(byte));
+ }
- file_ptr_out.flush();
- file_ptr_out.close();
+ if (kVerbose) kStdOut << "64asm: Wrote file with program in it.\n";
- if (kVerbose)
- kStdOut << "64asm: Exit succeeded.\n";
+ file_ptr_out.flush();
+ file_ptr_out.close();
- return 0;
- }
+ if (kVerbose) kStdOut << "64asm: Exit succeeded.\n";
+
+ return 0;
+ }
asm_fail_exit:
- if (kVerbose)
- kStdOut << "64asm: Exit failed.\n";
+ if (kVerbose) kStdOut << "64asm: Exit failed.\n";
- return -1;
+ return -1;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -339,165 +298,143 @@ asm_fail_exit:
/////////////////////////////////////////////////////////////////////////////////////////
-static bool asm_read_attributes(std::string &line)
-{
- // import is the opposite of export, it signals to the ld
- // that we need this symbol.
- if (ParserKit::find_word(line, "import "))
- {
- if (kOutputAsBinary)
- {
- detail::print_error("Invalid import directive in flat binary mode.", "64asm");
- throw std::runtime_error("invalid_import_bin");
- }
-
- auto name = line.substr(line.find("import ") + strlen("import "));
+static bool asm_read_attributes(std::string &line) {
+ // import is the opposite of export, it signals to the ld
+ // that we need this symbol.
+ if (ParserKit::find_word(line, "import ")) {
+ if (kOutputAsBinary) {
+ detail::print_error("Invalid import directive in flat binary mode.",
+ "64asm");
+ throw std::runtime_error("invalid_import_bin");
+ }
- std::string result = std::to_string(name.size());
- result += kUndefinedSymbol;
+ auto name = line.substr(line.find("import ") + strlen("import "));
- // mangle this
- for (char &j : name)
- {
- if (j == ' ' ||
- j == ',')
- j = '$';
- }
+ std::string result = std::to_string(name.size());
+ result += kUndefinedSymbol;
- result += name;
+ // mangle this
+ for (char &j : name) {
+ if (j == ' ' || j == ',') j = '$';
+ }
- if (name.find(".text") != std::string::npos)
- {
- // data is treated as code.
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
- else if (name.find(".data") != std::string::npos)
- {
- // no code will be executed from here.
- kCurrentRecord.fKind = CompilerKit::kPefData;
- }
- else if (name.find(".page_zero") != std::string::npos)
- {
- // this is a bss section.
- kCurrentRecord.fKind = CompilerKit::kPefZero;
- }
+ result += name;
+
+ if (name.find(".text") != std::string::npos) {
+ // data is treated as code.
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ } else if (name.find(".data") != std::string::npos) {
+ // no code will be executed from here.
+ kCurrentRecord.fKind = CompilerKit::kPefData;
+ } else if (name.find(".page_zero") != std::string::npos) {
+ // this is a bss section.
+ kCurrentRecord.fKind = CompilerKit::kPefZero;
+ }
- // this is a special case for the start stub.
- // we want this so that ld can find it.
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
- if (name == "__start")
- {
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
+ if (name == "__start") {
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ }
- // now we can tell the code size of the previous kCurrentRecord.
+ // now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty())
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, result.c_str(), result.size());
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, result.c_str(), result.size());
- ++kCounter;
+ ++kCounter;
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
- kRecords.emplace_back(kCurrentRecord);
+ kRecords.emplace_back(kCurrentRecord);
- return true;
+ return true;
+ }
+ // export is a special keyword used by 64asm to tell the AE output stage to
+ // mark this section as a header. it currently supports .text, .data.,
+ // page_zero
+ else if (ParserKit::find_word(line, "export ")) {
+ if (kOutputAsBinary) {
+ detail::print_error("Invalid export directive in flat binary mode.",
+ "64asm");
+ throw std::runtime_error("invalid_export_bin");
}
- // export is a special keyword used by 64asm to tell the AE output stage to mark this section as a header.
- // it currently supports .text, .data., page_zero
- else if (ParserKit::find_word(line, "export "))
- {
- if (kOutputAsBinary)
- {
- detail::print_error("Invalid export directive in flat binary mode.", "64asm");
- throw std::runtime_error("invalid_export_bin");
- }
- auto name = line.substr(line.find("export ") + strlen("export "));
+ auto name = line.substr(line.find("export ") + strlen("export "));
- std::string name_copy = name;
+ std::string name_copy = name;
- for (char &j : name)
- {
- if (j == ' ')
- j = '$';
- }
+ for (char &j : name) {
+ if (j == ' ') j = '$';
+ }
- if (name.find(".text") != std::string::npos)
- {
- // data is treated as code.
+ if (name.find(".text") != std::string::npos) {
+ // data is treated as code.
- name_copy.erase(name_copy.find(".text"), strlen(".text"));
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
- else if (name.find(".data") != std::string::npos)
- {
- // no code will be executed from here.
+ name_copy.erase(name_copy.find(".text"), strlen(".text"));
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ } else if (name.find(".data") != std::string::npos) {
+ // no code will be executed from here.
- name_copy.erase(name_copy.find(".data"), strlen(".data"));
- kCurrentRecord.fKind = CompilerKit::kPefData;
- }
- else if (name.find(".page_zero") != std::string::npos)
- {
- // this is a bss section.
+ name_copy.erase(name_copy.find(".data"), strlen(".data"));
+ kCurrentRecord.fKind = CompilerKit::kPefData;
+ } else if (name.find(".page_zero") != std::string::npos) {
+ // this is a bss section.
- name_copy.erase(name_copy.find(".page_zero"), strlen(".page_zero"));
- kCurrentRecord.fKind = CompilerKit::kPefZero;
- }
+ name_copy.erase(name_copy.find(".page_zero"), strlen(".page_zero"));
+ kCurrentRecord.fKind = CompilerKit::kPefZero;
+ }
- // this is a special case for the start stub.
- // we want this so that ld can find it.
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
- if (name == "__start")
- {
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
+ if (name == "__start") {
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ }
- while (name_copy.find(" ") != std::string::npos)
- name_copy.erase(name_copy.find(" "), 1);
+ while (name_copy.find(" ") != std::string::npos)
+ name_copy.erase(name_copy.find(" "), 1);
- kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
- ++kOrigin;
+ kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
+ ++kOrigin;
- // now we can tell the code size of the previous kCurrentRecord.
+ // now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty())
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, name.c_str(), name.size());
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, name.c_str(), name.size());
- ++kCounter;
+ ++kCounter;
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
- kRecords.emplace_back(kCurrentRecord);
+ kRecords.emplace_back(kCurrentRecord);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
// \brief algorithms and helpers.
-namespace detail::algorithm
-{
- // \brief authorize a brief set of characters.
- static inline bool is_not_alnum_space(char c)
- {
- return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') || (c == ',') ||
- (c == '(') || (c == ')') || (c == '"') || (c == '\'') || (c == '[') || (c == ']') || (c == '+') || (c == '_') || (c == ':') || (c == '@') || (c == '.'));
- }
+namespace detail::algorithm {
+// \brief authorize a brief set of characters.
+static inline bool is_not_alnum_space(char c) {
+ return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') ||
+ (c == ',') || (c == '(') || (c == ')') || (c == '"') ||
+ (c == '\'') || (c == '[') || (c == ']') || (c == '+') ||
+ (c == '_') || (c == ':') || (c == '@') || (c == '.'));
+}
- bool is_valid(const std::string &str)
- {
- return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
- }
+bool is_valid(const std::string &str) {
+ return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
}
+} // namespace detail::algorithm
/////////////////////////////////////////////////////////////////////////////////////////
@@ -505,262 +442,214 @@ namespace detail::algorithm
/////////////////////////////////////////////////////////////////////////////////////////
-std::string CompilerKit::PlatformAssembler64x0::CheckLine(std::string &line, const std::string &file)
-{
- std::string err_str;
-
- if (line.empty() ||
- ParserKit::find_word(line, "import") ||
- ParserKit::find_word(line, "export") ||
- ParserKit::find_word(line, "#") ||
- ParserKit::find_word(line, ";"))
- {
- if (line.find('#') != std::string::npos)
- {
- line.erase(line.find('#'));
- }
- else if (line.find(';') != std::string::npos)
- {
- line.erase(line.find(';'));
- }
- else
- {
- // now check the line for validity
- if (!detail::algorithm::is_valid(line))
- {
- err_str = "Line contains non alphanumeric characters.\nhere -> ";
- err_str += line;
- }
- }
-
- return err_str;
- }
-
- if (!detail::algorithm::is_valid(line))
- {
+std::string CompilerKit::PlatformAssembler64x0::CheckLine(
+ std::string &line, const std::string &file) {
+ std::string err_str;
+
+ if (line.empty() || ParserKit::find_word(line, "import") ||
+ ParserKit::find_word(line, "export") || ParserKit::find_word(line, "#") ||
+ ParserKit::find_word(line, ";")) {
+ if (line.find('#') != std::string::npos) {
+ line.erase(line.find('#'));
+ } else if (line.find(';') != std::string::npos) {
+ line.erase(line.find(';'));
+ } else {
+ // now check the line for validity
+ if (!detail::algorithm::is_valid(line)) {
err_str = "Line contains non alphanumeric characters.\nhere -> ";
err_str += line;
-
- return err_str;
+ }
}
- // check for a valid instruction format.
+ return err_str;
+ }
- if (line.find(',') != std::string::npos)
- {
- if (line.find(',') + 1 == line.size())
- {
- err_str += "\nInstruction lacks right register, here -> ";
- err_str += line.substr(line.find(','));
+ if (!detail::algorithm::is_valid(line)) {
+ err_str = "Line contains non alphanumeric characters.\nhere -> ";
+ err_str += line;
- return err_str;
- }
- else
- {
- bool nothing_on_right = true;
+ return err_str;
+ }
- if (line.find(',') + 1 > line.size())
- {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
+ // check for a valid instruction format.
- return err_str;
- }
+ if (line.find(',') != std::string::npos) {
+ if (line.find(',') + 1 == line.size()) {
+ err_str += "\nInstruction lacks right register, here -> ";
+ err_str += line.substr(line.find(','));
- auto substr = line.substr(line.find(',') + 1);
+ return err_str;
+ } else {
+ bool nothing_on_right = true;
- for (auto &ch : substr)
- {
- if (ch != ' ' &&
- ch != '\t')
- {
- nothing_on_right = false;
- }
- }
+ if (line.find(',') + 1 > line.size()) {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
- // this means we found nothing after that ',' .
- if (nothing_on_right)
- {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
+ return err_str;
+ }
- return err_str;
- }
- }
- }
+ auto substr = line.substr(line.find(',') + 1);
- // these do take an argument.
- std::vector<std::string> operands_inst = {"stw", "ldw", "lda", "sta"};
-
- // these don't.
- std::vector<std::string> filter_inst = {"jlr", "jrl", "int"};
-
- for (auto &opcode64x0 : kOpcodes64x0)
- {
- if (line.find(opcode64x0.fName) != std::string::npos)
- {
- if (opcode64x0.fFunct7 == kAsmNoArgs)
- return err_str;
-
- for (auto &op : operands_inst)
- {
- // if only the instruction was found.
- if (line == op)
- {
- err_str += "\nMalformed ";
- err_str += op;
- err_str += " instruction, here -> ";
- err_str += line;
- }
- }
+ for (auto &ch : substr) {
+ if (ch != ' ' && ch != '\t') {
+ nothing_on_right = false;
+ }
+ }
- // if it is like that -> addr1, 0x0
- if (auto it = std::find(filter_inst.begin(), filter_inst.end(), opcode64x0.fName);
- it == filter_inst.cend())
- {
- if (ParserKit::find_word(line, opcode64x0.fName))
- {
- if (!isspace(line[line.find(opcode64x0.fName) + strlen(opcode64x0.fName)]))
- {
- err_str += "\nMissing space between ";
- err_str += opcode64x0.fName;
- err_str += " and operands.\nhere -> ";
- err_str += line;
- }
- }
- }
+ // this means we found nothing after that ',' .
+ if (nothing_on_right) {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
- return err_str;
- }
+ return err_str;
+ }
+ }
+ }
+
+ // these do take an argument.
+ std::vector<std::string> operands_inst = {"stw", "ldw", "lda", "sta"};
+
+ // these don't.
+ std::vector<std::string> filter_inst = {"jlr", "jrl", "int"};
+
+ for (auto &opcode64x0 : kOpcodes64x0) {
+ if (line.find(opcode64x0.fName) != std::string::npos) {
+ if (opcode64x0.fFunct7 == kAsmNoArgs) return err_str;
+
+ for (auto &op : operands_inst) {
+ // if only the instruction was found.
+ if (line == op) {
+ err_str += "\nMalformed ";
+ err_str += op;
+ err_str += " instruction, here -> ";
+ err_str += line;
+ }
+ }
+
+ // if it is like that -> addr1, 0x0
+ if (auto it = std::find(filter_inst.begin(), filter_inst.end(),
+ opcode64x0.fName);
+ it == filter_inst.cend()) {
+ if (ParserKit::find_word(line, opcode64x0.fName)) {
+ if (!isspace(line[line.find(opcode64x0.fName) +
+ strlen(opcode64x0.fName)])) {
+ err_str += "\nMissing space between ";
+ err_str += opcode64x0.fName;
+ err_str += " and operands.\nhere -> ";
+ err_str += line;
+ }
+ }
+ }
+
+ return err_str;
}
+ }
- err_str += "Unrecognized instruction and operands: " + line;
+ err_str += "Unrecognized instruction and operands: " + line;
- return err_str;
+ return err_str;
}
-bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std::string &jump_label)
-{
- if (!isdigit(jump_label[pos]))
- return false;
-
- switch (jump_label[pos + 1])
- {
- case 'x':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid hex number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_hex");
- }
+bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos,
+ std::string &jump_label) {
+ if (!isdigit(jump_label[pos])) return false;
+
+ switch (jump_label[pos + 1]) {
+ case 'x': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid hex number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_hex");
}
+ }
- CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16));
+ CompilerKit::NumberCast64 num(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- for (char &i : num.number)
- {
- kBytes.push_back(i);
- }
+ for (char &i : num.number) {
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- return true;
+ return true;
}
- case 'b':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid binary number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_bin");
- }
+ case 'b': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid binary number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_bin");
}
+ }
- CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2));
+ CompilerKit::NumberCast64 num(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2));
- if (kVerbose)
- {
- kStdOut << "64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- kBytes.push_back(i);
- }
+ for (char &i : num.number) {
+ kBytes.push_back(i);
+ }
- return true;
+ return true;
}
- case 'o':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid octal number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_octal");
- }
+ case 'o': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid octal number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_octal");
}
+ }
- CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7));
+ CompilerKit::NumberCast64 num(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7));
- if (kVerbose)
- {
- kStdOut << "64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- kBytes.push_back(i);
- }
+ for (char &i : num.number) {
+ kBytes.push_back(i);
+ }
- return true;
- }
- default:
- {
- break;
+ return true;
}
+ default: {
+ break;
}
+ }
- /* check for errno and stuff like that */
- if (auto res = strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10);
- !res)
- {
- if (errno != 0)
- {
- return false;
- }
+ /* check for errno and stuff like that */
+ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
+ if (errno != 0) {
+ return false;
}
+ }
- CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10));
+ CompilerKit::NumberCast64 num(
+ strtoq(jump_label.substr(pos).c_str(), nullptr, 10));
- for (char &i : num.number)
- {
- kBytes.push_back(i);
- }
+ for (char &i : num.number) {
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
- return true;
+ return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -769,328 +658,284 @@ bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std
/////////////////////////////////////////////////////////////////////////////////////////
-bool CompilerKit::PlatformAssembler64x0::WriteLine(std::string &line, const std::string &file)
-{
- if (ParserKit::find_word(line, "export "))
- return true;
-
- for (auto &opcode64x0 : kOpcodes64x0)
- {
- // strict check here
- if (ParserKit::find_word(line, opcode64x0.fName) &&
- detail::algorithm::is_valid(line))
- {
- std::string name(opcode64x0.fName);
- std::string jump_label, cpy_jump_label;
-
- kBytes.emplace_back(opcode64x0.fOpcode);
- kBytes.emplace_back(opcode64x0.fFunct3);
- kBytes.emplace_back(opcode64x0.fFunct7);
-
- // check funct7 type.
- switch (opcode64x0.fFunct7)
- {
- // reg to reg means register to register transfer operation.
- case kAsmRegToReg:
- case kAsmImmediate:
- {
- // \brief how many registers we found.
- std::size_t found_some = 0UL;
-
- for (size_t line_index = 0UL; line_index < line.size(); line_index++)
- {
- if (line[line_index] == kAsmRegisterPrefix[0] &&
- isdigit(line[line_index + 1]))
- {
- std::string register_syntax = kAsmRegisterPrefix;
- register_syntax += line[line_index + 1];
-
- if (isdigit(line[line_index + 2]))
- register_syntax += line[line_index + 2];
-
- std::string reg_str;
- reg_str += line[line_index + 1];
-
- if (isdigit(line[line_index + 2]))
- reg_str += line[line_index + 2];
-
- // it ranges from r0 to r19
- // something like r190 doesn't exist in the instruction set.
- if (kOutputArch == CompilerKit::kPefArch64000)
- {
- if (isdigit(line[line_index + 3]) &&
- isdigit(line[line_index + 2]))
- {
- reg_str += line[line_index + 3];
- detail::print_error("invalid register index, r" + reg_str + "\nnote: The 64x0 accepts registers from r0 to r20.", file);
- throw std::runtime_error("invalid_register_index");
- }
- }
-
- // finally cast to a size_t
- std::size_t reg_index = strtoq(
- reg_str.c_str(),
- nullptr,
- 10);
-
- if (reg_index > kAsmRegisterLimit)
- {
- detail::print_error("invalid register index, r" + reg_str, file);
- throw std::runtime_error("invalid_register_index");
- }
-
- kBytes.emplace_back(reg_index);
- ++found_some;
-
- if (kVerbose)
- {
- kStdOut << "64asm: Register found: " << register_syntax << "\n";
- kStdOut << "64asm: Register amount in instruction: " << found_some << "\n";
- }
- }
+bool CompilerKit::PlatformAssembler64x0::WriteLine(std::string &line,
+ const std::string &file) {
+ if (ParserKit::find_word(line, "export ")) return true;
+
+ for (auto &opcode64x0 : kOpcodes64x0) {
+ // strict check here
+ if (ParserKit::find_word(line, opcode64x0.fName) &&
+ detail::algorithm::is_valid(line)) {
+ std::string name(opcode64x0.fName);
+ std::string jump_label, cpy_jump_label;
+
+ kBytes.emplace_back(opcode64x0.fOpcode);
+ kBytes.emplace_back(opcode64x0.fFunct3);
+ kBytes.emplace_back(opcode64x0.fFunct7);
+
+ // check funct7 type.
+ switch (opcode64x0.fFunct7) {
+ // reg to reg means register to register transfer operation.
+ case kAsmRegToReg:
+ case kAsmImmediate: {
+ // \brief how many registers we found.
+ std::size_t found_some = 0UL;
+
+ for (size_t line_index = 0UL; line_index < line.size();
+ line_index++) {
+ if (line[line_index] == kAsmRegisterPrefix[0] &&
+ isdigit(line[line_index + 1])) {
+ std::string register_syntax = kAsmRegisterPrefix;
+ register_syntax += line[line_index + 1];
+
+ if (isdigit(line[line_index + 2]))
+ register_syntax += line[line_index + 2];
+
+ std::string reg_str;
+ reg_str += line[line_index + 1];
+
+ if (isdigit(line[line_index + 2]))
+ reg_str += line[line_index + 2];
+
+ // it ranges from r0 to r19
+ // something like r190 doesn't exist in the instruction set.
+ if (kOutputArch == CompilerKit::kPefArch64000) {
+ if (isdigit(line[line_index + 3]) &&
+ isdigit(line[line_index + 2])) {
+ reg_str += line[line_index + 3];
+ detail::print_error(
+ "invalid register index, r" + reg_str +
+ "\nnote: The 64x0 accepts registers from r0 to r20.",
+ file);
+ throw std::runtime_error("invalid_register_index");
}
+ }
- // we're not in immediate addressing, reg to reg.
- if (opcode64x0.fFunct7 != kAsmImmediate)
- {
- // remember! register to register!
- if (found_some == 1)
- {
- detail::print_error("Unrecognized register found.\ntip: each 64asm register starts with 'r'.\nline: " + line, file);
- throw std::runtime_error("not_a_register");
- }
- }
+ // finally cast to a size_t
+ std::size_t reg_index = strtoq(reg_str.c_str(), nullptr, 10);
- if (found_some < 1 &&
- name != "ldw" &&
- name != "lda" &&
- name != "stw")
- {
- detail::print_error("invalid combination of opcode and registers.\nline: " + line, file);
- throw std::runtime_error("invalid_comb_op_reg");
- }
- else if (found_some == 1 &&
- name == "add")
- {
- detail::print_error("invalid combination of opcode and registers.\nline: " + line, file);
- throw std::runtime_error("invalid_comb_op_reg");
- }
- else if (found_some == 1 &&
- name == "dec")
- {
- detail::print_error("invalid combination of opcode and registers.\nline: " + line, file);
- throw std::runtime_error("invalid_comb_op_reg");
- }
+ if (reg_index > kAsmRegisterLimit) {
+ detail::print_error("invalid register index, r" + reg_str,
+ file);
+ throw std::runtime_error("invalid_register_index");
+ }
- if (found_some > 0 &&
- name == "pop")
- {
- detail::print_error("invalid combination for opcode 'pop'.\ntip: it expects nothing.\nline: " + line, file);
- throw std::runtime_error("invalid_comb_op_pop");
- }
+ kBytes.emplace_back(reg_index);
+ ++found_some;
+
+ if (kVerbose) {
+ kStdOut << "64asm: Register found: " << register_syntax << "\n";
+ kStdOut << "64asm: Register amount in instruction: "
+ << found_some << "\n";
+ }
}
- default:
- break;
+ }
+
+ // we're not in immediate addressing, reg to reg.
+ if (opcode64x0.fFunct7 != kAsmImmediate) {
+ // remember! register to register!
+ if (found_some == 1) {
+ detail::print_error(
+ "Unrecognized register found.\ntip: each 64asm register "
+ "starts with 'r'.\nline: " +
+ line,
+ file);
+ throw std::runtime_error("not_a_register");
}
+ }
+
+ if (found_some < 1 && name != "ldw" && name != "lda" &&
+ name != "stw") {
+ detail::print_error(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ } else if (found_some == 1 && name == "add") {
+ detail::print_error(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ } else if (found_some == 1 && name == "dec") {
+ detail::print_error(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ }
+
+ if (found_some > 0 && name == "pop") {
+ detail::print_error(
+ "invalid combination for opcode 'pop'.\ntip: it expects "
+ "nothing.\nline: " +
+ line,
+ file);
+ throw std::runtime_error("invalid_comb_op_pop");
+ }
+ }
+ default:
+ break;
+ }
+
+ // try to fetch a number from the name
+ if (name == "stw" || name == "ldw" || name == "lda" || name == "sta") {
+ auto where_string = name;
+
+ // if we load something, we'd need it's symbol/literal
+ if (name == "stw" || name == "sta" || name == "ldw" || name == "lda" ||
+ name == "sta")
+ where_string = ",";
+
+ jump_label = line;
+
+ auto found_sym = false;
+
+ while (jump_label.find(where_string) != std::string::npos) {
+ jump_label = jump_label.substr(jump_label.find(where_string) +
+ where_string.size());
+
+ while (jump_label.find(" ") != std::string::npos) {
+ jump_label.erase(jump_label.find(" "), 1);
+ }
+
+ if (jump_label[0] != kAsmRegisterPrefix[0] &&
+ !isdigit(jump_label[1])) {
+ if (found_sym) {
+ detail::print_error(
+ "invalid combination of opcode and operands.\nhere -> " +
+ jump_label,
+ file);
+ throw std::runtime_error("invalid_comb_op_ops");
+ } else {
+ // death trap installed.
+ found_sym = true;
+ }
+ }
+ }
- // try to fetch a number from the name
- if (name == "stw" ||
- name == "ldw" ||
- name == "lda" ||
- name == "sta")
- {
- auto where_string = name;
-
- // if we load something, we'd need it's symbol/literal
- if (name == "stw" ||
- name == "sta" ||
- name == "ldw" ||
- name == "lda" ||
- name == "sta")
- where_string = ",";
-
- jump_label = line;
-
- auto found_sym = false;
-
- while (jump_label.find(where_string) != std::string::npos)
- {
- jump_label = jump_label.substr(jump_label.find(where_string) + where_string.size());
-
- while (jump_label.find(" ") != std::string::npos)
- {
- jump_label.erase(jump_label.find(" "), 1);
- }
-
- if (jump_label[0] != kAsmRegisterPrefix[0] &&
- !isdigit(jump_label[1]))
- {
- if (found_sym)
- {
- detail::print_error("invalid combination of opcode and operands.\nhere -> " + jump_label, file);
- throw std::runtime_error("invalid_comb_op_ops");
- }
- else
- {
- // death trap installed.
- found_sym = true;
- }
- }
- }
+ cpy_jump_label = jump_label;
- cpy_jump_label = jump_label;
+ // replace any spaces with $
+ if (jump_label[0] == ' ') {
+ while (jump_label.find(' ') != std::string::npos) {
+ if (isalnum(jump_label[0]) || isdigit(jump_label[0])) break;
- // replace any spaces with $
- if (jump_label[0] == ' ')
- {
- while (jump_label.find(' ') != std::string::npos)
- {
- if (isalnum(jump_label[0]) ||
- isdigit(jump_label[0]))
- break;
+ jump_label.erase(jump_label.find(' '), 1);
+ }
+ }
- jump_label.erase(jump_label.find(' '), 1);
- }
- }
+ if (!this->WriteNumber(0, jump_label)) {
+ // sta expects this: sta 0x000000, r0
+ if (name == "sta") {
+ detail::print_error(
+ "invalid combination of opcode and operands.\nhere ->" + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_ops");
+ }
+ } else {
+ if (name == "sta" &&
+ cpy_jump_label.find("import ") != std::string::npos) {
+ detail::print_error("invalid usage import on 'sta', here: " + line,
+ file);
+ throw std::runtime_error("invalid_sta_usage");
+ }
+ }
- if (!this->WriteNumber(0, jump_label))
- {
- // sta expects this: sta 0x000000, r0
- if (name == "sta")
- {
- detail::print_error("invalid combination of opcode and operands.\nhere ->" + line, file);
- throw std::runtime_error("invalid_comb_op_ops");
- }
- }
- else
- {
- if (name == "sta" &&
- cpy_jump_label.find("import ") != std::string::npos)
- {
- detail::print_error("invalid usage import on 'sta', here: " + line, file);
- throw std::runtime_error("invalid_sta_usage");
- }
- }
+ goto asm_write_label;
+ }
- goto asm_write_label;
- }
+ // This is the case where we jump to a label, it is also used as a goto.
+ if (name == "lda" || name == "sta") {
+ asm_write_label:
+ if (cpy_jump_label.find('\n') != std::string::npos)
+ cpy_jump_label.erase(cpy_jump_label.find('\n'), 1);
- // This is the case where we jump to a label, it is also used as a goto.
- if (name == "lda" ||
- name == "sta")
- {
- asm_write_label:
- if (cpy_jump_label.find('\n') != std::string::npos)
- cpy_jump_label.erase(cpy_jump_label.find('\n'), 1);
-
- if (cpy_jump_label.find("import") != std::string::npos)
- {
- cpy_jump_label.erase(cpy_jump_label.find("import"), strlen("import"));
-
- if (name == "sta")
- {
- detail::print_error("import is not allowed on a sta operation.", file);
- throw std::runtime_error("import_sta_op");
- }
- else
- {
- goto asm_end_label_cpy;
- }
- }
+ if (cpy_jump_label.find("import") != std::string::npos) {
+ cpy_jump_label.erase(cpy_jump_label.find("import"), strlen("import"));
- if (name == "lda" ||
- name == "sta")
- {
- for (auto &label : kOriginLabel)
- {
- if (cpy_jump_label == label.first)
- {
- if (kVerbose)
- {
- kStdOut << "64asm: Replace label "
- << cpy_jump_label
- << " to address: "
- << label.second
- << std::endl;
- }
-
- CompilerKit::NumberCast64 num(label.second);
-
- for (auto &num : num.number)
- {
- kBytes.push_back(num);
- }
-
- goto asm_end_label_cpy;
- }
- }
-
- if (cpy_jump_label[0] == '0')
- {
- switch (cpy_jump_label[1])
- {
- case 'x':
- case 'o':
- case 'b':
- if (this->WriteNumber(0, cpy_jump_label))
- goto asm_end_label_cpy;
-
- break;
- default:
- break;
- }
-
- if (isdigit(cpy_jump_label[0]))
- {
- if (this->WriteNumber(0, cpy_jump_label))
- goto asm_end_label_cpy;
-
- break;
- }
- }
- }
+ if (name == "sta") {
+ detail::print_error("import is not allowed on a sta operation.",
+ file);
+ throw std::runtime_error("import_sta_op");
+ } else {
+ goto asm_end_label_cpy;
+ }
+ }
- if (cpy_jump_label.size() < 1)
- {
- detail::print_error("label is empty, can't jump on it.", file);
- throw std::runtime_error("label_empty");
- }
+ if (name == "lda" || name == "sta") {
+ for (auto &label : kOriginLabel) {
+ if (cpy_jump_label == label.first) {
+ if (kVerbose) {
+ kStdOut << "64asm: Replace label " << cpy_jump_label
+ << " to address: " << label.second << std::endl;
+ }
- auto mld_reloc_str = std::to_string(cpy_jump_label.size());
- mld_reloc_str += kRelocSymbol;
- mld_reloc_str += cpy_jump_label;
+ CompilerKit::NumberCast64 num(label.second);
- bool ignore_back_slash = false;
+ for (auto &num : num.number) {
+ kBytes.push_back(num);
+ }
- for (auto &reloc_chr : mld_reloc_str)
- {
- if (reloc_chr == '\\')
- {
- ignore_back_slash = true;
- continue;
- }
+ goto asm_end_label_cpy;
+ }
+ }
- if (ignore_back_slash)
- {
- ignore_back_slash = false;
- continue;
- }
+ if (cpy_jump_label[0] == '0') {
+ switch (cpy_jump_label[1]) {
+ case 'x':
+ case 'o':
+ case 'b':
+ if (this->WriteNumber(0, cpy_jump_label))
+ goto asm_end_label_cpy;
- kBytes.push_back(reloc_chr);
- }
+ break;
+ default:
+ break;
+ }
+
+ if (isdigit(cpy_jump_label[0])) {
+ if (this->WriteNumber(0, cpy_jump_label)) goto asm_end_label_cpy;
- kBytes.push_back('\0');
- goto asm_end_label_cpy;
+ break;
}
+ }
+ }
- asm_end_label_cpy:
- ++kOrigin;
+ if (cpy_jump_label.size() < 1) {
+ detail::print_error("label is empty, can't jump on it.", file);
+ throw std::runtime_error("label_empty");
+ }
- break;
+ auto mld_reloc_str = std::to_string(cpy_jump_label.size());
+ mld_reloc_str += kRelocSymbol;
+ mld_reloc_str += cpy_jump_label;
+
+ bool ignore_back_slash = false;
+
+ for (auto &reloc_chr : mld_reloc_str) {
+ if (reloc_chr == '\\') {
+ ignore_back_slash = true;
+ continue;
+ }
+
+ if (ignore_back_slash) {
+ ignore_back_slash = false;
+ continue;
+ }
+
+ kBytes.push_back(reloc_chr);
}
+
+ kBytes.push_back('\0');
+ goto asm_end_label_cpy;
+ }
+
+ asm_end_label_cpy:
+ ++kOrigin;
+
+ break;
}
+ }
- return true;
+ return true;
}
-// Last rev 13-1-24 \ No newline at end of file
+// Last rev 13-1-24
diff --git a/Private/Toolchain/bccl.cc b/Private/Toolchain/bccl.cc
index 048424b..2a03061 100644
--- a/Private/Toolchain/bccl.cc
+++ b/Private/Toolchain/bccl.cc
@@ -9,14 +9,15 @@
/// bugs: ?
-#include <cstdio>
-#include <vector>
-#include <string>
-#include <fstream>
-#include <iostream>
#include <uuid/uuid.h>
+
#include <CompilerKit/AsmKit/Arch/64x0.hpp>
#include <CompilerKit/ParserKit.hpp>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
#define kOk 0
@@ -46,87 +47,78 @@
/////////////////////////////////////
-namespace detail
-{
- // \brief name to register struct.
- struct CompilerRegisterMap final
- {
- std::string fName;
- std::string fReg;
- };
-
- // \brief Map for BCCL structs
- // \author amlel
- struct CompilerStructMap final
- {
- // 'my_foo'
- std::string fName;
-
- // if instance: stores a valid register.
- std::string fReg;
-
- // offset count
- std::size_t fOffsetsCnt;
-
- // offset array.
- std::vector<std::pair<Int32, std::string>> fOffsets;
- };
-
- struct CompilerState final
- {
- std::vector<ParserKit::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- ParserKit::SyntaxLeafList *fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool kVerbose;
- };
-}
+namespace detail {
+// \brief name to register struct.
+struct CompilerRegisterMap final {
+ std::string fName;
+ std::string fReg;
+};
+
+// \brief Map for BCCL structs
+// \author amlel
+struct CompilerStructMap final {
+ // 'my_foo'
+ std::string fName;
+
+ // if instance: stores a valid register.
+ std::string fReg;
+
+ // offset count
+ std::size_t fOffsetsCnt;
+
+ // offset array.
+ std::vector<std::pair<Int32, std::string>> fOffsets;
+};
+
+struct CompilerState final {
+ std::vector<ParserKit::SyntaxLeafList> fSyntaxTreeList;
+ std::vector<CompilerRegisterMap> kStackFrame;
+ std::vector<CompilerStructMap> kStructMap;
+ ParserKit::SyntaxLeafList *fSyntaxTree{nullptr};
+ std::unique_ptr<std::ofstream> fOutputAssembly;
+ std::string fLastFile;
+ std::string fLastError;
+ bool kVerbose;
+};
+} // namespace detail
static detail::CompilerState kState;
static SizeType kErrorLimit = 100;
static Int32 kAcceptableErrors = 0;
-namespace detail
-{
- void print_error(std::string reason, std::string file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
+namespace detail {
+void print_error(std::string reason, std::string file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- if (file.find(".pp") != std::string::npos)
- {
- file.erase(file.find(".pp"), 3);
- }
+ if (file.find(".pp") != std::string::npos) {
+ file.erase(file.find(".pp"), 3);
+ }
- if (kState.fLastFile != file)
- {
- std::cout << kRed << "[ bccl ] " << kWhite << ((file == "bccl") ? "internal compiler error " : ("in file, " + file)) << kBlank << std::endl;
- std::cout << kRed << "[ bccl ] " << kWhite << reason << kBlank << std::endl;
+ if (kState.fLastFile != file) {
+ std::cout << kRed << "[ bccl ] " << kWhite
+ << ((file == "bccl") ? "internal compiler error "
+ : ("in file, " + file))
+ << kBlank << std::endl;
+ std::cout << kRed << "[ bccl ] " << kWhite << reason << kBlank << std::endl;
- kState.fLastFile = file;
- }
- else
- {
- std::cout << kRed << "[ bccl ] [ " << kState.fLastFile << " ] " << kWhite << reason << kBlank << std::endl;
- }
+ kState.fLastFile = file;
+ } else {
+ std::cout << kRed << "[ bccl ] [ " << kState.fLastFile << " ] " << kWhite
+ << reason << kBlank << std::endl;
+ }
- if (kAcceptableErrors > kErrorLimit)
- std::exit(3);
-
- ++kAcceptableErrors;
- }
+ if (kAcceptableErrors > kErrorLimit) std::exit(3);
- struct CompilerType final
- {
- std::string fName;
- std::string fValue;
- };
+ ++kAcceptableErrors;
}
+struct CompilerType final {
+ std::string fName;
+ std::string fValue;
+};
+} // namespace detail
+
/////////////////////////////////////////////////////////////////////////////////////////
// Target architecture.
@@ -159,18 +151,17 @@ static bool kInBraces = false;
static size_t kBracesCount = 0UL;
/* @brief BCCL compiler backend for BCCL */
-class CompilerBackendBccl final : public ParserKit::CompilerBackend
-{
-public:
- explicit CompilerBackendBccl() = default;
- ~CompilerBackendBccl() override = default;
+class CompilerBackendBccl final : public ParserKit::CompilerBackend {
+ public:
+ explicit CompilerBackendBccl() = default;
+ ~CompilerBackendBccl() override = default;
- CXXKIT_COPY_DEFAULT(CompilerBackendBccl);
+ CXXKIT_COPY_DEFAULT(CompilerBackendBccl);
- std::string Check(const char *text, const char *file);
- bool Compile(const std::string &text, const char *file) override;
+ std::string Check(const char *text, const char *file);
+ bool Compile(const std::string &text, const char *file) override;
- const char *Language() override { return "BCCL 64x0, Generic MP/UX target."; }
+ const char *Language() override { return "BCCL 64x0, Generic MP/UX target."; }
};
static CompilerBackendBccl *kCompilerBackend = nullptr;
@@ -178,33 +169,28 @@ static std::vector<detail::CompilerType> kCompilerVariables;
static std::vector<std::string> kCompilerFunctions;
static std::vector<detail::CompilerType> kCompilerTypes;
-namespace detail
-{
- union number_cast final
- {
- public:
- number_cast(UInt64 _Raw) : _Raw(_Raw) {}
-
- public:
- char _Num[8];
- UInt64 _Raw;
-
- };
-
- union double_cast final
- {
- public:
- double_cast(float _Raw) : _Raw(_Raw) {}
-
- public:
- char _Sign;
- char _Lh[8];
- char _Rh[23];
-
- float _Raw;
-
- };
-}
+namespace detail {
+union number_cast final {
+ public:
+ number_cast(UInt64 _Raw) : _Raw(_Raw) {}
+
+ public:
+ char _Num[8];
+ UInt64 _Raw;
+};
+
+union double_cast final {
+ public:
+ double_cast(float _Raw) : _Raw(_Raw) {}
+
+ public:
+ char _Sign;
+ char _Lh[8];
+ char _Rh[23];
+
+ float _Raw;
+};
+} // namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
@@ -213,1067 +199,852 @@ namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
-bool CompilerBackendBccl::Compile(const std::string &text, const char *file)
-{
- std::string _text = text;
-
- auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf();
- bool type_found = false;
- bool function_found = false;
-
- // start parsing
- for (size_t text_index = 0; text_index < _text.size(); ++text_index)
- {
- uuid_t out{0};
+bool CompilerBackendBccl::Compile(const std::string &text, const char *file) {
+ std::string _text = text;
- uuid_generate_random(out);
- detail::number_cast time_off = (UInt64)out;
+ auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf();
+ bool type_found = false;
+ bool function_found = false;
- if (!type_found)
- {
- auto substr = _text.substr(text_index);
- std::string match_type;
+ // start parsing
+ for (size_t text_index = 0; text_index < _text.size(); ++text_index) {
+ uuid_t out{0};
- for (size_t y = 0; y < substr.size(); ++y)
- {
- if (substr[y] == ' ')
- {
- while (match_type.find(' ') != std::string::npos)
- {
- match_type.erase(match_type.find(' '));
- }
+ uuid_generate_random(out);
+ detail::number_cast time_off = (UInt64)out;
- for (auto &clType : kCompilerTypes)
- {
- if (clType.fName == match_type)
- {
- match_type.clear();
+ if (!type_found) {
+ auto substr = _text.substr(text_index);
+ std::string match_type;
- std::string buf;
+ for (size_t y = 0; y < substr.size(); ++y) {
+ if (substr[y] == ' ') {
+ while (match_type.find(' ') != std::string::npos) {
+ match_type.erase(match_type.find(' '));
+ }
- buf += clType.fValue;
- buf += ' ';
+ for (auto &clType : kCompilerTypes) {
+ if (clType.fName == match_type) {
+ match_type.clear();
- if (substr.find('=') != std::string::npos)
- {
- break;
- }
+ std::string buf;
- if (_text.find('(') != std::string::npos)
- {
- syntax_tree.fUserValue = buf;
+ buf += clType.fValue;
+ buf += ' ';
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- }
+ if (substr.find('=') != std::string::npos) {
+ break;
+ }
- type_found = true;
- break;
- }
- }
+ if (_text.find('(') != std::string::npos) {
+ syntax_tree.fUserValue = buf;
- break;
- }
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ }
- match_type += substr[y];
+ type_found = true;
+ break;
}
+ }
+
+ break;
}
- if (_text[text_index] == '{')
- {
- if (kInStruct)
- {
- continue;
- }
+ match_type += substr[y];
+ }
+ }
- kInBraces = true;
- ++kBracesCount;
+ if (_text[text_index] == '{') {
+ if (kInStruct) {
+ continue;
+ }
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- }
+ kInBraces = true;
+ ++kBracesCount;
- // return keyword handler
- if (_text[text_index] == 'r')
- {
- std::string return_keyword;
- return_keyword += "return";
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ }
- std::size_t index = 0UL;
+ // return keyword handler
+ if (_text[text_index] == 'r') {
+ std::string return_keyword;
+ return_keyword += "return";
- std::string value;
+ std::size_t index = 0UL;
- for (size_t return_index = text_index; return_index < _text.size(); ++return_index)
- {
- if (_text[return_index] != return_keyword[index])
- {
- for (size_t value_index = return_index; value_index < _text.size(); ++value_index)
- {
- if (_text[value_index] == ';')
- break;
+ std::string value;
- value += _text[value_index];
- }
+ for (size_t return_index = text_index; return_index < _text.size();
+ ++return_index) {
+ if (_text[return_index] != return_keyword[index]) {
+ for (size_t value_index = return_index; value_index < _text.size();
+ ++value_index) {
+ if (_text[value_index] == ';') break;
- break;
- }
+ value += _text[value_index];
+ }
- ++index;
- }
+ break;
+ }
- if (index == return_keyword.size())
- {
- if (!value.empty())
- {
- if (value.find('(') != std::string::npos)
- {
- value.erase(value.find('('));
- }
+ ++index;
+ }
- if (!isdigit(value[value.find('(') + 2]))
- {
- std::string tmp = value;
- bool reg_to_reg = false;
+ if (index == return_keyword.size()) {
+ if (!value.empty()) {
+ if (value.find('(') != std::string::npos) {
+ value.erase(value.find('('));
+ }
- value.clear();
+ if (!isdigit(value[value.find('(') + 2])) {
+ std::string tmp = value;
+ bool reg_to_reg = false;
- value += " import";
- value += tmp;
- }
+ value.clear();
- syntax_tree.fUserValue = "\tldw r1, ";
+ value += " import";
+ value += tmp;
+ }
- // make it pretty.
- if (value.find('\t') != std::string::npos)
- value.erase(value.find('\t'), 1);
+ syntax_tree.fUserValue = "\tldw r1, ";
- syntax_tree.fUserValue += value + "\n";
- }
+ // make it pretty.
+ if (value.find('\t') != std::string::npos)
+ value.erase(value.find('\t'), 1);
- syntax_tree.fUserValue += "\tjlr";
+ syntax_tree.fUserValue += value + "\n";
+ }
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ syntax_tree.fUserValue += "\tjlr";
- break;
- }
- }
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- // Parse expressions and instructions here.
- // what does this mean?
- // we encounter an assignment, or we reached the end of an expression.
- if (_text[text_index] == '=' ||
- _text[text_index] == ';')
- {
- if (function_found)
- continue;
-
- if (_text[text_index] == ';' &&
- kInStruct)
- continue;
-
- if (_text.find("typedef ") != std::string::npos)
- continue;
-
- if (_text[text_index] == '=' &&
- kInStruct)
- {
- detail::print_error("assignement of value in struct " + _text, file);
- continue;
- }
+ break;
+ }
+ }
- if (_text[text_index] == ';' &&
- kInStruct)
- {
- bool space_found_ = false;
- std::string sym;
+ // Parse expressions and instructions here.
+ // what does this mean?
+ // we encounter an assignment, or we reached the end of an expression.
+ if (_text[text_index] == '=' || _text[text_index] == ';') {
+ if (function_found) continue;
- for (auto &ch : _text)
- {
- if (ch == ' ')
- {
- space_found_ = true;
- }
+ if (_text[text_index] == ';' && kInStruct) continue;
- if (ch == ';')
- break;
+ if (_text.find("typedef ") != std::string::npos) continue;
- if (space_found_)
- sym.push_back(ch);
- }
+ if (_text[text_index] == '=' && kInStruct) {
+ detail::print_error("assignement of value in struct " + _text, file);
+ continue;
+ }
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
- std::make_pair(kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4, sym));
+ if (_text[text_index] == ';' && kInStruct) {
+ bool space_found_ = false;
+ std::string sym;
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt = kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
+ for (auto &ch : _text) {
+ if (ch == ' ') {
+ space_found_ = true;
+ }
- continue;
- }
+ if (ch == ';') break;
- if (_text[text_index] == '=' &&
- kInStruct)
- {
- continue;
- }
+ if (space_found_) sym.push_back(ch);
+ }
- if (_text[text_index + 1] == '=' ||
- _text[text_index - 1] == '!' ||
- _text[text_index - 1] == '<' ||
- _text[text_index - 1] == '>')
- {
- continue;
- }
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
+ std::make_pair(
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4,
+ sym));
- std::string substr;
-
- if (_text.find('=') != std::string::npos &&
- kInBraces)
- {
- if (_text.find("*") != std::string::npos)
- {
- if (_text.find("=") > _text.find("*"))
- substr += "\tlda ";
- else
- substr += "\tldw ";
- }
- else
- {
- substr += "\tldw ";
- }
- }
- else if (_text.find('=') != std::string::npos &&
- !kInBraces)
- {
- substr += "stw export .data ";
- }
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt =
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
- int first_encountered = 0;
+ continue;
+ }
- std::string str_name;
+ if (_text[text_index] == '=' && kInStruct) {
+ continue;
+ }
- for (size_t text_index_2 = 0; text_index_2 < _text.size(); ++text_index_2)
- {
- if (_text[text_index_2] == '\"')
- {
- ++text_index_2;
+ if (_text[text_index + 1] == '=' || _text[text_index - 1] == '!' ||
+ _text[text_index - 1] == '<' || _text[text_index - 1] == '>') {
+ continue;
+ }
+
+ std::string substr;
+
+ if (_text.find('=') != std::string::npos && kInBraces) {
+ if (_text.find("*") != std::string::npos) {
+ if (_text.find("=") > _text.find("*"))
+ substr += "\tlda ";
+ else
+ substr += "\tldw ";
+ } else {
+ substr += "\tldw ";
+ }
+ } else if (_text.find('=') != std::string::npos && !kInBraces) {
+ substr += "stw export .data ";
+ }
- // want to add this, so that the parser recognizes that this is a string.
- substr += '"';
+ int first_encountered = 0;
- for (; text_index_2 < _text.size(); ++text_index_2)
- {
- if (_text[text_index_2] == '\"')
- break;
+ std::string str_name;
- substr += _text[text_index_2];
- }
- }
+ for (size_t text_index_2 = 0; text_index_2 < _text.size();
+ ++text_index_2) {
+ if (_text[text_index_2] == '\"') {
+ ++text_index_2;
- if (_text[text_index_2] == '{' ||
- _text[text_index_2] == '}')
- continue;
+ // want to add this, so that the parser recognizes that this is a
+ // string.
+ substr += '"';
- if (_text[text_index_2] == ';')
- {
- break;
- }
+ for (; text_index_2 < _text.size(); ++text_index_2) {
+ if (_text[text_index_2] == '\"') break;
- if (_text[text_index_2] == ' ' ||
- _text[text_index_2] == '\t')
- {
- if (first_encountered != 2)
- {
- if (_text[text_index] != '=' &&
- substr.find("export .data") == std::string::npos &&
- !kInStruct)
- substr += "export .data ";
- }
+ substr += _text[text_index_2];
+ }
+ }
- ++first_encountered;
+ if (_text[text_index_2] == '{' || _text[text_index_2] == '}') continue;
- continue;
- }
+ if (_text[text_index_2] == ';') {
+ break;
+ }
- if (_text[text_index_2] == '=')
- {
- if (!kInBraces)
- {
- substr.replace(substr.find("export .data"), strlen("export .data"), "export .page_zero ");
- }
+ if (_text[text_index_2] == ' ' || _text[text_index_2] == '\t') {
+ if (first_encountered != 2) {
+ if (_text[text_index] != '=' &&
+ substr.find("export .data") == std::string::npos && !kInStruct)
+ substr += "export .data ";
+ }
- substr += ",";
- continue;
- }
+ ++first_encountered;
- substr += _text[text_index_2];
- }
+ continue;
+ }
- for (auto &clType : kCompilerTypes)
- {
- if (substr.find(clType.fName) != std::string::npos)
- {
- if (substr.find(clType.fName) > substr.find('"'))
- continue;
+ if (_text[text_index_2] == '=') {
+ if (!kInBraces) {
+ substr.replace(substr.find("export .data"), strlen("export .data"),
+ "export .page_zero ");
+ }
- substr.erase(substr.find(clType.fName), clType.fName.size());
- }
- else if (substr.find(clType.fValue) != std::string::npos)
- {
- if (substr.find(clType.fValue) > substr.find('"'))
- continue;
+ substr += ",";
+ continue;
+ }
- if (clType.fName == "const")
- continue;
+ substr += _text[text_index_2];
+ }
- substr.erase(substr.find(clType.fValue), clType.fValue.size());
- }
- }
+ for (auto &clType : kCompilerTypes) {
+ if (substr.find(clType.fName) != std::string::npos) {
+ if (substr.find(clType.fName) > substr.find('"')) continue;
- if (substr.find("extern") != std::string::npos)
- {
- substr.replace(substr.find("extern"), strlen("extern"), "import ");
+ substr.erase(substr.find(clType.fName), clType.fName.size());
+ } else if (substr.find(clType.fValue) != std::string::npos) {
+ if (substr.find(clType.fValue) > substr.find('"')) continue;
- if (substr.find("export .data") != std::string::npos)
- substr.erase(substr.find("export .data"), strlen("export .data"));
- }
+ if (clType.fName == "const") continue;
- auto var_to_find = std::find_if(kCompilerVariables.cbegin(), kCompilerVariables.cend(), [&](detail::CompilerType type)
- { return type.fName.find(substr) != std::string::npos; });
+ substr.erase(substr.find(clType.fValue), clType.fValue.size());
+ }
+ }
- if (kRegisterCounter == 5 ||
- kRegisterCounter == 6)
- ++kRegisterCounter;
+ if (substr.find("extern") != std::string::npos) {
+ substr.replace(substr.find("extern"), strlen("extern"), "import ");
- std::string reg = kAsmRegisterPrefix;
- reg += std::to_string(kRegisterCounter);
+ if (substr.find("export .data") != std::string::npos)
+ substr.erase(substr.find("export .data"), strlen("export .data"));
+ }
- if (var_to_find == kCompilerVariables.cend())
- {
- ++kRegisterCounter;
+ auto var_to_find =
+ std::find_if(kCompilerVariables.cbegin(), kCompilerVariables.cend(),
+ [&](detail::CompilerType type) {
+ return type.fName.find(substr) != std::string::npos;
+ });
- kState.kStackFrame.push_back({.fName = substr, .fReg = reg});
- kCompilerVariables.push_back({.fName = substr});
- }
+ if (kRegisterCounter == 5 || kRegisterCounter == 6) ++kRegisterCounter;
- syntax_tree.fUserValue += substr;
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ std::string reg = kAsmRegisterPrefix;
+ reg += std::to_string(kRegisterCounter);
- if (_text[text_index] == '=')
- break;
- }
+ if (var_to_find == kCompilerVariables.cend()) {
+ ++kRegisterCounter;
- // function handler.
+ kState.kStackFrame.push_back({.fName = substr, .fReg = reg});
+ kCompilerVariables.push_back({.fName = substr});
+ }
- if (_text[text_index] == '(' &&
- !function_found)
- {
- std::string substr;
- std::string args_buffer;
- std::string args;
+ syntax_tree.fUserValue += substr;
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- bool type_crossed = false;
+ if (_text[text_index] == '=') break;
+ }
- for (size_t idx = _text.find('(') + 1; idx < _text.size(); ++idx)
- {
- if (_text[idx] == ',')
- continue;
+ // function handler.
- if (_text[idx] == ' ')
- continue;
+ if (_text[text_index] == '(' && !function_found) {
+ std::string substr;
+ std::string args_buffer;
+ std::string args;
- if (_text[idx] == ')')
- break;
- }
+ bool type_crossed = false;
- for (char substr_first_index : _text)
- {
- if (substr_first_index != ',')
- args_buffer += substr_first_index;
- else
- args_buffer += '$';
+ for (size_t idx = _text.find('(') + 1; idx < _text.size(); ++idx) {
+ if (_text[idx] == ',') continue;
- if (substr_first_index == ';')
- {
- args_buffer = args_buffer.erase(0, args_buffer.find('('));
- args_buffer = args_buffer.erase(args_buffer.find(';'), 1);
- args_buffer = args_buffer.erase(args_buffer.find(')'), 1);
- args_buffer = args_buffer.erase(args_buffer.find('('), 1);
+ if (_text[idx] == ' ') continue;
- if (!args_buffer.empty())
- args += "\tldw r6, ";
+ if (_text[idx] == ')') break;
+ }
- std::string register_type;
- std::size_t index = 7UL;
+ for (char substr_first_index : _text) {
+ if (substr_first_index != ',')
+ args_buffer += substr_first_index;
+ else
+ args_buffer += '$';
- while (args_buffer.find("$") != std::string::npos)
- {
- register_type = kRegisterPrefix;
- register_type += std::to_string(index);
+ if (substr_first_index == ';') {
+ args_buffer = args_buffer.erase(0, args_buffer.find('('));
+ args_buffer = args_buffer.erase(args_buffer.find(';'), 1);
+ args_buffer = args_buffer.erase(args_buffer.find(')'), 1);
+ args_buffer = args_buffer.erase(args_buffer.find('('), 1);
- ++index;
+ if (!args_buffer.empty()) args += "\tldw r6, ";
- args_buffer.replace(args_buffer.find('$'), 1, "\n\tldw " + register_type + ",");
- }
+ std::string register_type;
+ std::size_t index = 7UL;
- args += args_buffer;
- args += "\n\tlda r19, ";
- }
- }
+ while (args_buffer.find("$") != std::string::npos) {
+ register_type = kRegisterPrefix;
+ register_type += std::to_string(index);
- for (char _text_i : _text)
- {
- if (_text_i == '\t' ||
- _text_i == ' ')
- {
- if (!type_crossed)
- {
- substr.clear();
- type_crossed = true;
- }
-
- continue;
- }
+ ++index;
- if (_text_i == '(')
- break;
+ args_buffer.replace(args_buffer.find('$'), 1,
+ "\n\tldw " + register_type + ",");
+ }
- substr += _text_i;
- }
+ args += args_buffer;
+ args += "\n\tlda r19, ";
+ }
+ }
- if (kInBraces)
- {
- syntax_tree.fUserValue = args;
- syntax_tree.fUserValue += substr;
- syntax_tree.fUserValue += "\n\tjrl\n";
+ for (char _text_i : _text) {
+ if (_text_i == '\t' || _text_i == ' ') {
+ if (!type_crossed) {
+ substr.clear();
+ type_crossed = true;
+ }
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ continue;
+ }
- function_found = true;
- }
- else
- {
- syntax_tree.fUserValue.clear();
+ if (_text_i == '(') break;
- syntax_tree.fUserValue += "export .text ";
+ substr += _text_i;
+ }
- syntax_tree.fUserValue += substr;
- syntax_tree.fUserValue += "\n";
+ if (kInBraces) {
+ syntax_tree.fUserValue = args;
+ syntax_tree.fUserValue += substr;
+ syntax_tree.fUserValue += "\n\tjrl\n";
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- function_found = true;
- }
+ function_found = true;
+ } else {
+ syntax_tree.fUserValue.clear();
- kCompilerFunctions.push_back(_text);
- }
+ syntax_tree.fUserValue += "export .text ";
- if (_text[text_index] == '-' &&
- _text[text_index + 1] == '-')
- {
- _text = _text.replace(_text.find("--"), strlen("--"), "");
+ syntax_tree.fUserValue += substr;
+ syntax_tree.fUserValue += "\n";
- for (int _text_i = 0; _text_i < _text.size(); ++_text_i)
- {
- if (_text[_text_i] == '\t' ||
- _text[_text_i] == ' ')
- _text.erase(_text_i, 1);
- }
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- syntax_tree.fUserValue += "dec ";
- syntax_tree.fUserValue += _text;
+ function_found = true;
+ }
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- break;
- }
+ kCompilerFunctions.push_back(_text);
+ }
- if (_text[text_index] == '}')
- {
- kRegisterCounter = kStartUsable;
+ if (_text[text_index] == '-' && _text[text_index + 1] == '-') {
+ _text = _text.replace(_text.find("--"), strlen("--"), "");
- --kBracesCount;
+ for (int _text_i = 0; _text_i < _text.size(); ++_text_i) {
+ if (_text[_text_i] == '\t' || _text[_text_i] == ' ')
+ _text.erase(_text_i, 1);
+ }
- if (kBracesCount < 1)
- {
- kInBraces = false;
- kBracesCount = 0;
- }
+ syntax_tree.fUserValue += "dec ";
+ syntax_tree.fUserValue += _text;
- if (kInStruct)
- kInStruct = false;
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ break;
+ }
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- }
+ if (_text[text_index] == '}') {
+ kRegisterCounter = kStartUsable;
- syntax_tree.fUserValue.clear();
+ --kBracesCount;
+
+ if (kBracesCount < 1) {
+ kInBraces = false;
+ kBracesCount = 0;
+ }
+
+ if (kInStruct) kInStruct = false;
+
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
}
- syntax_tree.fUserValue = "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
+ syntax_tree.fUserValue.clear();
+ }
+
+ syntax_tree.fUserValue = "\n";
+ kState.fSyntaxTree->fLeafList.push_back(syntax_tree);
- return true;
+ return true;
}
static bool kShouldHaveBraces = false;
static std::string kFnName;
-std::string CompilerBackendBccl::Check(const char *text, const char *file)
-{
- std::string err_str;
- std::string ln = text;
+std::string CompilerBackendBccl::Check(const char *text, const char *file) {
+ std::string err_str;
+ std::string ln = text;
- if (ln.empty())
- {
- return err_str;
- }
-
- bool non_ascii_found = false;
+ if (ln.empty()) {
+ return err_str;
+ }
- for (int i = 0; i < ln.size(); ++i)
- {
- if (isalnum(ln[i]))
- {
- non_ascii_found = true;
- break;
- }
- }
+ bool non_ascii_found = false;
- if (kShouldHaveBraces &&
- ln.find('{') != std::string::npos)
- {
- kShouldHaveBraces = false;
+ for (int i = 0; i < ln.size(); ++i) {
+ if (isalnum(ln[i])) {
+ non_ascii_found = true;
+ break;
}
+ }
- if (!non_ascii_found)
- return err_str;
+ if (kShouldHaveBraces && ln.find('{') != std::string::npos) {
+ kShouldHaveBraces = false;
+ }
- size_t string_index = 1UL;
+ if (!non_ascii_found) return err_str;
- if (ln.find('\'') != std::string::npos)
- {
- string_index = ln.find('\'') + 1;
+ size_t string_index = 1UL;
- for (; string_index < ln.size(); ++string_index)
- {
- if (ln[string_index] == '\'')
- {
- if (ln[string_index + 1] != ';')
- {
- ln.erase(string_index, 1);
- }
+ if (ln.find('\'') != std::string::npos) {
+ string_index = ln.find('\'') + 1;
- return err_str;
- }
- }
- }
- else if (ln.find('"') != std::string::npos)
- {
- string_index = ln.find('"') + 1;
-
- for (; string_index < ln.size(); ++string_index)
- {
- if (ln[string_index] == '"')
- {
- if (ln[string_index + 1] != ';')
- {
- ln.erase(string_index, 1);
- }
- else
- {
- break;
- }
- }
+ for (; string_index < ln.size(); ++string_index) {
+ if (ln[string_index] == '\'') {
+ if (ln[string_index + 1] != ';') {
+ ln.erase(string_index, 1);
}
+
+ return err_str;
+ }
}
- else if (ln.find('"') == std::string::npos &&
- ln.find('\'') == std::string::npos)
- {
- std::vector<std::string> forbidden_words;
-
- forbidden_words.push_back("\\");
- forbidden_words.push_back("?");
- forbidden_words.push_back("@");
- forbidden_words.push_back("~");
- forbidden_words.push_back("::");
- forbidden_words.push_back("/*");
- forbidden_words.push_back("*/");
-
- // add them to avoid stupid mistakes.
- forbidden_words.push_back("namespace");
- forbidden_words.push_back("struct");
- forbidden_words.push_back("union");
- forbidden_words.push_back("enum");
- forbidden_words.push_back(".");
- forbidden_words.push_back("->");
- forbidden_words.push_back("class");
- forbidden_words.push_back("*");
- forbidden_words.push_back("extern \"C\"");
-
- for (auto &forbidden : forbidden_words)
- {
- if (ln.find(forbidden) != std::string::npos)
- {
- err_str += "\nForbidden character detected: ";
- err_str += forbidden;
-
- return err_str;
- }
+ } else if (ln.find('"') != std::string::npos) {
+ string_index = ln.find('"') + 1;
+
+ for (; string_index < ln.size(); ++string_index) {
+ if (ln[string_index] == '"') {
+ if (ln[string_index + 1] != ';') {
+ ln.erase(string_index, 1);
+ } else {
+ break;
}
+ }
}
+ } else if (ln.find('"') == std::string::npos &&
+ ln.find('\'') == std::string::npos) {
+ std::vector<std::string> forbidden_words;
+
+ forbidden_words.push_back("\\");
+ forbidden_words.push_back("?");
+ forbidden_words.push_back("@");
+ forbidden_words.push_back("~");
+ forbidden_words.push_back("::");
+ forbidden_words.push_back("/*");
+ forbidden_words.push_back("*/");
+
+ // add them to avoid stupid mistakes.
+ forbidden_words.push_back("namespace");
+ forbidden_words.push_back("struct");
+ forbidden_words.push_back("union");
+ forbidden_words.push_back("enum");
+ forbidden_words.push_back(".");
+ forbidden_words.push_back("->");
+ forbidden_words.push_back("class");
+ forbidden_words.push_back("*");
+ forbidden_words.push_back("extern \"C\"");
+
+ for (auto &forbidden : forbidden_words) {
+ if (ln.find(forbidden) != std::string::npos) {
+ err_str += "\nForbidden character detected: ";
+ err_str += forbidden;
- struct CompilerVariableRange final
- {
- std::string fBegin;
- std::string fEnd;
- };
-
- const std::vector<CompilerVariableRange> variables_list = {
- {.fBegin = "static ", .fEnd = "="},
- {.fBegin = "=", .fEnd = ";"},
- {.fBegin = "if(", .fEnd = "="},
- {.fBegin = "if (", .fEnd = "="},
- {.fBegin = "if(", .fEnd = "<"},
- {.fBegin = "if (", .fEnd = "<"},
- {.fBegin = "if(", .fEnd = ">"},
- {.fBegin = "if (", .fEnd = ">"},
- {.fBegin = "if(", .fEnd = ")"},
- {.fBegin = "if (", .fEnd = ")"},
-
- {.fBegin = "else(", .fEnd = "="},
- {.fBegin = "else (", .fEnd = "="},
- {.fBegin = "else(", .fEnd = "<"},
- {.fBegin = "else (", .fEnd = "<"},
- {.fBegin = "else(", .fEnd = ">"},
- {.fBegin = "else (", .fEnd = ">"},
- {.fBegin = "else(", .fEnd = ")"},
- {.fBegin = "else (", .fEnd = ")"},
- };
-
- for (auto &variable : variables_list)
- {
- if (ln.find(variable.fBegin) != std::string::npos)
- {
- string_index = ln.find(variable.fBegin) + variable.fBegin.size();
-
- while (ln[string_index] == ' ')
- ++string_index;
-
- std::string keyword;
-
- for (; string_index < ln.size(); ++string_index)
- {
- if (ln[string_index] == variable.fEnd[0])
- {
- std::string varname = "";
-
- for (size_t index_keyword = ln.find(' '); ln[index_keyword] != variable.fBegin[0];
- ++index_keyword)
- {
- if (ln[index_keyword] == ' ')
- {
- continue;
- }
-
- if (isdigit(ln[index_keyword]))
- {
- goto cc_next_loop;
- }
-
- varname += ln[index_keyword];
- }
-
- if (varname.find(' ') != std::string::npos)
- {
- varname.erase(0, varname.find(' '));
-
- if (variable.fBegin == "extern")
- {
- varname.erase(0, varname.find(' '));
- }
- }
-
- if (kRegisterCounter == 5 ||
- kRegisterCounter == 6)
- ++kRegisterCounter;
-
- std::string reg = kAsmRegisterPrefix;
- reg += std::to_string(kRegisterCounter);
-
- kCompilerVariables.push_back({.fValue = varname});
- goto cc_check_done;
- }
+ return err_str;
+ }
+ }
+ }
+
+ struct CompilerVariableRange final {
+ std::string fBegin;
+ std::string fEnd;
+ };
+
+ const std::vector<CompilerVariableRange> variables_list = {
+ {.fBegin = "static ", .fEnd = "="}, {.fBegin = "=", .fEnd = ";"},
+ {.fBegin = "if(", .fEnd = "="}, {.fBegin = "if (", .fEnd = "="},
+ {.fBegin = "if(", .fEnd = "<"}, {.fBegin = "if (", .fEnd = "<"},
+ {.fBegin = "if(", .fEnd = ">"}, {.fBegin = "if (", .fEnd = ">"},
+ {.fBegin = "if(", .fEnd = ")"}, {.fBegin = "if (", .fEnd = ")"},
+
+ {.fBegin = "else(", .fEnd = "="}, {.fBegin = "else (", .fEnd = "="},
+ {.fBegin = "else(", .fEnd = "<"}, {.fBegin = "else (", .fEnd = "<"},
+ {.fBegin = "else(", .fEnd = ">"}, {.fBegin = "else (", .fEnd = ">"},
+ {.fBegin = "else(", .fEnd = ")"}, {.fBegin = "else (", .fEnd = ")"},
+ };
+
+ for (auto &variable : variables_list) {
+ if (ln.find(variable.fBegin) != std::string::npos) {
+ string_index = ln.find(variable.fBegin) + variable.fBegin.size();
+
+ while (ln[string_index] == ' ') ++string_index;
+
+ std::string keyword;
+
+ for (; string_index < ln.size(); ++string_index) {
+ if (ln[string_index] == variable.fEnd[0]) {
+ std::string varname = "";
+
+ for (size_t index_keyword = ln.find(' ');
+ ln[index_keyword] != variable.fBegin[0]; ++index_keyword) {
+ if (ln[index_keyword] == ' ') {
+ continue;
+ }
- keyword.push_back(ln[string_index]);
+ if (isdigit(ln[index_keyword])) {
+ goto cc_next_loop;
}
- goto cc_next_loop;
+ varname += ln[index_keyword];
+ }
- cc_check_done:
+ if (varname.find(' ') != std::string::npos) {
+ varname.erase(0, varname.find(' '));
- // skip digit value.
- if (isdigit(keyword[0]) ||
- keyword[0] == '"')
- {
- goto cc_next_loop;
+ if (variable.fBegin == "extern") {
+ varname.erase(0, varname.find(' '));
}
+ }
- while (keyword.find(' ') != std::string::npos)
- keyword.erase(keyword.find(' '), 1);
+ if (kRegisterCounter == 5 || kRegisterCounter == 6)
+ ++kRegisterCounter;
- for (auto &var : kCompilerVariables)
- {
- if (var.fValue.find(keyword) != std::string::npos)
- {
- err_str.clear();
- goto cc_next;
- }
- }
+ std::string reg = kAsmRegisterPrefix;
+ reg += std::to_string(kRegisterCounter);
- for (auto &fn : kCompilerFunctions)
- {
- if (fn.find(keyword[0]) != std::string::npos)
- {
- auto where_begin = fn.find(keyword[0]);
- auto keyword_begin = 0UL;
- auto failed = false;
-
- for (; where_begin < keyword.size(); ++where_begin)
- {
- if (fn[where_begin] == '(' &&
- keyword[keyword_begin] == '(')
- break;
-
- if (fn[where_begin] != keyword[keyword_begin])
- {
- failed = true;
- break;
- }
-
- ++keyword_begin;
- }
-
- if (!failed)
- {
- err_str.clear();
- goto cc_next;
- }
- else
- {
- continue;
- }
- }
- }
+ kCompilerVariables.push_back({.fValue = varname});
+ goto cc_check_done;
+ }
+
+ keyword.push_back(ln[string_index]);
+ }
+
+ goto cc_next_loop;
- cc_error_value:
- if (keyword.find("->") != std::string::npos)
- return err_str;
+ cc_check_done:
- if (keyword.find(".") != std::string::npos)
- return err_str;
+ // skip digit value.
+ if (isdigit(keyword[0]) || keyword[0] == '"') {
+ goto cc_next_loop;
+ }
- if (isalnum(keyword[0]))
- err_str += "\nUndefined value: " + keyword;
+ while (keyword.find(' ') != std::string::npos)
+ keyword.erase(keyword.find(' '), 1);
- return err_str;
+ for (auto &var : kCompilerVariables) {
+ if (var.fValue.find(keyword) != std::string::npos) {
+ err_str.clear();
+ goto cc_next;
}
+ }
- cc_next_loop:
- continue;
- }
+ for (auto &fn : kCompilerFunctions) {
+ if (fn.find(keyword[0]) != std::string::npos) {
+ auto where_begin = fn.find(keyword[0]);
+ auto keyword_begin = 0UL;
+ auto failed = false;
-cc_next:
+ for (; where_begin < keyword.size(); ++where_begin) {
+ if (fn[where_begin] == '(' && keyword[keyword_begin] == '(') break;
- // extern does not declare anything, it imports a variable.
- // so that's why it's not declare upper.
- if (ParserKit::find_word(ln, "extern"))
- {
- auto substr = ln.substr(ln.find("extern") + strlen("extern"));
- kCompilerVariables.push_back({.fValue = substr});
- }
+ if (fn[where_begin] != keyword[keyword_begin]) {
+ failed = true;
+ break;
+ }
- if (kShouldHaveBraces &&
- ln.find('{') == std::string::npos)
- {
- err_str += "Missing '{' for function ";
- err_str += kFnName;
- err_str += "\n";
+ ++keyword_begin;
+ }
- kShouldHaveBraces = false;
- kFnName.clear();
- }
- else if (kShouldHaveBraces &&
- ln.find('{') != std::string::npos)
- {
- kShouldHaveBraces = false;
- kFnName.clear();
- }
+ if (!failed) {
+ err_str.clear();
+ goto cc_next;
+ } else {
+ continue;
+ }
+ }
+ }
- bool type_not_found = true;
+ cc_error_value:
+ if (keyword.find("->") != std::string::npos) return err_str;
- if (ln.find('\'') != std::string::npos)
- {
- ln.replace(ln.find('\''), 3, "0");
+ if (keyword.find(".") != std::string::npos) return err_str;
+
+ if (isalnum(keyword[0])) err_str += "\nUndefined value: " + keyword;
+
+ return err_str;
}
- auto first = ln.find('"');
- if (first != std::string::npos)
- {
- auto second = 0UL;
- bool found_second_quote = false;
+ cc_next_loop:
+ continue;
+ }
- for (size_t i = first + 1; i < ln.size(); ++i)
- {
- if (ln[i] == '\"')
- {
- found_second_quote = true;
- second = i;
+cc_next:
- break;
- }
- }
+ // extern does not declare anything, it imports a variable.
+ // so that's why it's not declare upper.
+ if (ParserKit::find_word(ln, "extern")) {
+ auto substr = ln.substr(ln.find("extern") + strlen("extern"));
+ kCompilerVariables.push_back({.fValue = substr});
+ }
+
+ if (kShouldHaveBraces && ln.find('{') == std::string::npos) {
+ err_str += "Missing '{' for function ";
+ err_str += kFnName;
+ err_str += "\n";
+
+ kShouldHaveBraces = false;
+ kFnName.clear();
+ } else if (kShouldHaveBraces && ln.find('{') != std::string::npos) {
+ kShouldHaveBraces = false;
+ kFnName.clear();
+ }
+
+ bool type_not_found = true;
+
+ if (ln.find('\'') != std::string::npos) {
+ ln.replace(ln.find('\''), 3, "0");
+ }
+
+ auto first = ln.find('"');
+ if (first != std::string::npos) {
+ auto second = 0UL;
+ bool found_second_quote = false;
+
+ for (size_t i = first + 1; i < ln.size(); ++i) {
+ if (ln[i] == '\"') {
+ found_second_quote = true;
+ second = i;
+
+ break;
+ }
+ }
- if (!found_second_quote)
- {
- err_str += "Missing terminating \".";
- err_str += " here -> " + ln.substr(ln.find('"'), second);
- }
+ if (!found_second_quote) {
+ err_str += "Missing terminating \".";
+ err_str += " here -> " + ln.substr(ln.find('"'), second);
}
+ }
- if (ln.find(')') != std::string::npos &&
- ln.find(';') == std::string::npos)
- {
- if (ln.find('{') == std::string::npos)
- {
- kFnName = ln;
- kShouldHaveBraces = true;
+ if (ln.find(')') != std::string::npos && ln.find(';') == std::string::npos) {
+ if (ln.find('{') == std::string::npos) {
+ kFnName = ln;
+ kShouldHaveBraces = true;
- goto skip_braces_check;
- }
- else if (ln.find('{') != std::string::npos)
- {
- kShouldHaveBraces = false;
- }
+ goto skip_braces_check;
+ } else if (ln.find('{') != std::string::npos) {
+ kShouldHaveBraces = false;
}
+ }
skip_braces_check:
- for (auto &key : kCompilerTypes)
- {
- if (ParserKit::find_word(ln, key.fName))
- {
- if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1]))
- {
- err_str += "\nNumber cannot be set for ";
- err_str += key.fName;
- err_str += "'s name. here -> ";
- err_str += ln;
- }
+ for (auto &key : kCompilerTypes) {
+ if (ParserKit::find_word(ln, key.fName)) {
+ if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1])) {
+ err_str += "\nNumber cannot be set for ";
+ err_str += key.fName;
+ err_str += "'s name. here -> ";
+ err_str += ln;
+ }
- if (ln.find(key.fName) == 0 ||
- ln[ln.find(key.fName) - 1] == ' ' ||
- ln[ln.find(key.fName) - 1] == '\t')
- {
- type_not_found = false;
+ if (ln.find(key.fName) == 0 || ln[ln.find(key.fName) - 1] == ' ' ||
+ ln[ln.find(key.fName) - 1] == '\t') {
+ type_not_found = false;
- if (ln[ln.find(key.fName) + key.fName.size()] != ' ')
- {
- type_not_found = true;
+ if (ln[ln.find(key.fName) + key.fName.size()] != ' ') {
+ type_not_found = true;
- if (ln[ln.find(key.fName) + key.fName.size()] == '\t')
- type_not_found = false;
+ if (ln[ln.find(key.fName) + key.fName.size()] == '\t')
+ type_not_found = false;
- goto next;
- }
- else if (ln[ln.find(key.fName) + key.fName.size()] != '\t')
- {
- type_not_found = true;
+ goto next;
+ } else if (ln[ln.find(key.fName) + key.fName.size()] != '\t') {
+ type_not_found = true;
- if (ln[ln.find(key.fName) + key.fName.size()] == ' ')
- type_not_found = false;
- }
- }
+ if (ln[ln.find(key.fName) + key.fName.size()] == ' ')
+ type_not_found = false;
+ }
+ }
- next:
+ next:
- if (ln.find(';') == std::string::npos)
- {
- if (ln.find('(') != std::string::npos)
- {
- if (ln.find('=') == std::string::npos)
- continue;
- }
+ if (ln.find(';') == std::string::npos) {
+ if (ln.find('(') != std::string::npos) {
+ if (ln.find('=') == std::string::npos) continue;
+ }
- err_str += "\nMissing ';', here -> ";
- err_str += ln;
- }
- else
- {
- continue;
- }
+ err_str += "\nMissing ';', here -> ";
+ err_str += ln;
+ } else {
+ continue;
+ }
- if (ln.find('=') != std::string::npos)
- {
- if (ln.find('(') != std::string::npos)
- {
- if (ln.find(')') == std::string::npos)
- {
- err_str += "\nMissing ')', after '(' here -> ";
- err_str += ln.substr(ln.find('('));
- }
- }
- }
+ if (ln.find('=') != std::string::npos) {
+ if (ln.find('(') != std::string::npos) {
+ if (ln.find(')') == std::string::npos) {
+ err_str += "\nMissing ')', after '(' here -> ";
+ err_str += ln.substr(ln.find('('));
+ }
}
+ }
}
-
- if (kInBraces &&
- ln.find("struct") != std::string::npos &&
- ln.find("union") != std::string::npos &&
- ln.find("enum") != std::string::npos &&
- ln.find('=') != std::string::npos)
- {
- if (ln.find(';') == std::string::npos)
- {
- err_str += "\nMissing ';' after struct/union/enum declaration, here -> ";
- err_str += ln;
- }
+ }
+
+ if (kInBraces && ln.find("struct") != std::string::npos &&
+ ln.find("union") != std::string::npos &&
+ ln.find("enum") != std::string::npos &&
+ ln.find('=') != std::string::npos) {
+ if (ln.find(';') == std::string::npos) {
+ err_str += "\nMissing ';' after struct/union/enum declaration, here -> ";
+ err_str += ln;
}
-
- if (ln.find(';') != std::string::npos &&
- ln.find("for") == std::string::npos)
- {
- if (ln.find(';') + 1 != ln.size())
- {
- for (int i = 0; i < ln.substr(ln.find(';') + 1).size(); ++i)
- {
- if ((ln.substr(ln.find(';') + 1)[i] != ' ') ||
- (ln.substr(ln.find(';') + 1)[i] != '\t'))
- {
- if (auto err = this->Check(ln.substr(ln.find(';') + 1).c_str(), file);
- !err.empty())
- {
- err_str += "\nUnexpected text after ';' -> ";
- err_str += ln.substr(ln.find(';'));
- err_str += err;
- }
- }
- }
+ }
+
+ if (ln.find(';') != std::string::npos &&
+ ln.find("for") == std::string::npos) {
+ if (ln.find(';') + 1 != ln.size()) {
+ for (int i = 0; i < ln.substr(ln.find(';') + 1).size(); ++i) {
+ if ((ln.substr(ln.find(';') + 1)[i] != ' ') ||
+ (ln.substr(ln.find(';') + 1)[i] != '\t')) {
+ if (auto err = this->Check(ln.substr(ln.find(';') + 1).c_str(), file);
+ !err.empty()) {
+ err_str += "\nUnexpected text after ';' -> ";
+ err_str += ln.substr(ln.find(';'));
+ err_str += err;
+ }
}
+ }
}
+ }
+
+ if (ln.find('(') != std::string::npos) {
+ if (ln.find(';') == std::string::npos && !ParserKit::find_word(ln, "|") &&
+ !ParserKit::find_word(ln, "||") && !ParserKit::find_word(ln, "&") &&
+ !ParserKit::find_word(ln, "&&") && !ParserKit::find_word(ln, "~")) {
+ bool found_func = false;
+ size_t i = ln.find('(');
+ std::vector<char> opens;
+ std::vector<char> closes;
+
+ for (; i < ln.size(); ++i) {
+ if (ln[i] == ')') {
+ closes.push_back(1);
+ }
- if (ln.find('(') != std::string::npos)
- {
- if (ln.find(';') == std::string::npos &&
- !ParserKit::find_word(ln, "|") &&
- !ParserKit::find_word(ln, "||") &&
- !ParserKit::find_word(ln, "&") &&
- !ParserKit::find_word(ln, "&&") &&
- !ParserKit::find_word(ln, "~"))
- {
- bool found_func = false;
- size_t i = ln.find('(');
- std::vector<char> opens;
- std::vector<char> closes;
-
- for (; i < ln.size(); ++i)
- {
- if (ln[i] == ')')
- {
- closes.push_back(1);
- }
-
- if (ln[i] == '(')
- {
- opens.push_back(1);
- }
- }
-
- if (closes.size() != opens.size())
- err_str += "Unterminated (), here -> " + ln;
+ if (ln[i] == '(') {
+ opens.push_back(1);
+ }
+ }
- bool space_found = false;
+ if (closes.size() != opens.size())
+ err_str += "Unterminated (), here -> " + ln;
- for (int i = 0; i < ln.size(); ++i)
- {
- if (ln[i] == ')' &&
- !space_found)
- {
- space_found = true;
- continue;
- }
+ bool space_found = false;
- if (space_found)
- {
- if (ln[i] == ' ' &&
- isalnum(ln[i + 1]))
- {
- err_str += "\nBad function format here -> ";
- err_str += ln;
- }
- }
- }
+ for (int i = 0; i < ln.size(); ++i) {
+ if (ln[i] == ')' && !space_found) {
+ space_found = true;
+ continue;
}
- if (ln.find('(') < 1)
- {
- err_str += "\nMissing identifier before '(' here -> ";
+ if (space_found) {
+ if (ln[i] == ' ' && isalnum(ln[i + 1])) {
+ err_str += "\nBad function format here -> ";
err_str += ln;
+ }
}
- else
- {
- if (type_not_found &&
- ln.find(';') == std::string::npos &&
- ln.find("if") == std::string::npos &&
- ln.find("|") == std::string::npos &&
- ln.find("&") == std::string::npos &&
- ln.find("(") == std::string::npos &&
- ln.find(")") == std::string::npos)
- {
- err_str += "\n Missing ';' or type, here -> ";
- err_str += ln;
- }
- }
-
- if (ln.find(')') == std::string::npos)
- {
- err_str += "\nMissing ')', after '(' here -> ";
- err_str += ln.substr(ln.find('('));
- }
+ }
}
- else
- {
- if (ln.find("for") != std::string::npos ||
- ln.find("while") != std::string::npos)
- {
- err_str += "\nMissing '(', after \"for\", here -> ";
- err_str += ln;
- }
+
+ if (ln.find('(') < 1) {
+ err_str += "\nMissing identifier before '(' here -> ";
+ err_str += ln;
+ } else {
+ if (type_not_found && ln.find(';') == std::string::npos &&
+ ln.find("if") == std::string::npos &&
+ ln.find("|") == std::string::npos &&
+ ln.find("&") == std::string::npos &&
+ ln.find("(") == std::string::npos &&
+ ln.find(")") == std::string::npos) {
+ err_str += "\n Missing ';' or type, here -> ";
+ err_str += ln;
+ }
}
- if (ln.find('}') != std::string::npos &&
- !kInBraces)
- {
- if (!kInStruct &&
- ln.find(';') == std::string::npos)
- {
- err_str += "\nMismatched '}', here -> ";
- err_str += ln;
- }
+ if (ln.find(')') == std::string::npos) {
+ err_str += "\nMissing ')', after '(' here -> ";
+ err_str += ln.substr(ln.find('('));
}
+ } else {
+ if (ln.find("for") != std::string::npos ||
+ ln.find("while") != std::string::npos) {
+ err_str += "\nMissing '(', after \"for\", here -> ";
+ err_str += ln;
+ }
+ }
- if (!ln.empty())
- {
- if (ln.find(';') == std::string::npos &&
- ln.find('{') == std::string::npos &&
- ln.find('}') == std::string::npos &&
- ln.find(')') == std::string::npos &&
- ln.find('(') == std::string::npos &&
- ln.find(',') == std::string::npos)
- {
- if (ln.size() <= 2)
- return err_str;
-
- err_str += "\nMissing ';', here -> ";
- err_str += ln;
- }
+ if (ln.find('}') != std::string::npos && !kInBraces) {
+ if (!kInStruct && ln.find(';') == std::string::npos) {
+ err_str += "\nMismatched '}', here -> ";
+ err_str += ln;
+ }
+ }
+
+ if (!ln.empty()) {
+ if (ln.find(';') == std::string::npos &&
+ ln.find('{') == std::string::npos &&
+ ln.find('}') == std::string::npos &&
+ ln.find(')') == std::string::npos &&
+ ln.find('(') == std::string::npos &&
+ ln.find(',') == std::string::npos) {
+ if (ln.size() <= 2) return err_str;
+
+ err_str += "\nMissing ';', here -> ";
+ err_str += ln;
}
+ }
- return err_str;
+ return err_str;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1284,170 +1055,147 @@ skip_braces_check:
/////////////////////////////////////////////////////////////////////////////////////////
-class AssemblyMountpointBccl final : public CompilerKit::AssemblyMountpoint
-{
-public:
- explicit AssemblyMountpointBccl() = default;
- ~AssemblyMountpointBccl() override = default;
+class AssemblyMountpointBccl final : public CompilerKit::AssemblyMountpoint {
+ public:
+ explicit AssemblyMountpointBccl() = default;
+ ~AssemblyMountpointBccl() override = default;
- CXXKIT_COPY_DEFAULT(AssemblyMountpointBccl);
+ CXXKIT_COPY_DEFAULT(AssemblyMountpointBccl);
- [[maybe_unused]] static Int32 Arch() noexcept { return CompilerKit::AssemblyFactory::kArchRISCV; }
+ [[maybe_unused]] static Int32 Arch() noexcept {
+ return CompilerKit::AssemblyFactory::kArchRISCV;
+ }
- Int32 CompileToFormat(CompilerKit::StringView &src, Int32 arch) override
- {
- if (arch != AssemblyMountpointBccl::Arch())
- return -1;
+ Int32 CompileToFormat(CompilerKit::StringView &src, Int32 arch) override {
+ if (arch != AssemblyMountpointBccl::Arch()) return -1;
- if (kCompilerBackend == nullptr)
- return -1;
+ if (kCompilerBackend == nullptr) return -1;
- /* @brief copy contents wihtout extension */
- std::string src_file = src.CData();
- std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
- std::string dest;
+ /* @brief copy contents wihtout extension */
+ std::string src_file = src.CData();
+ std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
+ std::string dest;
- for (auto &ch : src_file)
- {
- if (ch == '.')
- {
- break;
- }
+ for (auto &ch : src_file) {
+ if (ch == '.') {
+ break;
+ }
- dest += ch;
- }
+ dest += ch;
+ }
- /* According to pef abi. */
- std::vector<const char*> exts = kAsmFileExts;
- dest += exts[0];
+ /* According to pef abi. */
+ std::vector<const char *> exts = kAsmFileExts;
+ dest += exts[0];
- kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
+ kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
- auto fmt = CompilerKit::current_date();
+ auto fmt = CompilerKit::current_date();
- (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
- (*kState.fOutputAssembly) << "# Language: MP-UX Assembly (Generated from BCCL)\n";
- (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n";
+ (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
+ (*kState.fOutputAssembly)
+ << "# Language: MP-UX Assembly (Generated from BCCL)\n";
+ (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n";
- ParserKit::SyntaxLeafList syntax;
+ ParserKit::SyntaxLeafList syntax;
- kState.fSyntaxTreeList.push_back(syntax);
- kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
+ kState.fSyntaxTreeList.push_back(syntax);
+ kState.fSyntaxTree =
+ &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
- std::string line_src;
+ std::string line_src;
- while (std::getline(src_fp, line_src))
- {
- if (auto err = kCompilerBackend->Check(line_src.c_str(), src.CData());
- err.empty())
- {
- kCompilerBackend->Compile(line_src, src.CData());
- }
- else
- {
- detail::print_error(err, src.CData());
- }
+ while (std::getline(src_fp, line_src)) {
+ if (auto err = kCompilerBackend->Check(line_src.c_str(), src.CData());
+ err.empty()) {
+ kCompilerBackend->Compile(line_src, src.CData());
+ } else {
+ detail::print_error(err, src.CData());
+ }
+ }
+
+ if (kAcceptableErrors > 0) return -1;
+
+ std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta",
+ "add", "dec", "mv"};
+
+ ///
+ /// Replace, optimize, fix assembly output.
+ ///
+
+ for (auto &leaf : kState.fSyntaxTree->fLeafList) {
+ std::vector<std::string> access_keywords = {"->", "."};
+
+ for (auto &access_ident : access_keywords) {
+ if (ParserKit::find_word(leaf.fUserValue, access_ident)) {
+ for (auto &struc : kState.kStructMap) {
+ }
}
+ }
- if (kAcceptableErrors > 0)
- return -1;
+ for (auto &keyword : keywords) {
+ if (ParserKit::find_word(leaf.fUserValue, keyword)) {
+ std::size_t cnt = 0UL;
- std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta", "add", "dec", "mv"};
+ for (auto &reg : kState.kStackFrame) {
+ std::string needle;
- ///
- /// Replace, optimize, fix assembly output.
- ///
+ for (size_t i = 0; i < reg.fName.size(); i++) {
+ if (reg.fName[i] == ' ') {
+ ++i;
+
+ for (; i < reg.fName.size(); i++) {
+ if (reg.fName[i] == ',') {
+ break;
+ }
- for (auto &leaf : kState.fSyntaxTree->fLeafList)
- {
- std::vector<std::string> access_keywords = {"->", "."};
+ if (reg.fName[i] == ' ') continue;
- for (auto &access_ident : access_keywords)
- {
- if (ParserKit::find_word(leaf.fUserValue, access_ident))
- {
- for (auto &struc : kState.kStructMap)
- {
- }
+ needle += reg.fName[i];
}
+
+ break;
+ }
}
- for (auto &keyword : keywords)
- {
- if (ParserKit::find_word(leaf.fUserValue, keyword))
- {
- std::size_t cnt = 0UL;
-
- for (auto &reg : kState.kStackFrame)
- {
- std::string needle;
-
- for (size_t i = 0; i < reg.fName.size(); i++)
- {
- if (reg.fName[i] == ' ')
- {
- ++i;
-
- for (; i < reg.fName.size(); i++)
- {
- if (reg.fName[i] == ',')
- {
- break;
- }
-
- if (reg.fName[i] == ' ')
- continue;
-
- needle += reg.fName[i];
- }
-
- break;
- }
- }
-
- if (ParserKit::find_word(leaf.fUserValue, needle))
- {
- if (leaf.fUserValue.find("ldw r6") != std::string::npos)
- {
- std::string::difference_type countComma = std::count(leaf.fUserValue.begin(),
- leaf.fUserValue.end(), ',');
-
- if (countComma == 1)
- {
- leaf.fUserValue.replace(leaf.fUserValue.find("ldw"), strlen("ldw"), "mv");
- }
- }
-
- leaf.fUserValue.replace(leaf.fUserValue.find(needle),
- needle.size(), reg.fReg);
-
- ++cnt;
- }
- }
-
- if (cnt > 1 &&
- keyword != "mv" &&
- keyword != "add" &&
- keyword != "dec")
- {
- leaf.fUserValue.replace(leaf.fUserValue.find(keyword), keyword.size(), "mv");
- }
+ if (ParserKit::find_word(leaf.fUserValue, needle)) {
+ if (leaf.fUserValue.find("ldw r6") != std::string::npos) {
+ std::string::difference_type countComma = std::count(
+ leaf.fUserValue.begin(), leaf.fUserValue.end(), ',');
+
+ if (countComma == 1) {
+ leaf.fUserValue.replace(leaf.fUserValue.find("ldw"),
+ strlen("ldw"), "mv");
}
+ }
+
+ leaf.fUserValue.replace(leaf.fUserValue.find(needle),
+ needle.size(), reg.fReg);
+
+ ++cnt;
}
- }
+ }
- for (auto &leaf : kState.fSyntaxTree->fLeafList)
- {
- (*kState.fOutputAssembly) << leaf.fUserValue;
+ if (cnt > 1 && keyword != "mv" && keyword != "add" &&
+ keyword != "dec") {
+ leaf.fUserValue.replace(leaf.fUserValue.find(keyword),
+ keyword.size(), "mv");
+ }
}
+ }
+ }
- kState.fSyntaxTree = nullptr;
+ for (auto &leaf : kState.fSyntaxTree->fLeafList) {
+ (*kState.fOutputAssembly) << leaf.fUserValue;
+ }
- kState.fOutputAssembly->flush();
- kState.fOutputAssembly.reset();
+ kState.fSyntaxTree = nullptr;
- return kOk;
- }
+ kState.fOutputAssembly->flush();
+ kState.fOutputAssembly.reset();
+
+ return kOk;
+ }
};
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1455,130 +1203,114 @@ public:
#define kPrintF printf
#define kSplashCxx() kPrintF(kWhite "%s\n", "bccl, v1.15, (c) Mahrouss Logic")
-static void cc_print_help()
-{
- kSplashCxx();
+static void cc_print_help() {
+ kSplashCxx();
- kPrintF(kWhite "--asm={ASSEMBLER}: %s\n", "Compile with a specific syntax. (64x0, 32x0)");
- kPrintF(kWhite "--compiler={COMPILER}: %s\n", "Select compiler engine (builtins are The dalvik engine).");
+ kPrintF(kWhite "--asm={ASSEMBLER}: %s\n",
+ "Compile with a specific syntax. (64x0, 32x0)");
+ kPrintF(kWhite "--compiler={COMPILER}: %s\n",
+ "Select compiler engine (builtins are The dalvik engine).");
}
/////////////////////////////////////////////////////////////////////////////////////////
#define kExt ".bccl"
-MPCC_MODULE(CompilerBccl64x0)
-{
- kCompilerTypes.push_back({.fName = "void", .fValue = "void"});
- kCompilerTypes.push_back({.fName = "char", .fValue = "byte"});
- kCompilerTypes.push_back({.fName = "short", .fValue = "hword"});
- kCompilerTypes.push_back({.fName = "int", .fValue = "dword"});
- kCompilerTypes.push_back({.fName = "long", .fValue = "qword"});
-
- bool skip = false;
-
- for (auto index = 1UL; index < argc; ++index)
- {
- if (skip)
- {
- skip = false;
- continue;
- }
+MPCC_MODULE(CompilerBccl64x0) {
+ kCompilerTypes.push_back({.fName = "void", .fValue = "void"});
+ kCompilerTypes.push_back({.fName = "char", .fValue = "byte"});
+ kCompilerTypes.push_back({.fName = "short", .fValue = "hword"});
+ kCompilerTypes.push_back({.fName = "int", .fValue = "dword"});
+ kCompilerTypes.push_back({.fName = "long", .fValue = "qword"});
- if (argv[index][0] == '-')
- {
- if (strcmp(argv[index], "-v") == 0 ||
- strcmp(argv[index], "--version") == 0)
- {
- kSplashCxx();
- return kOk;
- }
+ bool skip = false;
- if (strcmp(argv[index], "-verbose") == 0)
- {
- kState.kVerbose = true;
+ for (auto index = 1UL; index < argc; ++index) {
+ if (skip) {
+ skip = false;
+ continue;
+ }
- continue;
- }
+ if (argv[index][0] == '-') {
+ if (strcmp(argv[index], "-v") == 0 ||
+ strcmp(argv[index], "--version") == 0) {
+ kSplashCxx();
+ return kOk;
+ }
- if (strcmp(argv[index], "-h") == 0 ||
- strcmp(argv[index], "--help") == 0)
- {
- cc_print_help();
+ if (strcmp(argv[index], "-verbose") == 0) {
+ kState.kVerbose = true;
- return kOk;
- }
+ continue;
+ }
- if (strcmp(argv[index], "--dialect") == 0)
- {
- if (kCompilerBackend)
- std::cout << kCompilerBackend->Language() << "\n";
+ if (strcmp(argv[index], "-h") == 0 ||
+ strcmp(argv[index], "--help") == 0) {
+ cc_print_help();
- return kOk;
- }
+ return kOk;
+ }
- if (strcmp(argv[index], "--asm=masm") == 0)
- {
- delete kFactory.Unmount();
+ if (strcmp(argv[index], "--dialect") == 0) {
+ if (kCompilerBackend) std::cout << kCompilerBackend->Language() << "\n";
- kFactory.Mount(new AssemblyMountpointBccl());
- kMachine = CompilerKit::AssemblyFactory::kArchRISCV;
+ return kOk;
+ }
- continue;
- }
+ if (strcmp(argv[index], "--asm=masm") == 0) {
+ delete kFactory.Unmount();
- if (strcmp(argv[index], "--compiler=dalvik") == 0)
- {
- if (!kCompilerBackend)
- kCompilerBackend = new CompilerBackendBccl();
+ kFactory.Mount(new AssemblyMountpointBccl());
+ kMachine = CompilerKit::AssemblyFactory::kArch64x0;
- continue;
- }
+ continue;
+ }
- if (strcmp(argv[index], "-fmax-exceptions") == 0)
- {
- try
- {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...)
- {
- kErrorLimit = 0;
- }
+ if (strcmp(argv[index], "--compiler=dalvik") == 0) {
+ if (!kCompilerBackend) kCompilerBackend = new CompilerBackendBccl();
+
+ continue;
+ }
- skip = true;
+ if (strcmp(argv[index], "-fmax-exceptions") == 0) {
+ try {
+ kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
+ }
+ // catch anything here
+ catch (...) {
+ kErrorLimit = 0;
+ }
- continue;
- }
+ skip = true;
- std::string err = "Unknown command: ";
- err += argv[index];
+ continue;
+ }
- detail::print_error(err, "bccl");
+ std::string err = "Unknown command: ";
+ err += argv[index];
- continue;
- }
+ detail::print_error(err, "bccl");
- kFileList.emplace_back(argv[index]);
+ continue;
+ }
- CompilerKit::StringView srcFile = CompilerKit::StringBuilder::Construct(argv[index]);
+ kFileList.emplace_back(argv[index]);
- if (strstr(argv[index], kExt) == nullptr)
- {
- if (kState.kVerbose)
- {
- std::cerr << argv[index] << " is not a valid BCCL source.\n";
- }
+ CompilerKit::StringView srcFile =
+ CompilerKit::StringBuilder::Construct(argv[index]);
- return -1;
- }
+ if (strstr(argv[index], kExt) == nullptr) {
+ if (kState.kVerbose) {
+ std::cerr << argv[index] << " is not a valid BCCL source.\n";
+ }
- if (kFactory.Compile(srcFile, kMachine) != kOk)
- return -1;
+ return -1;
}
- return kOk;
+ if (kFactory.Compile(srcFile, kMachine) != kOk) return -1;
+ }
+
+ return kOk;
}
-// Last rev 8-1-24 \ No newline at end of file
+// Last rev 8-1-24
diff --git a/Private/Toolchain/bpp.cc b/Private/Toolchain/bpp.cc
index cd1bc47..291c25e 100644
--- a/Private/Toolchain/bpp.cc
+++ b/Private/Toolchain/bpp.cc
@@ -9,11 +9,10 @@
/// bugs: ?
-#include <CompilerKit/StdKit/ErrorID.hpp>
#include <CompilerKit/ParserKit.hpp>
-#include <sstream>
-#include <iostream>
+#include <CompilerKit/StdKit/ErrorID.hpp>
#include <fstream>
+#include <iostream>
#define kMacroPrefix '%'
@@ -21,7 +20,8 @@
// @file bpp.cc
// @brief BCCL preprocessor.
-typedef Int32 (*bpp_parser_fn_t)(std::string &line, std::ifstream &hdr_file, std::ofstream &pp_out);
+typedef Int32 (*bpp_parser_fn_t)(std::string &line, std::ifstream &hdr_file,
+ std::ofstream &pp_out);
/////////////////////////////////////////////////////////////////////////////////////////
@@ -29,43 +29,38 @@ typedef Int32 (*bpp_parser_fn_t)(std::string &line, std::ifstream &hdr_file, std
/////////////////////////////////////////////////////////////////////////////////////////
-namespace details
-{
- enum
- {
- kEqual,
- kGreaterEqThan,
- kLesserEqThan,
- kGreaterThan,
- kLesserThan,
- kNotEqual,
- };
-
- struct bpp_macro_condition final
- {
- int32_t fType;
- std::string fTypeName;
- };
-
- struct bpp_macro final
- {
- std::vector<std::string> fArgs;
- std::string fName;
- std::string fValue;
- };
-
- class bpp_pragma final
- {
- public:
- explicit bpp_pragma() = default;
- ~bpp_pragma() = default;
-
- CXXKIT_COPY_DEFAULT(bpp_pragma);
-
- std::string fMacroName;
- bpp_parser_fn_t fParse;
- };
-}
+namespace details {
+enum {
+ kEqual,
+ kGreaterEqThan,
+ kLesserEqThan,
+ kGreaterThan,
+ kLesserThan,
+ kNotEqual,
+};
+
+struct bpp_macro_condition final {
+ int32_t fType;
+ std::string fTypeName;
+};
+
+struct bpp_macro final {
+ std::vector<std::string> fArgs;
+ std::string fName;
+ std::string fValue;
+};
+
+class bpp_pragma final {
+ public:
+ explicit bpp_pragma() = default;
+ ~bpp_pragma() = default;
+
+ CXXKIT_COPY_DEFAULT(bpp_pragma);
+
+ std::string fMacroName;
+ bpp_parser_fn_t fParse;
+};
+} // namespace details
static std::vector<std::string> kFiles;
static std::vector<details::bpp_macro> kMacros;
@@ -74,16 +69,8 @@ static std::vector<std::string> kIncludes;
static std::string kWorkingDir;
static std::vector<std::string> kKeywords = {
- "inc",
- "if",
- "pragma",
- "def",
- "elif",
- "ifdef",
- "ifndef",
- "else",
- "warning",
- "error"};
+ "inc", "if", "pragma", "def", "elif",
+ "ifdef", "ifndef", "else", "warning", "error"};
#define kKeywordCxxCnt kKeywords.size()
@@ -95,177 +82,148 @@ static std::vector<std::string> kKeywords = {
/////////////////////////////////////////////////////////////////////////////////////////
int32_t bpp_parse_if_condition(details::bpp_macro_condition &cond,
- details::bpp_macro &macro,
- bool &inactive_code, bool &defined,
- std::string &macro_str)
-{
- if (cond.fType == details::kEqual)
- {
- auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
-
- if (substr_macro.find(macro.fValue) != std::string::npos)
- {
- if (macro.fValue == "0")
- {
- defined = false;
- inactive_code = true;
-
- return 1;
- }
-
- defined = true;
- inactive_code = false;
-
- return 1;
- }
- }
- else if (cond.fType == details::kNotEqual)
- {
- auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
-
- if (substr_macro.find(macro.fName) != std::string::npos)
- {
- if (substr_macro.find(macro.fValue) != std::string::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());
-
- std::string number;
-
- for (auto &macro_num : kMacros)
- {
- if (substr_macro.find(macro_num.fName) != std::string::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 == details::kGreaterThan)
- {
- if (lhs < rhs)
- {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == details::kGreaterEqThan)
- {
- if (lhs <= rhs)
- {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == details::kLesserEqThan)
- {
- if (lhs >= rhs)
- {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == details::kLesserThan)
- {
- if (lhs > rhs)
- {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- return 0;
+ details::bpp_macro &macro, bool &inactive_code,
+ bool &defined, std::string &macro_str) {
+ if (cond.fType == details::kEqual) {
+ auto substr_macro =
+ macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
+
+ if (substr_macro.find(macro.fValue) != std::string::npos) {
+ if (macro.fValue == "0") {
+ defined = false;
+ inactive_code = true;
+
+ return 1;
+ }
+
+ defined = true;
+ inactive_code = false;
+
+ return 1;
+ }
+ } else if (cond.fType == details::kNotEqual) {
+ auto substr_macro =
+ macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
+
+ if (substr_macro.find(macro.fName) != std::string::npos) {
+ if (substr_macro.find(macro.fValue) != std::string::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());
+
+ std::string number;
+
+ for (auto &macro_num : kMacros) {
+ if (substr_macro.find(macro_num.fName) != std::string::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 == details::kGreaterThan) {
+ if (lhs < rhs) {
+ defined = true;
+ inactive_code = false;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (cond.fType == details::kGreaterEqThan) {
+ if (lhs <= rhs) {
+ defined = true;
+ inactive_code = false;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (cond.fType == details::kLesserEqThan) {
+ if (lhs >= rhs) {
+ defined = true;
+ inactive_code = false;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (cond.fType == details::kLesserThan) {
+ if (lhs > rhs) {
+ defined = true;
+ inactive_code = false;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -283,703 +241,582 @@ std::vector<std::string> kAllIncludes;
/////////////////////////////////////////////////////////////////////////////////////////
-void bpp_parse_file(std::ifstream &hdr_file, std::ofstream &pp_out)
-{
- std::string hdr_line;
- std::string line_after_include;
-
- bool inactive_code = false;
- bool defined = false;
-
- try
- {
- while (std::getline(hdr_file, hdr_line))
- {
- if (hdr_line.find("@bdoc") != std::string::npos)
- {
- hdr_line.erase(hdr_line.find("@bdoc"));
- }
-
- if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("endif") != std::string::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 (ParserKit::find_word(hdr_line, macro.fName) &&
- hdr_line.find("%def") == std::string::npos)
- {
- auto substr = hdr_line.substr(hdr_line.find(macro.fName));
-
- std::vector<std::string> sym_vec;
- std::string sym_str;
-
- for (auto &subc : substr)
- {
- if (subc == ',' ||
- subc == ')')
- {
- if (sym_str.empty())
- continue;
-
- sym_vec.push_back(sym_str);
- sym_str.clear();
-
- continue;
- }
-
- if (isalnum(subc))
- sym_str.push_back(subc);
- }
-
- if (macro.fArgs.size() > 0)
- {
-
- for (auto &item : sym_vec)
- {
- std::size_t cnt = 0;
-
- for (auto &arg : macro.fArgs)
- {
- if (item == arg)
- ++cnt;
- }
-
- if (cnt > 1)
- {
- auto it = std::find(macro.fArgs.begin(), macro.fArgs.end(), item);
-
- while (it != macro.fArgs.end())
- {
- macro.fArgs.erase(it);
- it = std::find(macro.fArgs.begin(), macro.fArgs.end(), item);
- }
- }
- }
-
- if (sym_vec.size() != macro.fArgs.size())
- {
- throw std::runtime_error("bpp: arguments count mismatch, except " + std::to_string(sym_vec.size()) + ", got: " + std::to_string(macro.fArgs.size()));
- return;
- }
-
- substr = macro.fValue;
-
- std::size_t cnt = 0UL;
-
- for (auto &val : macro.fArgs)
- {
- substr.replace(substr.find(val), val.size(), sym_vec[cnt]);
- ++cnt;
- }
- }
-
- hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), substr);
- hdr_line.erase(hdr_line.find(substr) + substr.size());
- }
- }
-
- if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("def ") != std::string::npos)
- {
- auto line_after_define = hdr_line.substr(hdr_line.find("def ") + strlen("def "));
-
- std::string macro_value;
- std::string macro_key;
-
- std::size_t pos = 0UL;
-
- std::vector<std::string> 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;
- }
-
- std::vector<std::string> dupls;
- std::string str;
-
- line_after_define.erase(0, line_after_define.find("(") + 1);
-
- for (auto &subc : line_after_define)
- {
- if (subc == ',' ||
- subc == ')')
- {
- if (str.empty())
- continue;
-
- dupls.push_back(str);
- args.push_back(str);
-
- str.clear();
-
- continue;
- }
-
- if (isalnum(subc))
- str.push_back(subc);
- }
-
- for (auto &dupl : dupls)
- {
- std::size_t cnt = 0;
-
- for (auto &arg : args)
- {
- if (dupl == arg)
- ++cnt;
- }
-
- if (cnt > 1)
- {
- auto it = std::find(args.begin(), args.end(), dupl);
-
- while (it != args.end())
- {
- args.erase(it);
- it = std::find(args.begin(), args.end(), dupl);
- }
- }
- }
-
- details::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;
- }
-
- for (auto &macro : kMacros)
- {
- if (hdr_line.find(macro.fName) != std::string::npos)
- {
- std::vector<std::string> arg_values;
-
- if (macro.fArgs.size() > 0)
- {
- for (size_t i = 0; i < hdr_line.size(); ++i)
- {
- if (hdr_line[i] == '(')
- {
- std::string tmp_arg;
-
- for (size_t x = i; x < hdr_line.size(); x++)
- {
- if (hdr_line[x] == ')')
- break;
-
- if (hdr_line[x] == ' ')
- continue;
-
- if (hdr_line[i] == '\\')
- continue;
-
- if (hdr_line[x] == ',')
- {
- arg_values.push_back(tmp_arg);
- tmp_arg.clear();
- continue;
- }
-
- tmp_arg += hdr_line[x];
- }
-
- break;
- }
- }
-
- std::string symbol;
-
- for (char i : macro.fValue)
- {
- if (i == '(')
- break;
-
- if (i == '\\')
- continue;
-
- symbol += i;
- }
-
- hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), symbol);
-
- size_t x_arg_indx = 0;
-
- for (size_t i = hdr_line.find(macro.fValue); i < hdr_line.size(); ++i)
- {
- if (hdr_line.find(macro.fArgs[x_arg_indx]) == i)
- {
- hdr_line.replace(i, macro.fArgs[x_arg_indx].size(), arg_values[x_arg_indx]);
- ++x_arg_indx;
- }
- }
- }
- else
- {
- std::string symbol;
-
- for (size_t i = 0; i < macro.fValue.size(); i++)
- {
- if (macro.fValue[i] == ' ')
- continue;
-
- if (macro.fValue[i] == '\\')
- continue;
-
- symbol += macro.fValue[i];
- }
-
- hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), symbol);
- }
-
- break;
- }
- }
-
- pp_out << hdr_line << std::endl;
-
- continue;
- }
-
- if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("ifndef") != std::string::npos)
- {
- auto line_after_ifndef = hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1);
- std::string 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) != std::string::npos)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- {
- defined = false;
- inactive_code = true;
-
- continue;
- }
- }
- else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("else") != std::string::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") != std::string::npos)
- {
- auto line_after_ifdef = hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1);
- std::string 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) != std::string::npos)
- {
- defined = true;
- inactive_code = false;
-
- break;
- }
- }
- }
- else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("pragma") != std::string::npos)
- {
- line_after_include = hdr_line.substr(hdr_line.find("pragma once"));
-
- // search for this file
- auto it = std::find(kAllIncludes.cbegin(),
- kAllIncludes.cend(), line_after_include);
-
- if (it == kAllIncludes.cend())
- {
- goto kIncludeFile;
- }
- }
- else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("if") != std::string::npos)
- {
- inactive_code = true;
-
- std::vector<details::bpp_macro_condition> bpp_macro_condition_list = {
- {
- .fType = details::kEqual,
- .fTypeName = "==",
- },
- {
- .fType = details::kNotEqual,
- .fTypeName = "!=",
- },
- {
- .fType = details::kLesserThan,
- .fTypeName = "<",
- },
- {
- .fType = details::kGreaterThan,
- .fTypeName = ">",
- },
- {
- .fType = details::kLesserEqThan,
- .fTypeName = "<=",
- },
- {
- .fType = details::kGreaterEqThan,
- .fTypeName = ">=",
- },
- };
-
- int32_t good_to_go = 0;
-
- for (auto &macro_condition : bpp_macro_condition_list)
- {
- if (hdr_line.find(macro_condition.fTypeName) != std::string::npos)
- {
- for (auto &found_macro : kMacros)
- {
- if (hdr_line.find(found_macro.fName) != std::string::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);
- std::string 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) != std::string::npos &&
- macro_ref.fValue == "1")
- {
- inactive_code = false;
- defined = true;
-
- break;
- }
- }
- }
- else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("warning") != std::string::npos)
- {
- auto line_after_warning = hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1);
- std::string message;
-
- for (auto &ch : line_after_warning)
- {
- if (ch == '\r' ||
- ch == '\n')
- {
- break;
- }
-
- message += ch;
- }
-
- std::cout << "Warning: " << message << std::endl;
- }
- else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("error") != std::string::npos)
- {
- auto line_after_warning = hdr_line.substr(hdr_line.find("error") + strlen("error") + 1);
- std::string 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("inc ") != std::string::npos)
- {
- line_after_include = hdr_line.substr(hdr_line.find("inc ") + strlen("inc "));
-
- kIncludeFile:
- auto it = std::find(kAllIncludes.cbegin(),
- kAllIncludes.cend(), line_after_include);
-
- if (it != kAllIncludes.cend())
- {
- continue;
- }
-
- std::string 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 == '\'')
- {
- enable = true;
- continue;
- }
-
- if (enable)
- {
- if (not_local)
- {
- if (ch == '>')
- break;
- }
- else
- {
- if (ch == '\'')
- {
- break;
- }
- }
-
- path += ch;
- }
- }
-
- if (not_local)
- {
- bool open = false;
-
- for (auto &include : kIncludes)
- {
- std::string 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("bpp: no such include file: " + path);
- }
- }
- else
- {
- std::ifstream header(kWorkingDir + path);
-
- if (!header.is_open())
- throw std::runtime_error("bpp: no such include file: " + path);
-
- bpp_parse_file(header, pp_out);
- }
- }
- else
- {
- std::cerr << ("bpp: unknown pre-processor directive, " + hdr_line) << "\n";
- continue;
- }
- }
- }
- catch (std::out_of_range &oor)
- {
- return;
- }
+void bpp_parse_file(std::ifstream &hdr_file, std::ofstream &pp_out) {
+ std::string hdr_line;
+ std::string line_after_include;
+
+ bool inactive_code = false;
+ bool defined = false;
+
+ try {
+ while (std::getline(hdr_file, hdr_line)) {
+ if (hdr_line.find("@bdoc") != std::string::npos) {
+ hdr_line.erase(hdr_line.find("@bdoc"));
+ }
+
+ if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("endif") != std::string::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 (ParserKit::find_word(hdr_line, macro.fName) &&
+ hdr_line.find("%def") == std::string::npos) {
+ auto substr = hdr_line.substr(hdr_line.find(macro.fName));
+
+ std::vector<std::string> sym_vec;
+ std::string sym_str;
+
+ for (auto &subc : substr) {
+ if (subc == ',' || subc == ')') {
+ if (sym_str.empty()) continue;
+
+ sym_vec.push_back(sym_str);
+ sym_str.clear();
+
+ continue;
+ }
+
+ if (isalnum(subc)) sym_str.push_back(subc);
+ }
+
+ if (macro.fArgs.size() > 0) {
+ for (auto &item : sym_vec) {
+ std::size_t cnt = 0;
+
+ for (auto &arg : macro.fArgs) {
+ if (item == arg) ++cnt;
+ }
+
+ if (cnt > 1) {
+ auto it =
+ std::find(macro.fArgs.begin(), macro.fArgs.end(), item);
+
+ while (it != macro.fArgs.end()) {
+ macro.fArgs.erase(it);
+ it = std::find(macro.fArgs.begin(), macro.fArgs.end(), item);
+ }
+ }
+ }
+
+ if (sym_vec.size() != macro.fArgs.size()) {
+ throw std::runtime_error(
+ "bpp: arguments count mismatch, except " +
+ std::to_string(sym_vec.size()) +
+ ", got: " + std::to_string(macro.fArgs.size()));
+ return;
+ }
+
+ substr = macro.fValue;
+
+ std::size_t cnt = 0UL;
+
+ for (auto &val : macro.fArgs) {
+ substr.replace(substr.find(val), val.size(), sym_vec[cnt]);
+ ++cnt;
+ }
+ }
+
+ hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(),
+ substr);
+ hdr_line.erase(hdr_line.find(substr) + substr.size());
+ }
+ }
+
+ if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("def ") != std::string::npos) {
+ auto line_after_define =
+ hdr_line.substr(hdr_line.find("def ") + strlen("def "));
+
+ std::string macro_value;
+ std::string macro_key;
+
+ std::size_t pos = 0UL;
+
+ std::vector<std::string> 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;
+ }
+
+ std::vector<std::string> dupls;
+ std::string str;
+
+ line_after_define.erase(0, line_after_define.find("(") + 1);
+
+ for (auto &subc : line_after_define) {
+ if (subc == ',' || subc == ')') {
+ if (str.empty()) continue;
+
+ dupls.push_back(str);
+ args.push_back(str);
+
+ str.clear();
+
+ continue;
+ }
+
+ if (isalnum(subc)) str.push_back(subc);
+ }
+
+ for (auto &dupl : dupls) {
+ std::size_t cnt = 0;
+
+ for (auto &arg : args) {
+ if (dupl == arg) ++cnt;
+ }
+
+ if (cnt > 1) {
+ auto it = std::find(args.begin(), args.end(), dupl);
+
+ while (it != args.end()) {
+ args.erase(it);
+ it = std::find(args.begin(), args.end(), dupl);
+ }
+ }
+ }
+
+ details::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;
+ }
+
+ for (auto &macro : kMacros) {
+ if (hdr_line.find(macro.fName) != std::string::npos) {
+ std::vector<std::string> arg_values;
+
+ if (macro.fArgs.size() > 0) {
+ for (size_t i = 0; i < hdr_line.size(); ++i) {
+ if (hdr_line[i] == '(') {
+ std::string tmp_arg;
+
+ for (size_t x = i; x < hdr_line.size(); x++) {
+ if (hdr_line[x] == ')') break;
+
+ if (hdr_line[x] == ' ') continue;
+
+ if (hdr_line[i] == '\\') continue;
+
+ if (hdr_line[x] == ',') {
+ arg_values.push_back(tmp_arg);
+ tmp_arg.clear();
+ continue;
+ }
+
+ tmp_arg += hdr_line[x];
+ }
+
+ break;
+ }
+ }
+
+ std::string symbol;
+
+ for (char i : macro.fValue) {
+ if (i == '(') break;
+
+ if (i == '\\') continue;
+
+ symbol += i;
+ }
+
+ hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(),
+ symbol);
+
+ size_t x_arg_indx = 0;
+
+ for (size_t i = hdr_line.find(macro.fValue); i < hdr_line.size();
+ ++i) {
+ if (hdr_line.find(macro.fArgs[x_arg_indx]) == i) {
+ hdr_line.replace(i, macro.fArgs[x_arg_indx].size(),
+ arg_values[x_arg_indx]);
+ ++x_arg_indx;
+ }
+ }
+ } else {
+ std::string symbol;
+
+ for (size_t i = 0; i < macro.fValue.size(); i++) {
+ if (macro.fValue[i] == ' ') continue;
+
+ if (macro.fValue[i] == '\\') continue;
+
+ symbol += macro.fValue[i];
+ }
+
+ hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(),
+ symbol);
+ }
+
+ break;
+ }
+ }
+
+ pp_out << hdr_line << std::endl;
+
+ continue;
+ }
+
+ if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("ifndef") != std::string::npos) {
+ auto line_after_ifndef =
+ hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1);
+ std::string 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) != std::string::npos) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ defined = false;
+ inactive_code = true;
+
+ continue;
+ }
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("else") != std::string::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") != std::string::npos) {
+ auto line_after_ifdef =
+ hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1);
+ std::string 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) != std::string::npos) {
+ defined = true;
+ inactive_code = false;
+
+ break;
+ }
+ }
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("pragma") != std::string::npos) {
+ line_after_include = hdr_line.substr(hdr_line.find("pragma once"));
+
+ // search for this file
+ auto it = std::find(kAllIncludes.cbegin(), kAllIncludes.cend(),
+ line_after_include);
+
+ if (it == kAllIncludes.cend()) {
+ goto kIncludeFile;
+ }
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("if") != std::string::npos) {
+ inactive_code = true;
+
+ std::vector<details::bpp_macro_condition> bpp_macro_condition_list = {
+ {
+ .fType = details::kEqual,
+ .fTypeName = "==",
+ },
+ {
+ .fType = details::kNotEqual,
+ .fTypeName = "!=",
+ },
+ {
+ .fType = details::kLesserThan,
+ .fTypeName = "<",
+ },
+ {
+ .fType = details::kGreaterThan,
+ .fTypeName = ">",
+ },
+ {
+ .fType = details::kLesserEqThan,
+ .fTypeName = "<=",
+ },
+ {
+ .fType = details::kGreaterEqThan,
+ .fTypeName = ">=",
+ },
+ };
+
+ int32_t good_to_go = 0;
+
+ for (auto &macro_condition : bpp_macro_condition_list) {
+ if (hdr_line.find(macro_condition.fTypeName) != std::string::npos) {
+ for (auto &found_macro : kMacros) {
+ if (hdr_line.find(found_macro.fName) != std::string::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);
+ std::string 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) != std::string::npos &&
+ macro_ref.fValue == "1") {
+ inactive_code = false;
+ defined = true;
+
+ break;
+ }
+ }
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("warning") != std::string::npos) {
+ auto line_after_warning =
+ hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1);
+ std::string message;
+
+ for (auto &ch : line_after_warning) {
+ if (ch == '\r' || ch == '\n') {
+ break;
+ }
+
+ message += ch;
+ }
+
+ std::cout << "Warning: " << message << std::endl;
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("error") != std::string::npos) {
+ auto line_after_warning =
+ hdr_line.substr(hdr_line.find("error") + strlen("error") + 1);
+ std::string 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("inc ") != std::string::npos) {
+ line_after_include =
+ hdr_line.substr(hdr_line.find("inc ") + strlen("inc "));
+
+ kIncludeFile:
+ auto it = std::find(kAllIncludes.cbegin(), kAllIncludes.cend(),
+ line_after_include);
+
+ if (it != kAllIncludes.cend()) {
+ continue;
+ }
+
+ std::string 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 == '\'') {
+ enable = true;
+ continue;
+ }
+
+ if (enable) {
+ if (not_local) {
+ if (ch == '>') break;
+ } else {
+ if (ch == '\'') {
+ break;
+ }
+ }
+
+ path += ch;
+ }
+ }
+
+ if (not_local) {
+ bool open = false;
+
+ for (auto &include : kIncludes) {
+ std::string 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("bpp: no such include file: " + path);
+ }
+ } else {
+ std::ifstream header(kWorkingDir + path);
+
+ if (!header.is_open())
+ throw std::runtime_error("bpp: no such include file: " + path);
+
+ bpp_parse_file(header, pp_out);
+ }
+ } else {
+ std::cerr << ("bpp: unknown pre-processor directive, " + hdr_line)
+ << "\n";
+ continue;
+ }
+ }
+ } catch (std::out_of_range &oor) {
+ return;
+ }
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -988,140 +825,119 @@ void bpp_parse_file(std::ifstream &hdr_file, std::ofstream &pp_out)
/////////////////////////////////////////////////////////////////////////////////////////
-MPCC_MODULE(MPUXPreprocessor)
-{
- try
- {
- bool skip = false;
- bool double_skip = false;
-
- details::bpp_macro macro_1;
- macro_1.fName = "__true";
- macro_1.fValue = "1";
-
- kMacros.push_back(macro_1);
-
- details::bpp_macro macro_0;
- macro_0.fName = "__false";
- macro_0.fValue = "0";
-
- kMacros.push_back(macro_0);
-
- 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], "--version") == 0)
- {
- printf("%s\n", "bpp v1.11, (c) Mahrouss Logic");
- return 0;
- }
-
- if (strcmp(argv[index], "-h") == 0 ||
- strcmp(argv[index], "--help") == 0)
- {
- printf("%s\n", "bpp v1.11, (c) Mahrouss Logic");
- printf("%s\n", "--working-dir: set directory to working path.");
- printf("%s\n", "--include-dir: add directory to include path.");
- printf("%s\n", "--define: define macro.");
- printf("%s\n", "--version: print the version.");
-
- return 0;
- }
-
- if (strcmp(argv[index], "--include-dir") == 0)
- {
- std::string inc = argv[index + 1];
-
- skip = true;
-
- kIncludes.push_back(inc);
- }
-
- if (strcmp(argv[index], "--working-dir") == 0)
- {
- std::string inc = argv[index + 1];
- skip = true;
- kWorkingDir = inc;
- }
-
- if (strcmp(argv[index], "--define") == 0 &&
- argv[index + 1] != nullptr &&
- argv[index + 2] != nullptr)
- {
- std::string macro_key = argv[index + 1];
-
- std::string 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 += "\"";
-
- details::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 CXXKIT_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 0;
- }
- catch (const std::runtime_error &e)
- {
- std::cout << e.what() << '\n';
- }
-
- return 0;
+MPCC_MODULE(MPUXPreprocessor) {
+ try {
+ bool skip = false;
+ bool double_skip = false;
+
+ details::bpp_macro macro_1;
+ macro_1.fName = "__true";
+ macro_1.fValue = "1";
+
+ kMacros.push_back(macro_1);
+
+ details::bpp_macro macro_0;
+ macro_0.fName = "__false";
+ macro_0.fValue = "0";
+
+ kMacros.push_back(macro_0);
+
+ 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], "--version") == 0) {
+ printf("%s\n", "bpp v1.11, (c) Mahrouss Logic");
+ return 0;
+ }
+
+ if (strcmp(argv[index], "-h") == 0 ||
+ strcmp(argv[index], "--help") == 0) {
+ printf("%s\n", "bpp v1.11, (c) Mahrouss Logic");
+ printf("%s\n", "--working-dir: set directory to working path.");
+ printf("%s\n", "--include-dir: add directory to include path.");
+ printf("%s\n", "--define: define macro.");
+ printf("%s\n", "--version: print the version.");
+
+ return 0;
+ }
+
+ if (strcmp(argv[index], "--include-dir") == 0) {
+ std::string inc = argv[index + 1];
+
+ skip = true;
+
+ kIncludes.push_back(inc);
+ }
+
+ if (strcmp(argv[index], "--working-dir") == 0) {
+ std::string inc = argv[index + 1];
+ skip = true;
+ kWorkingDir = inc;
+ }
+
+ if (strcmp(argv[index], "--define") == 0 &&
+ argv[index + 1] != nullptr && argv[index + 2] != nullptr) {
+ std::string macro_key = argv[index + 1];
+
+ std::string 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 += "\"";
+
+ details::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 CXXKIT_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 0;
+ } catch (const std::runtime_error &e) {
+ std::cout << e.what() << '\n';
+ }
+
+ return 0;
}
-// Last rev 8-1-24 \ No newline at end of file
+// Last rev 8-1-24
diff --git a/Private/Toolchain/ccplus.cc b/Private/Toolchain/ccplus.cc
index 91e8a28..092e30a 100644
--- a/Private/Toolchain/ccplus.cc
+++ b/Private/Toolchain/ccplus.cc
@@ -9,16 +9,16 @@
/// bugs: ?
+#include <uuid/uuid.h>
+
+#include <CompilerKit/AsmKit/Arch/64x0.hpp>
+#include <CompilerKit/ParserKit.hpp>
#include <cstdio>
-#include <vector>
-#include <string>
#include <fstream>
#include <iostream>
-#include <stack>
+#include <string>
#include <utility>
-#include <uuid/uuid.h>
-#include <CompilerKit/AsmKit/Arch/64x0.hpp>
-#include <CompilerKit/ParserKit.hpp>
+#include <vector>
#define kOk 0
@@ -46,82 +46,74 @@
/////////////////////////////////////
-namespace detail
-{
- struct CompilerRegisterMap final
- {
- std::string fName;
- std::string fReg;
- };
+namespace detail {
+struct CompilerRegisterMap final {
+ std::string fName;
+ std::string fReg;
+};
- // \brief Offset based struct/class
- struct CompilerStructMap final
- {
- std::string fName;
- std::string fReg;
-
- // offset counter
- std::size_t fOffsetsCnt;
-
- // offset array
- std::vector<std::pair<Int32, std::string>> fOffsets;
- };
+// \brief Offset based struct/class
+struct CompilerStructMap final {
+ std::string fName;
+ std::string fReg;
- struct CompilerState final
- {
- std::vector<ParserKit::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- ParserKit::SyntaxLeafList* fSyntaxTree{ nullptr };
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool kVerbose;
- };
-}
+ // offset counter
+ std::size_t fOffsetsCnt;
+
+ // offset array
+ std::vector<std::pair<Int32, std::string>> fOffsets;
+};
+
+struct CompilerState final {
+ std::vector<ParserKit::SyntaxLeafList> fSyntaxTreeList;
+ std::vector<CompilerRegisterMap> kStackFrame;
+ std::vector<CompilerStructMap> kStructMap;
+ ParserKit::SyntaxLeafList* fSyntaxTree{nullptr};
+ std::unique_ptr<std::ofstream> fOutputAssembly;
+ std::string fLastFile;
+ std::string fLastError;
+ bool kVerbose;
+};
+} // namespace detail
static detail::CompilerState kState;
static SizeType kErrorLimit = 100;
static Int32 kAcceptableErrors = 0;
-namespace detail
-{
- void print_error(std::string reason, std::string file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
-
- if (file.find(".pp") != std::string::npos)
- {
- file.erase(file.find(".pp"), 3);
- }
+namespace detail {
+void print_error(std::string reason, std::string file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- if (kState.fLastFile != file)
- {
- std::cout << kRed << "[ ccplus ] " << kWhite << ((file == "ccplus") ? "internal compiler error " : ("in file, " + file)) << kBlank << std::endl;
- std::cout << kRed << "[ ccplus ] " << kWhite << reason << kBlank << std::endl;
+ if (file.find(".pp") != std::string::npos) {
+ file.erase(file.find(".pp"), 3);
+ }
- kState.fLastFile = file;
- }
- else
- {
- std::cout << kRed << "[ ccplus ] [ " << kState.fLastFile << " ] " << kWhite << reason << kBlank << std::endl;
- }
+ if (kState.fLastFile != file) {
+ std::cout << kRed << "[ ccplus ] " << kWhite
+ << ((file == "ccplus") ? "internal compiler error "
+ : ("in file, " + file))
+ << kBlank << std::endl;
+ std::cout << kRed << "[ ccplus ] " << kWhite << reason << kBlank
+ << std::endl;
- if (kAcceptableErrors > kErrorLimit)
- std::exit(3);
+ kState.fLastFile = file;
+ } else {
+ std::cout << kRed << "[ ccplus ] [ " << kState.fLastFile << " ] " << kWhite
+ << reason << kBlank << std::endl;
+ }
- ++kAcceptableErrors;
- }
+ if (kAcceptableErrors > kErrorLimit) std::exit(3);
- struct CompilerType
- {
- std::string fName;
- std::string fValue;
- };
+ ++kAcceptableErrors;
}
+struct CompilerType {
+ std::string fName;
+ std::string fValue;
+};
+} // namespace detail
+
/////////////////////////////////////////////////////////////////////////////////////////
// Target architecture.
@@ -155,41 +147,36 @@ static bool kInBraces = false;
static size_t kBracesCount = 0UL;
/* @brief C compiler backend for Mahrouss Logic C */
-class CompilerBackendClang final : public ParserKit::CompilerBackend
-{
-public:
- explicit CompilerBackendClang() = default;
- ~CompilerBackendClang() override = default;
+class CompilerBackendClang final : public ParserKit::CompilerBackend {
+ public:
+ explicit CompilerBackendClang() = default;
+ ~CompilerBackendClang() override = default;
- CXXKIT_COPY_DEFAULT(CompilerBackendClang);
+ CXXKIT_COPY_DEFAULT(CompilerBackendClang);
- bool Compile(const std::string& text, const char* file) override;
-
- const char* Language() override { return "64x0 C++, Generic MP/UX/h-core target."; }
+ bool Compile(const std::string& text, const char* file) override;
+ const char* Language() override {
+ return "64x0 C++, Generic MP/UX/h-core target.";
+ }
};
/// compiler variables
-static CompilerBackendClang* kCompilerBackend = nullptr;
-static std::vector<detail::CompilerType> kCompilerVariables;
-static std::vector<std::string> kCompilerFunctions;
+static CompilerBackendClang* kCompilerBackend = nullptr;
+static std::vector<detail::CompilerType> kCompilerVariables;
+static std::vector<std::string> kCompilerFunctions;
/// detail namespaces
-namespace detail
-{
- union number_cast final
- {
- number_cast(UInt64 raw)
- : raw(raw)
- {}
-
- char number[8];
- UInt64 raw;
-
- };
-}
+namespace detail {
+union number_cast final {
+ number_cast(UInt64 raw) : raw(raw) {}
+
+ char number[8];
+ UInt64 raw;
+};
+} // namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
@@ -198,46 +185,41 @@ namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
-bool CompilerBackendClang::Compile(const std::string& text, const char* file)
-{
- if (text.empty())
- return false;
+bool CompilerBackendClang::Compile(const std::string& text, const char* file) {
+ if (text.empty()) return false;
- // if (expr)
- // int name = expr;
- // expr;
+ // if (expr)
+ // int name = expr;
+ // expr;
- std::size_t index = 0UL;
+ std::size_t index = 0UL;
- auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf();
+ auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf();
- syntax_tree.fUserData = text;
- kState.fSyntaxTree->fLeafList.emplace_back(syntax_tree);
+ syntax_tree.fUserData = text;
+ kState.fSyntaxTree->fLeafList.emplace_back(syntax_tree);
- std::string text_cpy = text;
+ std::string text_cpy = text;
- std::vector<std::pair<std::string, std::size_t>> keywords_list;
+ std::vector<std::pair<std::string, std::size_t>> keywords_list;
- for (auto& keyword : kKeywords)
- {
- while (text_cpy.find(keyword) != std::string::npos)
- {
- keywords_list.emplace_back(std::make_pair(keyword, index));
- ++index;
+ for (auto& keyword : kKeywords) {
+ while (text_cpy.find(keyword) != std::string::npos) {
+ keywords_list.emplace_back(std::make_pair(keyword, index));
+ ++index;
- text_cpy.erase(text_cpy.find(keyword), keyword.size());
- }
+ text_cpy.erase(text_cpy.find(keyword), keyword.size());
}
+ }
- // TODO: sort keywords
+ // TODO: sort keywords
- for (auto& keyword : keywords_list)
- {
- syntax_tree.fUserData = keyword.first;
- kState.fSyntaxTree->fLeafList.emplace_back(syntax_tree);
- }
+ for (auto& keyword : keywords_list) {
+ syntax_tree.fUserData = keyword.first;
+ kState.fSyntaxTree->fLeafList.emplace_back(syntax_tree);
+ }
- return true;
+ return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -248,551 +230,483 @@ bool CompilerBackendClang::Compile(const std::string& text, const char* file)
/////////////////////////////////////////////////////////////////////////////////////////
-class AssemblyMountpointClang final : public CompilerKit::AssemblyMountpoint
-{
-public:
- explicit AssemblyMountpointClang() = default;
- ~AssemblyMountpointClang() override = default;
+class AssemblyMountpointClang final : public CompilerKit::AssemblyMountpoint {
+ public:
+ explicit AssemblyMountpointClang() = default;
+ ~AssemblyMountpointClang() override = default;
- CXXKIT_COPY_DEFAULT(AssemblyMountpointClang);
+ CXXKIT_COPY_DEFAULT(AssemblyMountpointClang);
- [[maybe_unused]] static Int32 Arch() noexcept { return CompilerKit::AssemblyFactory::kArchRISCV; }
+ [[maybe_unused]] static Int32 Arch() noexcept {
+ return CompilerKit::AssemblyFactory::kArchRISCV;
+ }
- Int32 CompileToFormat(CompilerKit::StringView& src, Int32 arch) override
- {
- if (arch != AssemblyMountpointClang::Arch())
- return -1;
+ Int32 CompileToFormat(CompilerKit::StringView& src, Int32 arch) override {
+ if (arch != AssemblyMountpointClang::Arch()) return -1;
- if (kCompilerBackend == nullptr)
- return -1;
+ if (kCompilerBackend == nullptr) return -1;
- /* @brief copy contents wihtout extension */
- std::string src_file = src.CData();
- std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
- std::string dest;
+ /* @brief copy contents wihtout extension */
+ std::string src_file = src.CData();
+ std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
+ std::string dest;
- for (auto& ch : src_file)
- {
- if (ch == '.')
- {
- break;
- }
+ for (auto& ch : src_file) {
+ if (ch == '.') {
+ break;
+ }
- dest += ch;
- }
+ dest += ch;
+ }
- /* According to pef abi. */
+ /* According to pef abi. */
- std::vector<const char*> exts = kAsmFileExts;
- dest += exts[0];
+ std::vector<const char*> exts = kAsmFileExts;
+ dest += exts[0];
- kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
+ kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
- auto fmt = CompilerKit::current_date();
+ auto fmt = CompilerKit::current_date();
- (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
- (*kState.fOutputAssembly) << "# Language: RISC 64x0 MP-UX Assembly (Generated from C++)\n";
- (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n";
+ (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
+ (*kState.fOutputAssembly)
+ << "# Language: RISC 64x0 MP-UX Assembly (Generated from C++)\n";
+ (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n";
- ParserKit::SyntaxLeafList syntax;
+ ParserKit::SyntaxLeafList syntax;
- kState.fSyntaxTreeList.emplace_back(syntax);
- kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
+ kState.fSyntaxTreeList.emplace_back(syntax);
+ kState.fSyntaxTree =
+ &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
- std::string source;
+ std::string source;
- while (std::getline(src_fp, source))
- {
- // compile into AST.
- kCompilerBackend->Compile(source.c_str(), src.CData());
- }
+ while (std::getline(src_fp, source)) {
+ // compile into AST.
+ kCompilerBackend->Compile(source.c_str(), src.CData());
+ }
+
+ if (kAcceptableErrors > 0) return -1;
- if (kAcceptableErrors > 0)
- return -1;
+ std::vector<std::string> lines;
- std::vector<std::string> lines;
-
- // \brief compiler scope type.
- struct scope_type
- {
- std::vector<std::string> vals;
- std::size_t reg_cnt{ kRegisterCounter };
- std::size_t id{ 0 };
+ // \brief compiler scope type.
+ struct scope_type {
+ std::vector<std::string> vals;
+ std::size_t reg_cnt{kRegisterCounter};
+ std::size_t id{0};
+
+ bool operator==(const scope_type& typ) const { return typ.id == id; }
+ };
- bool operator==(const scope_type& typ) const { return typ.id == id; }
- };
+ std::vector<scope_type> scope;
+ scope.emplace_back();
- std::vector<scope_type> scope;
+ bool found_type = false;
+ bool is_pointer = false;
+ bool found_expr = false;
+ bool found_func = false;
+ bool is_access_field = false;
+ std::string type;
+
+ for (auto& leaf : kState.fSyntaxTree->fLeafList) {
+ if (leaf.fUserData == "{") {
scope.emplace_back();
+ }
+
+ if (leaf.fUserData == "{") {
+ kRegisterCounter = kStartUsable;
+ scope.pop_back();
+ }
+
+ if (leaf.fUserData == "int" || leaf.fUserData == "long" ||
+ leaf.fUserData == "unsigned" || leaf.fUserData == "short" ||
+ leaf.fUserData == "char" || leaf.fUserData == "struct" ||
+ leaf.fUserData == "class") {
+ type += leaf.fUserData;
+ found_type = true;
+ }
+
+ if (leaf.fUserData == "(") {
+ if (found_type) {
+ found_expr = true;
+ found_type = false;
+ is_pointer = false;
+ }
+ }
- bool found_type = false;
- bool is_pointer = false;
- bool found_expr = false;
- bool found_func = false;
- bool is_access_field = false;
- std::string type;
-
- for (auto& leaf : kState.fSyntaxTree->fLeafList)
- {
- if (leaf.fUserData == "{")
- {
- scope.emplace_back();
- }
+ if (leaf.fUserData == ";") {
+ is_access_field = false;
+ }
- if (leaf.fUserData == "{")
- {
- kRegisterCounter = kStartUsable;
- scope.pop_back();
- }
+ if (leaf.fUserData.find(" this") != std::string::npos) {
+ leaf.fUserData.replace(leaf.fUserData.find(" this"), strlen(" this"),
+ "r6");
+ is_access_field = true;
+ }
- if (leaf.fUserData == "int" ||
- leaf.fUserData == "long" ||
- leaf.fUserData == "unsigned" ||
- leaf.fUserData == "short" ||
- leaf.fUserData == "char" ||
- leaf.fUserData == "struct" ||
- leaf.fUserData == "class")
- {
- type += leaf.fUserData;
- found_type = true;
- }
+ if (leaf.fUserData.find("->") != std::string::npos) {
+ leaf.fUserData.replace(leaf.fUserData.find("->"), strlen("->"), ", ");
- if (leaf.fUserData == "(")
- {
- if (found_type)
- {
- found_expr = true;
- found_type = false;
- is_pointer = false;
- }
- }
+ is_access_field = true;
+ }
- if (leaf.fUserData == ";")
- {
- is_access_field = false;
- }
+ if (leaf.fUserData == ")") {
+ if (found_expr) {
+ found_expr = false;
+ is_pointer = false;
+ } else {
+ leaf.fUserValue = "export .text _CppZ_MPUX_";
- if (leaf.fUserData.find(" this") != std::string::npos)
- {
- leaf.fUserData.replace(leaf.fUserData.find(" this"), strlen(" this"), "r6");
- is_access_field = true;
- }
+ for (auto& line : lines) {
+ if (line.find(type) != std::string::npos &&
+ line.find("(") != std::string::npos) {
+ auto fn_name = line.substr(line.find(type), line.find("("));
- if (leaf.fUserData.find("->") != std::string::npos)
- {
- leaf.fUserData.replace(leaf.fUserData.find("->"), strlen("->"), ", ");
-
- is_access_field = true;
- }
+ while (fn_name.find(' ') != std::string::npos)
+ fn_name.replace(fn_name.find(' '), 1, "@");
- if (leaf.fUserData == ")")
- {
- if (found_expr)
- {
- found_expr = false;
- is_pointer = false;
- }
- else
- {
- leaf.fUserValue = "export .text _CppZ_MPUX_";
-
- for (auto& line : lines)
- {
- if (line.find(type) != std::string::npos &&
- line.find("(") != std::string::npos)
- {
- auto fn_name = line.substr(line.find(type), line.find("("));
-
- while (fn_name.find(' ') != std::string::npos)
- fn_name.replace(fn_name.find(' '), 1, "@");
-
- leaf.fUserValue += fn_name;
-
- break;
- }
- }
-
- leaf.fUserValue += "\n";
-
- found_func = true;
- }
+ leaf.fUserValue += fn_name;
+
+ break;
}
+ }
- if (leaf.fUserData == ",")
- {
- if (is_pointer)
- {
- is_pointer = false;
- }
+ leaf.fUserValue += "\n";
- auto& front = scope.front();
+ found_func = true;
+ }
+ }
- std::string reg = "r";
- reg += std::to_string(front.reg_cnt);
- ++front.reg_cnt;
+ if (leaf.fUserData == ",") {
+ if (is_pointer) {
+ is_pointer = false;
+ }
- front.vals.push_back(reg);
- }
+ auto& front = scope.front();
- if (leaf.fUserData == "*" ||
- leaf.fUserData == "&")
- {
- if (found_type && !found_expr)
- is_pointer = true;
- }
+ std::string reg = "r";
+ reg += std::to_string(front.reg_cnt);
+ ++front.reg_cnt;
- if (leaf.fUserData == "=")
- {
- if (found_type)
- {
- auto& front = scope.front();
+ front.vals.push_back(reg);
+ }
- std::string reg = "r";
- reg += std::to_string(front.reg_cnt);
- ++front.reg_cnt;
+ if (leaf.fUserData == "*" || leaf.fUserData == "&") {
+ if (found_type && !found_expr) is_pointer = true;
+ }
- front.vals.push_back(reg);
+ if (leaf.fUserData == "=") {
+ if (found_type) {
+ auto& front = scope.front();
- leaf.fUserValue = !is_pointer ? "ldw %s, %s1\n" : "lda %s, %s1\n";
+ std::string reg = "r";
+ reg += std::to_string(front.reg_cnt);
+ ++front.reg_cnt;
- for (auto& ln : lines)
- {
- if (ln.find(leaf.fUserData) != std::string::npos &&
- ln.find(";") != std::string::npos)
- {
- auto val = ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size());
+ front.vals.push_back(reg);
- if (val.find(";") != std::string::npos)
- val.erase(val.find(";"), 1);
+ leaf.fUserValue = !is_pointer ? "ldw %s, %s1\n" : "lda %s, %s1\n";
- while (val.find(" ") != std::string::npos)
- val.erase(val.find(" "), 1);
+ for (auto& ln : lines) {
+ if (ln.find(leaf.fUserData) != std::string::npos &&
+ ln.find(";") != std::string::npos) {
+ auto val =
+ ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size());
- if (isalnum(val[0]) &&
- !isdigit(val[0]) &&
- ln.find("r6") == std::string::npos)
- val.insert(0, "import ");
+ if (val.find(";") != std::string::npos)
+ val.erase(val.find(";"), 1);
- leaf.fUserValue.replace(leaf.fUserValue.find("%s1"), strlen("%s1"), val);
- }
- }
+ while (val.find(" ") != std::string::npos)
+ val.erase(val.find(" "), 1);
- leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), reg);
+ if (isalnum(val[0]) && !isdigit(val[0]) &&
+ ln.find("r6") == std::string::npos)
+ val.insert(0, "import ");
- found_type = false;
- }
- else
- {
- leaf.fUserValue = !is_pointer ? "ldw %s, %s1\n" : "lda 0(%s), %s1\n";
-
- for (auto& ln : lines)
- {
- if (ln.find(leaf.fUserData) != std::string::npos &&
- ln.find(";") != std::string::npos)
- {
- std::string nm;
- for (auto i = ln.find('=') + 1; i < ln.size(); ++i)
- {
- if (ln[i] == ';')
- break;
-
- nm.push_back(ln[i]);
- }
-
- if (!nm.empty())
- {
- leaf.fUserValue.replace(leaf.fUserValue.find("%s1"), strlen("%s1"), nm);
- break;
- }
- }
- }
-
- auto& front = scope.front();
-
- std::string reg = "r";
- reg += std::to_string(front.reg_cnt);
- ++front.reg_cnt;
-
- leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), reg);
-
- front.vals.push_back(reg);
-
- if (is_pointer)
- {
- is_pointer = false;
- }
- }
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s1"),
+ strlen("%s1"), val);
}
+ }
- if (leaf.fUserData == "return")
- {
- leaf.fUserValue = "mv r1, %s\njlr";
-
- if (!lines.empty())
- {
- for (auto& ln : lines)
- {
- if (ln.find(leaf.fUserData) != std::string::npos &&
- ln.find(";") != std::string::npos)
- {
- auto val = ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size());
- val.erase(val.find(";"), 1);
-
- std::string val_reg;
- std::size_t reg_cnt = kRegisterCounter;
-
- for (int i = ln.find(leaf.fUserData) + leaf.fUserData.size(); i < ln.size(); ++i)
- {
- try
- {
- if (ln[i] == ',' ||
- ln[i] == '+' ||
- ln[i] == '/' ||
- ln[i] == '-' ||
- ln[i] == '*' ||
- ln[i] == '|' ||
- ln[i] == '&' ||
- ln[i] == '&' ||
- ln[i] == '|' ||
- ln[i] == ';')
- {
- val.replace(val.find(val_reg), val_reg.size(), "r" + std::to_string(reg_cnt));
- val_reg.clear();
- ++reg_cnt;
-
- continue;
- }
- }
- catch (...)
- {
-
- }
-
- if (isalnum(ln[i]))
- val_reg += ln[i];
- }
-
- while (val.find(" ") != std::string::npos)
- val.erase(val.find(" "), 1);
-
- leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), val);
- }
- }
- }
- else
- {
- leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), "0");
- }
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"),
+ reg);
+
+ found_type = false;
+ } else {
+ leaf.fUserValue = !is_pointer ? "ldw %s, %s1\n" : "lda 0(%s), %s1\n";
+
+ for (auto& ln : lines) {
+ if (ln.find(leaf.fUserData) != std::string::npos &&
+ ln.find(";") != std::string::npos) {
+ std::string nm;
+ for (auto i = ln.find('=') + 1; i < ln.size(); ++i) {
+ if (ln[i] == ';') break;
- continue;
+ nm.push_back(ln[i]);
+ }
+
+ if (!nm.empty()) {
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s1"),
+ strlen("%s1"), nm);
+ break;
+ }
}
+ }
+
+ auto& front = scope.front();
+
+ std::string reg = "r";
+ reg += std::to_string(front.reg_cnt);
+ ++front.reg_cnt;
- lines.emplace_back(leaf.fUserData);
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"),
+ reg);
+
+ front.vals.push_back(reg);
+
+ if (is_pointer) {
+ is_pointer = false;
+ }
}
+ }
+
+ if (leaf.fUserData == "return") {
+ leaf.fUserValue = "mv r1, %s\njlr";
+
+ if (!lines.empty()) {
+ for (auto& ln : lines) {
+ if (ln.find(leaf.fUserData) != std::string::npos &&
+ ln.find(";") != std::string::npos) {
+ auto val =
+ ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size());
+ val.erase(val.find(";"), 1);
+
+ std::string val_reg;
+ std::size_t reg_cnt = kRegisterCounter;
+
+ for (int i = ln.find(leaf.fUserData) + leaf.fUserData.size();
+ i < ln.size(); ++i) {
+ try {
+ if (ln[i] == ',' || ln[i] == '+' || ln[i] == '/' ||
+ ln[i] == '-' || ln[i] == '*' || ln[i] == '|' ||
+ ln[i] == '&' || ln[i] == '&' || ln[i] == '|' ||
+ ln[i] == ';') {
+ val.replace(val.find(val_reg), val_reg.size(),
+ "r" + std::to_string(reg_cnt));
+ val_reg.clear();
+ ++reg_cnt;
+
+ continue;
+ }
+ } catch (...) {
+ }
- for (auto& leaf : kState.fSyntaxTree->fLeafList)
- {
- (*kState.fOutputAssembly) << leaf.fUserValue;
+ if (isalnum(ln[i])) val_reg += ln[i];
+ }
+
+ while (val.find(" ") != std::string::npos)
+ val.erase(val.find(" "), 1);
+
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"),
+ val);
+ }
+ }
+ } else {
+ leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"),
+ "0");
}
- kState.fSyntaxTree = nullptr;
+ continue;
+ }
- kState.fOutputAssembly->flush();
- kState.fOutputAssembly.reset();
+ lines.emplace_back(leaf.fUserData);
+ }
- return kOk;
+ for (auto& leaf : kState.fSyntaxTree->fLeafList) {
+ (*kState.fOutputAssembly) << leaf.fUserValue;
}
+ kState.fSyntaxTree = nullptr;
+
+ kState.fOutputAssembly->flush();
+ kState.fOutputAssembly.reset();
+
+ return kOk;
+ }
};
/////////////////////////////////////////////////////////////////////////////////////////
#define kPrintF printf
-#define kSplashCxx() kPrintF(kWhite "%s\n", "ccplus, v1.15, (c) Mahrouss Logic.")
-
-static void cxx_print_help()
-{
- kSplashCxx();
- kPrintF(kWhite "--asm={ASSEMBLER}: %s\n", "Compile with a specific syntax. (64x0, 32x0)");
- kPrintF(kWhite "--compiler={COMPILER}: %s\n", "Select compiler engine (builtin -> vanhalen).");
+#define kSplashCxx() \
+ kPrintF(kWhite "%s\n", "ccplus, v1.15, (c) Mahrouss Logic.")
+
+static void cxx_print_help() {
+ kSplashCxx();
+ kPrintF(kWhite "--asm={ASSEMBLER}: %s\n",
+ "Compile with a specific syntax. (64x0, 32x0)");
+ kPrintF(kWhite "--compiler={COMPILER}: %s\n",
+ "Select compiler engine (builtin -> vanhalen).");
}
/////////////////////////////////////////////////////////////////////////////////////////
-#define kExt { ".cpp", ".cxx", ".cc", ".c++" }
-
-MPCC_MODULE(CompilerCPlusPlus64x0)
-{
- kKeywords.emplace_back("auto");
- kKeywords.emplace_back("else");
- kKeywords.emplace_back("break");
- kKeywords.emplace_back("switch");
- kKeywords.emplace_back("enum");
- kKeywords.emplace_back("register");
- kKeywords.emplace_back("do");
- kKeywords.emplace_back("return");
- kKeywords.emplace_back("if");
- kKeywords.emplace_back("default");
- kKeywords.emplace_back("struct");
- kKeywords.emplace_back("_Packed");
- kKeywords.emplace_back("extern");
- kKeywords.emplace_back("volatile");
- kKeywords.emplace_back("static");
- kKeywords.emplace_back("for");
- kKeywords.emplace_back("class");
- kKeywords.emplace_back("{");
- kKeywords.emplace_back("}");
- kKeywords.emplace_back("(");
- kKeywords.emplace_back(")");
- kKeywords.emplace_back("char");
- kKeywords.emplace_back("int");
- kKeywords.emplace_back("short");
- kKeywords.emplace_back("long");
- kKeywords.emplace_back("float");
- kKeywords.emplace_back("double");
- kKeywords.emplace_back("unsigned");
- kKeywords.emplace_back("__export__");
- kKeywords.emplace_back("__import__");
- kKeywords.emplace_back("__packed__");
- kKeywords.emplace_back("namespace");
- kKeywords.emplace_back("while");
- kKeywords.emplace_back("sizeof");
- kKeywords.emplace_back("private");
- kKeywords.emplace_back("->");
- kKeywords.emplace_back(".");
- kKeywords.emplace_back("::");
- kKeywords.emplace_back("*");
- kKeywords.emplace_back("+");
- kKeywords.emplace_back("-");
- kKeywords.emplace_back("/");
- kKeywords.emplace_back("=");
- kKeywords.emplace_back("==");
- kKeywords.emplace_back("!=");
- kKeywords.emplace_back(">=");
- kKeywords.emplace_back("<=");
- kKeywords.emplace_back(">");
- kKeywords.emplace_back("<");
- kKeywords.emplace_back(":");
- kKeywords.emplace_back(",");
- kKeywords.emplace_back(";");
- kKeywords.emplace_back("&");
- kKeywords.emplace_back("public");
- kKeywords.emplace_back("protected");
-
- bool skip = false;
-
- for (auto index = 1UL; index < argc; ++index)
- {
- if (skip)
- {
- skip = false;
- continue;
- }
+#define kExt \
+ { ".cpp", ".cxx", ".cc", ".c++" }
+
+MPCC_MODULE(CompilerCPlusPlus64x0) {
+ kKeywords.emplace_back("auto");
+ kKeywords.emplace_back("else");
+ kKeywords.emplace_back("break");
+ kKeywords.emplace_back("switch");
+ kKeywords.emplace_back("enum");
+ kKeywords.emplace_back("register");
+ kKeywords.emplace_back("do");
+ kKeywords.emplace_back("return");
+ kKeywords.emplace_back("if");
+ kKeywords.emplace_back("default");
+ kKeywords.emplace_back("struct");
+ kKeywords.emplace_back("_Packed");
+ kKeywords.emplace_back("extern");
+ kKeywords.emplace_back("volatile");
+ kKeywords.emplace_back("static");
+ kKeywords.emplace_back("for");
+ kKeywords.emplace_back("class");
+ kKeywords.emplace_back("{");
+ kKeywords.emplace_back("}");
+ kKeywords.emplace_back("(");
+ kKeywords.emplace_back(")");
+ kKeywords.emplace_back("char");
+ kKeywords.emplace_back("int");
+ kKeywords.emplace_back("short");
+ kKeywords.emplace_back("long");
+ kKeywords.emplace_back("float");
+ kKeywords.emplace_back("double");
+ kKeywords.emplace_back("unsigned");
+ kKeywords.emplace_back("__export__");
+ kKeywords.emplace_back("__import__");
+ kKeywords.emplace_back("__packed__");
+ kKeywords.emplace_back("namespace");
+ kKeywords.emplace_back("while");
+ kKeywords.emplace_back("sizeof");
+ kKeywords.emplace_back("private");
+ kKeywords.emplace_back("->");
+ kKeywords.emplace_back(".");
+ kKeywords.emplace_back("::");
+ kKeywords.emplace_back("*");
+ kKeywords.emplace_back("+");
+ kKeywords.emplace_back("-");
+ kKeywords.emplace_back("/");
+ kKeywords.emplace_back("=");
+ kKeywords.emplace_back("==");
+ kKeywords.emplace_back("!=");
+ kKeywords.emplace_back(">=");
+ kKeywords.emplace_back("<=");
+ kKeywords.emplace_back(">");
+ kKeywords.emplace_back("<");
+ kKeywords.emplace_back(":");
+ kKeywords.emplace_back(",");
+ kKeywords.emplace_back(";");
+ kKeywords.emplace_back("&");
+ kKeywords.emplace_back("public");
+ kKeywords.emplace_back("protected");
+
+ bool skip = false;
+
+ for (auto index = 1UL; index < argc; ++index) {
+ if (skip) {
+ skip = false;
+ continue;
+ }
- if (argv[index][0] == '-')
- {
- if (strcmp(argv[index], "-v") == 0 ||
- strcmp(argv[index], "--version") == 0)
- {
- kSplashCxx();
- return kOk;
- }
+ if (argv[index][0] == '-') {
+ if (strcmp(argv[index], "-v") == 0 ||
+ strcmp(argv[index], "--version") == 0) {
+ kSplashCxx();
+ return kOk;
+ }
- if (strcmp(argv[index], "-verbose") == 0)
- {
- kState.kVerbose = true;
+ if (strcmp(argv[index], "-verbose") == 0) {
+ kState.kVerbose = true;
- continue;
- }
+ continue;
+ }
- if (strcmp(argv[index], "-h") == 0 ||
- strcmp(argv[index], "--help") == 0)
- {
- cxx_print_help();
+ if (strcmp(argv[index], "-h") == 0 ||
+ strcmp(argv[index], "--help") == 0) {
+ cxx_print_help();
- return kOk;
- }
+ return kOk;
+ }
- if (strcmp(argv[index], "--dialect") == 0)
- {
- if (kCompilerBackend)
- std::cout << kCompilerBackend->Language() << "\n";
+ if (strcmp(argv[index], "--dialect") == 0) {
+ if (kCompilerBackend) std::cout << kCompilerBackend->Language() << "\n";
- return kOk;
- }
+ return kOk;
+ }
- if (strcmp(argv[index], "--asm=masm") == 0)
- {
- delete kFactory.Unmount();
+ if (strcmp(argv[index], "--asm=masm") == 0) {
+ delete kFactory.Unmount();
- kFactory.Mount(new AssemblyMountpointClang());
- kMachine = CompilerKit::AssemblyFactory::kArchRISCV;
+ kFactory.Mount(new AssemblyMountpointClang());
+ kMachine = CompilerKit::AssemblyFactory::kArch64x0;
- continue;
- }
+ continue;
+ }
- if (strcmp(argv[index], "--compiler=vanhalen") == 0)
- {
- if (!kCompilerBackend)
- kCompilerBackend = new CompilerBackendClang();
+ if (strcmp(argv[index], "--compiler=vanhalen") == 0) {
+ if (!kCompilerBackend) kCompilerBackend = new CompilerBackendClang();
- continue;
- }
+ continue;
+ }
- if (strcmp(argv[index], "-fmax-exceptions") == 0)
- {
- try
- {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...)
- {
- kErrorLimit = 0;
- }
+ if (strcmp(argv[index], "-fmax-exceptions") == 0) {
+ try {
+ kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
+ }
+ // catch anything here
+ catch (...) {
+ kErrorLimit = 0;
+ }
- skip = true;
+ skip = true;
- continue;
- }
+ continue;
+ }
- std::string err = "Unknown option: ";
- err += argv[index];
+ std::string err = "Unknown option: ";
+ err += argv[index];
- detail::print_error(err, "ccplus");
+ detail::print_error(err, "ccplus");
- continue;
- }
+ continue;
+ }
- kFileList.emplace_back(argv[index]);
+ kFileList.emplace_back(argv[index]);
- CompilerKit::StringView srcFile = CompilerKit::StringBuilder::Construct(argv[index]);
+ CompilerKit::StringView srcFile =
+ CompilerKit::StringBuilder::Construct(argv[index]);
- std::vector exts = kExt;
- std::string argv_i = argv[index];
+ std::vector exts = kExt;
+ std::string argv_i = argv[index];
- for (std::string ext : exts)
- {
- if (argv_i.find(ext) != std::string::npos)
- {
- if (kState.kVerbose)
- {
- std::cerr << argv[index] << " is not a valid C++ source.\n";
- }
-
- return -1;
- }
- else
- {
- break;
- }
+ for (std::string ext : exts) {
+ if (argv_i.find(ext) != std::string::npos) {
+ if (kState.kVerbose) {
+ std::cerr << argv[index] << " is not a valid C++ source.\n";
}
- if (kFactory.Compile(srcFile, kMachine) != kOk)
- return -1;
+ return -1;
+ } else {
+ break;
+ }
}
- return kOk;
+ if (kFactory.Compile(srcFile, kMachine) != kOk) return -1;
+ }
+
+ return kOk;
}
-// Last rev 8-1-24 \ No newline at end of file
+// Last rev 8-1-24
diff --git a/Private/Toolchain/compile_flags.txt b/Private/Toolchain/compile_flags.txt
new file mode 100644
index 0000000..9afc1ed
--- /dev/null
+++ b/Private/Toolchain/compile_flags.txt
@@ -0,0 +1,3 @@
+-std=c++20
+-I../
+-I../CompilerKit
diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc
index f23c3e9..1e3cde6 100644
--- a/Private/Toolchain/i64asm.cc
+++ b/Private/Toolchain/i64asm.cc
@@ -15,8 +15,8 @@
// @author Amlal El Mahrouss
// @brief AMD64 Assembler.
-// REMINDER: when dealing with an undefined symbol use (string size):LinkerFindSymbol:(string)
-// so that ld will look for it.
+// REMINDER: when dealing with an undefined symbol use (string
+// size):LinkerFindSymbol:(string) so that ld will look for it.
/////////////////////////////////////////////////////////////////////////////////////////
@@ -24,11 +24,11 @@
#include <CompilerKit/AsmKit/Arch/amd64.hpp>
#include <CompilerKit/ParserKit.hpp>
-#include <CompilerKit/StdKit/PEF.hpp>
#include <CompilerKit/StdKit/AE.hpp>
+#include <CompilerKit/StdKit/PEF.hpp>
#include <filesystem>
-#include <iostream>
#include <fstream>
+#include <iostream>
/////////////////////
@@ -60,10 +60,7 @@ static bool kVerbose = false;
static std::vector<e64_byte_t> kBytes;
static CompilerKit::AERecordHeader kCurrentRecord{
- .fName = "",
- .fKind = CompilerKit::kPefCode,
- .fSize = 0,
- .fOffset = 0};
+ .fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0};
static std::vector<CompilerKit::AERecordHeader> kRecords;
static std::vector<std::string> kUndefinedSymbols;
@@ -74,35 +71,32 @@ static const std::string kRelocSymbol = ":mld:";
// \brief forward decl.
static bool asm_read_attributes(std::string &line);
-namespace detail
-{
- void print_error(std::string reason, const std::string &file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
+namespace detail {
+void print_error(std::string reason, const std::string &file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- kStdErr << kRed << "[ i64asm ] " << kWhite << ((file == "i64asm") ? "internal assembler error " : ("in file, " + file)) << kBlank << std::endl;
- kStdErr << kRed << "[ i64asm ] " << kWhite << reason << kBlank << std::endl;
+ kStdErr << kRed << "[ i64asm ] " << kWhite
+ << ((file == "i64asm") ? "internal assembler error "
+ : ("in file, " + file))
+ << kBlank << std::endl;
+ kStdErr << kRed << "[ i64asm ] " << kWhite << reason << kBlank << std::endl;
- if (kAcceptableErrors > kErrorLimit)
- std::exit(3);
+ if (kAcceptableErrors > kErrorLimit) std::exit(3);
- ++kAcceptableErrors;
- }
+ ++kAcceptableErrors;
+}
- void print_warning(std::string reason, const std::string &file) noexcept
- {
- if (reason[0] == '\n')
- reason.erase(0, 1);
+void print_warning(std::string reason, const std::string &file) noexcept {
+ if (reason[0] == '\n') reason.erase(0, 1);
- if (!file.empty())
- {
- kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
- }
+ if (!file.empty()) {
+ kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
+ }
- kStdOut << kYellow << "[ i64asm ] " << kWhite << reason << kBlank << std::endl;
- }
+ kStdOut << kYellow << "[ i64asm ] " << kWhite << reason << kBlank
+ << std::endl;
}
+} // namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
@@ -110,269 +104,233 @@ namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
-MPCC_MODULE(MPUXAssemblerAMD64)
-{
- //////////////// CPU OPCODES BEGIN ////////////////
-
- std::string opcodes_jump[kJumpLimit] = {
- "ja", "jae", "jb", "jbe", "jc", "je", "jg", "jge",
- "jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng", "jnge",
- "jnl", "jnle", "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe", "jpo", "js", "jz"};
+MPCC_MODULE(MPUXAssemblerAMD64) {
+ //////////////// CPU OPCODES BEGIN ////////////////
- for (e64_hword_t i = 0; i < kJumpLimit; i++)
- {
- CpuCodeAMD64 code{.fName = opcodes_jump[i], .fOpcode = static_cast<e64_hword_t>(kAsmJumpOpcode + i)};
- kOpcodesAMD64.push_back(code);
- }
+ std::string opcodes_jump[kJumpLimit] = {
+ "ja", "jae", "jb", "jbe", "jc", "je", "jg", "jge", "jl", "jle",
+ "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng", "jnge", "jnl", "jnle",
+ "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe", "jpo", "js", "jz"};
- CpuCodeAMD64 code{.fName = "jcxz", .fOpcode = 0xE3};
+ for (e64_hword_t i = 0; i < kJumpLimit; i++) {
+ CpuCodeAMD64 code{.fName = opcodes_jump[i],
+ .fOpcode = static_cast<e64_hword_t>(kAsmJumpOpcode + i)};
kOpcodesAMD64.push_back(code);
+ }
- for (e64_hword_t i = kJumpLimitStandard; i < kJumpLimitStandardLimit; i++)
- {
- CpuCodeAMD64 code{.fName = "jmp", .fOpcode = i};
- kOpcodesAMD64.push_back(code);
- }
+ CpuCodeAMD64 code{.fName = "jcxz", .fOpcode = 0xE3};
+ kOpcodesAMD64.push_back(code);
- CpuCodeAMD64 lahf{.fName = "lahf", .fOpcode = 0x9F};
- kOpcodesAMD64.push_back(lahf);
+ for (e64_hword_t i = kJumpLimitStandard; i < kJumpLimitStandardLimit; i++) {
+ CpuCodeAMD64 code{.fName = "jmp", .fOpcode = i};
+ kOpcodesAMD64.push_back(code);
+ }
- CpuCodeAMD64 lds{.fName = "lds", .fOpcode = 0xC5};
- kOpcodesAMD64.push_back(lds);
+ CpuCodeAMD64 lahf{.fName = "lahf", .fOpcode = 0x9F};
+ kOpcodesAMD64.push_back(lahf);
- CpuCodeAMD64 lea{.fName = "lea", .fOpcode = 0x8D};
- kOpcodesAMD64.push_back(lea);
+ CpuCodeAMD64 lds{.fName = "lds", .fOpcode = 0xC5};
+ kOpcodesAMD64.push_back(lds);
- CpuCodeAMD64 mov{.fName = "nop", .fOpcode = 0x90};
- kOpcodesAMD64.push_back(mov);
+ CpuCodeAMD64 lea{.fName = "lea", .fOpcode = 0x8D};
+ kOpcodesAMD64.push_back(lea);
- //////////////// CPU OPCODES END ////////////////
+ CpuCodeAMD64 mov{.fName = "nop", .fOpcode = 0x90};
+ kOpcodesAMD64.push_back(mov);
- for (size_t i = 1; i < argc; ++i)
- {
- if (argv[i][0] == '-')
- {
- if (strcmp(argv[i], "-version") == 0 ||
- strcmp(argv[i], "-v") == 0)
- {
- kStdOut << "i64asm: AMD64 Assembler.\ni64asm: v1.10\ni64asm: Copyright (c) 2024 Mahrouss Logic.\n";
- return 0;
- }
- else if (strcmp(argv[i], "-h") == 0)
- {
- kStdOut << "i64asm: AMD64 Assembler.\ni64asm: Copyright (c) 2024 Mahrouss Logic.\n";
- kStdOut << "-version: Print program version.\n";
- kStdOut << "-verbose: Print verbose output.\n";
- kStdOut << "-binary: Output as flat binary.\n";
- kStdOut << "-64xxx: Compile for a subset of the X64000.\n";
-
- return 0;
- }
- else if (strcmp(argv[i], "-binary") == 0)
- {
- kOutputAsBinary = true;
- continue;
- }
- else if (strcmp(argv[i], "-verbose") == 0)
- {
- kVerbose = true;
- continue;
- }
+ //////////////// CPU OPCODES END ////////////////
- kStdOut << "i64asm: ignore " << argv[i] << "\n";
- continue;
- }
+ for (size_t i = 1; i < argc; ++i) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "-v") == 0) {
+ kStdOut << "i64asm: AMD64 Assembler.\ni64asm: v1.10\ni64asm: Copyright "
+ "(c) 2024 Mahrouss Logic.\n";
+ return 0;
+ } else if (strcmp(argv[i], "-h") == 0) {
+ kStdOut << "i64asm: AMD64 Assembler.\ni64asm: Copyright (c) 2024 "
+ "Mahrouss Logic.\n";
+ kStdOut << "-version: Print program version.\n";
+ kStdOut << "-verbose: Print verbose output.\n";
+ kStdOut << "-binary: Output as flat binary.\n";
+ kStdOut << "-64xxx: Compile for a subset of the X64000.\n";
- if (!std::filesystem::exists(argv[i]))
- {
- kStdOut << "i64asm: can't open: " << argv[i] << std::endl;
- goto asm_fail_exit;
- }
+ return 0;
+ } else if (strcmp(argv[i], "-binary") == 0) {
+ kOutputAsBinary = true;
+ continue;
+ } else if (strcmp(argv[i], "-verbose") == 0) {
+ kVerbose = true;
+ continue;
+ }
+
+ kStdOut << "i64asm: ignore " << argv[i] << "\n";
+ continue;
+ }
- std::string object_output(argv[i]);
+ if (!std::filesystem::exists(argv[i])) {
+ kStdOut << "i64asm: can't open: " << argv[i] << std::endl;
+ goto asm_fail_exit;
+ }
- for (auto &ext : kAsmFileExts)
- {
- if (object_output.find(ext) != std::string::npos)
- {
- object_output.erase(object_output.find(ext), std::strlen(ext));
- }
- }
+ std::string object_output(argv[i]);
- object_output += kObjectFileExt;
+ for (auto &ext : kAsmFileExts) {
+ if (object_output.find(ext) != std::string::npos) {
+ object_output.erase(object_output.find(ext), std::strlen(ext));
+ }
+ }
- std::ifstream file_ptr(argv[i]);
- std::ofstream file_ptr_out(object_output,
- std::ofstream::binary);
+ object_output += kObjectFileExt;
- if (file_ptr_out.bad())
- {
- if (kVerbose)
- {
- kStdOut << "i64asm: error: " << strerror(errno) << "\n";
- }
- }
+ std::ifstream file_ptr(argv[i]);
+ std::ofstream file_ptr_out(object_output, std::ofstream::binary);
- std::string line;
+ if (file_ptr_out.bad()) {
+ if (kVerbose) {
+ kStdOut << "i64asm: error: " << strerror(errno) << "\n";
+ }
+ }
- CompilerKit::AEHeader hdr{0};
+ std::string line;
- memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
+ CompilerKit::AEHeader hdr{0};
- hdr.fMagic[0] = kAEMag0;
- hdr.fMagic[1] = kAEMag1;
- hdr.fSize = sizeof(CompilerKit::AEHeader);
- hdr.fArch = kOutputArch;
+ memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
- /////////////////////////////////////////////////////////////////////////////////////////
+ hdr.fMagic[0] = kAEMag0;
+ hdr.fMagic[1] = kAEMag1;
+ hdr.fSize = sizeof(CompilerKit::AEHeader);
+ hdr.fArch = kOutputArch;
- // COMPILATION LOOP
+ /////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
+ // COMPILATION LOOP
- CompilerKit::PlatformAssemblerAMD64 asm64;
+ /////////////////////////////////////////////////////////////////////////////////////////
- while (std::getline(file_ptr, line))
- {
- if (auto ln = asm64.CheckLine(line, argv[i]);
- !ln.empty())
- {
- detail::print_error(ln, argv[i]);
- continue;
- }
+ CompilerKit::PlatformAssemblerAMD64 asm64;
- try
- {
- asm_read_attributes(line);
- asm64.WriteLine(line, argv[i]);
- }
- catch (const std::exception &e)
- {
- if (kVerbose)
- {
- std::string what = e.what();
- detail::print_warning("exit because of: " + what, "i64asm");
- }
-
- std::filesystem::remove(object_output);
- goto asm_fail_exit;
- }
+ while (std::getline(file_ptr, line)) {
+ if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) {
+ detail::print_error(ln, argv[i]);
+ continue;
+ }
+
+ try {
+ asm_read_attributes(line);
+ asm64.WriteLine(line, argv[i]);
+ } catch (const std::exception &e) {
+ if (kVerbose) {
+ std::string what = e.what();
+ detail::print_warning("exit because of: " + what, "i64asm");
}
- if (!kOutputAsBinary)
- {
- if (kVerbose)
- {
- kStdOut << "i64asm: Writing object file...\n";
- }
+ std::filesystem::remove(object_output);
+ goto asm_fail_exit;
+ }
+ }
- // this is the final step, write everything to the file.
+ if (!kOutputAsBinary) {
+ if (kVerbose) {
+ kStdOut << "i64asm: Writing object file...\n";
+ }
- auto pos = file_ptr_out.tellp();
+ // this is the final step, write everything to the file.
- hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
+ auto pos = file_ptr_out.tellp();
- file_ptr_out << hdr;
+ hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
- if (kRecords.empty())
- {
- kStdErr << "i64asm: At least one record is needed to write an object file.\ni64asm: Make one using `export .text foo_bar`.\n";
+ file_ptr_out << hdr;
- std::filesystem::remove(object_output);
- return -1;
- }
+ if (kRecords.empty()) {
+ kStdErr << "i64asm: At least one record is needed to write an object "
+ "file.\ni64asm: Make one using `export .text foo_bar`.\n";
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ std::filesystem::remove(object_output);
+ return -1;
+ }
- std::size_t record_count = 0UL;
+ kRecords[kRecords.size() - 1].fSize = kBytes.size();
- for (auto &rec : kRecords)
- {
- if (kVerbose)
- kStdOut << "i64asm: Wrote record " << rec.fName << " to file...\n";
+ std::size_t record_count = 0UL;
- rec.fFlags |= CompilerKit::kKindRelocationAtRuntime;
- rec.fOffset = record_count;
- ++record_count;
+ for (auto &rec : kRecords) {
+ if (kVerbose)
+ kStdOut << "i64asm: Wrote record " << rec.fName << " to file...\n";
- file_ptr_out << rec;
- }
+ rec.fFlags |= CompilerKit::kKindRelocationAtRuntime;
+ rec.fOffset = record_count;
+ ++record_count;
- // increment once again, so that we won't lie about the kUndefinedSymbols.
- ++record_count;
+ file_ptr_out << rec;
+ }
- for (auto &sym : kUndefinedSymbols)
- {
- CompilerKit::AERecordHeader _record_hdr{0};
+ // increment once again, so that we won't lie about the kUndefinedSymbols.
+ ++record_count;
- if (kVerbose)
- kStdOut << "i64asm: Wrote symbol " << sym << " to file...\n";
+ for (auto &sym : kUndefinedSymbols) {
+ CompilerKit::AERecordHeader _record_hdr{0};
- _record_hdr.fKind = kAEInvalidOpcode;
- _record_hdr.fSize = sym.size();
- _record_hdr.fOffset = record_count;
+ if (kVerbose)
+ kStdOut << "i64asm: Wrote symbol " << sym << " to file...\n";
- ++record_count;
+ _record_hdr.fKind = kAEInvalidOpcode;
+ _record_hdr.fSize = sym.size();
+ _record_hdr.fOffset = record_count;
- memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
- memcpy(_record_hdr.fName, sym.c_str(), sym.size());
+ ++record_count;
- file_ptr_out << _record_hdr;
+ memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
+ memcpy(_record_hdr.fName, sym.c_str(), sym.size());
- ++kCounter;
- }
+ file_ptr_out << _record_hdr;
- auto pos_end = file_ptr_out.tellp();
+ ++kCounter;
+ }
- file_ptr_out.seekp(pos);
+ auto pos_end = file_ptr_out.tellp();
- hdr.fStartCode = pos_end;
- hdr.fCodeSize = kBytes.size();
+ file_ptr_out.seekp(pos);
- file_ptr_out << hdr;
+ hdr.fStartCode = pos_end;
+ hdr.fCodeSize = kBytes.size();
- file_ptr_out.seekp(pos_end);
- }
- else
- {
- if (kVerbose)
- {
- kStdOut << "i64asm: Write raw binary...\n";
- }
- }
+ file_ptr_out << hdr;
- // byte from byte, we write this.
- for (auto &byte : kBytes)
- {
- if (byte == 0)
- continue;
+ file_ptr_out.seekp(pos_end);
+ } else {
+ if (kVerbose) {
+ kStdOut << "i64asm: Write raw binary...\n";
+ }
+ }
- if (byte == 0xFF)
- {
- byte = 0;
- }
+ // byte from byte, we write this.
+ for (auto &byte : kBytes) {
+ if (byte == 0) continue;
- file_ptr_out << reinterpret_cast<const char *>(&byte)[0];
- }
+ if (byte == 0xFF) {
+ byte = 0;
+ }
- if (kVerbose)
- kStdOut << "i64asm: Wrote file with program in it.\n";
+ file_ptr_out << reinterpret_cast<const char *>(&byte)[0];
+ }
- file_ptr_out.flush();
- file_ptr_out.close();
+ if (kVerbose) kStdOut << "i64asm: Wrote file with program in it.\n";
- if (kVerbose)
- kStdOut << "i64asm: Exit succeeded.\n";
+ file_ptr_out.flush();
+ file_ptr_out.close();
- return 0;
- }
+ if (kVerbose) kStdOut << "i64asm: Exit succeeded.\n";
+
+ return 0;
+ }
asm_fail_exit:
- if (kVerbose)
- kStdOut << "i64asm: Exit failed.\n";
+ if (kVerbose) kStdOut << "i64asm: Exit failed.\n";
- return -1;
+ return -1;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -382,165 +340,143 @@ asm_fail_exit:
/////////////////////////////////////////////////////////////////////////////////////////
-static bool asm_read_attributes(std::string &line)
-{
- // import is the opposite of export, it signals to the ld
- // that we need this symbol.
- if (ParserKit::find_word(line, "import "))
- {
- if (kOutputAsBinary)
- {
- detail::print_error("invalid import directive in flat binary mode.", "i64asm");
- throw std::runtime_error("invalid_import_bin");
- }
+static bool asm_read_attributes(std::string &line) {
+ // import is the opposite of export, it signals to the ld
+ // that we need this symbol.
+ if (ParserKit::find_word(line, "import ")) {
+ if (kOutputAsBinary) {
+ detail::print_error("invalid import directive in flat binary mode.",
+ "i64asm");
+ throw std::runtime_error("invalid_import_bin");
+ }
- auto name = line.substr(line.find("import ") + strlen("import "));
+ auto name = line.substr(line.find("import ") + strlen("import "));
- std::string result = std::to_string(name.size());
- result += kUndefinedSymbol;
+ std::string result = std::to_string(name.size());
+ result += kUndefinedSymbol;
- // mangle this
- for (char &j : name)
- {
- if (j == ' ' ||
- j == ',')
- j = '$';
- }
-
- result += name;
+ // mangle this
+ for (char &j : name) {
+ if (j == ' ' || j == ',') j = '$';
+ }
- if (name.find(".text") != std::string::npos)
- {
- // data is treated as code.
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
- else if (name.find(".data") != std::string::npos)
- {
- // no code will be executed from here.
- kCurrentRecord.fKind = CompilerKit::kPefData;
- }
- else if (name.find(".page_zero") != std::string::npos)
- {
- // this is a bss section.
- kCurrentRecord.fKind = CompilerKit::kPefZero;
- }
+ result += name;
+
+ if (name.find(".text") != std::string::npos) {
+ // data is treated as code.
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ } else if (name.find(".data") != std::string::npos) {
+ // no code will be executed from here.
+ kCurrentRecord.fKind = CompilerKit::kPefData;
+ } else if (name.find(".page_zero") != std::string::npos) {
+ // this is a bss section.
+ kCurrentRecord.fKind = CompilerKit::kPefZero;
+ }
- // this is a special case for the start stub.
- // we want this so that ld can find it.
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
- if (name == "__start")
- {
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
+ if (name == "__start") {
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ }
- // now we can tell the code size of the previous kCurrentRecord.
+ // now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty())
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, result.c_str(), result.size());
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, result.c_str(), result.size());
- ++kCounter;
+ ++kCounter;
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
- kRecords.emplace_back(kCurrentRecord);
+ kRecords.emplace_back(kCurrentRecord);
- return true;
+ return true;
+ }
+ // export is a special keyword used by i64asm to tell the AE output stage to
+ // mark this section as a header. it currently supports .text, .data.,
+ // page_zero
+ else if (ParserKit::find_word(line, "export ")) {
+ if (kOutputAsBinary) {
+ detail::print_error("invalid export directive in flat binary mode.",
+ "i64asm");
+ throw std::runtime_error("invalid_export_bin");
}
- // export is a special keyword used by i64asm to tell the AE output stage to mark this section as a header.
- // it currently supports .text, .data., page_zero
- else if (ParserKit::find_word(line, "export "))
- {
- if (kOutputAsBinary)
- {
- detail::print_error("invalid export directive in flat binary mode.", "i64asm");
- throw std::runtime_error("invalid_export_bin");
- }
- auto name = line.substr(line.find("export ") + strlen("export "));
+ auto name = line.substr(line.find("export ") + strlen("export "));
- std::string name_copy = name;
+ std::string name_copy = name;
- for (char &j : name)
- {
- if (j == ' ')
- j = '$';
- }
+ for (char &j : name) {
+ if (j == ' ') j = '$';
+ }
- if (name.find(".text") != std::string::npos)
- {
- // data is treated as code.
+ if (name.find(".text") != std::string::npos) {
+ // data is treated as code.
- name_copy.erase(name_copy.find(".text"), strlen(".text"));
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
- else if (name.find(".data") != std::string::npos)
- {
- // no code will be executed from here.
+ name_copy.erase(name_copy.find(".text"), strlen(".text"));
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ } else if (name.find(".data") != std::string::npos) {
+ // no code will be executed from here.
- name_copy.erase(name_copy.find(".data"), strlen(".data"));
- kCurrentRecord.fKind = CompilerKit::kPefData;
- }
- else if (name.find(".page_zero") != std::string::npos)
- {
- // this is a bss section.
+ name_copy.erase(name_copy.find(".data"), strlen(".data"));
+ kCurrentRecord.fKind = CompilerKit::kPefData;
+ } else if (name.find(".page_zero") != std::string::npos) {
+ // this is a bss section.
- name_copy.erase(name_copy.find(".page_zero"), strlen(".page_zero"));
- kCurrentRecord.fKind = CompilerKit::kPefZero;
- }
+ name_copy.erase(name_copy.find(".page_zero"), strlen(".page_zero"));
+ kCurrentRecord.fKind = CompilerKit::kPefZero;
+ }
- // this is a special case for the start stub.
- // we want this so that ld can find it.
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
- if (name == "__start")
- {
- kCurrentRecord.fKind = CompilerKit::kPefCode;
- }
+ if (name == "__start") {
+ kCurrentRecord.fKind = CompilerKit::kPefCode;
+ }
- while (name_copy.find(" ") != std::string::npos)
- name_copy.erase(name_copy.find(" "), 1);
+ while (name_copy.find(" ") != std::string::npos)
+ name_copy.erase(name_copy.find(" "), 1);
- kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
- ++kOrigin;
+ kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
+ ++kOrigin;
- // now we can tell the code size of the previous kCurrentRecord.
+ // now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty())
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, name.c_str(), name.size());
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, name.c_str(), name.size());
- ++kCounter;
+ ++kCounter;
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
- kRecords.emplace_back(kCurrentRecord);
+ kRecords.emplace_back(kCurrentRecord);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
// \brief algorithms and helpers.
-namespace detail::algorithm
-{
- // \brief authorize a brief set of characters.
- static inline bool is_not_alnum_space(char c)
- {
- return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') || (c == ',') ||
- (c == '(') || (c == ')') || (c == '"') || (c == '\'') || (c == '[') || (c == ']') || (c == '+') || (c == '_') || (c == ':') || (c == '@') || (c == '.'));
- }
+namespace detail::algorithm {
+// \brief authorize a brief set of characters.
+static inline bool is_not_alnum_space(char c) {
+ return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') ||
+ (c == ',') || (c == '(') || (c == ')') || (c == '"') ||
+ (c == '\'') || (c == '[') || (c == ']') || (c == '+') ||
+ (c == '_') || (c == ':') || (c == '@') || (c == '.'));
+}
- bool is_valid(const std::string &str)
- {
- return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
- }
+bool is_valid(const std::string &str) {
+ return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
}
+} // namespace detail::algorithm
/////////////////////////////////////////////////////////////////////////////////////////
@@ -548,611 +484,492 @@ namespace detail::algorithm
/////////////////////////////////////////////////////////////////////////////////////////
-std::string CompilerKit::PlatformAssemblerAMD64::CheckLine(std::string &line, const std::string &file)
-{
- std::string err_str;
-
- if (line.empty() ||
- ParserKit::find_word(line, "import") ||
- ParserKit::find_word(line, "export") ||
- ParserKit::find_word(line, "#") ||
- ParserKit::find_word(line, ";"))
- {
- if (line.find('#') != std::string::npos)
- {
- line.erase(line.find('#'));
- }
- else if (line.find(';') != std::string::npos)
- {
- line.erase(line.find(';'));
- }
- else
- {
- // now check the line for validity
- if (!detail::algorithm::is_valid(line))
- {
- err_str = "Line contains non alphanumeric characters.\nhere -> ";
- err_str += line;
- }
- }
-
- return err_str;
- }
-
- if (!detail::algorithm::is_valid(line))
- {
+std::string CompilerKit::PlatformAssemblerAMD64::CheckLine(
+ std::string &line, const std::string &file) {
+ std::string err_str;
+
+ if (line.empty() || ParserKit::find_word(line, "import") ||
+ ParserKit::find_word(line, "export") || ParserKit::find_word(line, "#") ||
+ ParserKit::find_word(line, ";")) {
+ if (line.find('#') != std::string::npos) {
+ line.erase(line.find('#'));
+ } else if (line.find(';') != std::string::npos) {
+ line.erase(line.find(';'));
+ } else {
+ // now check the line for validity
+ if (!detail::algorithm::is_valid(line)) {
err_str = "Line contains non alphanumeric characters.\nhere -> ";
err_str += line;
-
- return err_str;
+ }
}
- // check for a valid instruction format.
+ return err_str;
+ }
- if (line.find(',') != std::string::npos)
- {
- if (line.find(',') + 1 == line.size())
- {
- err_str += "\nInstruction lacks right register, here -> ";
- err_str += line.substr(line.find(','));
+ if (!detail::algorithm::is_valid(line)) {
+ err_str = "Line contains non alphanumeric characters.\nhere -> ";
+ err_str += line;
- return err_str;
- }
- else
- {
- bool nothing_on_right = true;
+ return err_str;
+ }
- if (line.find(',') + 1 > line.size())
- {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
+ // check for a valid instruction format.
- return err_str;
- }
+ if (line.find(',') != std::string::npos) {
+ if (line.find(',') + 1 == line.size()) {
+ err_str += "\nInstruction lacks right register, here -> ";
+ err_str += line.substr(line.find(','));
- auto substr = line.substr(line.find(',') + 1);
+ return err_str;
+ } else {
+ bool nothing_on_right = true;
- for (auto &ch : substr)
- {
- if (ch != ' ' &&
- ch != '\t')
- {
- nothing_on_right = false;
- }
- }
+ if (line.find(',') + 1 > line.size()) {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
- // this means we found nothing after that ',' .
- if (nothing_on_right)
- {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
+ return err_str;
+ }
- return err_str;
- }
+ auto substr = line.substr(line.find(',') + 1);
+
+ for (auto &ch : substr) {
+ if (ch != ' ' && ch != '\t') {
+ nothing_on_right = false;
}
+ }
+
+ // this means we found nothing after that ',' .
+ if (nothing_on_right) {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
+
+ return err_str;
+ }
}
+ }
- return err_str;
+ return err_str;
}
-bool CompilerKit::PlatformAssemblerAMD64::WriteNumber(const std::size_t &pos, std::string &jump_label)
-{
- if (!isdigit(jump_label[pos]))
- return false;
-
- switch (jump_label[pos + 1])
- {
- case 'x':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid hex number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_hex");
- }
- }
+bool CompilerKit::PlatformAssemblerAMD64::WriteNumber(const std::size_t &pos,
+ std::string &jump_label) {
+ if (!isdigit(jump_label[pos])) return false;
+
+ switch (jump_label[pos + 1]) {
+ case 'x': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid hex number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_hex");
+ }
+ }
- CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16));
+ CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- return true;
+ return true;
+ }
+ case 'b': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid binary number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_bin");
}
- case 'b':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid binary number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_bin");
- }
- }
+ }
- CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2));
+ CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
+ return true;
+ }
+ case 'o': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid octal number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_octal");
}
- case 'o':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid octal number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_octal");
- }
- }
+ }
- CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7));
+ CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
- }
- default:
- {
- break;
- }
+ return true;
+ }
+ default: {
+ break;
}
+ }
- /* check for errno and stuff like that */
- if (auto res = strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10);
- !res)
- {
- if (errno != 0)
- {
- return false;
- }
+ /* check for errno and stuff like that */
+ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
+ if (errno != 0) {
+ return false;
}
+ }
- CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10));
+ CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(
+ strtoq(jump_label.substr(pos).c_str(), nullptr, 10));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
- return true;
+ return true;
}
-bool CompilerKit::PlatformAssemblerAMD64::WriteNumber32(const std::size_t &pos, std::string &jump_label)
-{
- if (!isdigit(jump_label[pos]))
- return false;
-
- switch (jump_label[pos + 1])
- {
- case 'x':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid hex number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_hex");
- }
- }
+bool CompilerKit::PlatformAssemblerAMD64::WriteNumber32(
+ const std::size_t &pos, std::string &jump_label) {
+ if (!isdigit(jump_label[pos])) return false;
+
+ switch (jump_label[pos + 1]) {
+ case 'x': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid hex number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_hex");
+ }
+ }
- CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16));
+ CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- return true;
+ return true;
+ }
+ case 'b': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid binary number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_bin");
}
- case 'b':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid binary number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_bin");
- }
- }
+ }
- CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2));
+ CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
+ return true;
+ }
+ case 'o': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid octal number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_octal");
}
- case 'o':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid octal number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_octal");
- }
- }
+ }
- CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7));
+ CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
- }
- default:
- {
- break;
- }
+ return true;
}
+ default: {
+ break;
+ }
+ }
- /* check for errno and stuff like that */
- if (auto res = strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10);
- !res)
- {
- if (errno != 0)
- {
- return false;
- }
+ /* check for errno and stuff like that */
+ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
+ if (errno != 0) {
+ return false;
}
+ }
- CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10));
+ CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(
+ strtoq(jump_label.substr(pos).c_str(), nullptr, 10));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
- return true;
+ return true;
}
-bool CompilerKit::PlatformAssemblerAMD64::WriteNumber16(const std::size_t &pos, std::string &jump_label)
-{
- if (!isdigit(jump_label[pos]))
- return false;
-
- switch (jump_label[pos + 1])
- {
- case 'x':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid hex number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_hex");
- }
- }
+bool CompilerKit::PlatformAssemblerAMD64::WriteNumber16(
+ const std::size_t &pos, std::string &jump_label) {
+ if (!isdigit(jump_label[pos])) return false;
+
+ switch (jump_label[pos + 1]) {
+ case 'x': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid hex number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_hex");
+ }
+ }
- CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16));
+ CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- return true;
+ return true;
+ }
+ case 'b': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid binary number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_bin");
}
- case 'b':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid binary number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_bin");
- }
- }
+ }
- CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2));
+ CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
+ return true;
+ }
+ case 'o': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid octal number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_octal");
}
- case 'o':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid octal number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_octal");
- }
- }
+ }
- CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7));
+ CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- return true;
- }
- default:
- {
- break;
- }
+ return true;
+ }
+ default: {
+ break;
}
+ }
- /* check for errno and stuff like that */
- if (auto res = strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10);
- !res)
- {
- if (errno != 0)
- {
- return false;
- }
+ /* check for errno and stuff like that */
+ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
+ if (errno != 0) {
+ return false;
}
+ }
- CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10));
+ CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(
+ strtoq(jump_label.substr(pos).c_str(), nullptr, 10));
- for (char &i : num.number)
- {
- if (i == 0)
- i = 0xFF;
+ for (char &i : num.number) {
+ if (i == 0) i = 0xFF;
- kBytes.push_back(i);
- }
+ kBytes.push_back(i);
+ }
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
- return true;
+ return true;
}
-bool CompilerKit::PlatformAssemblerAMD64::WriteNumber8(const std::size_t &pos, std::string &jump_label)
-{
- if (!isdigit(jump_label[pos]))
- return false;
-
- switch (jump_label[pos + 1])
- {
- case 'x':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid hex number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_hex");
- }
- }
+bool CompilerKit::PlatformAssemblerAMD64::WriteNumber8(
+ const std::size_t &pos, std::string &jump_label) {
+ if (!isdigit(jump_label[pos])) return false;
+
+ switch (jump_label[pos + 1]) {
+ case 'x': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid hex number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_hex");
+ }
+ }
- CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 16));
+ CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- kBytes.push_back(num.number);
+ kBytes.push_back(num.number);
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- return true;
+ return true;
+ }
+ case 'b': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid binary number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_bin");
}
- case 'b':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid binary number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_bin");
- }
- }
+ }
- CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 2));
+ CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- kBytes.push_back(num.number);
+ kBytes.push_back(num.number);
- return true;
+ return true;
+ }
+ case 'o': {
+ if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res) {
+ if (errno != 0) {
+ detail::print_error("invalid octal number: " + jump_label, "i64asm");
+ throw std::runtime_error("invalid_octal");
}
- case 'o':
- {
- if (auto res = strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7);
- !res)
- {
- if (errno != 0)
- {
- detail::print_error("invalid octal number: " + jump_label, "i64asm");
- throw std::runtime_error("invalid_octal");
- }
- }
+ }
- CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(),
- nullptr, 7));
+ CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
+ strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7));
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
- kBytes.push_back(num.number);
+ kBytes.push_back(num.number);
- return true;
- }
- default:
- {
- break;
- }
+ return true;
+ }
+ default: {
+ break;
}
+ }
- /* check for errno and stuff like that */
- if (auto res = strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10);
- !res)
- {
- if (errno != 0)
- {
- return false;
- }
+ /* check for errno and stuff like that */
+ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
+ if (errno != 0) {
+ return false;
}
+ }
- CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos).c_str(),
- nullptr, 10));
+ CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
+ strtoq(jump_label.substr(pos).c_str(), nullptr, 10));
- kBytes.push_back(num.number);
+ kBytes.push_back(num.number);
- if (kVerbose)
- {
- kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n";
- }
+ if (kVerbose) {
+ kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
- return true;
+ return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1161,146 +978,120 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteNumber8(const std::size_t &pos, s
/////////////////////////////////////////////////////////////////////////////////////////
-bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, const std::string &file)
-{
- if (ParserKit::find_word(line, "export "))
- return true;
-
- for (auto &opcodeAMD64 : kOpcodesAMD64)
- {
- // strict check here
- if (ParserKit::find_word(line, opcodeAMD64.fName) &&
- detail::algorithm::is_valid(line))
- {
- std::string name(opcodeAMD64.fName);
-
- if (name.find("mov") != std::string::npos)
- {
- struct RegMapAMD64 {
- std::string fName;
- e64_byte_t fModRM;
- };
-
- std::vector<RegMapAMD64> regs {
- { .fName = "ax", .fModRM = 0 },
- { .fName = "cx", .fModRM = 1 },
- { .fName = "dx", .fModRM = 2 },
- { .fName = "bx", .fModRM = 3 },
- { .fName = "sp", .fModRM = 4 },
- { .fName = "bp", .fModRM = 5 },
- { .fName = "si", .fModRM = 6 },
- { .fName = "di", .fModRM = 7 },
- };
-
- std::string substr = line.substr(line.find(name) + name.size());
-
- uint64_t bits = 16;
-
- if (substr.find(",") == std::string::npos)
- {
- detail::print_error("Invalid combination of operands and registers.", "i64asm");
- throw std::runtime_error("comb_op_reg");
- }
-
- bool found = false;
-
- for (auto& reg : regs)
- {
- if (line.find(reg.fName) != std::string::npos)
- {
- if (!found)
- {
- if (line.substr(line.find(reg.fName) - 1)[0] == 'r')
- {
- bits = 64;
-
- kBytes.emplace_back(0x48);
- kBytes.emplace_back(0x89);
- kBytes.emplace_back(0x00);
- }
- else
- {
- detail::print_error("Invalid combination of registers, each 64-bit register must start with 'r'.", "i64asm");
- throw std::runtime_error("comb_op_reg");
- }
-
- found = true;
-
- kBytes.push_back(0xc0 + reg.fModRM);
-
- continue;
- }
- }
- }
-
- if (bits == 64)
- this->WriteNumber32(line.find(name) + name.size() + 2, line);
- else if (bits == 16)
- this->WriteNumber16(line.find(name) + name.size() + 2, line);
- else
- {
- detail::print_error("Invalid combination of operands and registers.", "i64asm");
- throw std::runtime_error("comb_op_reg");
- }
-
- break;
- }
- else if (name == "int" ||
- name == "into" ||
- name == "intd")
- {
- kBytes.emplace_back(opcodeAMD64.fOpcode);
- this->WriteNumber8(line.find(name) + name.size() + 1, line);
-
- break;
- }
- else if (name == "jmp" ||
- name == "call")
- {
- kBytes.emplace_back(opcodeAMD64.fOpcode);
- this->WriteNumber32(line.find(name) + name.size() + 1, line);
+bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
+ const std::string &file) {
+ if (ParserKit::find_word(line, "export ")) return true;
+
+ for (auto &opcodeAMD64 : kOpcodesAMD64) {
+ // strict check here
+ if (ParserKit::find_word(line, opcodeAMD64.fName) &&
+ detail::algorithm::is_valid(line)) {
+ std::string name(opcodeAMD64.fName);
+
+ if (name.find("mov") != std::string::npos) {
+ struct RegMapAMD64 {
+ std::string fName;
+ e64_byte_t fModRM;
+ };
+
+ std::vector<RegMapAMD64> regs{
+ {.fName = "ax", .fModRM = 0}, {.fName = "cx", .fModRM = 1},
+ {.fName = "dx", .fModRM = 2}, {.fName = "bx", .fModRM = 3},
+ {.fName = "sp", .fModRM = 4}, {.fName = "bp", .fModRM = 5},
+ {.fName = "si", .fModRM = 6}, {.fName = "di", .fModRM = 7},
+ };
+
+ std::string substr = line.substr(line.find(name) + name.size());
+
+ uint64_t bits = 16;
+
+ if (substr.find(",") == std::string::npos) {
+ detail::print_error("Invalid combination of operands and registers.",
+ "i64asm");
+ throw std::runtime_error("comb_op_reg");
+ }
- break;
- }
- else
- {
- kBytes.emplace_back(0);
- kBytes.emplace_back(opcodeAMD64.fOpcode);
+ bool found = false;
- break;
+ for (auto &reg : regs) {
+ if (line.find(reg.fName) != std::string::npos) {
+ if (!found) {
+ if (line.substr(line.find(reg.fName) - 1)[0] == 'r') {
+ bits = 64;
+
+ kBytes.emplace_back(0x48);
+ kBytes.emplace_back(0x89);
+ kBytes.emplace_back(0x00);
+ } else {
+ detail::print_error(
+ "Invalid combination of registers, each 64-bit register "
+ "must start with 'r'.",
+ "i64asm");
+ throw std::runtime_error("comb_op_reg");
+ }
+
+ found = true;
+
+ kBytes.push_back(0xc0 + reg.fModRM);
+
+ continue;
}
+ }
}
- }
- if (line.find("db") != std::string::npos)
- {
- this->WriteNumber(line.find("db") + strlen("db") + 1, line);
+ if (bits == 64)
+ this->WriteNumber32(line.find(name) + name.size() + 2, line);
+ else if (bits == 16)
+ this->WriteNumber16(line.find(name) + name.size() + 2, line);
+ else {
+ detail::print_error("Invalid combination of operands and registers.",
+ "i64asm");
+ throw std::runtime_error("comb_op_reg");
+ }
+
+ break;
+ } else if (name == "int" || name == "into" || name == "intd") {
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
+ this->WriteNumber8(line.find(name) + name.size() + 1, line);
+
+ break;
+ } else if (name == "jmp" || name == "call") {
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
+ this->WriteNumber32(line.find(name) + name.size() + 1, line);
+
+ break;
+ } else {
+ kBytes.emplace_back(0);
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
+
+ break;
+ }
}
- if (line.find("org ") != std::string::npos)
- {
- size_t base[] = {10, 16, 2, 7};
-
- for (size_t i = 0; i < 4; i++)
- {
- if (kOrigin = strtol((line.substr(line.find("org") + strlen("org") + 1)).c_str(), nullptr, base[i]);
- kOrigin)
- {
- if (errno != 0)
- {
- continue;
- }
- else
- {
- if (kVerbose)
- {
- kStdOut << "Origin: " << kOrigin << std::endl;
- }
- }
- }
+ }
+
+ if (line.find("db") != std::string::npos) {
+ this->WriteNumber(line.find("db") + strlen("db") + 1, line);
+ }
+ if (line.find("org ") != std::string::npos) {
+ size_t base[] = {10, 16, 2, 7};
+
+ for (size_t i = 0; i < 4; i++) {
+ if (kOrigin = strtol(
+ (line.substr(line.find("org") + strlen("org") + 1)).c_str(),
+ nullptr, base[i]);
+ kOrigin) {
+ if (errno != 0) {
+ continue;
+ } else {
+ if (kVerbose) {
+ kStdOut << "Origin: " << kOrigin << std::endl;
+ }
}
+ }
}
+ }
- return true;
+ return true;
}
-// Last rev 13-1-24 \ No newline at end of file
+// Last rev 13-1-24
diff --git a/Private/Toolchain/ld.cc b/Private/Toolchain/ld.cc
index 239c622..814cb14 100644
--- a/Private/Toolchain/ld.cc
+++ b/Private/Toolchain/ld.cc
@@ -25,11 +25,11 @@
#include <CompilerKit/StdKit/PEF.hpp>
//! Advanced Executable Object Format
-#include <CompilerKit/StdKit/AE.hpp>
+#include <uuid/uuid.h>
+#include <CompilerKit/StdKit/AE.hpp>
#include <fstream>
#include <iostream>
-#include <uuid/uuid.h>
//! @brief standard PEF entry.
#define kPefStart "__start"
@@ -67,534 +67,484 @@ static const char *kLdDynamicSym = ":mld:";
static std::vector<std::string> kObjectList;
static std::vector<char> kObjectBytes;
-MPCC_MODULE(MPUXLinker)
-{
- bool is_executable = true;
-
- /**
- * @brief parse flags and such.
- *
- */
- for (size_t i = 1; i < argc; ++i)
- {
- if (StringCompare(argv[i], "-h") == 0)
- {
- kStdOut << kToolVersion << "\n";
- kStdOut << "-version: Show program version.\n";
- kStdOut << "-verbose: Enable program trace.\n";
- kStdOut << "-shared: Output as a shared PEF.\n";
- kStdOut << "-fat-bin: Output as FAT PEF.\n";
- kStdOut << "-32x0: Output as 32x0 PEF.\n";
- kStdOut << "-64x0: Output as 64x0 PEF.\n";
- kStdOut << "-output-file: Select output file name.\n";
-
- return 0;
- }
- else if (StringCompare(argv[i], "-version") == 0)
- {
- kStdOut << kToolVersion << std::endl;
+MPCC_MODULE(MPUXLinker) {
+ bool is_executable = true;
+
+ /**
+ * @brief parse flags and such.
+ *
+ */
+ for (size_t i = 1; i < argc; ++i) {
+ if (StringCompare(argv[i], "-h") == 0) {
+ kStdOut << kToolVersion << "\n";
+ kStdOut << "-version: Show program version.\n";
+ kStdOut << "-verbose: Enable program trace.\n";
+ kStdOut << "-shared: Output as a shared PEF.\n";
+ kStdOut << "-fat-bin: Output as FAT PEF.\n";
+ kStdOut << "-32x0: Output as 32x0 PEF.\n";
+ kStdOut << "-64x0: Output as 64x0 PEF.\n";
+ kStdOut << "-output-file: Select output file name.\n";
+
+ return 0;
+ } else if (StringCompare(argv[i], "-version") == 0) {
+ kStdOut << kToolVersion << std::endl;
+
+ return 0;
+ } else if (StringCompare(argv[i], "-fat-bin") == 0) {
+ kFatBinaryEnable = true;
+
+ continue;
+ } else if (StringCompare(argv[i], "-64x0") == 0) {
+ kArch = CompilerKit::kPefArch64000;
+
+ continue;
+ } else if (StringCompare(argv[i], "-32x0") == 0) {
+ kArch = CompilerKit::kPefArch32000;
+
+ continue;
+ } else if (StringCompare(argv[i], "-verbose") == 0) {
+ kVerbose = true;
+
+ continue;
+ } else if (StringCompare(argv[i], "-shared") == 0) {
+ if (kOutput.find(kPefExt) != std::string::npos)
+ kOutput.erase(kOutput.find(kPefExt), strlen(kPefExt));
+
+ kOutput += kPefDylibExt;
+
+ is_executable = false;
+
+ continue;
+ } else if (StringCompare(argv[i], "-output-file") == 0) {
+ kOutput = argv[i + 1];
+ ++i;
+
+ continue;
+ } else {
+ if (argv[i][0] == '-') {
+ kStdOut << "ld: unknown flag: " << argv[i] << "\n";
+ return -CXXKIT_EXEC_ERROR;
+ }
- return 0;
- }
- else if (StringCompare(argv[i], "-fat-bin") == 0)
- {
- kFatBinaryEnable = true;
+ kObjectList.emplace_back(argv[i]);
- continue;
- }
- else if (StringCompare(argv[i], "-64x0") == 0)
- {
- kArch = CompilerKit::kPefArch64000;
+ continue;
+ }
+ }
+
+ // sanity check.
+ if (kObjectList.empty()) {
+ kStdOut << "ld: no input files." << std::endl;
+ return CXXKIT_EXEC_ERROR;
+ } else {
+ // check for existing files, if they don't throw an error.
+ for (auto &obj : kObjectList) {
+ if (!std::filesystem::exists(obj)) {
+ // if filesystem doesn't find file
+ // -> throw error.
+ kStdOut << "ld: no such file: " << obj << std::endl;
+ return CXXKIT_EXEC_ERROR;
+ }
+ }
+ }
- continue;
- }
- else if (StringCompare(argv[i], "-32x0") == 0)
- {
- kArch = CompilerKit::kPefArch32000;
+ // PEF expects a valid architecture when outputing a binary.
+ if (kArch == 0) {
+ kStdOut << "ld: no target architecture set, can't continue." << std::endl;
+ return CXXKIT_EXEC_ERROR;
+ }
- continue;
- }
- else if (StringCompare(argv[i], "-verbose") == 0)
- {
- kVerbose = true;
+ CompilerKit::PEFContainer pef_container{};
- continue;
- }
- else if (StringCompare(argv[i], "-shared") == 0)
- {
- if (kOutput.find(kPefExt) != std::string::npos)
- kOutput.erase(kOutput.find(kPefExt), strlen(kPefExt));
+ int32_t archs = kArch;
- kOutput += kPefDylibExt;
+ pef_container.Count = 0UL;
+ pef_container.Kind = CompilerKit::kPefKindExec;
+ pef_container.SubCpu = kSubArch;
+ pef_container.Linker = kPefLinkerNumId; // Mahrouss Logic Linker
+ pef_container.Abi = kAbi; // Multi-Processor UX ABI
+ pef_container.Magic[0] = kPefMagic[kFatBinaryEnable ? 2 : 0];
+ pef_container.Magic[1] = kPefMagic[1];
+ pef_container.Magic[2] = kPefMagic[kFatBinaryEnable ? 0 : 2];
+ pef_container.Version = kPefVersion;
- is_executable = false;
+ // specify the start address, can be 0x10000
+ pef_container.Start = kPefDeaultOrg;
+ pef_container.HdrSz = sizeof(CompilerKit::PEFContainer);
- continue;
- }
- else if (StringCompare(argv[i], "-output-file") == 0)
- {
- kOutput = argv[i + 1];
- ++i;
+ std::ofstream output_fc(kOutput, std::ofstream::binary);
- continue;
- }
- else
- {
- if (argv[i][0] == '-')
- {
- kStdOut << "ld: unknown flag: " << argv[i] << "\n";
- return -CXXKIT_EXEC_ERROR;
- }
+ if (output_fc.bad()) {
+ if (kVerbose) {
+ kStdOut << "ld: error: " << strerror(errno) << "\n";
+ }
- kObjectList.emplace_back(argv[i]);
+ return -CXXKIT_FILE_NOT_FOUND;
+ }
- continue;
- }
- }
+ //! Read AE to convert as PEF.
- // sanity check.
- if (kObjectList.empty())
- {
- kStdOut << "ld: no input files." << std::endl;
- return CXXKIT_EXEC_ERROR;
- }
- else
- {
- // check for existing files, if they don't throw an error.
- for (auto &obj : kObjectList)
- {
- if (!std::filesystem::exists(obj))
- {
- // if filesystem doesn't find file
- // -> throw error.
- kStdOut << "ld: no such file: " << obj << std::endl;
- return CXXKIT_EXEC_ERROR;
- }
- }
- }
+ std::vector<CompilerKit::PEFCommandHeader> pef_command_hdrs;
+ CompilerKit::Utils::AEReadableProtocol readProto{};
- // PEF expects a valid architecture when outputing a binary.
- if (kArch == 0)
- {
- kStdOut << "ld: no target architecture set, can't continue." << std::endl;
- return CXXKIT_EXEC_ERROR;
- }
+ for (const auto &i : kObjectList) {
+ if (!std::filesystem::exists(i)) continue;
- CompilerKit::PEFContainer pef_container{};
+ CompilerKit::AEHeader hdr{};
- int32_t archs = kArch;
+ readProto.FP = std::ifstream(i, std::ifstream::binary);
+ readProto.FP >> hdr;
- pef_container.Count = 0UL;
- pef_container.Kind = CompilerKit::kPefKindExec;
- pef_container.SubCpu = kSubArch;
- pef_container.Linker = kPefLinkerNumId; // Mahrouss Logic Linker
- pef_container.Abi = kAbi; // Multi-Processor UX ABI
- pef_container.Magic[0] = kPefMagic[kFatBinaryEnable ? 2 : 0];
- pef_container.Magic[1] = kPefMagic[1];
- pef_container.Magic[2] = kPefMagic[kFatBinaryEnable ? 0 : 2];
- pef_container.Version = kPefVersion;
+ auto ae_header = hdr;
- // specify the start address, can be 0x10000
- pef_container.Start = kPefDeaultOrg;
- pef_container.HdrSz = sizeof(CompilerKit::PEFContainer);
+ if (ae_header.fMagic[0] == kAEMag0 && ae_header.fMagic[1] == kAEMag1 &&
+ ae_header.fSize == sizeof(CompilerKit::AEHeader)) {
+ if (ae_header.fArch != kArch) {
+ if (kVerbose) kStdOut << "ld: info: is a fat binary? : ";
- std::ofstream output_fc(kOutput, std::ofstream::binary);
+ if (!kFatBinaryEnable) {
+ if (kVerbose) kStdOut << "no.\n";
- if (output_fc.bad())
- {
- if (kVerbose)
- {
- kStdOut << "ld: error: " << strerror(errno) << "\n";
+ kStdOut << "ld: error: object " << i
+ << " is a different kind of architecture and output isn't "
+ "treated as FAT binary."
+ << std::endl;
+
+ std::remove(kOutput.c_str());
+ return -CXXKIT_FAT_ERROR;
+ } else {
+ if (kVerbose) {
+ kStdOut << "yes.\n";
+ }
}
+ }
- return -CXXKIT_FILE_NOT_FOUND;
- }
+ // append arch type to archs varaible.
+ archs |= ae_header.fArch;
+ std::size_t cnt = ae_header.fCount;
- //! Read AE to convert as PEF.
-
- std::vector<CompilerKit::PEFCommandHeader> pef_command_hdrs;
- CompilerKit::Utils::AEReadableProtocol readProto{};
-
- for (const auto &i : kObjectList)
- {
- if (!std::filesystem::exists(i))
- continue;
-
- CompilerKit::AEHeader hdr{};
-
- readProto.FP = std::ifstream(i, std::ifstream::binary);
- readProto.FP >> hdr;
-
- auto ae_header = hdr;
-
- if (ae_header.fMagic[0] == kAEMag0 &&
- ae_header.fMagic[1] == kAEMag1 &&
- ae_header.fSize == sizeof(CompilerKit::AEHeader))
- {
- if (ae_header.fArch != kArch)
- {
- if (kVerbose)
- kStdOut << "ld: info: is a fat binary? : ";
-
- if (!kFatBinaryEnable)
- {
- if (kVerbose)
- kStdOut << "no.\n";
-
- kStdOut << "ld: error: object " << i << " is a different kind of architecture and output isn't treated as FAT binary." << std::endl;
-
- std::remove(kOutput.c_str());
- return -CXXKIT_FAT_ERROR;
- }
- else
- {
- if (kVerbose)
- {
- kStdOut << "yes.\n";
- }
- }
- }
+ if (kVerbose)
+ kStdOut << "ld: object header found, record count: " << cnt << "\n";
- // append arch type to archs varaible.
- archs |= ae_header.fArch;
- std::size_t cnt = ae_header.fCount;
-
- if (kVerbose)
- kStdOut << "ld: object header found, record count: " << cnt << "\n";
-
- pef_container.Count = cnt;
-
- char_type *raw_ae_records = new char[cnt * sizeof(CompilerKit::AERecordHeader)];
- memset(raw_ae_records, 0, cnt * sizeof(CompilerKit::AERecordHeader));
-
- auto *ae_records = readProto.Read(raw_ae_records, cnt);
-
- for (size_t ae_record_index = 0; ae_record_index < cnt; ++ae_record_index)
- {
- CompilerKit::PEFCommandHeader command_header{0};
-
- memcpy(command_header.Name, ae_records[ae_record_index].fName, kPefNameLen);
-
- // check this header if it's any valid.
- if (std::string(command_header.Name).find(".text") == std::string::npos &&
- std::string(command_header.Name).find(".data") == std::string::npos &&
- std::string(command_header.Name).find(".page_zero") == std::string::npos)
- {
- if (std::string(command_header.Name).find(kPefStart) == std::string::npos &&
- *command_header.Name == 0)
- {
- if (std::string(command_header.Name).find(kLdDefineSymbol) != std::string::npos)
- {
- goto ld_mark_header;
- }
- else
- {
- continue;
- }
- }
- }
-
- if (std::string(command_header.Name).find(kPefStart) != std::string::npos &&
- std::string(command_header.Name).find(".text") != std::string::npos)
- {
- kStartFound = true;
- pef_container.Start = ae_records[ae_record_index].fOffset;
- }
-
- ld_mark_header:
- command_header.Offset = ae_records[ae_record_index].fOffset;
- command_header.Kind = ae_records[ae_record_index].fKind;
- command_header.Size = ae_records[ae_record_index].fSize;
-
- if (kVerbose)
- kStdOut << "ld: object record: " << ae_records[ae_record_index].fName << " was marked.\n";
-
- pef_command_hdrs.emplace_back(command_header);
- }
+ pef_container.Count = cnt;
- delete[] raw_ae_records;
+ char_type *raw_ae_records =
+ new char[cnt * sizeof(CompilerKit::AERecordHeader)];
+ memset(raw_ae_records, 0, cnt * sizeof(CompilerKit::AERecordHeader));
- std::vector<char> bytes;
- bytes.resize(ae_header.fCodeSize);
+ auto *ae_records = readProto.Read(raw_ae_records, cnt);
- readProto.FP.seekg(std::streamsize(ae_header.fStartCode));
- readProto.FP.read(bytes.data(), std::streamsize(ae_header.fCodeSize));
+ for (size_t ae_record_index = 0; ae_record_index < cnt;
+ ++ae_record_index) {
+ CompilerKit::PEFCommandHeader command_header{0};
- for (auto &byte : bytes)
- {
- kObjectBytes.push_back(byte);
- }
+ memcpy(command_header.Name, ae_records[ae_record_index].fName,
+ kPefNameLen);
- readProto.FP.close();
+ // check this header if it's any valid.
+ if (std::string(command_header.Name).find(".text") ==
+ std::string::npos &&
+ std::string(command_header.Name).find(".data") ==
+ std::string::npos &&
+ std::string(command_header.Name).find(".page_zero") ==
+ std::string::npos) {
+ if (std::string(command_header.Name).find(kPefStart) ==
+ std::string::npos &&
+ *command_header.Name == 0) {
+ if (std::string(command_header.Name).find(kLdDefineSymbol) !=
+ std::string::npos) {
+ goto ld_mark_header;
+ } else {
+ continue;
+ }
+ }
+ }
- continue;
+ if (std::string(command_header.Name).find(kPefStart) !=
+ std::string::npos &&
+ std::string(command_header.Name).find(".text") !=
+ std::string::npos) {
+ kStartFound = true;
+ pef_container.Start = ae_records[ae_record_index].fOffset;
}
- kStdOut << "ld: not an object: " << i << std::endl;
- std::remove(kOutput.c_str());
+ ld_mark_header:
+ command_header.Offset = ae_records[ae_record_index].fOffset;
+ command_header.Kind = ae_records[ae_record_index].fKind;
+ command_header.Size = ae_records[ae_record_index].fSize;
- // don't continue, it is a fatal error.
- return -CXXKIT_EXEC_ERROR;
- }
+ if (kVerbose)
+ kStdOut << "ld: object record: " << ae_records[ae_record_index].fName
+ << " was marked.\n";
- pef_container.Cpu = archs;
+ pef_command_hdrs.emplace_back(command_header);
+ }
- output_fc << pef_container;
+ delete[] raw_ae_records;
- if (kVerbose)
- {
- kStdOut << "ld: pef: wrote container header.\n";
+ std::vector<char> bytes;
+ bytes.resize(ae_header.fCodeSize);
+
+ readProto.FP.seekg(std::streamsize(ae_header.fStartCode));
+ readProto.FP.read(bytes.data(), std::streamsize(ae_header.fCodeSize));
+
+ for (auto &byte : bytes) {
+ kObjectBytes.push_back(byte);
+ }
+
+ readProto.FP.close();
+
+ continue;
}
- output_fc.seekp(std::streamsize(pef_container.HdrSz));
+ kStdOut << "ld: not an object: " << i << std::endl;
+ std::remove(kOutput.c_str());
- std::vector<std::string> not_found;
- std::vector<std::string> symbols;
+ // don't continue, it is a fatal error.
+ return -CXXKIT_EXEC_ERROR;
+ }
- // step 2: check for errors (multiple symbols, undefined ones)
+ pef_container.Cpu = archs;
- for (auto &pef_command_hdr : pef_command_hdrs)
- {
- // check if this symbol needs to be resolved.
- if (std::string(pef_command_hdr.Name).find(kLdDefineSymbol) !=
- std::string::npos &&
- std::string(pef_command_hdr.Name).find(kLdDynamicSym) ==
- std::string::npos)
- {
- if (kVerbose)
- kStdOut << "ld: found undefined symbol: " << pef_command_hdr.Name << "\n";
-
- if (auto it = std::find(not_found.begin(), not_found.end(), std::string(pef_command_hdr.Name));
- it == not_found.end())
- {
- not_found.emplace_back(pef_command_hdr.Name);
- }
- }
+ output_fc << pef_container;
+
+ if (kVerbose) {
+ kStdOut << "ld: pef: wrote container header.\n";
+ }
+
+ output_fc.seekp(std::streamsize(pef_container.HdrSz));
+
+ std::vector<std::string> not_found;
+ std::vector<std::string> symbols;
+
+ // step 2: check for errors (multiple symbols, undefined ones)
- symbols.emplace_back(pef_command_hdr.Name);
+ for (auto &pef_command_hdr : pef_command_hdrs) {
+ // check if this symbol needs to be resolved.
+ if (std::string(pef_command_hdr.Name).find(kLdDefineSymbol) !=
+ std::string::npos &&
+ std::string(pef_command_hdr.Name).find(kLdDynamicSym) ==
+ std::string::npos) {
+ if (kVerbose)
+ kStdOut << "ld: found undefined symbol: " << pef_command_hdr.Name
+ << "\n";
+
+ if (auto it = std::find(not_found.begin(), not_found.end(),
+ std::string(pef_command_hdr.Name));
+ it == not_found.end()) {
+ not_found.emplace_back(pef_command_hdr.Name);
+ }
}
- // Now try to solve these symbols.
+ symbols.emplace_back(pef_command_hdr.Name);
+ }
- for (size_t not_found_idx = 0; not_found_idx < pef_command_hdrs.size(); ++not_found_idx)
- {
- if (auto it = std::find(not_found.begin(), not_found.end(), std::string(pef_command_hdrs[not_found_idx].Name));
- it != not_found.end())
- {
- std::string symbol_imp = *it;
+ // Now try to solve these symbols.
- if (symbol_imp.find(kLdDefineSymbol) == std::string::npos)
- continue;
+ for (size_t not_found_idx = 0; not_found_idx < pef_command_hdrs.size();
+ ++not_found_idx) {
+ if (auto it = std::find(not_found.begin(), not_found.end(),
+ std::string(pef_command_hdrs[not_found_idx].Name));
+ it != not_found.end()) {
+ std::string symbol_imp = *it;
- // erase the lookup prefix.
- symbol_imp.erase(0, symbol_imp.find(kLdDefineSymbol) + strlen(kLdDefineSymbol));
+ if (symbol_imp.find(kLdDefineSymbol) == std::string::npos) continue;
- // demangle everything.
- while (symbol_imp.find('$') != std::string::npos)
- symbol_imp.erase(symbol_imp.find('$'), 1);
+ // erase the lookup prefix.
+ symbol_imp.erase(
+ 0, symbol_imp.find(kLdDefineSymbol) + strlen(kLdDefineSymbol));
- // the reason we do is because, this may not match the symbol, and we need
- // to look for other matching symbols.
- for (auto &pef_command_hdr : pef_command_hdrs)
- {
- if (std::string(pef_command_hdr.Name).find(symbol_imp) != std::string::npos &&
- std::string(pef_command_hdr.Name).find(kLdDefineSymbol) == std::string::npos)
- {
- std::string undefined_symbol = pef_command_hdr.Name;
- auto result_of_sym = undefined_symbol.substr(undefined_symbol.find(symbol_imp));
+ // demangle everything.
+ while (symbol_imp.find('$') != std::string::npos)
+ symbol_imp.erase(symbol_imp.find('$'), 1);
- for (int i = 0; result_of_sym[i] != 0; ++i)
- {
- if (result_of_sym[i] != symbol_imp[i])
- goto ld_continue_search;
- }
+ // the reason we do is because, this may not match the symbol, and we need
+ // to look for other matching symbols.
+ for (auto &pef_command_hdr : pef_command_hdrs) {
+ if (std::string(pef_command_hdr.Name).find(symbol_imp) !=
+ std::string::npos &&
+ std::string(pef_command_hdr.Name).find(kLdDefineSymbol) ==
+ std::string::npos) {
+ std::string undefined_symbol = pef_command_hdr.Name;
+ auto result_of_sym =
+ undefined_symbol.substr(undefined_symbol.find(symbol_imp));
- not_found.erase(it);
+ for (int i = 0; result_of_sym[i] != 0; ++i) {
+ if (result_of_sym[i] != symbol_imp[i]) goto ld_continue_search;
+ }
- if (kVerbose)
- kStdOut << "ld: found symbol: " << pef_command_hdr.Name << "\n";
+ not_found.erase(it);
- break;
- }
- }
+ if (kVerbose)
+ kStdOut << "ld: found symbol: " << pef_command_hdr.Name << "\n";
- ld_continue_search:
- continue;
+ break;
}
+ }
+
+ ld_continue_search:
+ continue;
}
+ }
- // step 3: check for errors (recheck if we have those symbols.)
+ // step 3: check for errors (recheck if we have those symbols.)
- if (!kStartFound && is_executable)
- {
- if (kVerbose)
- kStdOut << "ld: undefined symbol: __start, you may have forget to link against your runtime library.\n";
+ if (!kStartFound && is_executable) {
+ if (kVerbose)
+ kStdOut << "ld: undefined symbol: __start, you may have forget to link "
+ "against your runtime library.\n";
- kStdOut << "ld: undefined entrypoint " << kPefStart << " for executable " << kOutput << "\n";
- }
+ kStdOut << "ld: undefined entrypoint " << kPefStart << " for executable "
+ << kOutput << "\n";
+ }
- // step 4: write some pef commands.
+ // step 4: write some pef commands.
- CompilerKit::PEFCommandHeader date_header{};
+ CompilerKit::PEFCommandHeader date_header{};
- time_t timestamp = time(nullptr);
+ time_t timestamp = time(nullptr);
- std::string timestamp_str = "ContainerDate:";
- timestamp_str += std::to_string(timestamp);
+ std::string timestamp_str = "ContainerDate:";
+ timestamp_str += std::to_string(timestamp);
- strcpy(date_header.Name, timestamp_str.c_str());
+ strcpy(date_header.Name, timestamp_str.c_str());
- date_header.Flags = 0;
- date_header.Kind = CompilerKit::kPefData;
- date_header.Offset = output_fc.tellp();
- date_header.Size = timestamp_str.size();
+ date_header.Flags = 0;
+ date_header.Kind = CompilerKit::kPefData;
+ date_header.Offset = output_fc.tellp();
+ date_header.Size = timestamp_str.size();
- output_fc << date_header;
+ output_fc << date_header;
- CompilerKit::PEFCommandHeader abi_header{};
+ CompilerKit::PEFCommandHeader abi_header{};
- memcpy(abi_header.Name, kPefAbiId, strlen(kPefAbiId));
+ memcpy(abi_header.Name, kPefAbiId, strlen(kPefAbiId));
- abi_header.Size = strlen(kPefAbiId);
- abi_header.Offset = output_fc.tellp();
- abi_header.Flags = 0;
- abi_header.Kind = CompilerKit::kPefLinkerID;
+ abi_header.Size = strlen(kPefAbiId);
+ abi_header.Offset = output_fc.tellp();
+ abi_header.Flags = 0;
+ abi_header.Kind = CompilerKit::kPefLinkerID;
- output_fc << abi_header;
+ output_fc << abi_header;
- CompilerKit::PEFCommandHeader uuid_header{};
+ CompilerKit::PEFCommandHeader uuid_header{};
- uuid_t uuid{0};
- uuid_generate_random(uuid);
+ uuid_t uuid{0};
+ uuid_generate_random(uuid);
- memcpy(uuid_header.Name, "UUID_TYPE:4:", strlen("UUID_TYPE:4:"));
- memcpy(uuid_header.Name + strlen("UUID_TYPE:4:"), uuid, 16);
+ memcpy(uuid_header.Name, "UUID_TYPE:4:", strlen("UUID_TYPE:4:"));
+ memcpy(uuid_header.Name + strlen("UUID_TYPE:4:"), uuid, 16);
- uuid_header.Size = 16;
- uuid_header.Offset = output_fc.tellp();
- uuid_header.Flags = 0;
- uuid_header.Kind = 0;
+ uuid_header.Size = 16;
+ uuid_header.Offset = output_fc.tellp();
+ uuid_header.Flags = 0;
+ uuid_header.Kind = 0;
- output_fc << uuid_header;
+ output_fc << uuid_header;
- // prepare a symbol vector.
- std::vector<std::string> undefined_symbols;
- std::vector<std::string> duplicate_symbols;
- std::vector<std::string> symbols_to_resolve;
+ // prepare a symbol vector.
+ std::vector<std::string> undefined_symbols;
+ std::vector<std::string> duplicate_symbols;
+ std::vector<std::string> symbols_to_resolve;
- // Finally write down the command headers.
- // And check for any duplications
- for (size_t cmd_hdr = 0UL; cmd_hdr < pef_command_hdrs.size(); ++cmd_hdr)
- {
- if (std::string(pef_command_hdrs[cmd_hdr].Name).find(kLdDefineSymbol) !=
- std::string::npos &&
- std::string(pef_command_hdrs[cmd_hdr].Name).find(kLdDynamicSym) ==
- std::string::npos)
- {
- // ignore :ld: headers, they do not contain code.
- continue;
- }
+ // Finally write down the command headers.
+ // And check for any duplications
+ for (size_t cmd_hdr = 0UL; cmd_hdr < pef_command_hdrs.size(); ++cmd_hdr) {
+ if (std::string(pef_command_hdrs[cmd_hdr].Name).find(kLdDefineSymbol) !=
+ std::string::npos &&
+ std::string(pef_command_hdrs[cmd_hdr].Name).find(kLdDynamicSym) ==
+ std::string::npos) {
+ // ignore :ld: headers, they do not contain code.
+ continue;
+ }
- std::string sym_name = pef_command_hdrs[cmd_hdr].Name;
+ std::string sym_name = pef_command_hdrs[cmd_hdr].Name;
- if (!sym_name.empty())
- {
- undefined_symbols.emplace_back(sym_name);
- }
+ if (!sym_name.empty()) {
+ undefined_symbols.emplace_back(sym_name);
+ }
- output_fc << pef_command_hdrs[cmd_hdr];
-
- for (size_t cmd_hdr_sub = 0UL; cmd_hdr_sub < pef_command_hdrs.size(); ++cmd_hdr_sub)
- {
- if (cmd_hdr_sub == cmd_hdr)
- continue;
-
- if (std::string(pef_command_hdrs[cmd_hdr_sub].Name).find(kLdDefineSymbol) !=
- std::string::npos &&
- std::string(pef_command_hdrs[cmd_hdr_sub].Name).find(kLdDynamicSym) ==
- std::string::npos)
- {
- if (kVerbose)
- {
- kStdOut << "ld: ignore :ld: command header...\n";
- }
-
- // ignore :ld: headers, they do not contain code.
- continue;
- }
+ output_fc << pef_command_hdrs[cmd_hdr];
- auto &pef_command_hdr = pef_command_hdrs[cmd_hdr_sub];
+ for (size_t cmd_hdr_sub = 0UL; cmd_hdr_sub < pef_command_hdrs.size();
+ ++cmd_hdr_sub) {
+ if (cmd_hdr_sub == cmd_hdr) continue;
- if (pef_command_hdr.Name == std::string(pef_command_hdrs[cmd_hdr].Name))
- {
- if (std::find(duplicate_symbols.cbegin(), duplicate_symbols.cend(), pef_command_hdr.Name) == duplicate_symbols.cend())
- {
- duplicate_symbols.emplace_back(pef_command_hdr.Name);
- }
+ if (std::string(pef_command_hdrs[cmd_hdr_sub].Name)
+ .find(kLdDefineSymbol) != std::string::npos &&
+ std::string(pef_command_hdrs[cmd_hdr_sub].Name).find(kLdDynamicSym) ==
+ std::string::npos) {
+ if (kVerbose) {
+ kStdOut << "ld: ignore :ld: command header...\n";
+ }
- if (kVerbose)
- kStdOut << "ld: found duplicate symbol: " << pef_command_hdr.Name << "\n";
+ // ignore :ld: headers, they do not contain code.
+ continue;
+ }
- kDuplicateSymbols = true;
- }
- }
- }
+ auto &pef_command_hdr = pef_command_hdrs[cmd_hdr_sub];
- if (!duplicate_symbols.empty())
- {
- for (auto &symbol : duplicate_symbols)
- {
- kStdOut << "ld: multiple symbols of " << symbol << ".\n";
+ if (pef_command_hdr.Name == std::string(pef_command_hdrs[cmd_hdr].Name)) {
+ if (std::find(duplicate_symbols.cbegin(), duplicate_symbols.cend(),
+ pef_command_hdr.Name) == duplicate_symbols.cend()) {
+ duplicate_symbols.emplace_back(pef_command_hdr.Name);
}
- std::remove(kOutput.c_str());
- return -CXXKIT_EXEC_ERROR;
- }
+ if (kVerbose)
+ kStdOut << "ld: found duplicate symbol: " << pef_command_hdr.Name
+ << "\n";
- // step 2.5: write program bytes.
+ kDuplicateSymbols = true;
+ }
+ }
+ }
- for (auto byte : kObjectBytes)
- {
- output_fc << byte;
+ if (!duplicate_symbols.empty()) {
+ for (auto &symbol : duplicate_symbols) {
+ kStdOut << "ld: multiple symbols of " << symbol << ".\n";
}
- if (kVerbose)
- kStdOut << "ld: wrote code for: " << kOutput << "\n";
+ std::remove(kOutput.c_str());
+ return -CXXKIT_EXEC_ERROR;
+ }
- // step 3: check if we have those symbols
+ // step 2.5: write program bytes.
- std::vector<std::string> unreferenced_symbols;
+ for (auto byte : kObjectBytes) {
+ output_fc << byte;
+ }
- for (auto &pef_command_hdr : pef_command_hdrs)
- {
- if (auto it = std::find(not_found.begin(), not_found.end(), std::string(pef_command_hdr.Name));
- it != not_found.end())
- {
- unreferenced_symbols.emplace_back(pef_command_hdr.Name);
- }
+ if (kVerbose) kStdOut << "ld: wrote code for: " << kOutput << "\n";
+
+ // step 3: check if we have those symbols
+
+ std::vector<std::string> unreferenced_symbols;
+
+ for (auto &pef_command_hdr : pef_command_hdrs) {
+ if (auto it = std::find(not_found.begin(), not_found.end(),
+ std::string(pef_command_hdr.Name));
+ it != not_found.end()) {
+ unreferenced_symbols.emplace_back(pef_command_hdr.Name);
}
+ }
- if (!unreferenced_symbols.empty())
- {
- for (auto &unreferenced_symbol : unreferenced_symbols)
- {
- kStdOut << "ld: undefined symbol " << unreferenced_symbol << "\n";
- }
+ if (!unreferenced_symbols.empty()) {
+ for (auto &unreferenced_symbol : unreferenced_symbols) {
+ kStdOut << "ld: undefined symbol " << unreferenced_symbol << "\n";
}
+ }
- if (!kStartFound ||
- kDuplicateSymbols &&
- std::filesystem::exists(kOutput) ||
- !unreferenced_symbols.empty())
- {
- if (kVerbose)
- kStdOut << "ld: code for: " << kOutput << ", is corrupt, removing file...\n";
+ if (!kStartFound || kDuplicateSymbols && std::filesystem::exists(kOutput) ||
+ !unreferenced_symbols.empty()) {
+ if (kVerbose)
+ kStdOut << "ld: code for: " << kOutput
+ << ", is corrupt, removing file...\n";
- std::remove(kOutput.c_str());
- return -CXXKIT_EXEC_ERROR;
- }
+ std::remove(kOutput.c_str());
+ return -CXXKIT_EXEC_ERROR;
+ }
- return 0;
+ return 0;
}
-// Last rev 13-1-24 \ No newline at end of file
+// Last rev 13-1-24
diff --git a/Public/PDF/325462-sdm-vol-1-2abcd-3abcd-4.pdf b/Public/Documentation/325462-sdm-vol-1-2abcd-3abcd-4.pdf
index 2481790..2481790 100644
--- a/Public/PDF/325462-sdm-vol-1-2abcd-3abcd-4.pdf
+++ b/Public/Documentation/325462-sdm-vol-1-2abcd-3abcd-4.pdf
Binary files differ
diff --git a/Public/PDF/ASM_SPECS.TXT b/Public/Documentation/ASM_SPECS.TXT
index a0c42bf..a0c42bf 100644
--- a/Public/PDF/ASM_SPECS.TXT
+++ b/Public/Documentation/ASM_SPECS.TXT
diff --git a/Public/PDF/HAVP.TXT b/Public/Documentation/HAVP.TXT
index 12fcec5..12fcec5 100644
--- a/Public/PDF/HAVP.TXT
+++ b/Public/Documentation/HAVP.TXT
diff --git a/Public/PDF/Inside 64x0.pdf b/Public/Documentation/Inside 64x0.pdf
index bcd6782..bcd6782 100644
--- a/Public/PDF/Inside 64x0.pdf
+++ b/Public/Documentation/Inside 64x0.pdf
Binary files differ
diff --git a/Public/PDF/NOTICE.TXT b/Public/Documentation/NOTICE.TXT
index 23691da..23691da 100644
--- a/Public/PDF/NOTICE.TXT
+++ b/Public/Documentation/NOTICE.TXT
diff --git a/Public/PDF/VNRP.TXT b/Public/Documentation/VNRP.TXT
index e17b494..e17b494 100644
--- a/Public/PDF/VNRP.TXT
+++ b/Public/Documentation/VNRP.TXT