summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-29 10:48:12 +0200
committerGitHub <noreply@github.com>2025-05-29 10:48:12 +0200
commit433bb5ef102b2bfa0049468be00d63011da8b973 (patch)
treee0893a30710477045a5bb085cb7a27aada425c14 /dev/LibCompiler/src
parent1ddeab9a4426abd781a5066ba79af2ba64de11d9 (diff)
parent756ee7f8dc954e27350fe5bdfbaa83b9f69780c8 (diff)
Merge pull request #6 from nekernel-org/dev
0.0.2e3
Diffstat (limited to 'dev/LibCompiler/src')
-rw-r--r--dev/LibCompiler/src/Backend/Assembler32x0.cc (renamed from dev/LibCompiler/src/Assembler32x0.cc)24
-rw-r--r--dev/LibCompiler/src/Backend/Assembler64x0.cc (renamed from dev/LibCompiler/src/Assembler64x0.cc)13
-rw-r--r--dev/LibCompiler/src/Backend/AssemblerAMD64.cc (renamed from dev/LibCompiler/src/AssemblerAMD64.cc)227
-rw-r--r--dev/LibCompiler/src/Backend/AssemblerARM64.cc (renamed from dev/LibCompiler/src/AssemblerARM64.cc)15
-rw-r--r--dev/LibCompiler/src/Backend/AssemblerPowerPC.cc (renamed from dev/LibCompiler/src/AssemblerPowerPC.cc)15
-rw-r--r--dev/LibCompiler/src/BasicString.cc (renamed from dev/LibCompiler/src/StringView.cc)34
-rw-r--r--dev/LibCompiler/src/CCompiler64x0.cc1288
-rw-r--r--dev/LibCompiler/src/CCompilerARM64.cc1286
-rw-r--r--dev/LibCompiler/src/CCompilerPower64.cc1305
-rw-r--r--dev/LibCompiler/src/CodeGen.cc (renamed from dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc)17
-rw-r--r--dev/LibCompiler/src/Frontend.cc51
-rw-r--r--dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc (renamed from dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc)433
-rw-r--r--dev/LibCompiler/src/Linkers/DynamicLinkerPEF.cc (renamed from dev/LibCompiler/src/DynamicLinkerPEF.cc)253
-rw-r--r--dev/LibCompiler/src/Macro/CPlusPlusCompilerPreProcessor.cc (renamed from dev/LibCompiler/src/CPlusPlusCompilerPreProcessor.cc)139
14 files changed, 633 insertions, 4467 deletions
diff --git a/dev/LibCompiler/src/Assembler32x0.cc b/dev/LibCompiler/src/Backend/Assembler32x0.cc
index ac24946..b7ff321 100644
--- a/dev/LibCompiler/src/Assembler32x0.cc
+++ b/dev/LibCompiler/src/Backend/Assembler32x0.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
@@ -17,26 +17,15 @@
/////////////////////////////////////////////////////////////////////////////////////////
+#ifndef __ASM_NEED_32x0__
#define __ASM_NEED_32x0__ 1
+#endif
#include <LibCompiler/AE.h>
#include <LibCompiler/Backend/32x0.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/PEF.h>
-#include <LibCompiler/Parser.h>
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-#define kYellow "\e[0;33m"
-
-#define kStdOut (std::cout << kWhite)
-#define kStdErr (std::cout << kRed)
+#include <LibCompiler/Util/CompilerUtils.h>
/////////////////////////////////////////////////////////////////////////////////////////
@@ -45,5 +34,6 @@
/////////////////////////////////////////////////////////////////////////////////////////
LIBCOMPILER_MODULE(NEAssemblerMain32000) {
- return 0;
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
+ return EXIT_SUCCESS;
}
diff --git a/dev/LibCompiler/src/Assembler64x0.cc b/dev/LibCompiler/src/Backend/Assembler64x0.cc
index 8483e9e..765bea2 100644
--- a/dev/LibCompiler/src/Assembler64x0.cc
+++ b/dev/LibCompiler/src/Backend/Assembler64x0.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
@@ -17,13 +17,15 @@
/////////////////////////////////////////////////////////////////////////////////////////
+#ifndef __ASM_NEED_64x0__
#define __ASM_NEED_64x0__ 1
+#endif
#include <LibCompiler/AE.h>
#include <LibCompiler/Backend/64x0.h>
-#include <LibCompiler/Detail/ClUtils.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/PEF.h>
-#include <LibCompiler/Parser.h>
+#include <LibCompiler/Util/CompilerUtils.h>
#include <algorithm>
#include <filesystem>
#include <fstream>
@@ -38,8 +40,7 @@
static char kOutputArch = LibCompiler::kPefArch64000;
-/// @note The 64x0 is VLSIW, so we need to jump to 4 bytes.
-constexpr auto k64x0IPAlignment = 0x4U;
+constexpr auto k64x0IPAlignment = 0x1U;
static std::size_t kCounter = 1UL;
@@ -67,7 +68,7 @@ static bool asm_read_attributes(std::string line);
/////////////////////////////////////////////////////////////////////////////////////////
LIBCOMPILER_MODULE(AssemblerMain64x0) {
- ::signal(SIGSEGV, Detail::segfault_handler);
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
for (size_t i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
diff --git a/dev/LibCompiler/src/AssemblerAMD64.cc b/dev/LibCompiler/src/Backend/AssemblerAMD64.cc
index 5e9a7cd..6551743 100644
--- a/dev/LibCompiler/src/AssemblerAMD64.cc
+++ b/dev/LibCompiler/src/Backend/AssemblerAMD64.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
@@ -21,15 +21,17 @@
/////////////////////////////////////////////////////////////////////////////////////////
+#ifndef __ASM_NEED_AMD64__
#define __ASM_NEED_AMD64__ 1
+#endif
#define kAssemblerPragmaSymStr "#"
#define kAssemblerPragmaSym '#'
#include <LibCompiler/AE.h>
-#include <LibCompiler/Backend/Amd64.h>
+#include <LibCompiler/Backend/X64.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/PEF.h>
-#include <LibCompiler/Parser.h>
#include <algorithm>
#include <cstdlib>
#include <filesystem>
@@ -48,9 +50,6 @@
#define kWhite "\e[0;97m"
#define kYellow "\e[0;33m"
-#define kStdOut (std::cout << kWhite)
-#define kStdErr (std::cout << kRed)
-
static char kOutputArch = LibCompiler::kPefArchAMD64;
constexpr auto kIPAlignement = 0x1U;
@@ -77,7 +76,7 @@ static const std::string kUndefinedSymbol = ":UndefinedSymbol:";
// \brief forward decl.
static bool asm_read_attributes(std::string line);
-#include <LibCompiler/Detail/AsmUtils.h>
+#include <LibCompiler/Util/AsmUtils.h>
/////////////////////////////////////////////////////////////////////////////////////////
@@ -88,7 +87,7 @@ static bool asm_read_attributes(std::string line);
LIBCOMPILER_MODULE(AssemblerMainAMD64) {
//////////////// CPU OPCODES BEGIN ////////////////
- ::signal(SIGSEGV, Detail::segfault_handler);
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
std::string opcodes_jump[kJumpLimit] = {"ja", "jae", "jb", "jbe", "jc", "je", "jg", "jge",
"jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne",
@@ -965,13 +964,9 @@ bool LibCompiler::EncoderAMD64::WriteLine(std::string line, std::string file) {
{.fName = "dx", .fModRM = 0x2}, {.fName = "bx", .fModRM = 3},
{.fName = "sp", .fModRM = 0x4}, {.fName = "bp", .fModRM = 5},
{.fName = "si", .fModRM = 0x6}, {.fName = "di", .fModRM = 7},
- {.fName = "r8", .fModRM = 8}, {.fName = "r13", .fModRM = 9},
- {.fName = "r9", .fModRM = 10}, {.fName = "r14", .fModRM = 11},
- {.fName = "r10", .fModRM = 12}, {.fName = "r15", .fModRM = 13},
- {.fName = "r11", .fModRM = 14},
};
- bool foundInstruction = false;
+ BOOL foundInstruction = false;
for (auto& opcodeAMD64 : kOpcodesAMD64) {
// strict check here
@@ -981,140 +976,157 @@ bool LibCompiler::EncoderAMD64::WriteLine(std::string line, std::string file) {
std::string name(opcodeAMD64.fName);
/// Move instruction handler.
- if (line.find(name) != std::string::npos && name == "mov") {
- std::string substr = line.substr(line.find(name) + name.size());
+ if (line.find(name) != std::string::npos) {
+ if (name == "mov" || name == "xor") {
+ std::string substr = line.substr(line.find(name) + name.size());
- uint64_t bits = kRegisterBitWidth;
+ uint64_t bits = kRegisterBitWidth;
- if (substr.find(",") == std::string::npos) {
- Detail::print_error("Syntax error: missing right operand.", "LibCompiler");
- throw std::runtime_error("syntax_err");
- }
+ if (substr.find(",") == std::string::npos) {
+ Detail::print_error("Syntax error: missing right operand.", "LibCompiler");
+ throw std::runtime_error("syntax_err");
+ }
- bool onlyOneReg = true;
+ bool onlyOneReg = true;
- std::vector<RegMapAMD64> currentRegList;
+ std::vector<RegMapAMD64> currentRegList;
- for (auto& reg : kRegisterList) {
- std::vector<char> regExt = {'e', 'r'};
+ for (auto& reg : kRegisterList) {
+ std::vector<char> regExt = {'e', 'r'};
- for (auto& ext : regExt) {
- std::string registerName;
+ for (auto& ext : regExt) {
+ std::string registerName;
- if (bits > 16) registerName.push_back(ext);
+ if (bits > 16) registerName.push_back(ext);
- registerName += reg.fName;
+ registerName += reg.fName;
- while (line.find(registerName) != std::string::npos) {
- line.erase(line.find(registerName), registerName.size());
+ while (line.find(registerName) != std::string::npos) {
+ line.erase(line.find(registerName), registerName.size());
- if (bits == 16) {
- if (registerName[0] == 'r') {
- Detail::print_error("invalid size for register, current bit width is: " +
- std::to_string(kRegisterBitWidth),
- file);
- throw std::runtime_error("invalid_reg_size");
+ if (bits == 16) {
+ if (registerName[0] == 'r') {
+ Detail::print_error("invalid size for register, current bit width is: " +
+ std::to_string(kRegisterBitWidth),
+ file);
+ throw std::runtime_error("invalid_reg_size");
+ }
}
- }
- currentRegList.push_back({.fName = registerName, .fModRM = reg.fModRM});
+ currentRegList.push_back({.fName = registerName, .fModRM = reg.fModRM});
+ }
}
}
- }
-
- if (currentRegList.size() > 1) onlyOneReg = false;
- bool hasRBasedRegs = false;
-
- if (!onlyOneReg) {
- /// very tricky to understand.
- /// but this checks for a r8 through r15 register.
- if (currentRegList[0].fName[0] == 'r' || currentRegList[1].fName[0] == 'r') {
- if (isdigit(currentRegList[0].fName[1]) && isdigit(currentRegList[1].fName[1])) {
- kAppBytes.emplace_back(0x4d);
- hasRBasedRegs = true;
- } else if (isdigit(currentRegList[0].fName[1]) || isdigit(currentRegList[1].fName[1])) {
- kAppBytes.emplace_back(0x4c);
- hasRBasedRegs = true;
+ if (currentRegList.size() > 1) onlyOneReg = false;
+
+ bool hasRBasedRegs = false;
+
+ if (!onlyOneReg) {
+ /// very tricky to understand.
+ /// but this checks for a r8 through r15 register.
+ if (currentRegList[0].fName[0] == 'r' || currentRegList[1].fName[0] == 'r') {
+ if (isdigit(currentRegList[0].fName[1]) && isdigit(currentRegList[1].fName[1])) {
+ kAppBytes.emplace_back(0x4d);
+ hasRBasedRegs = true;
+ } else if (isdigit(currentRegList[0].fName[1]) ||
+ isdigit(currentRegList[1].fName[1])) {
+ kAppBytes.emplace_back(0x4c);
+ hasRBasedRegs = true;
+ }
}
}
- }
- if (bits == 64 || bits == 32) {
- if (!hasRBasedRegs && bits >= 32) {
- kAppBytes.emplace_back(opcodeAMD64.fOpcode);
- }
+ if (name == "mov") {
+ if (bits == 64 || bits == 32) {
+ if (!hasRBasedRegs && bits >= 32) {
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
+ }
- if (!onlyOneReg) kAppBytes.emplace_back(0x89);
- } else if (bits == 16) {
- if (hasRBasedRegs) {
- Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
- throw std::runtime_error("comb_op_reg");
+ if (!onlyOneReg) kAppBytes.emplace_back(0x89);
+ } else if (bits == 16) {
+ if (hasRBasedRegs) {
+ Detail::print_error("Invalid combination of operands and registers.",
+ "LibCompiler");
+ throw std::runtime_error("comb_op_reg");
+ } else {
+ kAppBytes.emplace_back(0x66);
+ kAppBytes.emplace_back(0x89);
+ }
+ }
} else {
- kAppBytes.emplace_back(0x66);
- kAppBytes.emplace_back(0x89);
- }
- }
-
- if (onlyOneReg) {
- auto num = GetNumber32(line, ",");
+ if (!hasRBasedRegs && bits >= 32) {
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
+ }
- for (auto& num_idx : num.number) {
- if (num_idx == 0) num_idx = 0xFF;
+ kAppBytes.emplace_back(0x31);
}
- auto modrm = (0x3 << 6 | currentRegList[0].fModRM);
+ if (onlyOneReg) {
+ auto num = GetNumber32(line, ",");
- kAppBytes.emplace_back(0xC7); // prefixed before placing the modrm and then the number.
- kAppBytes.emplace_back(modrm);
- kAppBytes.emplace_back(num.number[0]);
- kAppBytes.emplace_back(num.number[1]);
- kAppBytes.emplace_back(num.number[2]);
- kAppBytes.emplace_back(num.number[3]);
+ for (auto& num_idx : num.number) {
+ if (num_idx == 0) num_idx = 0xFF;
+ }
- break;
- }
+ auto modrm = (0x3 << 6 | currentRegList[0].fModRM);
- if (currentRegList[1].fName[0] == 'r' && currentRegList[0].fName[0] == 'e') {
- Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
- throw std::runtime_error("comb_op_reg");
- }
+ kAppBytes.emplace_back(0xC7); // prefixed before placing the modrm and then the number.
+ kAppBytes.emplace_back(modrm);
- if (currentRegList[0].fName[0] == 'r' && currentRegList[1].fName[0] == 'e') {
- Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
- throw std::runtime_error("comb_op_reg");
- }
+ if (name != "xor") {
+ kAppBytes.emplace_back(num.number[0]);
+ kAppBytes.emplace_back(num.number[1]);
+ kAppBytes.emplace_back(num.number[2]);
+ kAppBytes.emplace_back(num.number[3]);
+ }
- if (bits == 16) {
- if (currentRegList[0].fName[0] == 'r' || currentRegList[0].fName[0] == 'e') {
- Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
- throw std::runtime_error("comb_op_reg");
+ break;
}
- if (currentRegList[1].fName[0] == 'r' || currentRegList[1].fName[0] == 'e') {
+ if (currentRegList[1].fName[0] == 'r' && currentRegList[0].fName[0] == 'e') {
Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
throw std::runtime_error("comb_op_reg");
}
- } else {
- if (currentRegList[0].fName[0] != 'r' || currentRegList[0].fName[0] == 'e') {
+
+ if (currentRegList[0].fName[0] == 'r' && currentRegList[1].fName[0] == 'e') {
Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
throw std::runtime_error("comb_op_reg");
}
- if (currentRegList[1].fName[0] != 'r' || currentRegList[1].fName[0] == 'e') {
- Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
- throw std::runtime_error("comb_op_reg");
+ if (bits == 16) {
+ if (currentRegList[0].fName[0] == 'r' || currentRegList[0].fName[0] == 'e') {
+ Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
+ throw std::runtime_error("comb_op_reg");
+ }
+
+ if (currentRegList[1].fName[0] == 'r' || currentRegList[1].fName[0] == 'e') {
+ Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
+ throw std::runtime_error("comb_op_reg");
+ }
+ } else {
+ if (currentRegList[0].fName[0] != 'r' || currentRegList[0].fName[0] == 'e') {
+ Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
+ throw std::runtime_error("comb_op_reg");
+ }
+
+ if (currentRegList[1].fName[0] != 'r' || currentRegList[1].fName[0] == 'e') {
+ Detail::print_error("Invalid combination of operands and registers.", "LibCompiler");
+ throw std::runtime_error("comb_op_reg");
+ }
}
- }
- /// encode register using the modrm encoding.
+ /// encode register using the modrm encoding.
- auto modrm = (0x3 << 6 | currentRegList[1].fModRM << 3 | currentRegList[0].fModRM);
+ auto modrm = (0x3 << 6 | currentRegList[1].fModRM << 3 | currentRegList[0].fModRM);
- kAppBytes.emplace_back(modrm);
+ kAppBytes.emplace_back(modrm);
- break;
- } else if (name == "int" || name == "into" || name == "intd") {
+ break;
+ }
+ }
+
+ if (name == "int" || name == "into" || name == "intd") {
kAppBytes.emplace_back(opcodeAMD64.fOpcode);
this->WriteNumber8(line.find(name) + name.size() + 1, line);
@@ -1127,6 +1139,11 @@ bool LibCompiler::EncoderAMD64::WriteLine(std::string line, std::string file) {
}
break;
+ } else if (name == "syscall") {
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
+ kAppBytes.emplace_back(0x05);
+
+ break;
} else {
kAppBytes.emplace_back(opcodeAMD64.fOpcode);
diff --git a/dev/LibCompiler/src/AssemblerARM64.cc b/dev/LibCompiler/src/Backend/AssemblerARM64.cc
index 8686edb..a1cc6dc 100644
--- a/dev/LibCompiler/src/AssemblerARM64.cc
+++ b/dev/LibCompiler/src/Backend/AssemblerARM64.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
@@ -15,14 +15,16 @@
/////////////////////////////////////////////////////////////////////////////////////////
+#ifndef __ASM_NEED_ARM64__
#define __ASM_NEED_ARM64__ 1
+#endif
#include <LibCompiler/AE.h>
#include <LibCompiler/Backend/Aarch64.h>
-#include <LibCompiler/Detail/AsmUtils.h>
#include <LibCompiler/ErrorID.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/PEF.h>
-#include <LibCompiler/Parser.h>
+#include <LibCompiler/Util/AsmUtils.h>
#include <LibCompiler/Version.h>
#include <algorithm>
#include <filesystem>
@@ -41,12 +43,9 @@
#define kWhite "\e[0;97m"
#define kYellow "\e[0;33m"
-#define kStdOut (std::cout << kWhite)
-#define kStdErr (std::cout << kRed)
-
constexpr auto cPowerIPAlignment = 0x1U;
-static CharType kOutputArch = LibCompiler::kPefArchARM64;
+static Char kOutputArch = LibCompiler::kPefArchARM64;
static std::size_t kCounter = 1UL;
@@ -74,7 +73,7 @@ static bool asm_read_attributes(std::string line);
/////////////////////////////////////////////////////////////////////////////////////////
LIBCOMPILER_MODULE(AssemblerMainARM64) {
- ::signal(SIGSEGV, Detail::segfault_handler);
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
for (size_t i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
diff --git a/dev/LibCompiler/src/AssemblerPowerPC.cc b/dev/LibCompiler/src/Backend/AssemblerPowerPC.cc
index f2c3be3..b979f64 100644
--- a/dev/LibCompiler/src/AssemblerPowerPC.cc
+++ b/dev/LibCompiler/src/Backend/AssemblerPowerPC.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
@@ -15,14 +15,16 @@
/////////////////////////////////////////////////////////////////////////////////////////
+#ifndef __ASM_NEED_PPC__
#define __ASM_NEED_PPC__ 1
+#endif
#include <LibCompiler/AE.h>
#include <LibCompiler/Backend/PowerPC.h>
-#include <LibCompiler/Detail/AsmUtils.h>
#include <LibCompiler/ErrorID.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/PEF.h>
-#include <LibCompiler/Parser.h>
+#include <LibCompiler/Util/AsmUtils.h>
#include <LibCompiler/Version.h>
#include <algorithm>
#include <filesystem>
@@ -41,12 +43,9 @@
#define kWhite "\e[0;97m"
#define kYellow "\e[0;33m"
-#define kStdOut (std::cout << kWhite)
-#define kStdErr (std::cout << kRed)
-
constexpr auto cPowerIPAlignment = 0x4U;
-static CharType kOutputArch = LibCompiler::kPefArchPowerPC;
+static Char kOutputArch = LibCompiler::kPefArchPowerPC;
static std::size_t kCounter = 1UL;
@@ -74,7 +73,7 @@ static bool asm_read_attributes(std::string line);
/////////////////////////////////////////////////////////////////////////////////////////
LIBCOMPILER_MODULE(AssemblerMainPower64) {
- ::signal(SIGSEGV, Detail::segfault_handler);
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
for (size_t i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
diff --git a/dev/LibCompiler/src/StringView.cc b/dev/LibCompiler/src/BasicString.cc
index 41ee636..41989fe 100644
--- a/dev/LibCompiler/src/StringView.cc
+++ b/dev/LibCompiler/src/BasicString.cc
@@ -8,7 +8,7 @@
*/
/**
- * @file String.cxx
+ * @file BasicString.cxx
* @author Amlal (amlal@el-mahrouss-logic.com)
* @brief C++ string manipulation API.
* @version 0.2
@@ -18,22 +18,22 @@
*
*/
-#include <LibCompiler/StringView.h>
+#include <LibCompiler/BasicString.h>
namespace LibCompiler {
-CharType* StringView::Data() {
+Char* BasicString::Data() {
return m_Data;
}
-const CharType* StringView::CData() const {
+const Char* BasicString::CData() const {
return m_Data;
}
-SizeType StringView::Length() const {
+SizeType BasicString::Length() const {
return strlen(m_Data);
}
-bool StringView::operator==(const StringView& rhs) const {
+bool BasicString::operator==(const BasicString& rhs) const {
if (rhs.Length() != Length()) return false;
for (SizeType index = 0; index < Length(); ++index) {
@@ -43,7 +43,7 @@ bool StringView::operator==(const StringView& rhs) const {
return true;
}
-bool StringView::operator==(const CharType* rhs) const {
+bool BasicString::operator==(const Char* rhs) const {
if (string_length(rhs) != Length()) return false;
for (SizeType index = 0; index < string_length(rhs); ++index) {
@@ -53,7 +53,7 @@ bool StringView::operator==(const CharType* rhs) const {
return true;
}
-bool StringView::operator!=(const StringView& rhs) const {
+bool BasicString::operator!=(const BasicString& rhs) const {
if (rhs.Length() != Length()) return false;
for (SizeType index = 0; index < rhs.Length(); ++index) {
@@ -63,7 +63,7 @@ bool StringView::operator!=(const StringView& rhs) const {
return true;
}
-bool StringView::operator!=(const CharType* rhs) const {
+bool BasicString::operator!=(const Char* rhs) const {
if (string_length(rhs) != Length()) return false;
for (SizeType index = 0; index < string_length(rhs); ++index) {
@@ -73,10 +73,10 @@ bool StringView::operator!=(const CharType* rhs) const {
return true;
}
-StringView StringBuilder::Construct(const CharType* data) {
- if (!data || *data == 0) return StringView(0);
+BasicString StringBuilder::Construct(const Char* data) {
+ if (!data || *data == 0) return BasicString(0);
- StringView view(strlen(data));
+ BasicString view(strlen(data));
view += data;
return view;
@@ -92,7 +92,7 @@ const char* StringBuilder::FromInt(const char* fmt, int i) {
memset(ret, 0, ret_len);
- CharType result[sizeof(int64_t)];
+ Char result[sizeof(int64_t)];
if (!to_str(result, sizeof(int64_t), i)) {
delete[] ret;
@@ -183,9 +183,9 @@ const char* StringBuilder::Format(const char* fmt, const char* fmtRight) {
return ret;
}
-StringView& StringView::operator+=(const CharType* rhs) {
+BasicString& BasicString::operator+=(const Char* rhs) {
if (strlen(rhs) > this->m_Sz) {
- throw std::runtime_error("out_of_bounds: StringView");
+ throw std::runtime_error("out_of_bounds: BasicString");
}
memcpy(this->m_Data + this->m_Cur, rhs, strlen(rhs));
@@ -194,9 +194,9 @@ StringView& StringView::operator+=(const CharType* rhs) {
return *this;
}
-StringView& StringView::operator+=(const StringView& rhs) {
+BasicString& BasicString::operator+=(const BasicString& rhs) {
if (rhs.m_Cur > this->m_Sz) {
- throw std::runtime_error("out_of_bounds: StringView");
+ throw std::runtime_error("out_of_bounds: BasicString");
}
memcpy(this->m_Data + this->m_Cur, rhs.CData(), strlen(rhs.CData()));
diff --git a/dev/LibCompiler/src/CCompiler64x0.cc b/dev/LibCompiler/src/CCompiler64x0.cc
deleted file mode 100644
index 79d32ce..0000000
--- a/dev/LibCompiler/src/CCompiler64x0.cc
+++ /dev/null
@@ -1,1288 +0,0 @@
-/*
- * ========================================================
- *
- * cc
- * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved.
- *
- * ========================================================
- */
-
-/// BUGS: 0
-/// TODO: none
-
-#include <LibCompiler/Backend/64x0.h>
-#include <LibCompiler/Detail/ClUtils.h>
-#include <LibCompiler/Parser.h>
-#include <LibCompiler/UUID.h>
-#include <cstdio>
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <random>
-#include <string>
-#include <utility>
-#include <vector>
-
-/* C driver */
-/* This is part of the LibCompiler. */
-/* (c) Amlal El Mahrouss */
-
-/// @author EL Mahrouss Amlal (amlel)
-/// @file 64x0-cc.cxx
-/// @brief 64x0 C Compiler.
-
-/// TODO: support structures, else if, else, . and ->
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kExitOK (0)
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-
-/////////////////////////////////////
-
-// INTERNAL STUFF OF THE C COMPILER
-
-/////////////////////////////////////
-
-namespace Detail {
-// \brief Register map structure, used to keep track of each variable's registers.
-struct CompilerRegisterMap final {
- std::string fName;
- std::string fReg;
-};
-
-// \brief Map for C 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<LibCompiler::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- LibCompiler::SyntaxLeafList* fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool fVerbose;
-};
-} // namespace Detail
-
-static Detail::CompilerState kState;
-static std::string kIfFunction = "";
-
-namespace Detail {
-/// @brief prints an error into stdout.
-/// @param reason the reason of the error.
-/// @param file where does it originate from?
-void print_error(std::string reason, std::string file) noexcept;
-
-struct CompilerType final {
- std::string fName;
- std::string fValue;
-};
-} // namespace Detail
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// Target architecture.
-static int kMachine = 0;
-
-/////////////////////////////////////////
-
-// REGISTERS ACCORDING TO USED ASSEMBLER
-
-/////////////////////////////////////////
-
-static size_t kRegisterCnt = kAsmRegisterLimit;
-static size_t kStartUsable = 2;
-static size_t kUsableLimit = 15;
-static size_t kRegisterCounter = kStartUsable;
-static std::string kRegisterPrefix = kAsmRegisterPrefix;
-
-/////////////////////////////////////////
-
-// COMPILER PARSING UTILITIES/STATES.
-
-/////////////////////////////////////////
-
-static std::vector<std::string> kFileList;
-static LibCompiler::AssemblyFactory kFactory;
-static bool kInStruct = false;
-static bool kOnWhileLoop = false;
-static bool kOnForLoop = false;
-static bool kInBraces = false;
-static bool kIfFound = false;
-static size_t kBracesCount = 0UL;
-
-/* @brief C compiler backend for C */
-class CompilerFrontend64x0 final : public LibCompiler::ICompilerFrontend {
- public:
- explicit CompilerFrontend64x0() = default;
- ~CompilerFrontend64x0() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(CompilerFrontend64x0);
-
- std::string Check(const char* text, const char* file);
- bool Compile(std::string text, std::string file) override;
-
- const char* Language() override { return "64k C"; }
-};
-
-static CompilerFrontend64x0* kCompilerFrontend = nullptr;
-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
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @name Compile
-// @brief Generate MASM from a C assignement.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-bool CompilerFrontend64x0::Compile(std::string text_, std::string file) {
- std::string text = text_;
-
- bool typeFound = false;
- bool fnFound = false;
-
- // setup generator.
- std::random_device rd;
-
- auto seed_data = std::array<int, std::mt19937::state_size>{};
- std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd));
- std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
- std::mt19937 generator(seq);
-
- // start parsing
- for (size_t text_index = 0; text_index < text.size(); ++text_index) {
- auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
-
- auto gen = uuids::uuid_random_generator{generator};
- uuids::uuid out = gen();
-
- Detail::number_cast time_off = (UInt64) out.as_bytes().data();
-
- if (!typeFound) {
- auto substr = text.substr(text_index);
- std::string match_type;
-
- 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(' '));
- }
-
- for (auto& clType : kCompilerTypes) {
- if (clType.fName == match_type) {
- match_type.clear();
-
- std::string buf;
-
- buf += clType.fValue;
- buf += ' ';
-
- if (substr.find('=') != std::string::npos) {
- break;
- }
-
- if (text.find('(') != std::string::npos) {
- syntaxLeaf.fUserValue = buf;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- typeFound = true;
- break;
- }
- }
-
- break;
- }
-
- match_type += substr[y];
- }
- }
-
- if (text[text_index] == '{') {
- if (kInStruct) {
- continue;
- }
-
- kInBraces = true;
- ++kBracesCount;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- // return keyword handler
- if (text[text_index] == 'r') {
- std::string return_keyword;
- return_keyword += "return";
-
- std::size_t index = 0UL;
-
- std::string value;
-
- 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;
-
- value += text[value_index];
- }
-
- break;
- }
-
- ++index;
- }
-
- if (index == return_keyword.size()) {
- if (!value.empty()) {
- if (value.find('(') != std::string::npos) {
- value.erase(value.find('('));
- }
-
- if (!isdigit(value[value.find('(') + 2])) {
- std::string tmp = value;
- bool reg_to_reg = false;
-
- value.clear();
-
- value += " extern_segment";
- value += tmp;
- }
-
- syntaxLeaf.fUserValue = "\tldw r19, ";
-
- // make it pretty.
- if (value.find('\t') != std::string::npos) value.erase(value.find('\t'), 1);
-
- syntaxLeaf.fUserValue += value + "\n";
- }
-
- syntaxLeaf.fUserValue += "\tjlr";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- break;
- }
- }
-
- if (text[text_index] == 'i' && text[text_index + 1] == 'f') {
- auto expr = text.substr(text_index + 2);
- text.erase(text_index, 2);
-
- if (expr.find("{") != std::string::npos) {
- expr.erase(expr.find("{"));
- }
-
- if (expr.find("(") != std::string::npos) expr.erase(expr.find("("));
-
- if (expr.find(")") != std::string::npos) expr.erase(expr.find(")"));
-
- kIfFunction = "__LIBCOMPILER_IF_PROC_";
- kIfFunction += std::to_string(time_off._Raw);
-
- syntaxLeaf.fUserValue = "\tlda r12, extern_segment ";
- syntaxLeaf.fUserValue += kIfFunction +
- "\n\t#r12 = Code to jump on, r11 right cond, r10 left cond.\n\tbeq "
- "r10, r11, r12\ndword public_segment .code64 " +
- kIfFunction + "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- kIfFound = true;
- }
-
- // 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 (fnFound) continue;
- if (kIfFound) 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;
- }
-
- if (text[text_index] == ';' && kInStruct) {
- bool space_found_ = false;
- std::string sym;
-
- for (auto& ch : text) {
- if (ch == ' ') {
- space_found_ = true;
- }
-
- if (ch == ';') break;
-
- if (space_found_) sym.push_back(ch);
- }
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
- std::make_pair(kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4, sym));
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt =
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
-
- continue;
- }
-
- if (text[text_index] == '=' && kInStruct) {
- continue;
- }
-
- 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 && !kIfFound) {
- 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 public_segment .data64 ";
- }
-
- int first_encountered = 0;
-
- std::string str_name;
-
- for (size_t text_index_2 = 0; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') {
- ++text_index_2;
-
- // want to add this, so that the parser recognizes that this is a
- // string.
- substr += '"';
-
- for (; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') break;
-
- substr += text[text_index_2];
- }
- }
-
- if (text[text_index_2] == '{' || text[text_index_2] == '}') continue;
-
- 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("public_segment .data64") == std::string::npos && !kInStruct)
- substr += "public_segment .data64 ";
- }
-
- ++first_encountered;
-
- continue;
- }
-
- if (text[text_index_2] == '=') {
- if (!kInBraces) {
- substr.replace(substr.find("public_segment .data64"), strlen("public_segment .data64"),
- "public_segment .zero64 ");
- }
-
- substr += ",";
- continue;
- }
-
- substr += text[text_index_2];
- }
-
- for (auto& clType : kCompilerTypes) {
- if (substr.find(clType.fName) != std::string::npos) {
- if (substr.find(clType.fName) > substr.find('"')) continue;
-
- 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 (clType.fName == "const") continue;
-
- substr.erase(substr.find(clType.fValue), clType.fValue.size());
- }
- }
-
- if (substr.find("extern") != std::string::npos) {
- substr.replace(substr.find("extern"), strlen("extern"), "extern_segment ");
-
- if (substr.find("public_segment .data64") != std::string::npos)
- substr.erase(substr.find("public_segment .data64"), strlen("public_segment .data64"));
- }
-
- auto var_to_find = std::find_if(
- kCompilerVariables.cbegin(), kCompilerVariables.cend(),
- [&](Detail::CompilerType type) { return type.fName.find(substr) != std::string::npos; });
-
- if (kRegisterCounter == 5 || kRegisterCounter == 6) ++kRegisterCounter;
-
- std::string reg = kAsmRegisterPrefix;
- reg += std::to_string(kRegisterCounter);
-
- if (var_to_find == kCompilerVariables.cend()) {
- ++kRegisterCounter;
-
- kState.kStackFrame.push_back({.fName = substr, .fReg = reg});
- kCompilerVariables.push_back({.fName = substr});
- }
-
- syntaxLeaf.fUserValue += substr;
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- if (text[text_index] == '=') break;
- }
-
- // function handler.
-
- if (text[text_index] == '(' && !fnFound && !kIfFound) {
- std::string substr;
- std::string args_buffer;
- std::string args;
-
- bool type_crossed = false;
-
- for (size_t idx = text.find('(') + 1; idx < text.size(); ++idx) {
- if (text[idx] == ',') continue;
-
- if (text[idx] == ' ') continue;
-
- if (text[idx] == ')') break;
- }
-
- for (char substr_first_index : text) {
- if (substr_first_index != ',')
- args_buffer += substr_first_index;
- else
- args_buffer += '$';
-
- 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 (!args_buffer.empty()) args += "\tldw r6, ";
-
- std::string register_type;
- std::size_t index = 7UL;
-
- while (args_buffer.find("$") != std::string::npos) {
- register_type = kRegisterPrefix;
- register_type += std::to_string(index);
-
- ++index;
-
- args_buffer.replace(args_buffer.find('$'), 1, "\n\tldw " + register_type + ",");
- }
-
- args += args_buffer;
- args += "\n\tlda r19, ";
- }
- }
-
- for (char _text_i : text) {
- if (_text_i == '\t' || _text_i == ' ') {
- if (!type_crossed) {
- substr.clear();
- type_crossed = true;
- }
-
- continue;
- }
-
- if (_text_i == '(') break;
-
- substr += _text_i;
- }
-
- if (kInBraces) {
- syntaxLeaf.fUserValue = args;
- syntaxLeaf.fUserValue += substr;
- syntaxLeaf.fUserValue += "\n\tjrl\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- fnFound = true;
- } else {
- syntaxLeaf.fUserValue.clear();
-
- syntaxLeaf.fUserValue += "public_segment .code64 ";
-
- syntaxLeaf.fUserValue += substr;
- syntaxLeaf.fUserValue += "\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- fnFound = true;
- }
-
- kCompilerFunctions.push_back(text);
- }
-
- if (text[text_index] == '-' && text[text_index + 1] == '-') {
- text = text.replace(text.find("--"), strlen("--"), "");
-
- for (int _text_i = 0; _text_i < text.size(); ++_text_i) {
- if (text[_text_i] == '\t' || text[_text_i] == ' ') text.erase(_text_i, 1);
- }
-
- syntaxLeaf.fUserValue += "sub ";
- syntaxLeaf.fUserValue += text;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- break;
- }
-
- if (text[text_index] == '}') {
- kRegisterCounter = kStartUsable;
-
- --kBracesCount;
-
- if (kBracesCount < 1) {
- kInBraces = false;
- kBracesCount = 0;
- }
-
- if (kIfFound) kIfFound = false;
-
- if (kInStruct) kInStruct = false;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- syntaxLeaf.fUserValue.clear();
- }
-
- auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
- syntaxLeaf.fUserValue = "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- return true;
-}
-
-static bool kShouldHaveBraces = false;
-static std::string kFnName;
-
-std::string CompilerFrontend64x0::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;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (isalnum(ln[i])) {
- non_ascii_found = true;
- break;
- }
- }
-
- if (kShouldHaveBraces && ln.find('{') != std::string::npos) {
- kShouldHaveBraces = false;
- }
-
- if (!non_ascii_found) return err_str;
-
- size_t string_index = 1UL;
-
- 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);
- }
-
- 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("class");
- 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;
- }
- }
- }
-
- 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;
- }
-
- keyword.push_back(ln[string_index]);
- }
-
- goto cc_next_loop;
-
- cc_check_done:
-
- // skip digit value.
- if (isdigit(keyword[0]) || keyword[0] == '"') {
- goto cc_next_loop;
- }
-
- while (keyword.find(' ') != std::string::npos) keyword.erase(keyword.find(' '), 1);
-
- for (auto& var : kCompilerVariables) {
- if (var.fValue.find(keyword) != std::string::npos) {
- err_str.clear();
- goto cc_next;
- }
- }
-
- 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;
- }
- }
- }
-
- cc_error_value:
- if (keyword.find("->") != std::string::npos) return err_str;
-
- if (keyword.find(".") != std::string::npos) return err_str;
-
- if (isalnum(keyword[0])) err_str += "\nUndefined value: " + keyword;
-
- return err_str;
- }
-
- cc_next_loop:
- continue;
- }
-
-cc_next:
-
- // extern does not declare anything, it extern_segments a variable.
- // so that's why it's not declare upper.
- if (LibCompiler::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 (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;
- }
- }
-
-skip_braces_check:
-
- for (auto& key : kCompilerTypes) {
- if (LibCompiler::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[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;
-
- 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;
- }
- }
-
- next:
-
- 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;
- }
-
- 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 (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 && !LibCompiler::find_word(ln, "|") &&
- !LibCompiler::find_word(ln, "||") && !LibCompiler::find_word(ln, "&") &&
- !LibCompiler::find_word(ln, "&&") && !LibCompiler::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;
-
- bool space_found = false;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (ln[i] == ')' && !space_found) {
- space_found = true;
- continue;
- }
-
- if (space_found) {
- if (ln[i] == ' ' && isalnum(ln[i + 1])) {
- err_str += "\nBad function format 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) {
- 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('}') != 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;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief C To Assembly mount-point.
- */
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class AssemblyCCInterface final ASSEMBLY_INTERFACE {
- public:
- explicit AssemblyCCInterface() = default;
- ~AssemblyCCInterface() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(AssemblyCCInterface);
-
- [[maybe_unused]] Int32 Arch() noexcept override {
- return LibCompiler::AssemblyFactory::kArch64x0;
- }
-
- Int32 CompileToFormat(std::string src, Int32 arch) override {
- if (kCompilerFrontend == nullptr) return 1;
-
- /* @brief copy contents wihtout extension */
- std::string src_file = src.data();
- std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
- std::string dest;
-
- for (auto& ch : src_file) {
- if (ch == '.') {
- break;
- }
-
- dest += ch;
- }
-
- /* According to PEF ABI. */
- std::vector<const char*> exts = kAsmFileExts;
- dest += exts[4];
-
- kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
-
- auto fmt = LibCompiler::current_date();
-
- (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
- (*kState.fOutputAssembly) << "# Language: 64x0 Assembly (Generated from ANSI C)\n";
- (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n";
-
- LibCompiler::SyntaxLeafList syntax;
-
- kState.fSyntaxTreeList.push_back(syntax);
- kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
-
- std::string line_src;
-
- while (std::getline(src_fp, line_src)) {
- if (auto err = kCompilerFrontend->Check(line_src.c_str(), src.data()); err.empty()) {
- kCompilerFrontend->Compile(line_src, src.data());
- } else {
- Detail::print_error(err, src.data());
- }
- }
-
- if (kAcceptableErrors > 0) return 1;
-
- std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta", "add", "sub", "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 (LibCompiler::find_word(leaf.fUserValue, access_ident)) {
- for (auto& struc : kState.kStructMap) {
- /// TODO:
- }
- }
- }
-
- for (auto& keyword : keywords) {
- if (LibCompiler::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 (LibCompiler::find_word(leaf.fUserValue, needle)) {
- if (leaf.fUserValue.find("extern_segment " + needle) != std::string::npos) {
- std::string range = "extern_segment " + needle;
- leaf.fUserValue.replace(leaf.fUserValue.find("extern_segment " + needle),
- range.size(), 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 != "sub") {
- leaf.fUserValue.replace(leaf.fUserValue.find(keyword), keyword.size(), "mv");
- }
- }
- }
- }
-
- for (auto& leaf : kState.fSyntaxTree->fLeafList) {
- (*kState.fOutputAssembly) << leaf.fUserValue;
- }
-
- kState.fSyntaxTree = nullptr;
-
- kState.fOutputAssembly->flush();
- kState.fOutputAssembly.reset();
-
- return kExitOK;
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#include <LibCompiler/Version.h>
-
-#define kPrintF printf
-#define kSplashCxx() kPrintF(kWhite "NE C Driver, %s, (c) Amlal El Mahrouss\n", kDistVersion)
-
-static void cc_print_help() {
- kSplashCxx();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define kExt ".c"
-
-LIBCOMPILER_MODULE(NeOSCompilerCLang64x0) {
- ::signal(SIGSEGV, Detail::segfault_handler);
-
- 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"});
- kCompilerTypes.push_back({.fName = "*", .fValue = "offset"});
-
- bool skip = false;
-
- kFactory.Mount(new AssemblyCCInterface());
- kMachine = LibCompiler::AssemblyFactory::kArch64x0;
- kCompilerFrontend = new CompilerFrontend64x0();
-
- 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 kExitOK;
- }
-
- if (strcmp(argv[index], "--verbose") == 0) {
- kState.fVerbose = true;
-
- continue;
- }
-
- if (strcmp(argv[index], "--h") == 0 || strcmp(argv[index], "--help") == 0) {
- cc_print_help();
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "--dialect") == 0) {
- if (kCompilerFrontend) std::cout << kCompilerFrontend->Language() << "\n";
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "--fmax-exceptions") == 0) {
- try {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...) {
- kErrorLimit = 0;
- }
-
- skip = true;
-
- continue;
- }
-
- std::string err = "Unknown command: ";
- err += argv[index];
-
- Detail::print_error(err, "cc");
-
- continue;
- }
-
- kFileList.emplace_back(argv[index]);
-
- std::string srcFile = argv[index];
-
- if (strstr(argv[index], kExt) == nullptr) {
- if (kState.fVerbose) {
- Detail::print_error(srcFile + " is not a valid C source.\n", "cc");
- }
-
- return 1;
- }
-
- if (kFactory.Compile(srcFile, kMachine) != kExitOK) return 1;
- }
-
- return kExitOK;
-}
-
-// Last rev 8-1-24
diff --git a/dev/LibCompiler/src/CCompilerARM64.cc b/dev/LibCompiler/src/CCompilerARM64.cc
deleted file mode 100644
index a5ddf43..0000000
--- a/dev/LibCompiler/src/CCompilerARM64.cc
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*
- * ========================================================
- *
- * cc
- * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved.
- *
- * ========================================================
- */
-
-/// BUGS: 0
-/// TODO: none
-
-#include <LibCompiler/Backend/Aarch64.h>
-#include <LibCompiler/Detail/ClUtils.h>
-#include <LibCompiler/Parser.h>
-#include <LibCompiler/UUID.h>
-#include <cstdio>
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <random>
-#include <string>
-#include <utility>
-#include <vector>
-
-/* C driver */
-/* This is part of the LibCompiler. */
-/* (c) Amlal El Mahrouss */
-
-/// @author EL Mahrouss Amlal (amlel)
-/// @file ARM64-cc.cxx
-/// @brief ARM64 C Compiler.
-
-/// TODO: support structures, else if, else, . and ->
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kExitOK (0)
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-
-/////////////////////////////////////
-
-// INTERNAL STUFF OF THE C COMPILER
-
-/////////////////////////////////////
-
-namespace Detail {
-// \brief Register map structure, used to keep track of each variable's registers.
-struct CompilerRegisterMap final {
- std::string fName;
- std::string fReg;
-};
-
-// \brief Map for C 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<LibCompiler::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- LibCompiler::SyntaxLeafList* fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool fVerbose;
-};
-} // namespace Detail
-
-static Detail::CompilerState kState;
-static std::string kIfFunction = "";
-
-namespace Detail {
-/// @brief prints an error into stdout.
-/// @param reason the reason of the error.
-/// @param file where does it originate from?
-void print_error(std::string reason, std::string file) noexcept;
-
-struct CompilerType final {
- std::string fName;
- std::string fValue;
-};
-} // namespace Detail
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// Target architecture.
-static int kMachine = 0;
-
-/////////////////////////////////////////
-
-// REGISTERS ACCORDING TO USED ASSEMBLER
-
-/////////////////////////////////////////
-
-static size_t kRegisterCnt = kAsmRegisterLimit;
-static size_t kStartUsable = 8;
-static size_t kUsableLimit = 15;
-static size_t kRegisterCounter = kStartUsable;
-static std::string kRegisterPrefix = kAsmRegisterPrefix;
-
-/////////////////////////////////////////
-
-// COMPILER PARSING UTILITIES/STATES.
-
-/////////////////////////////////////////
-
-static std::vector<std::string> kFileList;
-static LibCompiler::AssemblyFactory kFactory;
-static bool kInStruct = false;
-static bool kOnWhileLoop = false;
-static bool kOnForLoop = false;
-static bool kInBraces = false;
-static bool kIfFound = false;
-static size_t kBracesCount = 0UL;
-
-/* @brief C compiler backend for C */
-class CompilerFrontendARM64 final : public LibCompiler::ICompilerFrontend {
- public:
- explicit CompilerFrontendARM64() = default;
- ~CompilerFrontendARM64() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(CompilerFrontendARM64);
-
- std::string Check(const char* text, const char* file);
- bool Compile(std::string text, std::string file) override;
-
- const char* Language() override { return "64k C"; }
-};
-
-static CompilerFrontendARM64* kCompilerFrontend = nullptr;
-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
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @name Compile
-// @brief Generate MASM from a C assignement.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-bool CompilerFrontendARM64::Compile(std::string text, std::string file) {
- bool typeFound = false;
- bool fnFound = false;
-
- // setup generator.
- std::random_device rd;
-
- auto seed_data = std::array<int, std::mt19937::state_size>{};
- std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd));
- std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
- std::mt19937 generator(seq);
-
- // start parsing
- for (size_t text_index = 0; text_index < text.size(); ++text_index) {
- auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
-
- auto gen = uuids::uuid_random_generator{generator};
- uuids::uuid out = gen();
-
- Detail::number_cast time_off = (UInt64) out.as_bytes().data();
-
- if (!typeFound) {
- auto substr = text.substr(text_index);
- std::string match_type;
-
- 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(' '));
- }
-
- for (auto& clType : kCompilerTypes) {
- if (clType.fName == match_type) {
- match_type.clear();
-
- std::string buf;
-
- buf += clType.fValue;
- buf += ' ';
-
- if (substr.find('=') != std::string::npos) {
- break;
- }
-
- if (text.find('(') != std::string::npos) {
- syntaxLeaf.fUserValue = buf;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- typeFound = true;
- break;
- }
- }
-
- break;
- }
-
- match_type += substr[y];
- }
- }
-
- if (text[text_index] == '{') {
- if (kInStruct) {
- continue;
- }
-
- kInBraces = true;
- ++kBracesCount;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- // return keyword handler
- if (text[text_index] == 'r') {
- std::string return_keyword;
- return_keyword += "return";
-
- std::size_t index = 0UL;
-
- std::string value;
-
- 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;
-
- value += text[value_index];
- }
-
- break;
- }
-
- ++index;
- }
-
- if (index == return_keyword.size()) {
- if (!value.empty()) {
- if (value.find('(') != std::string::npos) {
- value.erase(value.find('('));
- }
-
- if (!isdigit(value[value.find('(') + 2])) {
- std::string tmp = value;
- bool reg_to_reg = false;
-
- value.clear();
-
- value += " extern_segment";
- value += tmp;
- }
-
- syntaxLeaf.fUserValue = "\tldw r19, ";
-
- // make it pretty.
- if (value.find('\t') != std::string::npos) value.erase(value.find('\t'), 1);
-
- syntaxLeaf.fUserValue += value + "\n";
- }
-
- syntaxLeaf.fUserValue += "\tjlr";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- break;
- }
- }
-
- if (text[text_index] == 'i' && text[text_index + 1] == 'f') {
- auto expr = text.substr(text_index + 2);
- text.erase(text_index, 2);
-
- if (expr.find("{") != std::string::npos) {
- expr.erase(expr.find("{"));
- }
-
- if (expr.find("(") != std::string::npos) expr.erase(expr.find("("));
-
- if (expr.find(")") != std::string::npos) expr.erase(expr.find(")"));
-
- kIfFunction = "__LIBCOMPILER_IF_PROC_";
- kIfFunction += std::to_string(time_off._Raw);
-
- syntaxLeaf.fUserValue = "\tlda r12, extern_segment ";
- syntaxLeaf.fUserValue += kIfFunction +
- "\n\t#r12 = Code to jump on, r11 right cond, r10 left cond.\n\tbeq "
- "r10, r11, r12\ndword public_segment .code64 " +
- kIfFunction + "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- kIfFound = true;
- }
-
- // 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 (fnFound) continue;
- if (kIfFound) 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;
- }
-
- if (text[text_index] == ';' && kInStruct) {
- bool space_found_ = false;
- std::string sym;
-
- for (auto& ch : text) {
- if (ch == ' ') {
- space_found_ = true;
- }
-
- if (ch == ';') break;
-
- if (space_found_) sym.push_back(ch);
- }
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
- std::make_pair(kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4, sym));
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt =
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
-
- continue;
- }
-
- if (text[text_index] == '=' && kInStruct) {
- continue;
- }
-
- 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 && !kIfFound) {
- 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 public_segment .data64 ";
- }
-
- int first_encountered = 0;
-
- std::string str_name;
-
- for (size_t text_index_2 = 0; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') {
- ++text_index_2;
-
- // want to add this, so that the parser recognizes that this is a
- // string.
- substr += '"';
-
- for (; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') break;
-
- substr += text[text_index_2];
- }
- }
-
- if (text[text_index_2] == '{' || text[text_index_2] == '}') continue;
-
- 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("public_segment .data64") == std::string::npos && !kInStruct)
- substr += "public_segment .data64 ";
- }
-
- ++first_encountered;
-
- continue;
- }
-
- if (text[text_index_2] == '=') {
- if (!kInBraces) {
- substr.replace(substr.find("public_segment .data64"), strlen("public_segment .data64"),
- "public_segment .zero64 ");
- }
-
- substr += ",";
- continue;
- }
-
- substr += text[text_index_2];
- }
-
- for (auto& clType : kCompilerTypes) {
- if (substr.find(clType.fName) != std::string::npos) {
- if (substr.find(clType.fName) > substr.find('"')) continue;
-
- 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 (clType.fName == "const") continue;
-
- substr.erase(substr.find(clType.fValue), clType.fValue.size());
- }
- }
-
- if (substr.find("extern") != std::string::npos) {
- substr.replace(substr.find("extern"), strlen("extern"), "extern_segment ");
-
- if (substr.find("public_segment .data64") != std::string::npos)
- substr.erase(substr.find("public_segment .data64"), strlen("public_segment .data64"));
- }
-
- auto var_to_find = std::find_if(
- kCompilerVariables.cbegin(), kCompilerVariables.cend(),
- [&](Detail::CompilerType type) { return type.fName.find(substr) != std::string::npos; });
-
- if (kRegisterCounter == 5 || kRegisterCounter == 6) ++kRegisterCounter;
-
- std::string reg = kAsmRegisterPrefix;
- reg += std::to_string(kRegisterCounter);
-
- if (var_to_find == kCompilerVariables.cend()) {
- ++kRegisterCounter;
-
- kState.kStackFrame.push_back({.fName = substr, .fReg = reg});
- kCompilerVariables.push_back({.fName = substr});
- }
-
- syntaxLeaf.fUserValue += substr;
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- if (text[text_index] == '=') break;
- }
-
- // function handler.
-
- if (text[text_index] == '(' && !fnFound && !kIfFound) {
- std::string substr;
- std::string args_buffer;
- std::string args;
-
- bool type_crossed = false;
-
- for (size_t idx = text.find('(') + 1; idx < text.size(); ++idx) {
- if (text[idx] == ',') continue;
-
- if (text[idx] == ' ') continue;
-
- if (text[idx] == ')') break;
- }
-
- for (char substr_first_index : text) {
- if (substr_first_index != ',')
- args_buffer += substr_first_index;
- else
- args_buffer += '$';
-
- 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 (!args_buffer.empty()) args += "\tldw r6, ";
-
- std::string register_type;
- std::size_t index = 7UL;
-
- while (args_buffer.find("$") != std::string::npos) {
- register_type = kRegisterPrefix;
- register_type += std::to_string(index);
-
- ++index;
-
- args_buffer.replace(args_buffer.find('$'), 1, "\n\tldw " + register_type + ",");
- }
-
- args += args_buffer;
- args += "\n\tlda r19, ";
- }
- }
-
- for (char _text_i : text) {
- if (_text_i == '\t' || _text_i == ' ') {
- if (!type_crossed) {
- substr.clear();
- type_crossed = true;
- }
-
- continue;
- }
-
- if (_text_i == '(') break;
-
- substr += _text_i;
- }
-
- if (kInBraces) {
- syntaxLeaf.fUserValue = args;
- syntaxLeaf.fUserValue += substr;
- syntaxLeaf.fUserValue += "\n\tjrl\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- fnFound = true;
- } else {
- syntaxLeaf.fUserValue.clear();
-
- syntaxLeaf.fUserValue += "public_segment .code64 ";
-
- syntaxLeaf.fUserValue += substr;
- syntaxLeaf.fUserValue += "\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- fnFound = true;
- }
-
- kCompilerFunctions.push_back(text);
- }
-
- if (text[text_index] == '-' && text[text_index + 1] == '-') {
- text = text.replace(text.find("--"), strlen("--"), "");
-
- for (int _text_i = 0; _text_i < text.size(); ++_text_i) {
- if (text[_text_i] == '\t' || text[_text_i] == ' ') text.erase(_text_i, 1);
- }
-
- syntaxLeaf.fUserValue += "sub ";
- syntaxLeaf.fUserValue += text;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- break;
- }
-
- if (text[text_index] == '}') {
- kRegisterCounter = kStartUsable;
-
- --kBracesCount;
-
- if (kBracesCount < 1) {
- kInBraces = false;
- kBracesCount = 0;
- }
-
- if (kIfFound) kIfFound = false;
-
- if (kInStruct) kInStruct = false;
-
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
- }
-
- syntaxLeaf.fUserValue.clear();
- }
-
- auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
- syntaxLeaf.fUserValue = "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
-
- return true;
-}
-
-static bool kShouldHaveBraces = false;
-static std::string kFnName;
-
-std::string CompilerFrontendARM64::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;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (isalnum(ln[i])) {
- non_ascii_found = true;
- break;
- }
- }
-
- if (kShouldHaveBraces && ln.find('{') != std::string::npos) {
- kShouldHaveBraces = false;
- }
-
- if (!non_ascii_found) return err_str;
-
- size_t string_index = 1UL;
-
- 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);
- }
-
- 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("class");
- 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;
- }
- }
- }
-
- 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;
- }
-
- keyword.push_back(ln[string_index]);
- }
-
- goto cc_next_loop;
-
- cc_check_done:
-
- // skip digit value.
- if (isdigit(keyword[0]) || keyword[0] == '"') {
- goto cc_next_loop;
- }
-
- while (keyword.find(' ') != std::string::npos) keyword.erase(keyword.find(' '), 1);
-
- for (auto& var : kCompilerVariables) {
- if (var.fValue.find(keyword) != std::string::npos) {
- err_str.clear();
- goto cc_next;
- }
- }
-
- 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;
- }
- }
- }
-
- cc_error_value:
- if (keyword.find("->") != std::string::npos) return err_str;
-
- if (keyword.find(".") != std::string::npos) return err_str;
-
- if (isalnum(keyword[0])) err_str += "\nUndefined value: " + keyword;
-
- return err_str;
- }
-
- cc_next_loop:
- continue;
- }
-
-cc_next:
-
- // extern does not declare anything, it extern_segments a variable.
- // so that's why it's not declare upper.
- if (LibCompiler::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 (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;
- }
- }
-
-skip_braces_check:
-
- for (auto& key : kCompilerTypes) {
- if (LibCompiler::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[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;
-
- 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;
- }
- }
-
- next:
-
- 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;
- }
-
- 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 (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 && !LibCompiler::find_word(ln, "|") &&
- !LibCompiler::find_word(ln, "||") && !LibCompiler::find_word(ln, "&") &&
- !LibCompiler::find_word(ln, "&&") && !LibCompiler::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;
-
- bool space_found = false;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (ln[i] == ')' && !space_found) {
- space_found = true;
- continue;
- }
-
- if (space_found) {
- if (ln[i] == ' ' && isalnum(ln[i + 1])) {
- err_str += "\nBad function format 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) {
- 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('}') != 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;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief C To Assembly mount-point.
- */
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class AssemblyCCInterface final ASSEMBLY_INTERFACE {
- public:
- explicit AssemblyCCInterface() = default;
- ~AssemblyCCInterface() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(AssemblyCCInterface);
-
- [[maybe_unused]] Int32 Arch() noexcept override {
- return LibCompiler::AssemblyFactory::kArchAARCH64;
- }
-
- Int32 CompileToFormat(std::string src, Int32 arch) override {
- if (kCompilerFrontend == nullptr) return 1;
-
- /* @brief copy contents wihtout extension */
- std::string src_file = src.data();
- std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
- std::string dest;
-
- for (auto& ch : src_file) {
- if (ch == '.') {
- break;
- }
-
- dest += ch;
- }
-
- /* According to PEF ABI. */
- std::vector<const char*> exts = kAsmFileExts;
- dest += exts[4];
-
- kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
-
- auto fmt = LibCompiler::current_date();
-
- (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
- (*kState.fOutputAssembly) << "# Language: ARM64 Assembly (Generated from ANSI C)\n";
- (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n";
-
- LibCompiler::SyntaxLeafList syntax;
-
- kState.fSyntaxTreeList.push_back(syntax);
- kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
-
- std::string line_src;
-
- while (std::getline(src_fp, line_src)) {
- if (auto err = kCompilerFrontend->Check(line_src.c_str(), src.data()); err.empty()) {
- kCompilerFrontend->Compile(line_src, src.data());
- } else {
- Detail::print_error(err, src.data());
- }
- }
-
- if (kAcceptableErrors > 0) return 1;
-
- std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta", "add", "sub", "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 (LibCompiler::find_word(leaf.fUserValue, access_ident)) {
- for (auto& struc : kState.kStructMap) {
- /// TODO:
- }
- }
- }
-
- for (auto& keyword : keywords) {
- if (LibCompiler::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 (LibCompiler::find_word(leaf.fUserValue, needle)) {
- if (leaf.fUserValue.find("extern_segment " + needle) != std::string::npos) {
- std::string range = "extern_segment " + needle;
- leaf.fUserValue.replace(leaf.fUserValue.find("extern_segment " + needle),
- range.size(), 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 != "sub") {
- leaf.fUserValue.replace(leaf.fUserValue.find(keyword), keyword.size(), "mv");
- }
- }
- }
- }
-
- for (auto& leaf : kState.fSyntaxTree->fLeafList) {
- (*kState.fOutputAssembly) << leaf.fUserValue;
- }
-
- kState.fSyntaxTree = nullptr;
-
- kState.fOutputAssembly->flush();
- kState.fOutputAssembly.reset();
-
- return kExitOK;
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#include <LibCompiler/Version.h>
-
-#define kPrintF printf
-#define kSplashCxx() kPrintF(kWhite "NE C Driver, %s, (c) Amlal El Mahrouss\n", kDistVersion)
-
-static void cc_print_help() {
- kSplashCxx();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define kCExtension ".c"
-
-LIBCOMPILER_MODULE(NeOSCompilerCLangARM64) {
- ::signal(SIGSEGV, Detail::segfault_handler);
-
- 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"});
- kCompilerTypes.push_back({.fName = "*", .fValue = "offset"});
-
- bool skip = false;
-
- kFactory.Mount(new AssemblyCCInterface());
- kMachine = LibCompiler::AssemblyFactory::kArchAARCH64;
- kCompilerFrontend = new CompilerFrontendARM64();
-
- 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 kExitOK;
- }
-
- if (strcmp(argv[index], "--verbose") == 0) {
- kState.fVerbose = true;
-
- continue;
- }
-
- if (strcmp(argv[index], "--h") == 0 || strcmp(argv[index], "--help") == 0) {
- cc_print_help();
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "--dialect") == 0) {
- if (kCompilerFrontend) std::cout << kCompilerFrontend->Language() << "\n";
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "--fmax-exceptions") == 0) {
- try {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...) {
- kErrorLimit = 0;
- }
-
- skip = true;
-
- continue;
- }
-
- std::string err = "Unknown command: ";
- err += argv[index];
-
- Detail::print_error(err, "cc");
-
- continue;
- }
-
- kFileList.emplace_back(argv[index]);
-
- std::string srcFile = argv[index];
-
- if (strstr(argv[index], kCExtension) == nullptr) {
- if (kState.fVerbose) {
- Detail::print_error(srcFile + " is not a valid C source.\n", "cc");
- }
-
- return 1;
- }
-
- if (kFactory.Compile(srcFile, kMachine) != kExitOK) return 1;
- }
-
- return kExitOK;
-}
-
-// Last rev 8-1-24
diff --git a/dev/LibCompiler/src/CCompilerPower64.cc b/dev/LibCompiler/src/CCompilerPower64.cc
deleted file mode 100644
index f2eba43..0000000
--- a/dev/LibCompiler/src/CCompilerPower64.cc
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * ========================================================
- *
- * CompilerPower64
- * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved.
- *
- * ========================================================
- */
-
-#include <LibCompiler/Backend/PowerPC.h>
-#include <LibCompiler/Detail/ClUtils.h>
-#include <LibCompiler/Parser.h>
-#include <LibCompiler/UUID.h>
-#include <cstdio>
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <random>
-#include <string>
-#include <utility>
-#include <vector>
-
-#define kExitOK 0
-
-/// @author EL Mahrouss Amlal (amlal@nekernel.org)
-/// @file cc.cxx
-/// @brief POWER64 C Compiler.
-
-/////////////////////
-
-/// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-
-/////////////////////////////////////
-
-/// INTERNAL STRUCTURES OF THE C COMPILER
-
-/////////////////////////////////////
-
-namespace Detail {
-// \brief name to register struct.
-struct CompilerRegisterMap final {
- std::string fName;
- std::string fReg;
-};
-
-// \brief Map for C structs
-// \author amlel
-struct CompilerStructMap final {
- /// 'struct::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<LibCompiler::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- LibCompiler::SyntaxLeafList* fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool fVerbose;
-};
-} // namespace Detail
-
-static Detail::CompilerState kState;
-static std::string kIfFunction = "";
-
-namespace Detail {
-/// @brief prints an error into stdout.
-/// @param reason the reason of the error.
-/// @param file where does it originate from?
-void print_error(std::string reason, std::string file) noexcept;
-
-struct CompilerType final {
- std::string fName;
- std::string fValue;
-};
-} // namespace Detail
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// Target architecture.
-static int kMachine = 0;
-
-/////////////////////////////////////////
-
-// REGISTERS ACCORDING TO USED ASSEMBLER
-
-/////////////////////////////////////////
-
-static size_t kRegisterCnt = kAsmRegisterLimit;
-static size_t kStartUsable = 2;
-static size_t kUsableLimit = 15;
-static size_t kRegisterCounter = kStartUsable;
-static std::string kRegisterPrefix = kAsmRegisterPrefix;
-
-/////////////////////////////////////////
-
-// COMPILER PARSING UTILITIES/STATES.
-
-/////////////////////////////////////////
-
-static std::vector<std::string> kFileList;
-static LibCompiler::AssemblyFactory kFactory;
-static bool kInStruct = false;
-static bool kOnWhileLoop = false;
-static bool kOnForLoop = false;
-static bool kInBraces = false;
-static bool kIfFound = false;
-static size_t kBracesCount = 0UL;
-
-/* @brief C compiler backend for C */
-class CompilerFrontendPower64 final : public LibCompiler::ICompilerFrontend {
- public:
- explicit CompilerFrontendPower64() = default;
- ~CompilerFrontendPower64() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(CompilerFrontendPower64);
-
- std::string Check(const char* text, const char* file);
- bool Compile(std::string text, std::string file) override;
-
- const char* Language() override { return "POWER C"; }
-};
-
-static CompilerFrontendPower64* kCompilerFrontend = nullptr;
-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
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @name Compile
-// @brief Generate MASM from a C assignement.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-bool CompilerFrontendPower64::Compile(std::string text_, std::string file) {
- std::string text = text_;
-
- bool typeFound = false;
- bool fnFound = false;
-
- // setup generator.
- std::random_device rd;
-
- auto seed_data = std::array<int, std::mt19937::state_size>{};
- std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd));
- std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
- std::mt19937 generator(seq);
-
- // start parsing
- for (size_t text_index = 0; text_index < text.size(); ++text_index) {
- auto syntax_leaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
-
- auto gen = uuids::uuid_random_generator{generator};
- uuids::uuid out = gen();
-
- Detail::number_cast time_off = (UInt64) out.as_bytes().data();
-
- if (!typeFound) {
- auto substr = text.substr(text_index);
- std::string match_type;
-
- 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(' '));
- }
-
- for (auto& clType : kCompilerTypes) {
- if (clType.fName == match_type) {
- match_type.clear();
-
- std::string buf;
-
- buf += clType.fValue;
- buf += ' ';
-
- if (substr.find('=') != std::string::npos) {
- break;
- }
-
- if (text.find('(') != std::string::npos) {
- syntax_leaf.fUserValue = buf;
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
- }
-
- typeFound = true;
- break;
- }
- }
-
- break;
- }
-
- match_type += substr[y];
- }
- }
-
- if (text[text_index] == '{') {
- if (kInStruct) {
- continue;
- }
-
- kInBraces = true;
- ++kBracesCount;
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
- }
-
- // return keyword handler
- if (text[text_index] == 'r') {
- std::string return_keyword;
- return_keyword += "return";
-
- std::size_t index = 0UL;
-
- std::string value;
-
- 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;
-
- value += text[value_index];
- }
-
- break;
- }
-
- ++index;
- }
-
- if (index == return_keyword.size()) {
- if (!value.empty()) {
- if (value.find('(') != std::string::npos) {
- value.erase(value.find('('));
- }
-
- if (!isdigit(value[value.find('(') + 2])) {
- std::string tmp = value;
- bool reg_to_reg = false;
-
- value.clear();
-
- value += " extern_segment";
- value += tmp;
- }
-
- syntax_leaf.fUserValue = "\tmr r31, ";
-
- // make it pretty.
- while (value.find('\t') != std::string::npos) value.erase(value.find('\t'), 1);
-
- while (value.find(' ') != std::string::npos) value.erase(value.find(' '), 1);
-
- while (value.find("extern_segment") != std::string::npos)
- value.erase(value.find("extern_segment"), strlen("extern_segment"));
-
- bool found = false;
-
- for (auto& reg : kState.kStackFrame) {
- if (value.find(reg.fName) != std::string::npos) {
- found = true;
- syntax_leaf.fUserValue += reg.fReg;
- break;
- }
- }
-
- if (!found) syntax_leaf.fUserValue += "r0";
- }
-
- syntax_leaf.fUserValue += "\n\tblr";
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
-
- break;
- }
- }
-
- if (text[text_index] == 'i' && text[text_index + 1] == 'f') {
- auto expr = text.substr(text_index + 2);
- text.erase(text_index, 2);
-
- if (expr.find("{") != std::string::npos) {
- expr.erase(expr.find("{"));
- }
-
- if (expr.find("(") != std::string::npos) expr.erase(expr.find("("));
-
- if (expr.find(")") != std::string::npos) expr.erase(expr.find(")"));
-
- kIfFunction = "__LIBCOMPILER_IF_PROC_";
- kIfFunction += std::to_string(time_off._Raw);
-
- syntax_leaf.fUserValue =
- "\tcmpw "
- "r10, r11";
-
- syntax_leaf.fUserValue += "\n\tbeq extern_segment " + kIfFunction +
- " \ndword public_segment .code64 " + kIfFunction + "\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
-
- kIfFound = true;
- }
-
- // 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 (fnFound) continue;
- if (kIfFound) 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 inside a struct " + text, file);
- continue;
- }
-
- if (text[text_index] == ';' && kInStruct) {
- bool space_found_ = false;
- std::string sym;
-
- for (auto& ch : text) {
- if (ch == ' ') {
- space_found_ = true;
- }
-
- if (ch == ';') break;
-
- if (space_found_) sym.push_back(ch);
- }
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
- std::make_pair(kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4, sym));
-
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt =
- kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
-
- continue;
- }
-
- if (text[text_index] == '=' && kInStruct) {
- continue;
- }
-
- 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 && !kIfFound) {
- if (text.find("*") != std::string::npos) {
- if (text.find("=") > text.find("*"))
- substr += "\tli ";
- else
- substr += "\tli ";
- } else {
- substr += "\tli ";
- }
- } else if (text.find('=') != std::string::npos && !kInBraces) {
- substr += "stw public_segment .data64 ";
- }
-
- int first_encountered = 0;
-
- std::string str_name;
-
- for (size_t text_index_2 = 0; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') {
- ++text_index_2;
-
- // want to add this, so that the parser recognizes that this is a
- // string.
- substr += '"';
-
- for (; text_index_2 < text.size(); ++text_index_2) {
- if (text[text_index_2] == '\"') break;
-
- substr += text[text_index_2];
- }
- }
-
- if (text[text_index_2] == '{' || text[text_index_2] == '}') continue;
-
- 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("public_segment .data64") == std::string::npos && !kInStruct)
- substr += "public_segment .data64 ";
- }
-
- ++first_encountered;
-
- continue;
- }
-
- if (text[text_index_2] == '=') {
- if (!kInBraces) {
- substr.replace(substr.find("public_segment .data64"), strlen("public_segment .data64"),
- "public_segment .zero64 ");
- }
-
- substr += ",";
- continue;
- }
-
- substr += text[text_index_2];
- }
-
- for (auto& clType : kCompilerTypes) {
- if (substr.find(clType.fName) != std::string::npos) {
- if (substr.find(clType.fName) > substr.find('"')) continue;
-
- 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 (clType.fName == "const") continue;
-
- substr.erase(substr.find(clType.fValue), clType.fValue.size());
- }
- }
-
- if (substr.find("extern") != std::string::npos) {
- substr.replace(substr.find("extern"), strlen("extern"), "extern_segment ");
-
- if (substr.find("public_segment .data64") != std::string::npos)
- substr.erase(substr.find("public_segment .data64"), strlen("public_segment .data64"));
- }
-
- auto var_to_find = std::find_if(
- kCompilerVariables.cbegin(), kCompilerVariables.cend(),
- [&](Detail::CompilerType type) { return type.fName.find(substr) != std::string::npos; });
-
- kCompilerVariables.push_back({.fName = substr});
-
- if (text[text_index] == ';') break;
-
- std::string reg = kAsmRegisterPrefix;
-
- ++kRegisterCounter;
- reg += std::to_string(kRegisterCounter);
-
- auto newSubstr = substr.substr(substr.find(" "));
-
- std::string symbol;
-
- for (size_t start = 0; start < newSubstr.size(); ++start) {
- if (newSubstr[start] == ',') break;
-
- if (newSubstr[start] == ' ') continue;
-
- symbol += (newSubstr[start]);
- }
-
- kState.kStackFrame.push_back({.fName = symbol, .fReg = reg});
-
- syntax_leaf.fUserValue += "\n\tli " + reg + substr.substr(substr.find(','));
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
- }
-
- // function handler.
-
- if (text[text_index] == '(' && !fnFound && !kIfFound) {
- std::string substr;
- std::string args_buffer;
- std::string args;
-
- bool type_crossed = false;
-
- for (size_t idx = text.find('(') + 1; idx < text.size(); ++idx) {
- if (text[idx] == ',') continue;
-
- if (text[idx] == ' ') continue;
-
- if (text[idx] == ')') break;
- }
-
- for (char substr_first_index : text) {
- if (substr_first_index != ',')
- args_buffer += substr_first_index;
- else
- args_buffer += '$';
-
- 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 (!args_buffer.empty()) args += "\tldw r6, ";
-
- std::string register_type;
- std::size_t index = 7UL;
-
- while (args_buffer.find("$") != std::string::npos) {
- register_type = kRegisterPrefix;
- register_type += std::to_string(index);
-
- ++index;
-
- args_buffer.replace(args_buffer.find('$'), 1, "\n\tldw " + register_type + ",");
- }
-
- args += args_buffer;
- args += "\n\tli r31, ";
- }
- }
-
- for (char _text_i : text) {
- if (_text_i == '\t' || _text_i == ' ') {
- if (!type_crossed) {
- substr.clear();
- type_crossed = true;
- }
-
- continue;
- }
-
- if (_text_i == '(') break;
-
- substr += _text_i;
- }
-
- if (kInBraces) {
- syntax_leaf.fUserValue = args;
- syntax_leaf.fUserValue += substr;
-
- syntax_leaf.fUserValue += "\n\tblr\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
-
- fnFound = true;
- } else {
- syntax_leaf.fUserValue.clear();
-
- syntax_leaf.fUserValue += "public_segment .code64 ";
-
- syntax_leaf.fUserValue += substr;
- syntax_leaf.fUserValue += "\n";
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
-
- fnFound = true;
- }
-
- kCompilerFunctions.push_back(text);
- }
-
- if (text[text_index] == '-' && text[text_index + 1] == '-') {
- text = text.replace(text.find("--"), strlen("--"), "");
-
- for (int _text_i = 0; _text_i < text.size(); ++_text_i) {
- if (text[_text_i] == '\t' || text[_text_i] == ' ') text.erase(_text_i, 1);
- }
-
- syntax_leaf.fUserValue += "dec ";
- syntax_leaf.fUserValue += text;
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
- break;
- }
-
- if (text[text_index] == '}') {
- kRegisterCounter = kStartUsable;
-
- --kBracesCount;
-
- if (kBracesCount < 1) {
- kInBraces = false;
- kBracesCount = 0;
- }
-
- if (kIfFound) kIfFound = false;
-
- if (kInStruct) kInStruct = false;
-
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
- }
-
- syntax_leaf.fUserValue.clear();
- }
-
- auto syntax_leaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
- syntax_leaf.fUserValue = "\n";
- kState.fSyntaxTree->fLeafList.push_back(syntax_leaf);
-
- return true;
-}
-
-static bool kShouldHaveBraces = false;
-static std::string kFnName;
-
-std::string CompilerFrontendPower64::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;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (isalnum(ln[i])) {
- non_ascii_found = true;
- break;
- }
- }
-
- if (kShouldHaveBraces && ln.find('{') != std::string::npos) {
- kShouldHaveBraces = false;
- }
-
- if (!non_ascii_found) return err_str;
-
- size_t string_index = 1UL;
-
- 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);
- }
-
- 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("class");
- 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;
- }
- }
- }
-
- 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;
- }
-
- keyword.push_back(ln[string_index]);
- }
-
- goto cc_next_loop;
-
- cc_check_done:
-
- // skip digit value.
- if (isdigit(keyword[0]) || keyword[0] == '"') {
- goto cc_next_loop;
- }
-
- while (keyword.find(' ') != std::string::npos) keyword.erase(keyword.find(' '), 1);
-
- for (auto& var : kCompilerVariables) {
- if (var.fValue.find(keyword) != std::string::npos) {
- err_str.clear();
- goto cc_next;
- }
- }
-
- 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;
- }
- }
- }
-
- cc_error_value:
- if (keyword.find("->") != std::string::npos) return err_str;
-
- if (keyword.find(".") != std::string::npos) return err_str;
-
- if (isalnum(keyword[0])) err_str += "\nUndefined value: " + keyword;
-
- return err_str;
- }
-
- cc_next_loop:
- continue;
- }
-
-cc_next:
-
- // extern does not declare anything, it extern_segments a variable.
- // so that's why it's not declare upper.
- if (LibCompiler::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 (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;
- }
- }
-
-skip_braces_check:
-
- for (auto& key : kCompilerTypes) {
- if (LibCompiler::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[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;
-
- 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;
- }
- }
-
- next:
-
- 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;
- }
-
- 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 (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 && !LibCompiler::find_word(ln, "|") &&
- !LibCompiler::find_word(ln, "||") && !LibCompiler::find_word(ln, "&") &&
- !LibCompiler::find_word(ln, "&&") && !LibCompiler::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;
-
- bool space_found = false;
-
- for (int i = 0; i < ln.size(); ++i) {
- if (ln[i] == ')' && !space_found) {
- space_found = true;
- continue;
- }
-
- if (space_found) {
- if (ln[i] == ' ' && isalnum(ln[i + 1])) {
- err_str += "\nBad function format 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) {
- 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('}') != 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;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief C To Assembly mount-point.
- */
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class AssemblyMountpointCLang final ASSEMBLY_INTERFACE {
- public:
- explicit AssemblyMountpointCLang() = default;
- ~AssemblyMountpointCLang() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(AssemblyMountpointCLang);
-
- [[maybe_unused]] Int32 Arch() noexcept override {
- return LibCompiler::AssemblyFactory::kArchPowerPC;
- }
-
- Int32 CompileToFormat(std::string src, Int32 arch) override {
- if (kCompilerFrontend == nullptr) return 1;
-
- /* @brief copy contents wihtout extension */
- std::string src_file = src.data();
- std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
- std::string dest;
-
- for (auto& ch : src_file) {
- if (ch == '.') {
- break;
- }
-
- dest += ch;
- }
-
- /* According to PEF ABI. */
- std::vector<const char*> exts = kAsmFileExts;
- dest += exts[4];
-
- kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
-
- auto fmt = LibCompiler::current_date();
-
- (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
- (*kState.fOutputAssembly) << "# Language: POWER Assembly (Generated from C)\n";
- (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n";
-
- LibCompiler::SyntaxLeafList syntax;
-
- kState.fSyntaxTreeList.push_back(syntax);
- kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
-
- std::string line_src;
-
- while (std::getline(src_fp, line_src)) {
- if (auto err = kCompilerFrontend->Check(line_src.c_str(), src.data()); err.empty()) {
- kCompilerFrontend->Compile(line_src, src.data());
- } else {
- Detail::print_error(err, src.data());
- }
- }
-
- if (kAcceptableErrors > 0) return 1;
-
- std::vector<std::string> keywords = {"ld", "stw", "add", "sub", "or"};
-
- ///
- /// Replace, optimize, fix assembly output.
- ///
-
- for (auto& leaf : kState.fSyntaxTree->fLeafList) {
- std::vector<std::string> access_keywords = {"->", "."};
-
- for (auto& access_ident : access_keywords) {
- if (LibCompiler::find_word(leaf.fUserValue, access_ident)) {
- for (auto& struc : kState.kStructMap) {
- /// TODO:
- }
- }
- }
-
- for (auto& keyword : keywords) {
- if (LibCompiler::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 (LibCompiler::find_word(leaf.fUserValue, needle)) {
- if (leaf.fUserValue.find("extern_segment ") != std::string::npos) {
- std::string range = "extern_segment ";
- leaf.fUserValue.replace(leaf.fUserValue.find(range), range.size(), "");
- }
-
- 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"), "mr");
- }
- }
-
- leaf.fUserValue.replace(leaf.fUserValue.find(needle), needle.size(), reg.fReg);
-
- ++cnt;
- }
- }
-
- if (cnt > 1 && keyword != "mr" && keyword != "add" && keyword != "dec") {
- leaf.fUserValue.replace(leaf.fUserValue.find(keyword), keyword.size(), "mr");
- }
- }
- }
- }
-
- for (auto& leaf : kState.fSyntaxTree->fLeafList) {
- (*kState.fOutputAssembly) << leaf.fUserValue;
- }
-
- kState.fSyntaxTree = nullptr;
-
- kState.fOutputAssembly->flush();
- kState.fOutputAssembly.reset();
-
- return kExitOK;
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#include <LibCompiler/Version.h>
-
-#define kPrintF printf
-#define kSplashCxx() kPrintF(kWhite "cc, %s, (c) Amlal El Mahrouss\n", kDistVersion)
-
-static void cc_print_help() {
- kSplashCxx();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define kExt ".c"
-
-LIBCOMPILER_MODULE(NeOSCompilerCLangPowerPC) {
- ::signal(SIGSEGV, Detail::segfault_handler);
-
- 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"});
- kCompilerTypes.push_back({.fName = "*", .fValue = "offset"});
-
- bool skip = false;
-
- kFactory.Mount(new AssemblyMountpointCLang());
- kMachine = LibCompiler::AssemblyFactory::kArchPowerPC;
- kCompilerFrontend = new CompilerFrontendPower64();
-
- 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 kExitOK;
- }
-
- if (strcmp(argv[index], "-verbose") == 0) {
- kState.fVerbose = true;
-
- continue;
- }
-
- if (strcmp(argv[index], "-h") == 0 || strcmp(argv[index], "-help") == 0) {
- cc_print_help();
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "-dialect") == 0) {
- if (kCompilerFrontend) std::cout << kCompilerFrontend->Language() << "\n";
-
- return kExitOK;
- }
-
- if (strcmp(argv[index], "-fmax-exceptions") == 0) {
- try {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...) {
- kErrorLimit = 0;
- }
-
- skip = true;
-
- continue;
- }
-
- std::string err = "Unknown command: ";
- err += argv[index];
-
- Detail::print_error(err, "cc");
-
- continue;
- }
-
- kFileList.emplace_back(argv[index]);
-
- std::string srcFile = argv[index];
-
- if (strstr(argv[index], kExt) == nullptr) {
- if (kState.fVerbose) {
- Detail::print_error(srcFile + " is not a valid C source.\n", "cc");
- }
-
- return 1;
- }
-
- if (kFactory.Compile(srcFile, kMachine) != kExitOK) return 1;
- }
-
- return kExitOK;
-}
-
-// Last rev 8-1-24
diff --git a/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc b/dev/LibCompiler/src/CodeGen.cc
index 11655fb..3f215c5 100644
--- a/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc
+++ b/dev/LibCompiler/src/CodeGen.cc
@@ -1,10 +1,10 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+ Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved
------------------------------------------- */
-#include <LibCompiler/AssemblyInterface.h>
+#include <LibCompiler/CodeGen.h>
#include <LibCompiler/ErrorID.h>
/**
@@ -23,12 +23,17 @@
namespace LibCompiler {
///! @brief Compile for specific format (ELF, PEF, ZBIN)
-Int32 AssemblyFactory::Compile(std::string sourceFile, const Int32& arch) noexcept {
- if (sourceFile.length() < 1 || !fMounted) return LIBCOMPILER_UNIMPLEMENTED;
+Int32 AssemblyFactory::Compile(STLString sourceFile, const Int32& arch) noexcept {
+ if (sourceFile.length() < 1) return LIBCOMPILER_UNIMPLEMENTED;
+ if (!fMounted) return LIBCOMPILER_UNIMPLEMENTED;
if (arch != fMounted->Arch()) return LIBCOMPILER_INVALID_ARCH;
- return fMounted->CompileToFormat(sourceFile, arch);
+ try {
+ return this->fMounted->CompileToFormat(sourceFile, arch);
+ } catch (std::exception& e) {
+ return LIBCOMPILER_EXEC_ERROR;
+ }
}
///! @brief mount assembly backend.
@@ -42,7 +47,7 @@ void AssemblyFactory::Mount(AssemblyInterface* mountPtr) noexcept {
AssemblyInterface* AssemblyFactory::Unmount() noexcept {
auto mount_prev = fMounted;
- if (mount_prev) {
+ if (fMounted) {
fMounted = nullptr;
}
diff --git a/dev/LibCompiler/src/Frontend.cc b/dev/LibCompiler/src/Frontend.cc
new file mode 100644
index 0000000..69ff6fd
--- /dev/null
+++ b/dev/LibCompiler/src/Frontend.cc
@@ -0,0 +1,51 @@
+/* -------------------------------------------
+
+ Copyright (C) 2025 Amlal EL Mahrouss, all rights reserved
+
+------------------------------------------- */
+
+#include <LibCompiler/Frontend.h>
+
+namespace LibCompiler {
+/// find the perfect matching word in a haystack.
+/// \param haystack base string
+/// \param needle the string we search for.
+/// \return if we found it or not.
+bool find_word(std::string haystack, 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.
+std::size_t find_word_range(std::string haystack, 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 std::string::npos;
+}
+} // namespace LibCompiler \ No newline at end of file
diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc
index ace6d17..df9035d 100644
--- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
+++ b/dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc
@@ -16,14 +16,12 @@
// extern_segment, @autodelete { ... }, fn foo() -> auto { ... }
-#include <LibCompiler/Backend/Amd64.h>
-#include <LibCompiler/Detail/ClUtils.h>
-#include <LibCompiler/Parser.h>
+#include <LibCompiler/Backend/X64.h>
+#include <LibCompiler/Frontend.h>
#include <LibCompiler/UUID.h>
+#include <LibCompiler/Util/CompilerUtils.h>
-#include <cstdio>
-
-/* NE C++ Compiler */
+/* NeKernel C++ Compiler Driver */
/* This is part of the LibCompiler. */
/* (c) Amlal El Mahrouss */
@@ -69,29 +67,23 @@ std::filesystem::path expand_home(const std::filesystem::path& p) {
}
struct CompilerRegisterMap final {
- std::string fName;
- std::string fReg;
+ LibCompiler::STLString fName;
+ LibCompiler::STLString fReg;
};
-// \brief Offset based struct/class
+/// \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;
+ LibCompiler::STLString fName;
+ LibCompiler::STLString fReg;
+ std::vector<std::pair<UInt32, LibCompiler::STLString>> fOffsets;
};
+/// \brief Compiler state structure.
struct CompilerState final {
std::vector<CompilerRegisterMap> fStackMapVector;
std::vector<CompilerStructMap> fStructMapVector;
- std::string fOutputValue;
- std::string fLastFile;
- std::string fLastError;
- Boolean fVerbose;
+ LibCompiler::STLString fLastFile;
+ LibCompiler::STLString fLastError;
};
} // namespace Detail
@@ -99,22 +91,10 @@ static Detail::CompilerState kState;
static Int32 kOnClassScope = 0;
-namespace Detail {
-/// @brief prints an error into stdout.
-/// @param reason the reason of the error.
-/// @param file where does it originate from?
-void print_error(std::string reason, std::string file) noexcept;
-
-struct CompilerType final {
- std::string fName;
- std::string fValue;
-};
-} // namespace Detail
-
/////////////////////////////////////////////////////////////////////////////////////////
// Target architecture.
-static int kMachine = LibCompiler::AssemblyFactory::kArchAMD64;
+static Int32 kMachine = LibCompiler::AssemblyFactory::kArchAMD64;
/////////////////////////////////////////
@@ -122,10 +102,6 @@ static int kMachine = LibCompiler::AssemblyFactory::kArchAMD64;
/////////////////////////////////////////
-static size_t kRegisterCnt = kAsmRegisterLimit;
-static size_t kStartUsable = 8;
-static size_t kUsableLimit = 15;
-static size_t kRegisterCounter = kStartUsable;
static std::vector<LibCompiler::CompilerKeyword> kKeywords;
/////////////////////////////////////////
@@ -141,15 +117,16 @@ static Boolean kOnForLoop = false;
static Boolean kInBraces = false;
static size_t kBracesCount = 0UL;
-/* @brief C++ compiler backend for the NE C++ driver */
-class CompilerFrontendCPlusPlus final : public LibCompiler::ICompilerFrontend {
+/* @brief C++ compiler backend for the NeKernel C++ driver */
+class CompilerFrontendCPlusPlus final LC_COMPILER_FRONTEND {
public:
explicit CompilerFrontendCPlusPlus() = default;
~CompilerFrontendCPlusPlus() override = default;
LIBCOMPILER_COPY_DEFAULT(CompilerFrontendCPlusPlus);
- Boolean Compile(const std::string text, std::string file) override;
+ LibCompiler::SyntaxLeafList::SyntaxLeaf Compile(const LibCompiler::STLString text,
+ LibCompiler::STLString file) override;
const char* Language() override;
};
@@ -158,15 +135,15 @@ class CompilerFrontendCPlusPlus final : public LibCompiler::ICompilerFrontend {
static CompilerFrontendCPlusPlus* kCompilerFrontend = nullptr;
-static std::vector<std::string> kRegisterMap;
+static std::vector<LibCompiler::STLString> kRegisterMap;
-static std::vector<std::string> kRegisterList = {
+static std::vector<LibCompiler::STLString> kRegisterList = {
"rbx", "rsi", "r10", "r11", "r12", "r13", "r14", "r15", "xmm12", "xmm13", "xmm14", "xmm15",
};
/// @brief The PEF calling convention (caller must save rax, rbp)
/// @note callee must return via **rax**.
-static std::vector<std::string> kRegisterConventionCallList = {
+static std::vector<LibCompiler::STLString> kRegisterConventionCallList = {
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
};
@@ -178,8 +155,8 @@ const char* CompilerFrontendCPlusPlus::Language() {
return "AMD64 C++";
}
-static std::uintptr_t kOrigin = 0x1000000;
-static std::vector<std::pair<std::string, std::uintptr_t>> kOriginMap;
+static std::uintptr_t kOrigin = 0x1000000;
+static std::vector<std::pair<LibCompiler::STLString, std::uintptr_t>> kOriginMap;
/////////////////////////////////////////////////////////////////////////////////////////
@@ -188,8 +165,11 @@ static std::vector<std::pair<std::string, std::uintptr_t>> kOriginMap;
/////////////////////////////////////////////////////////////////////////////////////////
-Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
- if (text.empty()) return false;
+LibCompiler::SyntaxLeafList::SyntaxLeaf CompilerFrontendCPlusPlus::Compile(
+ LibCompiler::STLString text, LibCompiler::STLString file) {
+ LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree;
+
+ if (text.length() < 1) return syntax_tree;
std::size_t index = 0UL;
std::vector<std::pair<LibCompiler::CompilerKeyword, std::size_t>> keywords_list;
@@ -204,16 +184,22 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
break;
}
- if (text[text.find(keyword.keyword_name) - 1] == '+' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
+ std::size_t pos = text.find(keyword.keyword_name);
+ if (pos == std::string::npos) continue;
+
+ // Safe guard: can't go before start of string
+ if (pos > 0 && text[pos - 1] == '+' &&
+ keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
continue;
- if (text[text.find(keyword.keyword_name) - 1] == '-' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
+ if (pos > 0 && text[pos - 1] == '-' &&
+ keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
continue;
- if (text[text.find(keyword.keyword_name) + 1] == '=' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
+ // Safe guard: don't go out of range
+ if ((pos + keyword.keyword_name.size()) < text.size() &&
+ text[pos + keyword.keyword_name.size()] == '=' &&
+ keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
continue;
keywords_list.emplace_back(std::make_pair(keyword, index));
@@ -221,20 +207,29 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
}
}
- LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree;
-
for (auto& keyword : keywords_list) {
+ if (text.find(keyword.first.keyword_name) == LibCompiler::STLString::npos) continue;
+
switch (keyword.first.keyword_kind) {
case LibCompiler::KeywordKind::kKeywordKindClass: {
++kOnClassScope;
break;
}
case LibCompiler::KeywordKind::kKeywordKindIf: {
- auto expr = text.substr(
- text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 1,
- text.find(")") - 1);
+ std::size_t keywordPos = text.find(keyword.first.keyword_name);
+ std::size_t openParen = text.find("(", keywordPos);
+ std::size_t closeParen = text.find(")", openParen);
+
+ if (keywordPos == LibCompiler::STLString::npos ||
+ openParen == LibCompiler::STLString::npos ||
+ closeParen == LibCompiler::STLString::npos || closeParen <= openParen) {
+ Detail::print_error("Malformed if expression: " + text, file);
+ break;
+ }
+
+ auto expr = text.substr(openParen + 1, closeParen - openParen - 1);
- if (expr.find(">=") != std::string::npos) {
+ if (expr.find(">=") != LibCompiler::STLString::npos) {
auto left = text.substr(
text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 2,
expr.find("<=") + strlen("<="));
@@ -272,34 +267,36 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
auto& valueOfVar = !isdigit(left[0]) ? left : right;
- for (auto pairRight : kRegisterMap) {
- ++indexRight;
+ if (!valueOfVar.empty()) {
+ for (auto pairRight : kRegisterMap) {
+ ++indexRight;
+
+ if (pairRight != valueOfVar) {
+ auto& valueOfVarOpposite = isdigit(left[0]) ? left : right;
+
+ syntax_tree.fUserValue +=
+ "mov " + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
+ syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + "," +
+ kRegisterList[indexRight + 1] + "\n";
+
+ goto done_iterarting_on_if;
+ }
- if (pairRight != valueOfVar) {
auto& valueOfVarOpposite = isdigit(left[0]) ? left : right;
syntax_tree.fUserValue +=
"mov " + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + "," +
+ syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + ", " +
kRegisterList[indexRight + 1] + "\n";
- goto done_iterarting_on_if;
+ break;
}
-
- auto& valueOfVarOpposite = isdigit(left[0]) ? left : right;
-
- syntax_tree.fUserValue +=
- "mov " + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + ", " +
- kRegisterList[indexRight + 1] + "\n";
-
- break;
}
}
done_iterarting_on_if:
- std::string fnName = text;
+ LibCompiler::STLString fnName = text;
fnName.erase(fnName.find(keyword.first.keyword_name));
for (auto& ch : fnName) {
@@ -322,11 +319,11 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
goto accept;
dont_accept:
- return false;
+ break;
accept:
- std::string fnName = text;
- size_t indexFnName = 0;
+ LibCompiler::STLString fnName = text;
+ size_t indexFnName = 0;
// this one is for the type.
for (auto& ch : text) {
@@ -338,12 +335,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
fnName = text.substr(indexFnName);
- if (text.find("return ") != std::string::npos) {
+ if (text.find("return ") != LibCompiler::STLString::npos) {
text.erase(0, text.find("return "));
break;
}
- if (text.ends_with(";") && text.find("return") == std::string::npos)
+ if (text.ends_with(";") && text.find("return") == LibCompiler::STLString::npos)
goto lc_write_assembly;
else if (text.size() <= indexFnName)
Detail::print_error("Invalid function name: " + fnName, file);
@@ -359,7 +356,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
++indexFnName;
}
- if (fnName.find("(") != LibCompiler::String::npos) {
+ if (fnName.find("(") != LibCompiler::STLString::npos) {
fnName.erase(fnName.find("("));
}
@@ -371,10 +368,11 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
break;
lc_write_assembly:
- auto it = std::find_if(kOriginMap.begin(), kOriginMap.end(),
- [&fnName](std::pair<std::string, std::uintptr_t> pair) -> bool {
- return fnName == pair.first;
- });
+ auto it =
+ std::find_if(kOriginMap.begin(), kOriginMap.end(),
+ [&fnName](std::pair<LibCompiler::STLString, std::uintptr_t> pair) -> bool {
+ return fnName == pair.first;
+ });
if (it != kOriginMap.end()) {
std::stringstream ss;
@@ -403,7 +401,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
case LibCompiler::KeywordKind::kKeywordKindVariableInc:
case LibCompiler::KeywordKind::kKeywordKindVariableDec:
case LibCompiler::KeywordKind::kKeywordKindVariableAssign: {
- std::string valueOfVar = "";
+ LibCompiler::STLString valueOfVar = "";
if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc) {
valueOfVar = text.substr(text.find("+=") + 2);
@@ -417,12 +415,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
break;
}
- while (valueOfVar.find(";") != std::string::npos &&
+ while (valueOfVar.find(";") != LibCompiler::STLString::npos &&
keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindEndInstr) {
valueOfVar.erase(valueOfVar.find(";"));
}
- std::string varName = text;
+ LibCompiler::STLString varName = text;
if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc) {
varName.erase(varName.find("+="));
@@ -440,7 +438,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
for (auto& keyword : kKeywords) {
if (keyword.keyword_kind == LibCompiler::kKeywordKindType) {
- if (text.find(keyword.keyword_name) != std::string::npos) {
+ if (text.find(keyword.keyword_name) != LibCompiler::STLString::npos) {
if (text[text.find(keyword.keyword_name)] == ' ') {
typeFound = false;
continue;
@@ -451,7 +449,9 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
}
}
- std::string instr = "mov ";
+ LibCompiler::STLString instr = "mov ";
+
+ std::vector<LibCompiler::STLString> newVars;
if (typeFound &&
keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindVariableInc &&
@@ -460,11 +460,11 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
++kFunctionEmbedLevel;
}
- while (varName.find(" ") != std::string::npos) {
+ while (varName.find(" ") != LibCompiler::STLString::npos) {
varName.erase(varName.find(" "), 1);
}
- while (varName.find("\t") != std::string::npos) {
+ while (varName.find("\t") != LibCompiler::STLString::npos) {
varName.erase(varName.find("\t"), 1);
}
@@ -527,24 +527,27 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
}
Detail::print_error("Variable not declared: " + varName, file);
- return false;
+ break;
}
done:
for (auto& keyword : kKeywords) {
if (keyword.keyword_kind == LibCompiler::kKeywordKindType &&
- varName.find(keyword.keyword_name) != std::string::npos) {
+ varName.find(keyword.keyword_name) != LibCompiler::STLString::npos) {
varName.erase(varName.find(keyword.keyword_name), keyword.keyword_name.size());
break;
}
}
- kRegisterMap.push_back(varName);
+ newVars.push_back(varName);
break;
}
- if (kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindType ||
+ kRegisterMap.insert(kRegisterMap.end(), newVars.begin(), newVars.end());
+
+ if (keyword.second > 0 &&
+ kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindType ||
kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindTypePtr) {
syntax_tree.fUserValue = "\n";
continue;
@@ -562,13 +565,13 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
instr = "sub ";
}
- std::string varErrCpy = varName;
+ LibCompiler::STLString varErrCpy = varName;
- while (varName.find(" ") != std::string::npos) {
+ while (varName.find(" ") != LibCompiler::STLString::npos) {
varName.erase(varName.find(" "), 1);
}
- while (varName.find("\t") != std::string::npos) {
+ while (varName.find("\t") != LibCompiler::STLString::npos) {
varName.erase(varName.find("\t"), 1);
}
@@ -580,11 +583,11 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
valueOfVar.erase(i, 1);
}
- while (valueOfVar.find(" ") != std::string::npos) {
+ while (valueOfVar.find(" ") != LibCompiler::STLString::npos) {
valueOfVar.erase(valueOfVar.find(" "), 1);
}
- while (valueOfVar.find("\t") != std::string::npos) {
+ while (valueOfVar.find("\t") != LibCompiler::STLString::npos) {
valueOfVar.erase(valueOfVar.find("\t"), 1);
}
@@ -622,6 +625,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
break;
}
+ newVars.push_back(varName);
break;
}
@@ -629,14 +633,16 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
Detail::print_error("Variable not declared: " + varName, file);
}
+ kRegisterMap.insert(kRegisterMap.end(), newVars.begin(), newVars.end());
+
break;
}
case LibCompiler::KeywordKind::kKeywordKindReturn: {
try {
- auto pos = text.find("return") + strlen("return") + 1;
- std::string subText = text.substr(pos);
- subText = subText.erase(subText.find(";"));
- size_t indxReg = 0UL;
+ auto pos = text.find("return") + strlen("return") + 1;
+ LibCompiler::STLString subText = text.substr(pos);
+ subText = subText.erase(subText.find(";"));
+ size_t indxReg = 0UL;
if (subText[0] != '\"' && subText[0] != '\'') {
if (!isdigit(subText[0])) {
@@ -666,14 +672,14 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
}
if (syntax_tree.fUserValue.empty()) {
- if (subText.find("(") != std::string::npos) {
+ if (subText.find("(") != LibCompiler::STLString::npos) {
subText.erase(subText.find("("));
- auto it =
- std::find_if(kOriginMap.begin(), kOriginMap.end(),
- [&subText](std::pair<std::string, std::uintptr_t> pair) -> bool {
- return pair.first.find(subText) != std::string::npos;
- });
+ auto it = std::find_if(
+ kOriginMap.begin(), kOriginMap.end(),
+ [&subText](std::pair<LibCompiler::STLString, std::uintptr_t> pair) -> bool {
+ return pair.first.find(subText) != LibCompiler::STLString::npos;
+ });
if (it == kOriginMap.end())
Detail::print_error("Invalid return value: " + subText, file);
@@ -699,8 +705,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
}
}
- kState.fOutputValue = syntax_tree.fUserValue;
- return true;
+ return syntax_tree;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -711,39 +716,33 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
/////////////////////////////////////////////////////////////////////////////////////////
-class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE {
+class AssemblyCPlusPlusInterface final LC_ASSEMBLY_INTERFACE {
public:
explicit AssemblyCPlusPlusInterface() = default;
~AssemblyCPlusPlusInterface() override = default;
LIBCOMPILER_COPY_DEFAULT(AssemblyCPlusPlusInterface);
- [[maybe_unused]] Int32 Arch() noexcept override {
- return LibCompiler::AssemblyFactory::kArchAMD64;
- }
+ UInt32 Arch() noexcept override { return LibCompiler::AssemblyFactory::kArchAMD64; }
- Int32 CompileToFormat(std::string src, Int32 arch) override {
+ Int32 CompileToFormat(LibCompiler::STLString src, Int32 arch) override {
if (kCompilerFrontend == nullptr) return kExitNO;
- /* @brief copy contents wihtout extension */
- std::ifstream src_fp = std::ifstream(src, std::ios::in);
+ LibCompiler::STLString dest = src;
+ dest += ".pp.masm";
- std::string dest = src;
- dest += ".masm";
+ std::ofstream out_fp(dest);
+ std::ifstream src_fp = std::ifstream(src + ".pp");
- std::string line_source;
+ LibCompiler::STLString line_source;
- std::ofstream out(dest);
+ out_fp << "#bits 64\n";
+ out_fp << "#org " << kOrigin << "\n\n";
while (std::getline(src_fp, line_source)) {
- kCompilerFrontend->Compile(line_source, src);
- out << kState.fOutputValue;
+ out_fp << kCompilerFrontend->Compile(line_source, src).fUserValue;
}
- out.flush();
-
- if (kAcceptableErrors > 0) return kExitNO;
-
return kExitOK;
}
};
@@ -758,87 +757,74 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE {
LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
Boolean skip = false;
- kKeywords.push_back({.keyword_name = "if", .keyword_kind = LibCompiler::kKeywordKindIf});
- kKeywords.push_back({.keyword_name = "else", .keyword_kind = LibCompiler::kKeywordKindElse});
- kKeywords.push_back({.keyword_name = "else if", .keyword_kind = LibCompiler::kKeywordKindElseIf});
-
- kKeywords.push_back({.keyword_name = "class", .keyword_kind = LibCompiler::kKeywordKindClass});
- kKeywords.push_back({.keyword_name = "struct", .keyword_kind = LibCompiler::kKeywordKindClass});
- kKeywords.push_back(
- {.keyword_name = "namespace", .keyword_kind = LibCompiler::kKeywordKindNamespace});
- kKeywords.push_back(
- {.keyword_name = "typedef", .keyword_kind = LibCompiler::kKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "using", .keyword_kind = LibCompiler::kKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "{", .keyword_kind = LibCompiler::kKeywordKindBodyStart});
- kKeywords.push_back({.keyword_name = "}", .keyword_kind = LibCompiler::kKeywordKindBodyEnd});
- kKeywords.push_back({.keyword_name = "auto", .keyword_kind = LibCompiler::kKeywordKindVariable});
- kKeywords.push_back({.keyword_name = "int", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "Boolean", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "short", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "char", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "long", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "float", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "double", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "void", .keyword_kind = LibCompiler::kKeywordKindType});
-
- kKeywords.push_back(
- {.keyword_name = "auto*", .keyword_kind = LibCompiler::kKeywordKindVariablePtr});
- kKeywords.push_back({.keyword_name = "int*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back(
- {.keyword_name = "Boolean*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back(
- {.keyword_name = "unsigned*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "short*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "char*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "long*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "float*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back(
- {.keyword_name = "double*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "void*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
-
- kKeywords.push_back(
- {.keyword_name = "(", .keyword_kind = LibCompiler::kKeywordKindFunctionStart});
- kKeywords.push_back({.keyword_name = ")", .keyword_kind = LibCompiler::kKeywordKindFunctionEnd});
- kKeywords.push_back(
- {.keyword_name = "=", .keyword_kind = LibCompiler::kKeywordKindVariableAssign});
- kKeywords.push_back({.keyword_name = "+=", .keyword_kind = LibCompiler::kKeywordKindVariableInc});
- kKeywords.push_back({.keyword_name = "-=", .keyword_kind = LibCompiler::kKeywordKindVariableDec});
- kKeywords.push_back({.keyword_name = "const", .keyword_kind = LibCompiler::kKeywordKindConstant});
- kKeywords.push_back({.keyword_name = "*", .keyword_kind = LibCompiler::kKeywordKindPtr});
- kKeywords.push_back({.keyword_name = "->", .keyword_kind = LibCompiler::kKeywordKindPtrAccess});
- kKeywords.push_back({.keyword_name = ".", .keyword_kind = LibCompiler::kKeywordKindAccess});
- kKeywords.push_back({.keyword_name = ",", .keyword_kind = LibCompiler::kKeywordKindArgSeparator});
- kKeywords.push_back({.keyword_name = ";", .keyword_kind = LibCompiler::kKeywordKindEndInstr});
- kKeywords.push_back({.keyword_name = ":", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "public:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "private:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "protected:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "final", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "return", .keyword_kind = LibCompiler::kKeywordKindReturn});
- kKeywords.push_back(
- {.keyword_name = "--*", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineStart});
- kKeywords.push_back(
- {.keyword_name = "*/", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineStart});
- kKeywords.push_back(
- {.keyword_name = "--/", .keyword_kind = LibCompiler::kKeywordKindCommentInline});
- kKeywords.push_back({.keyword_name = "==", .keyword_kind = LibCompiler::kKeywordKindEq});
- kKeywords.push_back({.keyword_name = "!=", .keyword_kind = LibCompiler::kKeywordKindNotEq});
- kKeywords.push_back({.keyword_name = ">=", .keyword_kind = LibCompiler::kKeywordKindGreaterEq});
- kKeywords.push_back({.keyword_name = "<=", .keyword_kind = LibCompiler::kKeywordKindLessEq});
-
- kErrorLimit = 100;
+ kKeywords.emplace_back("if", LibCompiler::kKeywordKindIf);
+ kKeywords.emplace_back("else", LibCompiler::kKeywordKindElse);
+ kKeywords.emplace_back("else if", LibCompiler::kKeywordKindElseIf);
+
+ kKeywords.emplace_back("class", LibCompiler::kKeywordKindClass);
+ kKeywords.emplace_back("struct", LibCompiler::kKeywordKindClass);
+ kKeywords.emplace_back("namespace", LibCompiler::kKeywordKindNamespace);
+ kKeywords.emplace_back("typedef", LibCompiler::kKeywordKindTypedef);
+ kKeywords.emplace_back("using", LibCompiler::kKeywordKindTypedef);
+ kKeywords.emplace_back("{", LibCompiler::kKeywordKindBodyStart);
+ kKeywords.emplace_back("}", LibCompiler::kKeywordKindBodyEnd);
+ kKeywords.emplace_back("auto", LibCompiler::kKeywordKindVariable);
+ kKeywords.emplace_back("int", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("bool", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("unsigned", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("short", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("char", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("long", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("float", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("double", LibCompiler::kKeywordKindType);
+ kKeywords.emplace_back("void", LibCompiler::kKeywordKindType);
+
+ kKeywords.emplace_back("auto*", LibCompiler::kKeywordKindVariablePtr);
+ kKeywords.emplace_back("int*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("bool*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("unsigned*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("short*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("char*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("long*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("float*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("double*", LibCompiler::kKeywordKindTypePtr);
+ kKeywords.emplace_back("void*", LibCompiler::kKeywordKindTypePtr);
+
+ kKeywords.emplace_back("(", LibCompiler::kKeywordKindFunctionStart);
+ kKeywords.emplace_back(")", LibCompiler::kKeywordKindFunctionEnd);
+ kKeywords.emplace_back("=", LibCompiler::kKeywordKindVariableAssign);
+ kKeywords.emplace_back("+=", LibCompiler::kKeywordKindVariableInc);
+ kKeywords.emplace_back("-=", LibCompiler::kKeywordKindVariableDec);
+ kKeywords.emplace_back("const", LibCompiler::kKeywordKindConstant);
+ kKeywords.emplace_back("*", LibCompiler::kKeywordKindPtr);
+ kKeywords.emplace_back("->", LibCompiler::kKeywordKindPtrAccess);
+ kKeywords.emplace_back(".", LibCompiler::kKeywordKindAccess);
+ kKeywords.emplace_back(",", LibCompiler::kKeywordKindArgSeparator);
+ kKeywords.emplace_back(";", LibCompiler::kKeywordKindEndInstr);
+ kKeywords.emplace_back(":", LibCompiler::kKeywordKindSpecifier);
+ kKeywords.emplace_back("public:", LibCompiler::kKeywordKindSpecifier);
+ kKeywords.emplace_back("private:", LibCompiler::kKeywordKindSpecifier);
+ kKeywords.emplace_back("protected:", LibCompiler::kKeywordKindSpecifier);
+ kKeywords.emplace_back("final", LibCompiler::kKeywordKindSpecifier);
+ kKeywords.emplace_back("return", LibCompiler::kKeywordKindReturn);
+ kKeywords.emplace_back("/*", LibCompiler::kKeywordKindCommentMultiLineStart);
+ kKeywords.emplace_back("*/", LibCompiler::kKeywordKindCommentMultiLineEnd);
+ kKeywords.emplace_back("//", LibCompiler::kKeywordKindCommentInline);
+ kKeywords.emplace_back("==", LibCompiler::kKeywordKindEq);
+ kKeywords.emplace_back("!=", LibCompiler::kKeywordKindNotEq);
+ kKeywords.emplace_back(">=", LibCompiler::kKeywordKindGreaterEq);
+ kKeywords.emplace_back("<=", LibCompiler::kKeywordKindLessEq);
+
+ kErrorLimit = 0;
kCompilerFrontend = new CompilerFrontendCPlusPlus();
kFactory.Mount(new AssemblyCPlusPlusInterface());
- ::signal(SIGSEGV, Detail::segfault_handler);
+ LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler);
for (auto index = 1UL; index < argc; ++index) {
+ if (!argv[index]) break;
+
if (argv[index][0] == '-') {
if (skip) {
skip = false;
@@ -846,7 +832,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
}
if (strcmp(argv[index], "-cxx-verbose") == 0) {
- kState.fVerbose = true;
+ kVerbose = true;
continue;
}
@@ -854,7 +840,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
if (strcmp(argv[index], "-cxx-dialect") == 0) {
if (kCompilerFrontend) std::cout << kCompilerFrontend->Language() << "\n";
- return kExitOK;
+ return LIBCOMPILER_SUCCESS;
}
if (strcmp(argv[index], "-cxx-max-err") == 0) {
@@ -871,7 +857,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
continue;
}
- std::string err = "Unknown option: ";
+ LibCompiler::STLString err = "Unknown option: ";
err += argv[index];
Detail::print_error(err, "cxxdrv");
@@ -879,31 +865,26 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
continue;
}
- std::string argv_i = argv[index];
+ LibCompiler::STLString argv_i = argv[index];
- std::vector exts = kExtListCxx;
- Boolean found = false;
+ std::vector<LibCompiler::STLString> exts = kExtListCxx;
- for (std::string ext : exts) {
- if (argv_i.find(ext) != std::string::npos) {
- found = true;
- break;
- }
- }
+ for (LibCompiler::STLString ext : exts) {
+ if (argv_i.ends_with(ext)) {
+ if (kFactory.Compile(argv_i, kMachine) != kExitOK) {
+ return LIBCOMPILER_INVALID_DATA;
+ }
- if (!found) {
- if (kState.fVerbose) {
- Detail::print_error(argv_i + " is not a valid C++ source.\n", "cxxdrv");
+ break;
}
-
- return kExitNO;
}
-
- kFactory.Compile(argv_i, kMachine);
}
- return kExitNO;
+ kFactory.Unmount();
+
+ return LIBCOMPILER_SUCCESS;
}
-// Last rev 8-1-24
+//
+// Last rev 23-5-25
//
diff --git a/dev/LibCompiler/src/DynamicLinkerPEF.cc b/dev/LibCompiler/src/Linkers/DynamicLinkerPEF.cc
index 9e3be82..b58c786 100644
--- a/dev/LibCompiler/src/DynamicLinkerPEF.cc
+++ b/dev/LibCompiler/src/Linkers/DynamicLinkerPEF.cc
@@ -20,7 +20,7 @@
#include <LibCompiler/ErrorID.h>
//! Assembler Kit
-#include <LibCompiler/AssemblyInterface.h>
+#include <LibCompiler/CodeGen.h>
//! Preferred Executable Format
#include <LibCompiler/PEF.h>
@@ -34,17 +34,14 @@
//! Advanced Executable Object Format.
#include <LibCompiler/AE.h>
-//! Format header.
-#include <format>
-
//! LibCompiler utils.
-#include <LibCompiler/Detail/ClUtils.h>
+#include <LibCompiler/Util/CompilerUtils.h>
//! I/O stream from std c++
#include <iostream>
#define kLinkerVersionStr \
- "NeKernel 64-Bit Linker (Preferred Executable Format) {}, (c) Amlal El Mahrouss " \
+ "NeKernel 64-Bit Linker (Preferred Executable Format) %s, (c) Amlal El Mahrouss " \
"2024-2025 " \
"all rights reserved.\n"
@@ -59,19 +56,19 @@
#define kLinkerAbiContainer "__PEFContainer:ABI:"
#define kPrintF printf
-#define kLinkerSplash() kOutCon << std::format(kLinkerVersionStr, kDistVersion)
+#define kLinkerSplash() kConsoleOut << std::printf(kLinkerVersionStr, kDistVersion)
/// @brief PEF stack size symbol.
#define kLinkerStackSizeSymbol "__PEFSizeOfReserveStack"
-#define kOutCon \
+#define kConsoleOut \
(std::cout << "\e[0;31m" \
<< "ld64: " \
<< "\e[0;97m")
namespace Detail {
struct DynamicLinkerBlob final {
- std::vector<CharType> mBlob{}; // PEF code/bss/data blob.
+ std::vector<Char> mBlob{}; // PEF code/bss/data blob.
UIntPtr mOffset{0UL}; // the offset of the PEF container header...
};
} // namespace Detail
@@ -83,20 +80,20 @@ enum {
kABITypeInvalid = 0xFFFF,
};
-static LibCompiler::String kOutput = "a" kPefExt;
-static Int32 kAbi = kABITypeNE;
-static Int32 kSubArch = kPefNoSubCpu;
-static Int32 kArch = LibCompiler::kPefArchInvalid;
-static Bool kFatBinaryEnable = false;
-static Bool kStartFound = false;
-static Bool kDuplicateSymbols = false;
+static LibCompiler::STLString kOutput = "a" kPefExt;
+static Int32 kAbi = kABITypeNE;
+static Int32 kSubArch = kPefNoSubCpu;
+static Int32 kArch = LibCompiler::kPefArchInvalid;
+static Bool kFatBinaryEnable = false;
+static Bool kStartFound = false;
+static Bool kDuplicateSymbols = false;
/* ld64 is to be found, mld is to be found at runtime. */
-static const CharType* kLdDefineSymbol = ":UndefinedSymbol:";
-static const CharType* kLdDynamicSym = ":RuntimeSymbol:";
+static const Char* kLdDefineSymbol = ":UndefinedSymbol:";
+static const Char* kLdDynamicSym = ":RuntimeSymbol:";
/* object code and list. */
-static std::vector<LibCompiler::String> kObjectList;
+static std::vector<LibCompiler::STLString> kObjectList;
static std::vector<Detail::DynamicLinkerBlob> kObjectBytes;
/// @brief NE 64-bit Linker.
@@ -104,7 +101,7 @@ static std::vector<Detail::DynamicLinkerBlob> kObjectBytes;
LIBCOMPILER_MODULE(DynamicLinker64PEF) {
bool is_executable = true;
- ::signal(SIGSEGV, Detail::segfault_handler);
+ ::signal(SIGSEGV, Detail::drvi_crash_handler);
/**
* @brief parse flags and trigger options.
@@ -113,23 +110,24 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (StringCompare(argv[linker_arg], "-help") == 0) {
kLinkerSplash();
- kOutCon << "-version: Show linker version.\n";
- kOutCon << "-help: Show linker help.\n";
- kOutCon << "-ld-verbose: Enable linker trace.\n";
- kOutCon << "-dylib: Output as a Dynamic PEF.\n";
- kOutCon << "-fat: Output as a FAT PEF.\n";
- kOutCon << "-32k: Output as a 32x0 PEF.\n";
- kOutCon << "-64k: Output as a 64x0 PEF.\n";
- kOutCon << "-amd64: Output as a AMD64 PEF.\n";
- kOutCon << "-rv64: Output as a RISC-V PEF.\n";
- kOutCon << "-power64: Output as a POWER PEF.\n";
- kOutCon << "-arm64: Output as a ARM64 PEF.\n";
- kOutCon << "-output: Select the output file name.\n";
-
- return EXIT_SUCCESS;
+ kConsoleOut << "-version: Show linker version.\n";
+ kConsoleOut << "-help: Show linker help.\n";
+ kConsoleOut << "-ld-verbose: Enable linker trace.\n";
+ kConsoleOut << "-dylib: Output as a Dynamic PEF.\n";
+ kConsoleOut << "-fat: Output as a FAT PEF.\n";
+ kConsoleOut << "-32k: Output as a 32x0 PEF.\n";
+ kConsoleOut << "-64k: Output as a 64x0 PEF.\n";
+ kConsoleOut << "-amd64: Output as a AMD64 PEF.\n";
+ kConsoleOut << "-rv64: Output as a RISC-V PEF.\n";
+ kConsoleOut << "-power64: Output as a POWER PEF.\n";
+ kConsoleOut << "-arm64: Output as a ARM64 PEF.\n";
+ kConsoleOut << "-output: Select the output file name.\n";
+
+ return LIBCOMPILER_SUCCESS;
} else if (StringCompare(argv[linker_arg], "-version") == 0) {
kLinkerSplash();
- return EXIT_SUCCESS;
+
+ return LIBCOMPILER_SUCCESS;
} else if (StringCompare(argv[linker_arg], "-fat-binary") == 0) {
kFatBinaryEnable = true;
@@ -167,7 +165,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
continue;
}
- if (kOutput.find(kPefExt) != LibCompiler::String::npos)
+ if (kOutput.find(kPefExt) != LibCompiler::STLString::npos)
kOutput.erase(kOutput.find(kPefExt), strlen(kPefExt));
kOutput += kPefDylibExt;
@@ -184,7 +182,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
continue;
} else {
if (argv[linker_arg][0] == '-') {
- kOutCon << "unknown flag: " << argv[linker_arg] << "\n";
+ kConsoleOut << "unknown flag: " << argv[linker_arg] << "\n";
return EXIT_FAILURE;
}
@@ -195,10 +193,10 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
}
if (kOutput.empty()) {
- kOutCon << "no output filename set." << std::endl;
+ kConsoleOut << "no output filename set." << std::endl;
return LIBCOMPILER_EXEC_ERROR;
} else if (kObjectList.empty()) {
- kOutCon << "no input files." << std::endl;
+ kConsoleOut << "no input files." << std::endl;
return LIBCOMPILER_EXEC_ERROR;
} else {
namespace FS = std::filesystem;
@@ -208,15 +206,15 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (!FS::exists(obj)) {
// if filesystem doesn't find file
// -> throw error.
- kOutCon << "no such file: " << obj << std::endl;
+ kConsoleOut << "no such file: " << obj << std::endl;
return LIBCOMPILER_EXEC_ERROR;
}
}
}
// PEF expects a valid target architecture when outputing a binary.
- if (kArch == 0) {
- kOutCon << "no target architecture set, can't continue." << std::endl;
+ if (kArch == LibCompiler::kPefArchInvalid) {
+ kConsoleOut << "no target architecture set, can't continue." << std::endl;
return LIBCOMPILER_EXEC_ERROR;
}
@@ -244,7 +242,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (output_fc.bad()) {
if (kVerbose) {
- kOutCon << "error: " << strerror(errno) << "\n";
+ kConsoleOut << "error: " << strerror(errno) << "\n";
}
return LIBCOMPILER_FILE_NOT_FOUND;
@@ -263,41 +261,39 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
reader_protocol.FP = std::ifstream(objectFile, std::ifstream::binary);
reader_protocol.FP >> hdr;
- auto ae_header = hdr;
-
- if (ae_header.fMagic[0] == kAEMag0 && ae_header.fMagic[1] == kAEMag1 &&
- ae_header.fSize == sizeof(LibCompiler::AEHeader)) {
- if (ae_header.fArch != kArch) {
- if (kVerbose) kOutCon << "Info: is this a FAT binary? : ";
+ if (hdr.fMagic[0] == kAEMag0 && hdr.fMagic[1] == kAEMag1 &&
+ hdr.fSize == sizeof(LibCompiler::AEHeader)) {
+ if (hdr.fArch != kArch) {
+ if (kVerbose) kConsoleOut << "is this a FAT binary? : ";
if (!kFatBinaryEnable) {
- if (kVerbose) kOutCon << "No.\n";
+ if (kVerbose) kConsoleOut << "not a FAT binary.\n";
- kOutCon << "Error: object " << objectFile
- << " is a different kind of architecture and output isn't "
- "treated as a FAT binary."
- << std::endl;
+ kConsoleOut << "object " << objectFile
+ << " is a different kind of architecture and output isn't "
+ "treated as a FAT binary."
+ << std::endl;
return LIBCOMPILER_FAT_ERROR;
} else {
if (kVerbose) {
- kOutCon << "Architecture matches what we expect.\n";
+ kConsoleOut << "Architecture matches what we expect.\n";
}
}
}
// append arch type to archs varaible.
- archs |= ae_header.fArch;
- std::size_t cnt = ae_header.fCount;
+ archs |= hdr.fArch;
+ std::size_t cnt = hdr.fCount;
- if (kVerbose) kOutCon << "Object header found, record count: " << cnt << "\n";
+ if (kVerbose) kConsoleOut << "Object header found, record count: " << cnt << "\n";
pef_container.Count = cnt;
char_type* raw_ae_records = new char_type[cnt * sizeof(LibCompiler::AERecordHeader)];
if (!raw_ae_records) {
- if (kVerbose) kOutCon << "Allocation failure for records of count: " << cnt << "\n";
+ if (kVerbose) kConsoleOut << "Allocation failure for records of count: " << cnt << "\n";
}
memset(raw_ae_records, 0, cnt * sizeof(LibCompiler::AERecordHeader));
@@ -312,15 +308,15 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
MemoryCopy(command_header.Name, ae_records[ae_record_index].fName, kPefNameLen);
- LibCompiler::String cmd_hdr_name(command_header.Name);
+ LibCompiler::STLString cmd_hdr_name(command_header.Name);
// check this header if it's any valid.
- if (cmd_hdr_name.find(kPefCode64) == LibCompiler::String::npos &&
- cmd_hdr_name.find(kPefData64) == LibCompiler::String::npos &&
- cmd_hdr_name.find(kPefZero64) == LibCompiler::String::npos) {
- if (cmd_hdr_name.find(kPefStart) == LibCompiler::String::npos &&
+ if (cmd_hdr_name.find(kPefCode64) == LibCompiler::STLString::npos &&
+ cmd_hdr_name.find(kPefData64) == LibCompiler::STLString::npos &&
+ cmd_hdr_name.find(kPefZero64) == LibCompiler::STLString::npos) {
+ if (cmd_hdr_name.find(kPefStart) == LibCompiler::STLString::npos &&
*command_header.Name == 0) {
- if (cmd_hdr_name.find(kLdDefineSymbol) != LibCompiler::String::npos) {
+ if (cmd_hdr_name.find(kLdDefineSymbol) != LibCompiler::STLString::npos) {
goto ld_mark_header;
} else {
continue;
@@ -328,8 +324,8 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
}
}
- if (cmd_hdr_name.find(kPefStart) != LibCompiler::String::npos &&
- cmd_hdr_name.find(kPefCode64) != LibCompiler::String::npos) {
+ if (cmd_hdr_name.find(kPefStart) != LibCompiler::STLString::npos &&
+ cmd_hdr_name.find(kPefCode64) != LibCompiler::STLString::npos) {
kStartFound = true;
}
@@ -337,16 +333,16 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
command_header.Offset = offset_of_obj;
command_header.Kind = ae_records[ae_record_index].fKind;
command_header.Size = ae_records[ae_record_index].fSize;
- command_header.Cpu = ae_header.fArch;
+ command_header.Cpu = hdr.fArch;
command_header.VMAddress = org; /// TODO:
- command_header.SubCpu = ae_header.fSubArch;
+ command_header.SubCpu = hdr.fSubArch;
org += command_header.Size;
if (kVerbose) {
- kOutCon << "Record: " << ae_records[ae_record_index].fName << " is marked.\n";
+ kConsoleOut << "Record: " << ae_records[ae_record_index].fName << " is marked.\n";
- kOutCon << "Offset: " << command_header.Offset << "\n";
+ kConsoleOut << "Offset: " << command_header.Offset << "\n";
}
command_headers.emplace_back(command_header);
@@ -356,12 +352,12 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
raw_ae_records = nullptr;
std::vector<char> bytes;
- bytes.resize(ae_header.fCodeSize);
+ bytes.resize(hdr.fCodeSize);
- reader_protocol.FP.seekg(std::streamsize(ae_header.fStartCode));
- reader_protocol.FP.read(bytes.data(), std::streamsize(ae_header.fCodeSize));
+ reader_protocol.FP.seekg(std::streamsize(hdr.fStartCode));
+ reader_protocol.FP.read(bytes.data(), std::streamsize(hdr.fCodeSize));
- kObjectBytes.push_back({.mBlob = bytes, .mOffset = ae_header.fStartCode});
+ kObjectBytes.push_back({.mBlob = bytes, .mOffset = hdr.fStartCode});
// Blob was written, close fp.
@@ -370,7 +366,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
continue;
}
- kOutCon << "Not an container: " << objectFile << std::endl;
+ kConsoleOut << "Not an AE container: " << objectFile << std::endl;
// don't continue, it is a fatal error.
return LIBCOMPILER_EXEC_ERROR;
}
@@ -380,24 +376,26 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
output_fc << pef_container;
if (kVerbose) {
- kOutCon << "Wrote container to: " << output_fc.tellp() << ".\n";
+ kConsoleOut << "Wrote container to: " << output_fc.tellp() << ".\n";
}
output_fc.seekp(std::streamsize(pef_container.HdrSz));
- std::vector<LibCompiler::String> not_found;
- std::vector<LibCompiler::String> symbols;
+ std::vector<LibCompiler::STLString> not_found;
+ std::vector<LibCompiler::STLString> symbols;
// step 2: check for errors (multiple symbols, undefined ones)
for (auto& command_hdr : command_headers) {
// check if this symbol needs to be resolved.
- if (LibCompiler::String(command_hdr.Name).find(kLdDefineSymbol) != LibCompiler::String::npos &&
- LibCompiler::String(command_hdr.Name).find(kLdDynamicSym) == LibCompiler::String::npos) {
- if (kVerbose) kOutCon << "Found undefined symbol: " << command_hdr.Name << "\n";
-
- if (auto it =
- std::find(not_found.begin(), not_found.end(), LibCompiler::String(command_hdr.Name));
+ if (LibCompiler::STLString(command_hdr.Name).find(kLdDefineSymbol) !=
+ LibCompiler::STLString::npos &&
+ LibCompiler::STLString(command_hdr.Name).find(kLdDynamicSym) ==
+ LibCompiler::STLString::npos) {
+ if (kVerbose) kConsoleOut << "Found undefined symbol: " << command_hdr.Name << "\n";
+
+ if (auto it = std::find(not_found.begin(), not_found.end(),
+ LibCompiler::STLString(command_hdr.Name));
it == not_found.end()) {
not_found.emplace_back(command_hdr.Name);
}
@@ -410,26 +408,27 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
for (size_t not_found_idx = 0; not_found_idx < command_headers.size(); ++not_found_idx) {
if (const auto it = std::find(not_found.begin(), not_found.end(),
- LibCompiler::String(command_headers[not_found_idx].Name));
+ LibCompiler::STLString(command_headers[not_found_idx].Name));
it != not_found.end()) {
- LibCompiler::String symbol_imp = *it;
+ LibCompiler::STLString symbol_imp = *it;
- if (symbol_imp.find(kLdDefineSymbol) == LibCompiler::String::npos) continue;
+ if (symbol_imp.find(kLdDefineSymbol) == LibCompiler::STLString::npos) continue;
// erase the lookup prefix.
symbol_imp.erase(0, symbol_imp.find(kLdDefineSymbol) + strlen(kLdDefineSymbol));
// demangle everything.
- while (symbol_imp.find('$') != LibCompiler::String::npos)
+ while (symbol_imp.find('$') != LibCompiler::STLString::npos)
symbol_imp.erase(symbol_imp.find('$'), 1);
// the reason we do is because, this may not match the symbol, and we need
// to look for other matching symbols.
for (auto& command_hdr : command_headers) {
- if (LibCompiler::String(command_hdr.Name).find(symbol_imp) != LibCompiler::String::npos &&
- LibCompiler::String(command_hdr.Name).find(kLdDefineSymbol) ==
- LibCompiler::String::npos) {
- LibCompiler::String undefined_symbol = command_hdr.Name;
+ if (LibCompiler::STLString(command_hdr.Name).find(symbol_imp) !=
+ LibCompiler::STLString::npos &&
+ LibCompiler::STLString(command_hdr.Name).find(kLdDefineSymbol) ==
+ LibCompiler::STLString::npos) {
+ LibCompiler::STLString undefined_symbol = command_hdr.Name;
auto result_of_sym = undefined_symbol.substr(undefined_symbol.find(symbol_imp));
for (int i = 0; result_of_sym[i] != 0; ++i) {
@@ -438,7 +437,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
not_found.erase(it);
- if (kVerbose) kOutCon << "Found symbol: " << command_hdr.Name << "\n";
+ if (kVerbose) kConsoleOut << "Found symbol: " << command_hdr.Name << "\n";
break;
}
@@ -453,11 +452,11 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (!kStartFound && is_executable) {
if (kVerbose)
- kOutCon << "Undefined entrypoint: " << kPefStart
- << ", you may have forget to link "
- "against the C++ runtime library.\n";
+ kConsoleOut << "Undefined entrypoint: " << kPefStart
+ << ", you may have forget to link "
+ "against the C++ runtime library.\n";
- kOutCon << "Undefined entrypoint " << kPefStart << " for executable: " << kOutput << "\n";
+ kConsoleOut << "Undefined entrypoint " << kPefStart << " for executable: " << kOutput << "\n";
}
// step 4: write all PEF commands.
@@ -466,7 +465,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
time_t timestamp = time(nullptr);
- LibCompiler::String timeStampStr = "Container:BuildEpoch:";
+ LibCompiler::STLString timeStampStr = "Container:BuildEpoch:";
timeStampStr += std::to_string(timestamp);
strncpy(date_cmd_hdr.Name, timeStampStr.c_str(), timeStampStr.size());
@@ -480,7 +479,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
LibCompiler::PEFCommandHeader abi_cmd_hdr{};
- LibCompiler::String abi = kLinkerAbiContainer;
+ LibCompiler::STLString abi = kLinkerAbiContainer;
switch (kArch) {
case LibCompiler::kPefArchAMD64: {
@@ -546,9 +545,9 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
command_headers.push_back(uuid_cmd_hdr);
// prepare a symbol vector.
- std::vector<LibCompiler::String> undef_symbols;
- std::vector<LibCompiler::String> dupl_symbols;
- std::vector<LibCompiler::String> resolve_symbols;
+ std::vector<LibCompiler::STLString> undef_symbols;
+ std::vector<LibCompiler::STLString> dupl_symbols;
+ std::vector<LibCompiler::STLString> resolve_symbols;
constexpr Int32 kPaddingOffset = 16;
@@ -571,15 +570,15 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
// And check for any duplications
for (size_t commandHeaderIndex = 0UL; commandHeaderIndex < command_headers.size();
++commandHeaderIndex) {
- if (LibCompiler::String(command_headers[commandHeaderIndex].Name).find(kLdDefineSymbol) !=
- LibCompiler::String::npos &&
- LibCompiler::String(command_headers[commandHeaderIndex].Name).find(kLdDynamicSym) ==
- LibCompiler::String::npos) {
+ if (LibCompiler::STLString(command_headers[commandHeaderIndex].Name).find(kLdDefineSymbol) !=
+ LibCompiler::STLString::npos &&
+ LibCompiler::STLString(command_headers[commandHeaderIndex].Name).find(kLdDynamicSym) ==
+ LibCompiler::STLString::npos) {
// ignore :UndefinedSymbol: headers, they do not contain code.
continue;
}
- LibCompiler::String symbol_name = command_headers[commandHeaderIndex].Name;
+ LibCompiler::STLString symbol_name = command_headers[commandHeaderIndex].Name;
if (!symbol_name.empty()) {
undef_symbols.emplace_back(symbol_name);
@@ -588,13 +587,13 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
command_headers[commandHeaderIndex].Offset += previous_offset;
previous_offset += command_headers[commandHeaderIndex].Size;
- LibCompiler::String name = command_headers[commandHeaderIndex].Name;
+ LibCompiler::STLString name = command_headers[commandHeaderIndex].Name;
/// so this is valid when we get to the entrypoint.
/// it is always a code64 container. And should equal to kPefStart as well.
/// this chunk of code updates the pef_container.Start with the updated offset.
- if (name.find(kPefStart) != LibCompiler::String::npos &&
- name.find(kPefCode64) != LibCompiler::String::npos) {
+ if (name.find(kPefStart) != LibCompiler::STLString::npos &&
+ name.find(kPefCode64) != LibCompiler::STLString::npos) {
pef_container.Start = command_headers[commandHeaderIndex].Offset;
auto tellCurPos = output_fc.tellp();
@@ -605,9 +604,9 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
}
if (kVerbose) {
- kOutCon << "Command name: " << name << "\n";
- kOutCon << "VMAddress of command content: " << command_headers[commandHeaderIndex].Offset
- << "\n";
+ kConsoleOut << "Command name: " << name << "\n";
+ kConsoleOut << "VMAddress of command content: " << command_headers[commandHeaderIndex].Offset
+ << "\n";
}
output_fc << command_headers[commandHeaderIndex];
@@ -616,12 +615,12 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
++sub_command_header_index) {
if (sub_command_header_index == commandHeaderIndex) continue;
- if (LibCompiler::String(command_headers[sub_command_header_index].Name)
- .find(kLdDefineSymbol) != LibCompiler::String::npos &&
- LibCompiler::String(command_headers[sub_command_header_index].Name).find(kLdDynamicSym) ==
- LibCompiler::String::npos) {
+ if (LibCompiler::STLString(command_headers[sub_command_header_index].Name)
+ .find(kLdDefineSymbol) != LibCompiler::STLString::npos &&
+ LibCompiler::STLString(command_headers[sub_command_header_index].Name)
+ .find(kLdDynamicSym) == LibCompiler::STLString::npos) {
if (kVerbose) {
- kOutCon << "Ignoring :UndefinedSymbol: headers...\n";
+ kConsoleOut << "Ignoring :UndefinedSymbol: headers...\n";
}
// ignore :UndefinedSymbol: headers, they do not contain code.
@@ -630,13 +629,13 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
auto& command_hdr = command_headers[sub_command_header_index];
- if (command_hdr.Name == LibCompiler::String(command_headers[commandHeaderIndex].Name)) {
+ if (command_hdr.Name == LibCompiler::STLString(command_headers[commandHeaderIndex].Name)) {
if (std::find(dupl_symbols.cbegin(), dupl_symbols.cend(), command_hdr.Name) ==
dupl_symbols.cend()) {
dupl_symbols.emplace_back(command_hdr.Name);
}
- if (kVerbose) kOutCon << "Found duplicate symbols of: " << command_hdr.Name << "\n";
+ if (kVerbose) kConsoleOut << "Found duplicate symbols of: " << command_hdr.Name << "\n";
kDuplicateSymbols = true;
}
@@ -645,7 +644,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (!dupl_symbols.empty()) {
for (auto& symbol : dupl_symbols) {
- kOutCon << "Multiple symbols of: " << symbol << " detected, cannot continue.\n";
+ kConsoleOut << "Multiple symbols of: " << symbol << " detected, cannot continue.\n";
}
return LIBCOMPILER_EXEC_ERROR;
@@ -658,16 +657,16 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
}
if (kVerbose) {
- kOutCon << "Wrote contents of: " << kOutput << "\n";
+ kConsoleOut << "Wrote contents of: " << kOutput << "\n";
}
// step 3: check if we have those symbols
- std::vector<LibCompiler::String> unreferenced_symbols;
+ std::vector<LibCompiler::STLString> unreferenced_symbols;
for (auto& command_hdr : command_headers) {
if (auto it =
- std::find(not_found.begin(), not_found.end(), LibCompiler::String(command_hdr.Name));
+ std::find(not_found.begin(), not_found.end(), LibCompiler::STLString(command_hdr.Name));
it != not_found.end()) {
unreferenced_symbols.emplace_back(command_hdr.Name);
}
@@ -675,7 +674,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if (!unreferenced_symbols.empty()) {
for (auto& unreferenced_symbol : unreferenced_symbols) {
- kOutCon << "Undefined symbol " << unreferenced_symbol << "\n";
+ kConsoleOut << "Undefined symbol " << unreferenced_symbol << "\n";
}
return LIBCOMPILER_EXEC_ERROR;
@@ -684,7 +683,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) {
if ((!kStartFound || kDuplicateSymbols) &&
(std::filesystem::exists(kOutput) || !unreferenced_symbols.empty())) {
if (kVerbose) {
- kOutCon << "File: " << kOutput << ", is corrupt, removing file...\n";
+ kConsoleOut << "File: " << kOutput << ", is corrupt, removing file...\n";
}
return LIBCOMPILER_EXEC_ERROR;
diff --git a/dev/LibCompiler/src/CPlusPlusCompilerPreProcessor.cc b/dev/LibCompiler/src/Macro/CPlusPlusCompilerPreProcessor.cc
index 5d035da..2c7c551 100644
--- a/dev/LibCompiler/src/CPlusPlusCompilerPreProcessor.cc
+++ b/dev/LibCompiler/src/Macro/CPlusPlusCompilerPreProcessor.cc
@@ -10,7 +10,7 @@
/// BUGS: 0
#include <LibCompiler/ErrorID.h>
-#include <LibCompiler/Parser.h>
+#include <LibCompiler/Frontend.h>
#include <algorithm>
#include <filesystem>
#include <fstream>
@@ -24,7 +24,7 @@
/// @file bpp.cxx
/// @brief Preprocessor.
-typedef Int32 (*bpp_parser_fn_t)(LibCompiler::String& line, std::ifstream& hdr_file,
+typedef Int32 (*bpp_parser_fn_t)(LibCompiler::STLString& line, std::ifstream& hdr_file,
std::ofstream& pp_out);
/////////////////////////////////////////////////////////////////////////////////////////
@@ -46,8 +46,8 @@ enum {
};
struct bpp_macro_condition final {
- int32_t fType;
- LibCompiler::String fTypeName;
+ int32_t fType;
+ LibCompiler::STLString fTypeName;
void Print() {
std::cout << "type: " << fType << "\n";
@@ -56,9 +56,9 @@ struct bpp_macro_condition final {
};
struct bpp_macro final {
- std::vector<LibCompiler::String> fArgs;
- LibCompiler::String fName;
- LibCompiler::String fValue;
+ std::vector<LibCompiler::STLString> fArgs;
+ LibCompiler::STLString fName;
+ LibCompiler::STLString fValue;
void Print() {
std::cout << "name: " << fName << "\n";
@@ -71,11 +71,11 @@ struct bpp_macro final {
};
} // namespace Detail
-static std::vector<LibCompiler::String> kFiles;
-static std::vector<Detail::bpp_macro> kMacros;
-static std::vector<LibCompiler::String> kIncludes;
+static std::vector<LibCompiler::STLString> kFiles;
+static std::vector<Detail::bpp_macro> kMacros;
+static std::vector<LibCompiler::STLString> kIncludes;
-static LibCompiler::String kWorkingDir = "";
+static LibCompiler::STLString kWorkingDir = "";
/////////////////////////////////////////////////////////////////////////////////////////
@@ -85,11 +85,12 @@ static LibCompiler::String kWorkingDir = "";
/////////////////////////////////////////////////////////////////////////////////////////
int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_macro& macro,
- bool& inactive_code, bool& defined, LibCompiler::String& macro_str) {
+ bool& inactive_code, bool& defined,
+ LibCompiler::STLString& macro_str) {
if (cond.fType == Detail::kEqual) {
auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
- if (substr_macro.find(macro.fValue) != LibCompiler::String::npos) {
+ if (substr_macro.find(macro.fValue) != LibCompiler::STLString::npos) {
if (macro.fValue == "0") {
defined = false;
inactive_code = true;
@@ -105,8 +106,8 @@ int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_ma
} else if (cond.fType == Detail::kNotEqual) {
auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
- if (substr_macro.find(macro.fName) != LibCompiler::String::npos) {
- if (substr_macro.find(macro.fValue) != LibCompiler::String::npos) {
+ if (substr_macro.find(macro.fName) != LibCompiler::STLString::npos) {
+ if (substr_macro.find(macro.fValue) != LibCompiler::STLString::npos) {
defined = false;
inactive_code = true;
@@ -124,10 +125,10 @@ int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_ma
auto substr_macro = macro_str.substr(macro_str.find(macro.fName) + macro.fName.size());
- LibCompiler::String number;
+ LibCompiler::STLString number;
for (auto& macro_num : kMacros) {
- if (substr_macro.find(macro_num.fName) != LibCompiler::String::npos) {
+ if (substr_macro.find(macro_num.fName) != LibCompiler::STLString::npos) {
for (size_t i = 0; i < macro_num.fName.size(); ++i) {
if (isdigit(macro_num.fValue[i])) {
number += macro_num.fValue[i];
@@ -231,7 +232,7 @@ int32_t bpp_parse_if_condition(Detail::bpp_macro_condition& cond, Detail::bpp_ma
/////////////////////////////////////////////////////////////////////////////////////////
-std::vector<LibCompiler::String> kAllIncludes;
+std::vector<LibCompiler::STLString> kAllIncludes;
/////////////////////////////////////////////////////////////////////////////////////////
@@ -241,8 +242,8 @@ std::vector<LibCompiler::String> kAllIncludes;
/////////////////////////////////////////////////////////////////////////////////////////
void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
- LibCompiler::String hdr_line;
- LibCompiler::String line_after_include;
+ LibCompiler::STLString hdr_line;
+ LibCompiler::STLString line_after_include;
bool inactive_code = false;
bool defined = false;
@@ -250,36 +251,36 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
try {
while (std::getline(hdr_file, hdr_line)) {
if (inactive_code) {
- if (hdr_line.find("#endif") == LibCompiler::String::npos) {
+ if (hdr_line.find("#endif") == LibCompiler::STLString::npos) {
continue;
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("#endif") != LibCompiler::String::npos) {
+ hdr_line.find("#endif") != LibCompiler::STLString::npos) {
inactive_code = false;
}
- if (hdr_line.find("*/") != LibCompiler::String::npos) {
+ if (hdr_line.find("*/") != LibCompiler::STLString::npos) {
continue;
}
}
- if (hdr_line.find("--/") != LibCompiler::String::npos) {
+ if (hdr_line.find("--/") != LibCompiler::STLString::npos) {
hdr_line.erase(hdr_line.find("--/"));
}
- if (hdr_line.find("--*") != LibCompiler::String::npos) {
+ if (hdr_line.find("--*") != LibCompiler::STLString::npos) {
inactive_code = true;
// get rid of comment.
hdr_line.erase(hdr_line.find("--*"));
}
/// BPP 'brief' documentation.
- if (hdr_line.find("@brief") != LibCompiler::String::npos) {
+ if (hdr_line.find("@brief") != LibCompiler::STLString::npos) {
hdr_line.erase(hdr_line.find("@brief"));
// TODO: Write an <file_name>.html or append to it.
}
- if (hdr_line[0] == kMacroPrefix && hdr_line.find("endif") != LibCompiler::String::npos) {
+ if (hdr_line[0] == kMacroPrefix && hdr_line.find("endif") != LibCompiler::STLString::npos) {
if (!defined && inactive_code) {
inactive_code = false;
defined = false;
@@ -301,17 +302,17 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
for (auto macro : kMacros) {
if (LibCompiler::find_word(hdr_line, macro.fName)) {
if (hdr_line.substr(hdr_line.find(macro.fName)).find(macro.fName + '(') !=
- LibCompiler::String::npos) {
+ LibCompiler::STLString::npos) {
if (!macro.fArgs.empty()) {
- LibCompiler::String symbol_val = macro.fValue;
- std::vector<LibCompiler::String> args;
+ LibCompiler::STLString symbol_val = macro.fValue;
+ std::vector<LibCompiler::STLString> args;
size_t x_arg_indx = 0;
- LibCompiler::String line_after_define = hdr_line;
- LibCompiler::String str_arg;
+ LibCompiler::STLString line_after_define = hdr_line;
+ LibCompiler::STLString str_arg;
- if (line_after_define.find("(") != LibCompiler::String::npos) {
+ if (line_after_define.find("(") != LibCompiler::STLString::npos) {
line_after_define.erase(0, line_after_define.find("(") + 1);
for (auto& subc : line_after_define) {
@@ -332,7 +333,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
}
for (auto arg : macro.fArgs) {
- if (symbol_val.find(macro.fArgs[x_arg_indx]) != LibCompiler::String::npos) {
+ if (symbol_val.find(macro.fArgs[x_arg_indx]) != LibCompiler::STLString::npos) {
symbol_val.replace(symbol_val.find(macro.fArgs[x_arg_indx]),
macro.fArgs[x_arg_indx].size(), args[x_arg_indx]);
++x_arg_indx;
@@ -358,16 +359,16 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
}
}
- if (hdr_line[0] == kMacroPrefix && hdr_line.find("define ") != LibCompiler::String::npos) {
+ if (hdr_line[0] == kMacroPrefix && hdr_line.find("define ") != LibCompiler::STLString::npos) {
auto line_after_define = hdr_line.substr(hdr_line.find("define ") + strlen("define "));
- LibCompiler::String macro_value;
- LibCompiler::String macro_key;
+ LibCompiler::STLString macro_value;
+ LibCompiler::STLString macro_key;
std::size_t pos = 0UL;
- std::vector<LibCompiler::String> args;
- bool on_args = false;
+ std::vector<LibCompiler::STLString> args;
+ bool on_args = false;
for (auto& ch : line_after_define) {
++pos;
@@ -397,9 +398,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
macro_key += ch;
}
- LibCompiler::String str;
+ LibCompiler::STLString str;
- if (line_after_define.find("(") != LibCompiler::String::npos) {
+ if (line_after_define.find("(") != LibCompiler::STLString::npos) {
line_after_define.erase(0, line_after_define.find("(") + 1);
for (auto& subc : line_after_define) {
@@ -438,9 +439,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
continue;
}
- if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != LibCompiler::String::npos) {
+ if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != LibCompiler::STLString::npos) {
auto line_after_ifndef = hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1);
- LibCompiler::String macro;
+ LibCompiler::STLString macro;
for (auto& ch : line_after_ifndef) {
if (ch == ' ') {
@@ -469,7 +470,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
inactive_code = false;
for (auto& macro_ref : kMacros) {
- if (hdr_line.find(macro_ref.fName) != LibCompiler::String::npos) {
+ if (hdr_line.find(macro_ref.fName) != LibCompiler::STLString::npos) {
found = true;
break;
}
@@ -482,7 +483,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
continue;
}
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("else") != LibCompiler::String::npos) {
+ hdr_line.find("else") != LibCompiler::STLString::npos) {
if (!defined && inactive_code) {
inactive_code = false;
defined = true;
@@ -495,9 +496,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
continue;
}
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("ifdef") != LibCompiler::String::npos) {
+ hdr_line.find("ifdef") != LibCompiler::STLString::npos) {
auto line_after_ifdef = hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1);
- LibCompiler::String macro;
+ LibCompiler::STLString macro;
for (auto& ch : line_after_ifdef) {
if (ch == ' ') {
@@ -525,14 +526,15 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
inactive_code = true;
for (auto& macro_ref : kMacros) {
- if (hdr_line.find(macro_ref.fName) != LibCompiler::String::npos) {
+ if (hdr_line.find(macro_ref.fName) != LibCompiler::STLString::npos) {
defined = true;
inactive_code = false;
break;
}
}
- } else if (hdr_line[0] == kMacroPrefix && hdr_line.find("if") != LibCompiler::String::npos) {
+ } else if (hdr_line[0] == kMacroPrefix &&
+ hdr_line.find("if") != LibCompiler::STLString::npos) {
inactive_code = true;
std::vector<Detail::bpp_macro_condition> bpp_macro_condition_list = {
@@ -565,9 +567,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
int32_t good_to_go = 0;
for (auto& macro_condition : bpp_macro_condition_list) {
- if (hdr_line.find(macro_condition.fTypeName) != LibCompiler::String::npos) {
+ if (hdr_line.find(macro_condition.fTypeName) != LibCompiler::STLString::npos) {
for (auto& found_macro : kMacros) {
- if (hdr_line.find(found_macro.fName) != LibCompiler::String::npos) {
+ if (hdr_line.find(found_macro.fName) != LibCompiler::STLString::npos) {
good_to_go = bpp_parse_if_condition(macro_condition, found_macro, inactive_code,
defined, hdr_line);
@@ -579,8 +581,8 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
if (good_to_go) continue;
- auto line_after_if = hdr_line.substr(hdr_line.find("if") + strlen("if") + 1);
- LibCompiler::String macro;
+ auto line_after_if = hdr_line.substr(hdr_line.find("if") + strlen("if") + 1);
+ LibCompiler::STLString macro;
for (auto& ch : line_after_if) {
if (ch == ' ') {
@@ -605,7 +607,8 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
// last try, is it defined to be one?
for (auto& macro_ref : kMacros) {
- if (macro_ref.fName.find(macro) != LibCompiler::String::npos && macro_ref.fValue == "1") {
+ if (macro_ref.fName.find(macro) != LibCompiler::STLString::npos &&
+ macro_ref.fValue == "1") {
inactive_code = false;
defined = true;
@@ -613,9 +616,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
}
}
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("warning") != LibCompiler::String::npos) {
+ hdr_line.find("warning") != LibCompiler::STLString::npos) {
auto line_after_warning = hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1);
- LibCompiler::String message;
+ LibCompiler::STLString message;
for (auto& ch : line_after_warning) {
if (ch == '\r' || ch == '\n') {
@@ -627,9 +630,9 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
std::cout << "warn: " << message << std::endl;
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("error") != LibCompiler::String::npos) {
+ hdr_line.find("error") != LibCompiler::STLString::npos) {
auto line_after_warning = hdr_line.substr(hdr_line.find("error") + strlen("error") + 1);
- LibCompiler::String message;
+ LibCompiler::STLString message;
for (auto& ch : line_after_warning) {
if (ch == '\r' || ch == '\n') {
@@ -641,7 +644,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
throw std::runtime_error("error: " + message);
} else if (hdr_line[0] == kMacroPrefix &&
- hdr_line.find("include ") != LibCompiler::String::npos) {
+ hdr_line.find("include ") != LibCompiler::STLString::npos) {
line_after_include = hdr_line.substr(hdr_line.find("include ") + strlen("include "));
kIncludeFile:
@@ -651,7 +654,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
continue;
}
- LibCompiler::String path;
+ LibCompiler::STLString path;
kAllIncludes.push_back(line_after_include);
@@ -691,7 +694,7 @@ void bpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
}
for (auto& include : kIncludes) {
- LibCompiler::String header_path = include;
+ LibCompiler::STLString header_path = include;
header_path.push_back('/');
header_path += path;
@@ -830,7 +833,7 @@ LIBCOMPILER_MODULE(CPlusPlusPreprocessorMain) {
}
if (strcmp(argv[index], "--cppdrv:include-dir") == 0) {
- LibCompiler::String inc = argv[index + 1];
+ LibCompiler::STLString inc = argv[index + 1];
skip = true;
@@ -838,17 +841,17 @@ LIBCOMPILER_MODULE(CPlusPlusPreprocessorMain) {
}
if (strcmp(argv[index], "--cppdrv:working-dir") == 0) {
- LibCompiler::String inc = argv[index + 1];
- skip = true;
- kWorkingDir = inc;
+ LibCompiler::STLString inc = argv[index + 1];
+ skip = true;
+ kWorkingDir = inc;
}
if (strcmp(argv[index], "--cppdrv:def") == 0 && argv[index + 1] != nullptr &&
argv[index + 2] != nullptr) {
- LibCompiler::String macro_key = argv[index + 1];
+ LibCompiler::STLString macro_key = argv[index + 1];
- LibCompiler::String macro_value;
- bool is_string = false;
+ LibCompiler::STLString macro_value;
+ bool is_string = false;
for (int argv_find_len = 0; argv_find_len < strlen(argv[index]); ++argv_find_len) {
if (!isdigit(argv[index][argv_find_len])) {