summaryrefslogtreecommitdiffhomepage
path: root/src/CompilerKit
diff options
context:
space:
mode:
Diffstat (limited to 'src/CompilerKit')
-rw-r--r--src/CompilerKit/ck-win64.json27
-rw-r--r--src/CompilerKit/src/Backends/Assembler+32x0.cpp (renamed from src/CompilerKit/src/Assemblers/Assembler+32x0.cpp)2
-rw-r--r--src/CompilerKit/src/Backends/Assembler+64x0.cpp (renamed from src/CompilerKit/src/Assemblers/Assembler+64x0.cpp)10
-rw-r--r--src/CompilerKit/src/Backends/Assembler+AMD64.cpp (renamed from src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp)75
-rw-r--r--src/CompilerKit/src/Backends/Assembler+ARM64.cpp (renamed from src/CompilerKit/src/Assemblers/Assembler+ARM64.cpp)15
-rw-r--r--src/CompilerKit/src/Backends/Assembler+PowerPC.cpp (renamed from src/CompilerKit/src/Assemblers/Assembler+PowerPC.cpp)15
-rw-r--r--src/CompilerKit/src/CodeGenerator+AssemblyFactory.cpp24
-rw-r--r--src/CompilerKit/src/Frontends/NectarCompiler+AMD64.cpp (renamed from src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cpp)82
-rw-r--r--src/CompilerKit/src/Frontends/NectarCompiler+Chk.cpp100
-rw-r--r--src/CompilerKit/src/Frontends/NectarCompiler+PTX.cpp (renamed from src/CompilerKit/src/Compilers/NectarCompiler+PTX.cpp)109
-rw-r--r--src/CompilerKit/src/Frontends/README.md (renamed from src/CompilerKit/src/Compilers/README.md)2
-rw-r--r--src/CompilerKit/src/Generators/DynamicLinker64+MachO.cpp (renamed from src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cpp)42
-rw-r--r--src/CompilerKit/src/Generators/DynamicLinker64+PEF.cpp (renamed from src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cpp)26
-rw-r--r--src/CompilerKit/src/Optimizers/NectarOptimize+AMD64.cpp17
-rw-r--r--src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cpp918
-rw-r--r--src/CompilerKit/test/Compilers/NectarCodegen.test.cpp6
-rw-r--r--src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cpp8
-rw-r--r--src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cpp8
18 files changed, 353 insertions, 1133 deletions
diff --git a/src/CompilerKit/ck-win64.json b/src/CompilerKit/ck-win64.json
new file mode 100644
index 0000000..dca9350
--- /dev/null
+++ b/src/CompilerKit/ck-win64.json
@@ -0,0 +1,27 @@
+{
+ "compiler_path": "g++",
+ "compiler_std": "c++20",
+ "headers_path": [
+ "../../include/CompilerKit",
+ "../../include/",
+ "../../include/CompilerKit/src/",
+ "../../include/CompilerKit/src/impl"
+ ],
+ "sources_path": [
+ "src/*.cpp",
+ "src/*/*.cpp"
+ ],
+ "output_name": "Ne-app.CompilerKit.dll",
+ "compiler_flags": [
+ "-fPIC",
+ "-shared"
+ ],
+ "cpp_macros": [
+ "__NECTAR__=202602",
+ "CK_USE_STRUCTS=1",
+ "CK_WINDOWS=1",
+ "kDistReleaseBranch=$(git rev-parse --abbrev-ref HEAD)-$(uuidgen)"
+ ],
+ "description": "CompilerKit for Windows NT. The Compiler Kit is the framework behind Nectar."
+}
+
diff --git a/src/CompilerKit/src/Assemblers/Assembler+32x0.cpp b/src/CompilerKit/src/Backends/Assembler+32x0.cpp
index a2eb191..c8e18bd 100644
--- a/src/CompilerKit/src/Assemblers/Assembler+32x0.cpp
+++ b/src/CompilerKit/src/Backends/Assembler+32x0.cpp
@@ -24,7 +24,7 @@
#include <CompilerKit/AST.h>
#include <CompilerKit/Detail/32x0.h>
#include <CompilerKit/PEF.h>
-#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utils/Compiler.h>
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/CompilerKit/src/Assemblers/Assembler+64x0.cpp b/src/CompilerKit/src/Backends/Assembler+64x0.cpp
index 41b123a..f6e77c1 100644
--- a/src/CompilerKit/src/Assemblers/Assembler+64x0.cpp
+++ b/src/CompilerKit/src/Backends/Assembler+64x0.cpp
@@ -1,4 +1,4 @@
-// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
+// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org)
// Licensed under the Apache License, Version 2.0 (See accompanying
// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
// Official repository: https://github.com/ne-foss-org/nectar
@@ -24,13 +24,7 @@
#include <CompilerKit/AST.h>
#include <CompilerKit/Detail/64x0.h>
#include <CompilerKit/PEF.h>
-#include <CompilerKit/Utilities/Compiler.h>
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
+#include <CompilerKit/Utils/Compiler.h>
static char kOutputArch = CompilerKit::kPefArch64000;
diff --git a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp b/src/CompilerKit/src/Backends/Assembler+AMD64.cpp
index 6ec5a69..add9fce 100644
--- a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp
+++ b/src/CompilerKit/src/Backends/Assembler+AMD64.cpp
@@ -32,18 +32,7 @@
#include <CompilerKit/AST.h>
#include <CompilerKit/Detail/AMD64.h>
#include <CompilerKit/PEF.h>
-#include <CompilerKit/Utilities/Assembler.h>
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-#define kYellow "\e[0;33m"
+#include <CompilerKit/Utils/Assembler.h>
static char kOutputArch = CompilerKit::kPefArchAMD64;
@@ -114,21 +103,21 @@ NECTAR_MODULE(AssemblerMainAMD64) {
//////////////// CPU OPCODES END ////////////////
- for (i64_hword_t i{1}; i < argc; ++i) {
+ for (i64_hword_t i{1}; i < argc; ++i) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "-v") == 0) {
kStdOut
<< "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: Copyright (c) 2024-2026 "
"Amlal El Mahrouss\n";
- kStdOut
- << "AssemblerAMD64: This software is part of the Ne.org project. (https://www.nekernel.org)\n";
+ kStdOut << "AssemblerAMD64: This software is part of the Ne.app. "
+ "(https://www.nekernel.org)\n";
return 0;
} else if (strcmp(argv[i], "-help") == 0) {
kStdOut
<< "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: Copyright (c) 2024-2026 "
"Amlal El Mahrouss\n";
- kStdOut
- << "AssemblerAMD64: This Software is part of the Ne.org project. (https://www.nekernel.org)\n";
+ kStdOut << "AssemblerAMD64: This Software is part of the Ne.app. "
+ "(https://www.nekernel.org)\n";
kStdOut << "-version: Print program version.\n";
kStdOut << "-fverbose: Print verbose output.\n";
kStdOut << "-fbinary: Output as flat binary.\n";
@@ -901,10 +890,11 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, std::string
/////////////////////////////////////////////////////////////////////////////////////////
-bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerKit::STLString file) {
+bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line,
+ CompilerKit::STLString file) {
if (CompilerKit::ast_find_needle(line, "public_segment ")) return true;
if (CompilerKit::ast_find_needle(line, "extern_segment ")) return true;
-
+
struct RegMapAMD64 final {
CompilerKit::STLString fName;
i64_byte_t fModRM;
@@ -928,9 +918,9 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
/// Move instruction handler.
if (line.find(name) != std::string::npos) {
- if ((line.find(name) + name.size()) > line.size()) continue;
-
- if (name == "mov" || name == "xor") {
+ if ((line.find(name) + name.size()) > line.size()) continue;
+
+ if (name == "mov" || name == "xor") {
std::string substr = line.substr(line.find(name) + name.size());
uint64_t bits = kRegisterBitWidth;
@@ -1134,7 +1124,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
std::vector<RegMapAMD64> currentRegList;
- currentRegList.reserve(3);
+ currentRegList.reserve(3);
for (auto reg : kRegisterList) {
std::string registerName;
@@ -1216,7 +1206,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
}
if (onlyOneReg && currentRegList.size() > 0) {
- auto num = GetNumber32(line, ",");
+ auto num = GetNumber32(line, ",");
auto modrm = (0x3 << 6 | currentRegList[0].fModRM);
kAppBytes.emplace_back(0xC7); // prefixed before placing the modrm and then the number.
@@ -1232,20 +1222,19 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
break;
}
-
- if (currentRegList.size() > 0) {
- if (currentRegList[1].fName[0] == 'r' && currentRegList[0].fName[0] == 'e') {
- CompilerKit::Detail::print_error("Invalid combination of operands and registers.",
- "CompilerKit");
- throw std::runtime_error("comb_op_reg");
- }
-
- if (currentRegList[0].fName[0] == 'r' && currentRegList[1].fName[0] == 'e') {
- CompilerKit::Detail::print_error("Invalid combination of operands and registers.",
- "CompilerKit");
- throw std::runtime_error("comb_op_reg");
- }
- }
+ if (currentRegList.size() > 0) {
+ if (currentRegList[1].fName[0] == 'r' && currentRegList[0].fName[0] == 'e') {
+ CompilerKit::Detail::print_error("Invalid combination of operands and registers.",
+ "CompilerKit");
+ throw std::runtime_error("comb_op_reg");
+ }
+
+ if (currentRegList[0].fName[0] == 'r' && currentRegList[1].fName[0] == 'e') {
+ CompilerKit::Detail::print_error("Invalid combination of operands and registers.",
+ "CompilerKit");
+ throw std::runtime_error("comb_op_reg");
+ }
+ }
if (bits == 16) {
if (currentRegList[0].fName[0] == 'r' || currentRegList[0].fName[0] == 'e') {
@@ -1293,8 +1282,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
// Register lookup table
struct RegInfo final {
- CompilerKit::STLString name;
- i64_byte_t code;
+ CompilerKit::STLString name;
+ i64_byte_t code;
};
RegInfo regs64[] = {{"rax", 0}, {"rcx", 1}, {"rdx", 2}, {"rbx", 3},
@@ -1544,8 +1533,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
// Register lookup table
struct RegInfo final {
- CompilerKit::STLString name;
- i64_byte_t code;
+ CompilerKit::STLString name;
+ i64_byte_t code;
};
RegInfo regs64[] = {{"rax", 0}, {"rcx", 1}, {"rdx", 2}, {"rbx", 3},
@@ -1838,7 +1827,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerK
}
}
}
-
+
/// write a dword
else if (auto pos = line.find(".dword"); pos != std::string::npos) {
this->WriteNumber32(pos + strlen(".dword") + 1, line);
diff --git a/src/CompilerKit/src/Assemblers/Assembler+ARM64.cpp b/src/CompilerKit/src/Backends/Assembler+ARM64.cpp
index 0017af0..ca16060 100644
--- a/src/CompilerKit/src/Assemblers/Assembler+ARM64.cpp
+++ b/src/CompilerKit/src/Backends/Assembler+ARM64.cpp
@@ -1,4 +1,4 @@
-// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
+// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org)
// Licensed under the Apache License, Version 2.0 (See accompanying
// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
// Official repository: https://github.com/ne-foss-org/nectar
@@ -24,18 +24,7 @@
#include <CompilerKit/Detail/Config.h>
#include <CompilerKit/ErrorID.h>
#include <CompilerKit/PEF.h>
-#include <CompilerKit/Utilities/Assembler.h>
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-#define kYellow "\e[0;33m"
+#include <CompilerKit/Utils/Assembler.h>
constexpr auto kArm64Alignment = 0x1U;
diff --git a/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cpp b/src/CompilerKit/src/Backends/Assembler+PowerPC.cpp
index ced2cf2..fc49ba2 100644
--- a/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cpp
+++ b/src/CompilerKit/src/Backends/Assembler+PowerPC.cpp
@@ -1,4 +1,4 @@
-// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
+// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org)
// Licensed under the Apache License, Version 2.0 (See accompanying
// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
// Official repository: https://github.com/ne-foss-org/nectar
@@ -24,18 +24,7 @@
#include <CompilerKit/Detail/Power64.h>
#include <CompilerKit/ErrorID.h>
#include <CompilerKit/PEF.h>
-#include <CompilerKit/Utilities/Assembler.h>
-
-/////////////////////
-
-// ANSI ESCAPE CODES
-
-/////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-#define kYellow "\e[0;33m"
+#include <CompilerKit/Utils/Assembler.h>
constexpr auto kPowerIPAlignment = 0x1U;
diff --git a/src/CompilerKit/src/CodeGenerator+AssemblyFactory.cpp b/src/CompilerKit/src/CodeGenerator+AssemblyFactory.cpp
index 7e9e1af..6224c3e 100644
--- a/src/CompilerKit/src/CodeGenerator+AssemblyFactory.cpp
+++ b/src/CompilerKit/src/CodeGenerator+AssemblyFactory.cpp
@@ -16,22 +16,29 @@
*/
namespace CompilerKit {
+
///! @brief Compile for specific format (ELF, PEF, AE)
-Int32 AssemblyFactory::Compile(STLString sourceFile, const Int32& arch) {
- if (sourceFile.length() == 0) return NECTAR_UNIMPLEMENTED;
+Int32 AssemblyFactory::Compile(STLString source_file, const Int32& arch) {
+ if (source_file.length() == 0) return NECTAR_UNIMPLEMENTED;
if (!this->fMounted) return NECTAR_UNIMPLEMENTED;
if (arch != this->fMounted->Arch()) return NECTAR_INVALID_ARCH;
- if (!std::filesystem::is_regular_file(sourceFile)) return NECTAR_UNIMPLEMENTED;
+ if (!std::filesystem::is_regular_file(source_file)) return NECTAR_UNIMPLEMENTED;
+
+ auto compiled_unit = source_file + ".ignore";
- auto compiledUnit = sourceFile + ".ignore";
+ try {
+ std::filesystem::copy(source_file, compiled_unit);
+ auto ret = this->fMounted->CompileToFormat(compiled_unit, arch);
- std::filesystem::copy(sourceFile, compiledUnit);
- auto ret = this->fMounted->CompileToFormat(compiledUnit, arch);
- std::filesystem::remove(compiledUnit);
+ std::filesystem::remove(compiled_unit);
+ return ret;
+ } catch (...) {
+ std::filesystem::remove(compiled_unit);
+ }
- return ret;
+ return NECTAR_INVALID_DATA;
}
///! @brief mount assembly backend.
@@ -51,4 +58,5 @@ WeakRef<IAssembly> AssemblyFactory::Unmount() noexcept {
return WeakRef<IAssembly>{mount_prev};
}
+
} // namespace CompilerKit
diff --git a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cpp b/src/CompilerKit/src/Frontends/NectarCompiler+AMD64.cpp
index 92cc52d..822a2d0 100644
--- a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cpp
+++ b/src/CompilerKit/src/Frontends/NectarCompiler+AMD64.cpp
@@ -6,30 +6,18 @@
/// BUGS: 0
-///////////////////////
-
-// ANSI ESCAPE CODES //
-
-///////////////////////
-
-///////////////////////
-
-// MACROS //
-
-///////////////////////
-
#include <CompilerKit/AST.h>
#include <CompilerKit/Detail/AMD64.h>
#include <CompilerKit/PEF.h>
#include <CompilerKit/UUID.h>
-#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utils/Compiler.h>
-/* NeKernel Nectar Compiler Driver. */
+/* Nectar Compiler Driver. */
/* This is part of the CompilerKit. */
/* (c) Amlal El Mahrouss 2024-2026 */
/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/// @file NectarCompiler+AMD64.cc
+/// @file NectarCompiler+AMD64.cpp
/// @brief NECTAR Compiler Driver.
/////////////////////////////////////
@@ -45,8 +33,8 @@ static std::filesystem::path nectar_expand_home(const std::filesystem::path& inp
if (!raw.empty() && raw[0] == '~') {
const char* home = std::getenv("HOME");
- if (!home) home = std::getenv("USERPROFILE");
+ if (!home) home = std::getenv("USERPROFILE");
if (!home) throw std::runtime_error("Home directory not found in environment variables");
return std::filesystem::path(home) / raw.substr(1);
@@ -78,6 +66,8 @@ struct CompilerState final {
static CompilerState kState;
+static bool kFreestandingMode = true;
+
/// \brief Embed Scope of a class.
static Int32 kOnClassScope = 0;
@@ -134,6 +124,9 @@ struct CompilerContext {
UInt32 fInstructionCounter{0};
};
+/// @brief This function is for internal uses only, do not call it without a wrapper!
+CK_IMPORT_C bool NectarCheckLine(CompilerKit::STLString& input);
+
/// \brief Global compiler context (replaces kState)
static CompilerContext kContext;
@@ -252,13 +245,13 @@ static std::vector<CompilerKit::STLString> kRegisterConventionCallList = {
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
};
-static std::size_t kFunctionEmbedLevel{};
+static std::size_t kFunctionEmbedLevel{};
static CompilerKit::STLString kCurrentIfSymbol{};
static CompilerKit::STLString kCurrentReturnAddress{};
-static bool kCurrentIfCondition{false};
+static bool kCurrentIfCondition{false};
const char* CompilerFrontendNectarAMD64::Language() {
return "Common Nectar (AMD64)";
@@ -291,7 +284,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile(
CompilerKit::SyntaxLeafList::SyntaxLeaf syntax_tree;
CompilerKit::STLString syntax_rem_buffer;
- if (text.empty()) return syntax_tree;
+ if (!NectarCheckLine(text)) return syntax_tree;
std::size_t index{};
std::vector<std::pair<CompilerKit::SyntaxKeyword, std::size_t>> keywords_list;
@@ -355,10 +348,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile(
}
std::vector<std::pair<CompilerKit::STLString, CompilerKit::STLString>> operators = {
- {"=:", "jne"},
- {"!=:", "je"},
- {">:", "jl"},
- {"<:", "jg"},
+ {"!==", "ne"}, {"===", "eq"}, {">", "jl"}, {"<", "jg"}, {">=", "jle"}, {"<=", "jge"},
};
for (auto& op : operators) {
@@ -685,6 +675,9 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile(
arg += ch;
}
+ if (keyword.first.fKeywordKind == CompilerKit::KeywordKind::kKeywordKindAccessChecked)
+ syntax_tree.fUserValue += "call __nsan__begin\n";
+
if (!nectar_get_variable_ref(nameVar).empty()) {
if (!kNasmOutput) {
syntax_tree.fUserValue += buf;
@@ -716,6 +709,9 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile(
res += syntax_rem_buffer;
syntax_tree.fUserValue += res;
+
+ if (keyword.first.fKeywordKind == CompilerKit::KeywordKind::kKeywordKindAccessChecked)
+ syntax_tree.fUserValue += "call __nsan_end\n";
}
break;
@@ -1307,7 +1303,7 @@ static CompilerKit::STLString nectar_get_variable_ref(const CompilerKit::STLStri
}
if (!varInfo) {
- return "";
+ return {};
}
if (varInfo->fIsConstant) {
@@ -1331,7 +1327,7 @@ static CompilerKit::STLString nectar_get_variable_ref(const CompilerKit::STLStri
return reg;
}
- return "";
+ return {};
}
/// \brief Allocate a register for a variable
@@ -1387,7 +1383,7 @@ static CompilerKit::STLString nectar_allocate_register(const CompilerKit::STLStr
}
// No free register
- return "";
+ return {};
}
/// \brief Spill the least recently used variable to stack
@@ -1407,7 +1403,7 @@ static CompilerKit::STLString nectar_spill_lru_variable() {
}
if (!lruVar) {
- return ""; // No variable to spill
+ return {}; // No variable to spill
}
// Allocate stack space
@@ -1496,7 +1492,7 @@ static CompilerKit::STLString nectar_generate_destructor_call(
auto* varInfo = nectar_find_variable(obj_name);
if (!varInfo) {
- return "";
+ return {};
}
nectar_push_scope(ScopeKind::kScopeClass, class_name);
@@ -1612,12 +1608,14 @@ class AssemblyNectarInterfaceAMD64 final CK_ASSEMBLY_INTERFACE {
prevRes = res.fUserValue;
}
- // Output header
+ // Output bits and imports.
if (!kNasmOutput)
out_fp << "%bits 64\n";
else {
out_fp << "[bits 64]\n";
- out_fp << "extern __operator_new\nextern __operator_delete\n";
+ if (kFreestandingMode) {
+ out_fp << "extern __operator_new\nextern __operator_delete\n";
+ }
}
// For NASM output: emit extern declarations for undefined symbols
@@ -1655,6 +1653,7 @@ NECTAR_MODULE(CompilerNectarAMD64) {
kKeywords.emplace_back("(", CompilerKit::KeywordKind::kKeywordKindFunctionStart);
kKeywords.emplace_back(")", CompilerKit::KeywordKind::kKeywordKindFunctionEnd);
kKeywords.emplace_back(":=", CompilerKit::KeywordKind::kKeywordKindVariableAssign);
+ kKeywords.emplace_back(":==", CompilerKit::KeywordKind::kKeywordKindVariableEquals);
kKeywords.emplace_back("+=", CompilerKit::KeywordKind::kKeywordKindVariableInc);
kKeywords.emplace_back("-=", CompilerKit::KeywordKind::kKeywordKindVariableDec);
kKeywords.emplace_back("const", CompilerKit::KeywordKind::kKeywordKindVariable);
@@ -1696,6 +1695,27 @@ NECTAR_MODULE(CompilerNectarAMD64) {
continue;
}
+ if (strcmp(argv[index], "--help") == 0 || strcmp(argv[index], "-h") == 0) {
+ std::cout << "====================================================\n";
+ std::cout << "NECTAR X64 FRONTEND:\n";
+ std::cout << "====================================================\n";
+ std::cout << "-fverbose: Enable Verbose output.\n";
+ std::cout << "-fuse-masm: Use the NeSystem Assembler syntax.\n";
+ std::cout << "-fprint-dialect: Prints the current Nectar dialect.\n";
+ std::cout << "-fuse-nasm: Use the Netwide Assembler syntax.\n";
+ std::cout << "====================================================\n";
+
+ continue;
+ }
+
+ if (strcmp(argv[index], "--version") == 0 || strcmp(argv[index], "-v") == 0) {
+ std::cout << "====================================================\n";
+ std::cout << "NECTAR X64 FRONTEND:\nDIST RELEASE:";
+ std::cout << kDistRelease << "\n";
+ std::cout << "====================================================\n";
+ continue;
+ }
+
if (strcmp(argv[index], "-fverbose") == 0) {
kVerbose = true;
continue;
@@ -1720,7 +1740,7 @@ NECTAR_MODULE(CompilerNectarAMD64) {
CompilerKit::STLString err = "Unknown option: ";
err += argv[index];
- CompilerKit::Detail::print_error(err, "Nectar");
+ CompilerKit::Detail::print_error(err, "frontend");
continue;
}
diff --git a/src/CompilerKit/src/Frontends/NectarCompiler+Chk.cpp b/src/CompilerKit/src/Frontends/NectarCompiler+Chk.cpp
new file mode 100644
index 0000000..c3faf49
--- /dev/null
+++ b/src/CompilerKit/src/Frontends/NectarCompiler+Chk.cpp
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright 2026, Amlal El Mahrouss (amlal@nekernel.org)
+// Licensed under the Apache License, Version 2.0 (See accompanying
+// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
+// Official repository: https://github.com/ne-foss-org/nectar
+
+/// BUGS: 0
+
+#include <CompilerKit/AST.h>
+#include <CompilerKit/Detail/AMD64.h>
+#include <CompilerKit/PEF.h>
+#include <CompilerKit/UUID.h>
+#include <CompilerKit/Utils/Compiler.h>
+
+/* Nectar Compiler Check Driver. */
+/* This is part of the CompilerKit. */
+/* (c) Amlal El Mahrouss 2026 */
+
+using namespace CompilerKit;
+
+static bool kInIfBody = false;
+static bool kInElseBody = false;
+static bool kInTraitBody = false;
+
+CK_IMPORT_C bool NectarCheckLine(CompilerKit::STLString& input) {
+ if (input.empty()) return false;
+
+ if (input.ends_with(":")) {
+ if (!input.ends_with("):")) {
+ Detail::print_error("Invalid keyword 'else if' is not a Nectar keyword!", "check");
+ return false;
+ }
+
+ kInIfBody = true;
+ }
+
+ if (input.find("(") != CompilerKit::STLString::npos) {
+ if (input.find(")") == CompilerKit::STLString::npos) {
+ Detail::print_error("Invalid call to function, Nectar expects the ')' character at the end!",
+ "check");
+ return false;
+ }
+ }
+
+ if (input.find("let ") != CompilerKit::STLString::npos && !input.ends_with(";")) {
+ if (input.find(":=") != CompilerKit::STLString::npos) {
+ Detail::print_error("A declaration must always end with ';'", "check");
+ return false;
+ }
+ }
+
+ if (input.find(":=") != CompilerKit::STLString::npos) {
+ if (input.find(";") == CompilerKit::STLString::npos) {
+ Detail::print_error("An assignment call must always end with ';'", "check");
+ return false;
+ }
+ }
+
+ if (input.find("(") != CompilerKit::STLString::npos &&
+ input.find("const") == CompilerKit::STLString::npos &&
+ input.find("let") == CompilerKit::STLString::npos &&
+ input.find("if") == CompilerKit::STLString::npos &&
+ input.find("else") == CompilerKit::STLString::npos) {
+ if (input.find(";") == CompilerKit::STLString::npos) {
+ Detail::print_error("A function call must always end with ';'", "check");
+ return false;
+ }
+ }
+
+ if (input.find("const ") != CompilerKit::STLString::npos && !input.ends_with(";")) {
+ if (input.find(":=") != CompilerKit::STLString::npos) {
+ Detail::print_error("A declaration must always end with ';'", "check");
+ return false;
+ }
+ }
+
+ if (input.find("let ") != CompilerKit::STLString::npos && input.ends_with(";")) {
+ if (input.find(":=") == CompilerKit::STLString::npos) {
+ Detail::print_error("A declaration must always include with ':='", "check");
+ return false;
+ }
+ }
+
+ if (input.find("const ") != CompilerKit::STLString::npos && input.ends_with(";")) {
+ if (input.find(":=") == CompilerKit::STLString::npos) {
+ Detail::print_error("A declaration must always end with ':='", "check");
+ return false;
+ }
+ }
+
+ if (input == "}" || input == "}\n" || input == "}\r\n") {
+ if (kInIfBody) kInIfBody = false;
+ }
+
+ if (input == "}" || input == "}\n" || input == "}\r\n") {
+ if (kInTraitBody) kInTraitBody = false;
+ }
+
+ return true;
+}
diff --git a/src/CompilerKit/src/Compilers/NectarCompiler+PTX.cpp b/src/CompilerKit/src/Frontends/NectarCompiler+PTX.cpp
index 5737cfe..ed13b09 100644
--- a/src/CompilerKit/src/Compilers/NectarCompiler+PTX.cpp
+++ b/src/CompilerKit/src/Frontends/NectarCompiler+PTX.cpp
@@ -8,23 +8,11 @@
/// BUGS: 0
-///////////////////////
-
-// ANSI ESCAPE CODES //
-
-///////////////////////
-
-///////////////////////
-
-// MACROS //
-
-///////////////////////
-
#include <CompilerKit/AST.h>
#include <CompilerKit/UUID.h>
-#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utils/Compiler.h>
-/* NeKernel Nectar Compiler Driver. */
+/* Nectar Compiler Driver. */
/* This is part of the CompilerKit. */
/* (c) Amlal El Mahrouss 2024-2026 */
@@ -134,6 +122,9 @@ struct CompilerContext {
UInt32 fInstructionCounter{0};
};
+/// @brief This function is for internal uses only, do not call it without a wrapper!
+CK_IMPORT_C bool NectarCheckLine(CompilerKit::STLString& input);
+
/// \brief Global compiler context (replaces kState)
static CompilerContext kContext;
@@ -243,18 +234,17 @@ class CompilerFrontendNectarPTX final CK_COMPILER_FRONTEND {
static CompilerFrontendNectarPTX* kFrontend = nullptr;
-static constexpr const char* kPtxRetReg = "%rd0";
-static constexpr const char* kPtxTmpRegA = "%rd1";
-static constexpr const char* kPtxTmpRegB = "%rd2";
-static constexpr const char* kPtxThisReg = "%rd3";
-static constexpr const char* kPtxPredReg = "%p1";
+static constexpr const char* kPtxRetReg = "%rd0";
+static constexpr const char* kPtxTmpRegA = "%rd1";
+static constexpr const char* kPtxTmpRegB = "%rd2";
+static constexpr const char* kPtxThisReg = "%rd3";
+static constexpr const char* kPtxPredReg = "%p1";
static std::vector<CompilerKit::STLString> kRegisterList = {
- "%rd16", "%rd17", "%rd18", "%rd19", "%rd20", "%rd21", "%rd22", "%rd23",
- "%rd24", "%rd25", "%rd26", "%rd27", "%rd28", "%rd29", "%rd30", "%rd31",
- "%rd32", "%rd33", "%rd34", "%rd35", "%rd36", "%rd37", "%rd38", "%rd39",
- "%rd40", "%rd41", "%rd42", "%rd43", "%rd44", "%rd45", "%rd46", "%rd47",
- "%rd48", "%rd49", "%rd50", "%rd51", "%rd52", "%rd53", "%rd54", "%rd55",
+ "%rd16", "%rd17", "%rd18", "%rd19", "%rd20", "%rd21", "%rd22", "%rd23", "%rd24", "%rd25",
+ "%rd26", "%rd27", "%rd28", "%rd29", "%rd30", "%rd31", "%rd32", "%rd33", "%rd34", "%rd35",
+ "%rd36", "%rd37", "%rd38", "%rd39", "%rd40", "%rd41", "%rd42", "%rd43", "%rd44", "%rd45",
+ "%rd46", "%rd47", "%rd48", "%rd49", "%rd50", "%rd51", "%rd52", "%rd53", "%rd54", "%rd55",
"%rd56", "%rd57", "%rd58", "%rd59", "%rd60", "%rd61", "%rd62", "%rd63",
};
@@ -285,7 +275,7 @@ static std::vector<std::pair<CompilerKit::STLString, std::uintptr_t>> kOriginMap
/////////////////////////////////////////////////////////////////////////////////////////
static auto nectar_get_impl_member(const CompilerKit::STLString& class_name,
- const CompilerKit::STLString& member_name) {
+ const CompilerKit::STLString& member_name) -> CompilerStructMap {
// Find or create struct map entry
for (auto& sm : kContext.fStructMapVector) {
if (sm.fName == class_name) {
@@ -293,7 +283,7 @@ static auto nectar_get_impl_member(const CompilerKit::STLString& class_name,
}
}
- return CompilerStructMap{};
+ return {};
}
CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
@@ -301,7 +291,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
CompilerKit::SyntaxLeafList::SyntaxLeaf syntax_tree;
CompilerKit::STLString syntax_rem_buffer;
- if (text.empty()) return syntax_tree;
+ if (!NectarCheckLine(text)) return syntax_tree;
std::size_t index{};
std::vector<std::pair<CompilerKit::SyntaxKeyword, std::size_t>> keywords_list;
@@ -365,10 +355,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
}
std::vector<std::pair<CompilerKit::STLString, CompilerKit::STLString>> operators = {
- {"=:", "ne"},
- {"!=:", "eq"},
- {">:", "lt"},
- {"<:", "gt"},
+ {"!==", "ne"}, {"===", "eq"}, {">", "lt"}, {"<", "gt"}, {">=", "lte"}, {"<=", "gte"},
};
for (auto& op : operators) {
@@ -418,7 +405,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
CompilerKit::STLString{kPtxPredReg} + ", " +
CompilerKit::STLString{kPtxTmpRegA} + ", " +
CompilerKit::STLString{kPtxTmpRegB} + ";\n";
- syntax_tree.fUserValue += "@"+ CompilerKit::STLString{kPtxPredReg} + " bra __ret_" +
+ syntax_tree.fUserValue += "@" + CompilerKit::STLString{kPtxPredReg} + " bra __ret_" +
std::to_string(kOrigin) + "_" + kCurrentIfSymbol + ";\n";
kCurrentIfSymbol = std::to_string(kOrigin) + "_" + kCurrentIfSymbol;
@@ -587,8 +574,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
case CompilerKit::KeywordKind::kKeywordKindNew: {
if (auto pos = syntax_tree.fUserValue.find(keyword.first.fKeywordName);
pos != CompilerKit::STLString::npos) {
- syntax_tree.fUserValue.replace(pos, keyword.first.fKeywordName.size(),
- "__operator_new");
+ syntax_tree.fUserValue.replace(pos, keyword.first.fKeywordName.size(), "__operator_new");
}
continue;
@@ -657,9 +643,8 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
}
if (!nectar_get_variable_ref(nameVar).empty())
- syntax_tree.fUserValue +=
- "mov.u64 " + CompilerKit::STLString{kPtxThisReg} + ", " +
- nectar_get_variable_ref(nameVar) + ";\n";
+ syntax_tree.fUserValue += "mov.u64 " + CompilerKit::STLString{kPtxThisReg} + ", " +
+ nectar_get_variable_ref(nameVar) + ";\n";
if (CompilerKit::KeywordKind::kKeywordKindFunctionAccess != keyword.first.fKeywordKind)
method = valueOfVar.erase(valueOfVar.find("("));
@@ -688,8 +673,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
}
}
- if (!arg.empty())
- buf += "mov.u64 %rd" + std::to_string(index) + ", " + val + ";\n";
+ if (!arg.empty()) buf += "mov.u64 %rd" + std::to_string(index) + ", " + val + ";\n";
arg.clear();
++index;
@@ -706,7 +690,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
syntax_tree.fUserValue += "call.uni ";
syntax_tree.fUserValue +=
(keyword.first.fKeywordName.ends_with('>') ? nectar_get_variable_ref(nameVar)
- : nectar_get_variable_ref(nameVar)) +
+ : nectar_get_variable_ref(nameVar)) +
method + ";\n";
} else {
auto res = buf;
@@ -866,9 +850,8 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarPTX::Compile(
kExternalSymbols.insert(mangled + valueOfVar);
syntax_tree.fUserValue += "call " + mangled + valueOfVar + ";\n";
- syntax_tree.fUserValue +=
- instr + nectar_get_variable_ref(varName) + ", " +
- CompilerKit::STLString{kPtxRetReg} + ";\n";
+ syntax_tree.fUserValue += instr + nectar_get_variable_ref(varName) + ", " +
+ CompilerKit::STLString{kPtxRetReg} + ";\n";
}
break;
@@ -1214,7 +1197,7 @@ static CompilerKit::STLString nectar_generate_prologue() {
/// \brief Generate function epilogue
static CompilerKit::STLString nectar_generate_epilogue() {
- return "";
+ return {};
}
/// \brief Generate PTX function header
@@ -1303,7 +1286,7 @@ static CompilerKit::STLString nectar_get_variable_ref(const CompilerKit::STLStri
}
if (!varInfo) {
- return "";
+ return {};
}
if (varInfo->fIsConstant) {
@@ -1327,7 +1310,7 @@ static CompilerKit::STLString nectar_get_variable_ref(const CompilerKit::STLStri
delete varInfo;
return reg;
- return "";
+ return {};
}
/// \brief Allocate a register for a variable
@@ -1383,12 +1366,12 @@ static CompilerKit::STLString nectar_allocate_register(const CompilerKit::STLStr
}
// No free register
- return "";
+ return {};
}
/// \brief Spill the least recently used variable to stack
static CompilerKit::STLString nectar_spill_lru_variable() {
- return "";
+ return {};
}
/// \brief Add a class member to the struct map
@@ -1444,7 +1427,7 @@ static CompilerKit::STLString nectar_generate_constructor_call(
nectar_pop_scope();
CompilerKit::STLString code;
- auto objReg = nectar_allocate_register(obj_name);
+ auto objReg = nectar_allocate_register(obj_name);
if (!objReg.empty()) {
code += "mov.u64 " + CompilerKit::STLString{kPtxThisReg} + ", " + objReg + ";\n";
}
@@ -1458,7 +1441,7 @@ static CompilerKit::STLString nectar_generate_destructor_call(
auto* varInfo = nectar_find_variable(obj_name);
if (!varInfo) {
- return "";
+ return {};
}
nectar_push_scope(ScopeKind::kScopeClass, class_name);
@@ -1479,8 +1462,8 @@ static CompilerKit::STLString nectar_generate_destructor_call(
static void nectar_process_function_parameters(const std::vector<CompilerKit::STLString>& args) {
for (size_t i = 0; i < args.size(); ++i) {
VariableInfo param;
- param.fName = "arg" + std::to_string(i);
- param.fLocation = VarLocation::kRegister;
+ param.fName = "arg" + std::to_string(i);
+ param.fLocation = VarLocation::kRegister;
if (i < kRegisterConventionCallList.size()) {
param.fRegister = kRegisterConventionCallList[i];
} else {
@@ -1608,6 +1591,7 @@ NECTAR_MODULE(CompilerNectarPTX) {
kKeywords.emplace_back("->", CompilerKit::KeywordKind::kKeywordKindAccessChecked);
kKeywords.emplace_back("(", CompilerKit::KeywordKind::kKeywordKindFunctionAccess);
kKeywords.emplace_back(";", CompilerKit::KeywordKind::kKeywordKindEndLine);
+ kKeywords.emplace_back(":==", CompilerKit::KeywordKind::kKeywordKindVariableEquals);
kKeywords.emplace_back("return", CompilerKit::KeywordKind::kKeywordKindReturn);
kKeywords.emplace_back("extern", CompilerKit::KeywordKind::kKeywordKindExtern);
kKeywords.emplace_back("import", CompilerKit::KeywordKind::kKeywordKindImport);
@@ -1639,6 +1623,25 @@ NECTAR_MODULE(CompilerNectarPTX) {
continue;
}
+ if (strcmp(argv[index], "--help") == 0 || strcmp(argv[index], "-h") == 0) {
+ std::cout << "====================================================\n";
+ std::cout << "NECTAR PTX FRONTEND:\n";
+ std::cout << "====================================================\n";
+ std::cout << "-fverbose: Enable Verbose output.\n";
+ std::cout << "-fprint-dialect: Prints the current Nectar dialect.\n";
+ std::cout << "====================================================\n";
+
+ continue;
+ }
+
+ if (strcmp(argv[index], "--version") == 0 || strcmp(argv[index], "-v") == 0) {
+ std::cout << "====================================================\n";
+ std::cout << "NECTAR PTX FRONTEND:\nDIST RELEASE:";
+ std::cout << kDistRelease << "\n";
+ std::cout << "====================================================\n";
+ continue;
+ }
+
if (strcmp(argv[index], "-fverbose") == 0) {
kVerbose = true;
continue;
@@ -1653,7 +1656,7 @@ NECTAR_MODULE(CompilerNectarPTX) {
CompilerKit::STLString err = "Unknown option: ";
err += argv[index];
- CompilerKit::Detail::print_error(err, "Nectar");
+ CompilerKit::Detail::print_error(err, "frontend");
continue;
}
diff --git a/src/CompilerKit/src/Compilers/README.md b/src/CompilerKit/src/Frontends/README.md
index 2e32d07..56b6e34 100644
--- a/src/CompilerKit/src/Compilers/README.md
+++ b/src/CompilerKit/src/Frontends/README.md
@@ -1,5 +1,7 @@
# Nectar Frontends:
+The implemented Nectar frontends are implemented here.
+
## Current Status:
The following frontend are implemented as of March 2026:
diff --git a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cpp b/src/CompilerKit/src/Generators/DynamicLinker64+MachO.cpp
index f016c6e..72c8284 100644
--- a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cpp
+++ b/src/CompilerKit/src/Generators/DynamicLinker64+MachO.cpp
@@ -6,7 +6,7 @@
/// @author Amlal El Mahrouss (amlal@nekernel.org)
/// @brief NeKernel.org 64-bit Mach-O Linker.
-/// Last Rev: 2026
+/// @version Last Rev: 2026
/// @note Outputs Mach-O executables with __TEXT and __DATA segments.
#ifdef CK_USE_MACHO_LINKER
@@ -18,7 +18,7 @@
#include <CompilerKit/MachO.h>
#include <CompilerKit/PEF.h>
#include <CompilerKit/UUID.h>
-#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utils/Compiler.h>
#define kLatestOSX (15)
@@ -29,10 +29,7 @@
#define kLinkerSplash() kStdOut << kLinkerVersionStr << kStdEndl
-#define kConsoleOut \
- (std::cout << "\e[0;31m" \
- << "mld64: " \
- << "\e[0;97m")
+#define kConsoleOut (std::cout << kRed << "ld: " << kReset)
static CompilerKit::STLString kOutput = kMachODefaultOutput;
static cpu_type_t kCpuType = CPU_TYPE_X86_64;
@@ -132,21 +129,22 @@ NECTAR_MODULE(DynamicLinker64MachO) {
* @brief parse flags and trigger options.
*/
for (size_t linker_arg{1}; linker_arg < argc; ++linker_arg) {
- if (std::strcmp(argv[linker_arg], "-help") == 0) {
+ if (std::strcmp(argv[linker_arg], "--help") == 0 || std::strcmp(argv[linker_arg], "-h") == 0) {
kLinkerSplash();
- kConsoleOut << "-version: Show linker version.\n";
- kConsoleOut << "-help: Show linker help.\n";
- kConsoleOut << "-verbose: Enable linker trace.\n";
+ kConsoleOut << "--version: Show linker version.\n";
+ kConsoleOut << "--help: Show linker help.\n";
+ kConsoleOut << "--verbose: Enable linker trace.\n";
kConsoleOut << "-fdylib: Output as a Dynamic Library.\n";
kConsoleOut << "-ffat: Output as a FAT binary.\n";
kConsoleOut << "-famd64: Output as an x86_64 Mach-O.\n";
kConsoleOut << "-farm64: Output as an ARM64 Mach-O.\n";
- kConsoleOut << "-output: Select the output file name.\n";
+ kConsoleOut << "--output: Select the output file name.\n";
kConsoleOut << "-fstart: Specify entry point symbol.\n";
return NECTAR_SUCCESS;
- } else if (std::strcmp(argv[linker_arg], "-version") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--version") == 0 ||
+ std::strcmp(argv[linker_arg], "-v") == 0) {
kLinkerSplash();
return NECTAR_SUCCESS;
@@ -171,7 +169,7 @@ NECTAR_MODULE(DynamicLinker64MachO) {
linker_arg += 1;
continue;
- } else if (std::strcmp(argv[linker_arg], "-verbose") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--verbose") == 0) {
kVerbose = true;
continue;
@@ -184,7 +182,7 @@ NECTAR_MODULE(DynamicLinker64MachO) {
}
continue;
- } else if (std::strcmp(argv[linker_arg], "-output") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--output") == 0) {
if ((linker_arg + 1) > argc) continue;
kOutput = argv[linker_arg + 1];
@@ -363,8 +361,7 @@ NECTAR_MODULE(DynamicLinker64MachO) {
UInt32 symtabCmdSize = sizeof(symtab_command);
UInt32 dysymtabCmdSize = sizeof(dysymtab_command);
UInt32 linkeditCmdSize = sizeof(segment_command_64); // No sections
- UInt32 dylinkerCmdSize =
- (13 + 1 + 7) & ~7; // "/usr/lib/dyld" + padding to 8-byte align
+ UInt32 dylinkerCmdSize = (13 + 1 + 7) & ~7; // "/usr/lib/dyld" + padding to 8-byte align
sizeOfCmds = pageZeroSize + textSegCmdSize + dataSegCmdSize + buildCmdSize + uuidCmdSize +
symtabCmdSize + dysymtabCmdSize + linkeditCmdSize;
@@ -515,12 +512,12 @@ NECTAR_MODULE(DynamicLinker64MachO) {
output_fc.write(reinterpret_cast<const char*>(&linkeditSegment), sizeof(linkeditSegment));
// Write LC_LOAD_DYLINKER command
- constexpr const char* dyldPath = "/usr/lib/dyld";
- std::vector<char> dylinkerCmd(dylinkerCmdSize, 0);
- dylinker_command* dylinker = reinterpret_cast<dylinker_command*>(dylinkerCmd.data());
- dylinker->cmd = LC_LOAD_DYLINKER;
- dylinker->cmdsize = dylinkerCmdSize;
- dylinker->name.offset = sizeof(dylinker_command);
+ constexpr const char* dyldPath = "/usr/lib/dyld";
+ std::vector<char> dylinkerCmd(dylinkerCmdSize, 0);
+ dylinker_command* dylinker = reinterpret_cast<dylinker_command*>(dylinkerCmd.data());
+ dylinker->cmd = LC_LOAD_DYLINKER;
+ dylinker->cmdsize = dylinkerCmdSize;
+ dylinker->name.offset = sizeof(dylinker_command);
std::memcpy(dylinkerCmd.data() + sizeof(dylinker_command), dyldPath, strlen(dyldPath) + 1);
output_fc.write(dylinkerCmd.data(), dylinkerCmd.size());
@@ -623,7 +620,6 @@ NECTAR_MODULE(DynamicLinker64MachO) {
output_fc.write(reinterpret_cast<const char*>(&sym), sizeof(nlist_64));
}
-
// Write string table
output_fc.write(kStringTable.data(), kStringTable.size());
diff --git a/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cpp b/src/CompilerKit/src/Generators/DynamicLinker64+PEF.cpp
index 0ef8531..b3a152a 100644
--- a/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cpp
+++ b/src/CompilerKit/src/Generators/DynamicLinker64+PEF.cpp
@@ -6,7 +6,7 @@
/// @author Amlal El Mahrouss (amlal@nekernel.org)
/// @brief NeKernel.org 64-bit PEF Linker.
-/// Last Rev: Sun Feb 8 CET 2026
+/// @version Last Rev: Sun Feb 8 CET 2026
/// @note Do not look up for anything with .code64/.data64/.zero64!
/// It will be loaded when the program loader will start the image.
@@ -16,7 +16,7 @@
#include <CompilerKit/ErrorID.h>
#include <CompilerKit/PEF.h>
#include <CompilerKit/UUID.h>
-#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utils/Compiler.h>
#define kLinkerPefNoCpu (0U)
#define kLinkerPefNoSubCpu (0U)
@@ -37,10 +37,7 @@
/// @brief PEF stack size symbol.
#define kLinkerStackSizeSymbol "__PEFSizeOfReserveStack"
-#define kConsoleOut \
- (std::cout << "\e[0;31m" \
- << "ld64: " \
- << "\e[0;97m")
+#define kConsoleOut (std::cout << kRed << "ld: " << kReset)
enum struct ABIType : Int32 {
kABITypeNull = 0,
@@ -79,12 +76,12 @@ NECTAR_MODULE(DynamicLinker64PEF) {
* @brief parse flags and trigger options.
*/
for (size_t linker_arg = 1; linker_arg < argc; ++linker_arg) {
- if (std::strcmp(argv[linker_arg], "-help") == 0) {
+ if (std::strcmp(argv[linker_arg], "--help") == 0 || std::strcmp(argv[linker_arg], "-h") == 0) {
kLinkerSplash();
- kConsoleOut << "-version: Show linker version.\n";
- kConsoleOut << "-help: Show linker help.\n";
- kConsoleOut << "-verbose: Enable linker trace.\n";
+ kConsoleOut << "--version: Show linker version.\n";
+ kConsoleOut << "--help: Show linker help.\n";
+ kConsoleOut << "--verbose: Enable linker trace.\n";
kConsoleOut << "-fdylib: Output as a Dynamic PEF.\n";
kConsoleOut << "-ffat: Output as a FAT PEF.\n";
kConsoleOut << "-f32k: Output as a 32x0 PEF.\n";
@@ -93,10 +90,11 @@ NECTAR_MODULE(DynamicLinker64PEF) {
kConsoleOut << "-frv64: Output as a RISC-V PEF.\n";
kConsoleOut << "-fpower64: Output as a POWER PEF.\n";
kConsoleOut << "-farm64: Output as a ARM64 PEF.\n";
- kConsoleOut << "-output: Select the output file name.\n";
+ kConsoleOut << "--output: Select the output file name.\n";
return NECTAR_SUCCESS;
- } else if (std::strcmp(argv[linker_arg], "-version") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--version") == 0 ||
+ std::strcmp(argv[linker_arg], "-v") == 0) {
kLinkerSplash();
return NECTAR_SUCCESS;
@@ -135,7 +133,7 @@ NECTAR_MODULE(DynamicLinker64PEF) {
kArch = CompilerKit::kPefArchARM64;
continue;
- } else if (std::strcmp(argv[linker_arg], "-verbose") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--verbose") == 0) {
kVerbose = true;
continue;
@@ -151,7 +149,7 @@ NECTAR_MODULE(DynamicLinker64PEF) {
is_executable = false;
continue;
- } else if (std::strcmp(argv[linker_arg], "-output") == 0) {
+ } else if (std::strcmp(argv[linker_arg], "--output") == 0) {
if ((linker_arg + 1) > argc) continue;
kOutput = argv[linker_arg + 1];
diff --git a/src/CompilerKit/src/Optimizers/NectarOptimize+AMD64.cpp b/src/CompilerKit/src/Optimizers/NectarOptimize+AMD64.cpp
new file mode 100644
index 0000000..f754fbb
--- /dev/null
+++ b/src/CompilerKit/src/Optimizers/NectarOptimize+AMD64.cpp
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright 2026, Amlal El Mahrouss (amlal@nekernel.org)
+// Licensed under the Apache License, Version 2.0 (See accompanying
+// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
+// Official repository: https://github.com/ne-foss-org/nectar
+
+/// BUGS: 0
+
+#include <CompilerKit/AST.h>
+#include <CompilerKit/Detail/AMD64.h>
+#include <CompilerKit/PEF.h>
+#include <CompilerKit/UUID.h>
+#include <CompilerKit/Utils/Compiler.h>
+
+/* Nectar Compiler Optimizing Driver. */
+/* This is part of the CompilerKit. */
+/* (c) Amlal El Mahrouss 2024-2026 */ \ No newline at end of file
diff --git a/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cpp b/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cpp
deleted file mode 100644
index e2d20df..0000000
--- a/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cpp
+++ /dev/null
@@ -1,918 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org)
-// Licensed under the Apache License, Version 2.0 (See accompanying
-// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0)
-// Official repository: https://github.com/ne-foss-org/nectar
-
-/// BUGS: 0
-
-#include <CompilerKit/AST.h>
-#include <CompilerKit/ErrorID.h>
-#include <algorithm>
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <stdexcept>
-#include <vector>
-
-#define kMacroPrefix '#'
-
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/// @file Preprocessor+Generic.cpp
-/// @brief Nectar Preprocessor.
-
-using pp_parser_fn_t = Int32 (*)(CompilerKit::STLString&, std::ifstream&,
- std::ofstream&);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @brief Preprocessor internal types.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-namespace Detail {
-enum PPOperatorType : Int32 {
- kInvalid = 0,
- kEqual = 100,
- kGreaterEqThan,
- kLesserEqThan,
- kGreaterThan,
- kLesserThan,
- kNotEqual,
- kCount = 6,
-};
-
-struct pp_macro_condition final {
- int32_t fType;
- CompilerKit::STLString fTypeName;
-
- void Print() {
- std::cout << "type: " << fType << "\n";
- std::cout << "type_name: " << fTypeName << "\n";
- }
-};
-
-struct pp_macro final {
- std::vector<CompilerKit::STLString> fArgs;
- CompilerKit::STLString fName;
- CompilerKit::STLString fValue;
-
- void Print() {
- std::cout << "name: " << fName << "\n";
- std::cout << "value: " << fValue << "\n";
-
- for (auto& arg : fArgs) {
- std::cout << "arg: " << arg << "\n";
- }
- }
-};
-} // namespace Detail
-
-static std::vector<CompilerKit::STLString> kFiles;
-static std::vector<Detail::pp_macro> kMacros;
-static std::vector<CompilerKit::STLString> kIncludes;
-
-static CompilerKit::STLString kWorkingDir = "";
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @name pp_parse_if_condition
-// @brief parse #if condition
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro& macro,
- bool& inactive_code, bool& defined,
- CompilerKit::STLString& macro_str) {
- if (cond.fType == Detail::PPOperatorType::kEqual) {
- auto pos = macro_str.find(macro.fName);
- if (pos == CompilerKit::STLString::npos) return 0;
-
- auto substr_macro = macro_str.substr(pos + macro.fName.size());
-
- if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) {
- if (macro.fValue == "0") {
- defined = false;
- inactive_code = true;
-
- return 1;
- }
-
- defined = true;
- inactive_code = false;
-
- return 1;
- }
- } else if (cond.fType == Detail::kNotEqual) {
- auto pos = macro_str.find(macro.fName);
- if (pos == CompilerKit::STLString::npos) return 0;
-
- auto substr_macro = macro_str.substr(pos + macro.fName.size());
-
- if (substr_macro.find(macro.fName) != CompilerKit::STLString::npos) {
- if (substr_macro.find(macro.fValue) != CompilerKit::STLString::npos) {
- defined = false;
- inactive_code = true;
-
- return 1;
- }
-
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- auto pos = macro_str.find(macro.fName);
- if (pos == CompilerKit::STLString::npos) return 0;
-
- auto substr_macro = macro_str.substr(pos + macro.fName.size());
-
- CompilerKit::STLString number;
-
- for (auto& macro_num : kMacros) {
- if (substr_macro.find(macro_num.fName) != CompilerKit::STLString::npos) {
- for (size_t i = 0; i < macro_num.fValue.size(); ++i) {
- if (isdigit(macro_num.fValue[i])) {
- number += macro_num.fValue[i];
- } else {
- number.clear();
- break;
- }
- }
-
- break;
- }
- }
-
- size_t y = 2;
-
- /* last try */
- for (; y < macro_str.size(); y++) {
- if (isdigit(macro_str[y])) {
- for (size_t x = y; x < macro_str.size(); x++) {
- if (macro_str[x] == ' ') break;
-
- number += macro_str[x];
- }
-
- break;
- }
- }
-
- size_t rhs = atol(macro.fValue.c_str());
- size_t lhs = atol(number.c_str());
-
- if (lhs == 0) {
- number.clear();
- ++y;
-
- for (; y < macro_str.size(); y++) {
- if (isdigit(macro_str[y])) {
- for (size_t x = y; x < macro_str.size(); x++) {
- if (macro_str[x] == ' ') break;
-
- number += macro_str[x];
- }
-
- break;
- }
- }
-
- lhs = atol(number.c_str());
- }
-
- if (cond.fType == Detail::PPOperatorType::kGreaterThan) {
- if (lhs > rhs) {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == Detail::PPOperatorType::kGreaterEqThan) {
- if (lhs >= rhs) {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == Detail::PPOperatorType::kLesserEqThan) {
- if (lhs <= rhs) {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- if (cond.fType == Detail::PPOperatorType::kLesserThan) {
- if (lhs < rhs) {
- defined = true;
- inactive_code = false;
-
- return 1;
- }
-
- return 0;
- }
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @brief stores every included file here.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-std::vector<CompilerKit::STLString> kAllIncludes;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @name pp_parse_file
-// @brief parse file to preprocess it.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void pp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) {
- CompilerKit::STLString hdr_line;
- CompilerKit::STLString line_after_include;
-
- bool inactive_code = false;
- bool defined = false;
-
- try {
- while (std::getline(hdr_file, hdr_line)) {
- if (inactive_code) {
- if (hdr_line.find("#endif") == CompilerKit::STLString::npos) {
- continue;
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("#endif") != CompilerKit::STLString::npos) {
- inactive_code = false;
- }
- }
-
- if (hdr_line.find("*/") != CompilerKit::STLString::npos) {
- hdr_line.erase(hdr_line.find("*/"), strlen("*/"));
- }
-
- if (hdr_line.find("/*") != CompilerKit::STLString::npos) {
- inactive_code = true;
-
- // get rid of comment.
- hdr_line.erase(hdr_line.find("/*"));
- }
-
- if (hdr_line[0] == '#' && hdr_line.find("endif") != CompilerKit::STLString::npos) {
- if (!defined && inactive_code) {
- inactive_code = false;
- defined = false;
-
- continue;
- }
-
- continue;
- }
-
- if (!defined && inactive_code) {
- continue;
- }
-
- if (defined && inactive_code) {
- continue;
- }
-
- for (auto macro : kMacros) {
- if (CompilerKit::ast_find_needle(hdr_line, macro.fName)) {
- auto macro_pos = hdr_line.find(macro.fName);
- if (macro_pos == CompilerKit::STLString::npos) continue;
-
- if (hdr_line.substr(macro_pos).find(macro.fName + '(') != CompilerKit::STLString::npos) {
- if (!macro.fArgs.empty()) {
- CompilerKit::STLString symbol_val = macro.fValue;
- std::vector<CompilerKit::STLString> args;
-
- size_t x_arg_indx = 0;
-
- CompilerKit::STLString line_after_define = hdr_line;
- CompilerKit::STLString str_arg;
-
- if (line_after_define.find("(") != CompilerKit::STLString::npos) {
- line_after_define.erase(0, line_after_define.find("(") + 1);
-
- for (auto& subc : line_after_define) {
- if (subc == ' ' || subc == '\t') continue;
-
- if (subc == ',' || subc == ')') {
- if (str_arg.empty()) continue;
-
- args.push_back(str_arg);
-
- str_arg.clear();
-
- continue;
- }
-
- str_arg.push_back(subc);
- }
- }
-
- for (auto arg : macro.fArgs) {
- if (symbol_val.find(macro.fArgs[x_arg_indx]) != CompilerKit::STLString::npos) {
- symbol_val.replace(symbol_val.find(macro.fArgs[x_arg_indx]),
- macro.fArgs[x_arg_indx].size(), args[x_arg_indx]);
- ++x_arg_indx;
- } else {
- throw std::runtime_error("cppdrv: Internal error.");
- }
- }
-
- auto len = macro.fName.size();
- len += symbol_val.size();
- len += 2; // ( and )
-
- auto paren_pos = hdr_line.find(")");
- if (paren_pos != CompilerKit::STLString::npos) {
- hdr_line.erase(paren_pos, 1);
- }
-
- auto macro_call_pos = hdr_line.find(macro.fName + '(');
- if (macro_call_pos != CompilerKit::STLString::npos) {
- hdr_line.replace(macro_call_pos, len, symbol_val);
- }
- } else {
- auto value = macro.fValue;
-
- hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), value);
- }
- }
- }
- }
-
- if (hdr_line[0] == '#' && hdr_line.find("define") != CompilerKit::STLString::npos) {
- auto define_pos = hdr_line.find("define");
- if (define_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_define = hdr_line.substr(define_pos + strlen("define"));
-
- CompilerKit::STLString macro_value;
- CompilerKit::STLString macro_key;
-
- std::size_t pos = 0UL;
-
- std::vector<CompilerKit::STLString> args;
- bool on_args = false;
-
- for (auto& ch : line_after_define) {
- ++pos;
-
- if (ch == '(') {
- on_args = true;
- continue;
- }
-
- if (ch == ')') {
- on_args = false;
- continue;
- }
-
- if (ch == '\\') continue;
-
- if (on_args) continue;
-
- if (ch == ' ') {
- for (size_t i = pos; i < line_after_define.size(); i++) {
- macro_value += line_after_define[i];
- }
-
- break;
- }
-
- macro_key += ch;
- }
-
- CompilerKit::STLString str;
-
- if (line_after_define.find("(") != CompilerKit::STLString::npos) {
- line_after_define.erase(0, line_after_define.find("(") + 1);
-
- for (auto& subc : line_after_define) {
- if (subc == ',' || subc == ')') {
- if (str.empty()) continue;
-
- args.push_back(str);
-
- str.clear();
-
- continue;
- }
-
- str.push_back(subc);
- }
- }
-
- Detail::pp_macro macro;
-
- macro.fArgs = args;
- macro.fName = macro_key;
- macro.fValue = macro_value;
-
- kMacros.emplace_back(macro);
-
- continue;
- }
-
- if (hdr_line[0] != kMacroPrefix) {
- if (inactive_code) {
- continue;
- }
-
- pp_out << hdr_line << std::endl;
-
- continue;
- }
-
- if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != CompilerKit::STLString::npos) {
- auto ifndef_pos = hdr_line.find("ifndef");
- if (ifndef_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_ifndef = hdr_line.substr(ifndef_pos + strlen("ifndef") + 1);
- CompilerKit::STLString macro;
-
- for (auto& ch : line_after_ifndef) {
- if (ch == ' ') {
- break;
- }
-
- macro += ch;
- }
-
- if (macro == "0") {
- defined = true;
- inactive_code = false;
- continue;
- }
-
- if (macro == "1") {
- defined = false;
- inactive_code = true;
-
- continue;
- }
-
- bool found = false;
-
- defined = true;
- inactive_code = false;
-
- for (auto& macro_ref : kMacros) {
- if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) {
- found = true;
- break;
- }
- }
-
- if (found) {
- defined = false;
- inactive_code = true;
-
- continue;
- }
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("else") != CompilerKit::STLString::npos) {
- if (!defined && inactive_code) {
- inactive_code = false;
- defined = true;
-
- continue;
- } else {
- defined = false;
- inactive_code = true;
-
- continue;
- }
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("ifdef") != CompilerKit::STLString::npos) {
- auto ifdef_pos = hdr_line.find("ifdef");
- if (ifdef_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_ifdef = hdr_line.substr(ifdef_pos + strlen("ifdef") + 1);
- CompilerKit::STLString macro;
-
- for (auto& ch : line_after_ifdef) {
- if (ch == ' ') {
- break;
- }
-
- macro += ch;
- }
-
- if (macro == "0") {
- defined = false;
- inactive_code = true;
-
- continue;
- }
-
- if (macro == "1") {
- defined = true;
- inactive_code = false;
-
- continue;
- }
-
- defined = false;
- inactive_code = true;
-
- for (auto& macro_ref : kMacros) {
- if (hdr_line.find(macro_ref.fName) != CompilerKit::STLString::npos) {
- defined = true;
- inactive_code = false;
-
- break;
- }
- }
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("if") != CompilerKit::STLString::npos) {
- inactive_code = true;
-
- std::vector<Detail::pp_macro_condition> pp_macro_condition_list = {
- {
- .fType = Detail::PPOperatorType::kEqual,
- .fTypeName = "==",
- },
- {
- .fType = Detail::PPOperatorType::kNotEqual,
- .fTypeName = "!=",
- },
- {
- .fType = Detail::PPOperatorType::kLesserThan,
- .fTypeName = "<",
- },
- {
- .fType = Detail::PPOperatorType::kGreaterThan,
- .fTypeName = ">",
- },
- {
- .fType = Detail::PPOperatorType::kLesserEqThan,
- .fTypeName = "<=",
- },
- {
- .fType = Detail::PPOperatorType::kGreaterEqThan,
- .fTypeName = ">=",
- },
- };
-
- int32_t good_to_go = 0;
-
- for (auto& macro_condition : pp_macro_condition_list) {
- if (hdr_line.find(macro_condition.fTypeName) != CompilerKit::STLString::npos) {
- for (auto& found_macro : kMacros) {
- if (hdr_line.find(found_macro.fName) != CompilerKit::STLString::npos) {
- good_to_go = pp_parse_if_condition(macro_condition, found_macro, inactive_code,
- defined, hdr_line);
-
- break;
- }
- }
- }
- }
-
- if (good_to_go) continue;
-
- auto if_pos = hdr_line.find("if");
- if (if_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_if = hdr_line.substr(if_pos + strlen("if") + 1);
- CompilerKit::STLString macro;
-
- for (auto& ch : line_after_if) {
- if (ch == ' ') {
- break;
- }
-
- macro += ch;
- }
-
- if (macro == "0") {
- defined = false;
- inactive_code = true;
- continue;
- }
-
- if (macro == "1") {
- defined = true;
- inactive_code = false;
-
- continue;
- }
-
- // last try, is it defined to be one?
- for (auto& macro_ref : kMacros) {
- if (macro_ref.fName.find(macro) != CompilerKit::STLString::npos &&
- macro_ref.fValue == "1") {
- inactive_code = false;
- defined = true;
-
- break;
- }
- }
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("warning") != CompilerKit::STLString::npos) {
- auto warning_pos = hdr_line.find("warning");
- if (warning_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_warning = hdr_line.substr(warning_pos + strlen("warning") + 1);
- CompilerKit::STLString message;
-
- for (auto& ch : line_after_warning) {
- if (ch == '\r' || ch == '\n') {
- break;
- }
-
- message += ch;
- }
-
- std::cerr << "warn: " << message << std::endl;
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("error") != CompilerKit::STLString::npos) {
- auto error_pos = hdr_line.find("error");
- if (error_pos == CompilerKit::STLString::npos) continue;
-
- auto line_after_warning = hdr_line.substr(error_pos + strlen("error") + 1);
- CompilerKit::STLString message;
-
- for (auto& ch : line_after_warning) {
- if (ch == '\r' || ch == '\n') {
- break;
- }
-
- message += ch;
- }
-
- throw std::runtime_error("error: " + message);
- } else if (hdr_line[0] == '#' &&
- hdr_line.find("include ") != CompilerKit::STLString::npos) {
- auto include_pos = hdr_line.find("include ");
- if (include_pos == CompilerKit::STLString::npos) continue;
-
- line_after_include = hdr_line.substr(include_pos + strlen("include "));
-
- kIncludeFile:
- auto it = std::find(kAllIncludes.cbegin(), kAllIncludes.cend(), line_after_include);
-
- if (it != kAllIncludes.cend()) {
- continue;
- }
-
- CompilerKit::STLString path;
-
- kAllIncludes.push_back(line_after_include);
-
- bool enable = false;
- bool not_local = false;
-
- for (auto& ch : line_after_include) {
- if (ch == ' ') continue;
-
- if (ch == '<') {
- not_local = true;
- enable = true;
-
- continue;
- }
-
- if (ch == '\"') {
- not_local = false;
- enable = true;
- continue;
- }
-
- if (enable) {
- path += ch;
- }
- }
-
- if (not_local) {
- bool open = false;
-
- if (path.ends_with('>')) {
- path.erase(path.find('>'));
- }
-
- if (path.ends_with('"')) {
- path.erase(path.find('"'));
- }
-
- for (auto& include : kIncludes) {
- CompilerKit::STLString header_path = include;
- header_path.push_back('/');
- header_path += path;
-
- std::ifstream header(header_path);
-
- if (!header.is_open()) continue;
-
- open = true;
-
- pp_parse_file(header, pp_out);
-
- break;
- }
-
- if (!open) {
- throw std::runtime_error("cppdrv: no such include file: " + path);
- }
- } else {
- std::ifstream header(path);
-
- if (!header.is_open()) throw std::runtime_error("cppdrv: no such include file: " + path);
-
- pp_parse_file(header, pp_out);
- }
- } else {
- std::cerr << ("cppdrv: unknown pre-processor directive, " + hdr_line) << "\n";
- continue;
- }
- }
- } catch (const std::out_of_range& oor) {
- return;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// @brief main entrypoint of app.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-NECTAR_MODULE(GenericPreprocessorMain) {
- try {
- bool skip = false;
- bool double_skip = false;
-
- Detail::pp_macro macro_1;
-
- macro_1.fName = "__true";
- macro_1.fValue = "1";
-
- kMacros.push_back(macro_1);
-
- Detail::pp_macro macro_unreachable;
-
- macro_unreachable.fName = "__unreachable";
- macro_unreachable.fValue = "__compilerkit_unreachable";
-
- kMacros.push_back(macro_unreachable);
-
- Detail::pp_macro macro_unused;
-
- macro_unused.fName = "__unused";
- macro_unused.fValue = "__compilerkit_unused";
-
- kMacros.push_back(macro_unused);
-
- Detail::pp_macro macro_0;
-
- macro_0.fName = "__false";
- macro_0.fValue = "0";
-
- kMacros.push_back(macro_0);
-
- Detail::pp_macro macro_nectar;
-
- macro_nectar.fName = "__NECTAR__";
- macro_nectar.fValue = "1";
-
- kMacros.push_back(macro_nectar);
-
- Detail::pp_macro macro_lang;
-
- macro_lang.fName = "__ncpp";
- macro_lang.fValue = "202601L";
-
- kMacros.push_back(macro_lang);
-
- Detail::pp_macro macro_nil;
-
- macro_nil.fName = "nil";
- macro_nil.fValue = "0";
-
- kMacros.push_back(macro_nil);
-
- for (auto index = 1UL; index < argc; ++index) {
- if (skip) {
- skip = false;
- continue;
- }
-
- if (double_skip) {
- ++index;
- double_skip = false;
- continue;
- }
-
- if (argv[index][0] == '-') {
- if (strcmp(argv[index], "-cpp-ver") == 0) {
- printf("%s\n",
- "Nectar Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2026 all rights "
- "reserved.");
-
- return NECTAR_SUCCESS;
- }
-
- if (strcmp(argv[index], "-cpp-help") == 0) {
- printf("%s\n",
- "Nectar Preprocessor Driver v1.11, (c) Amlal El Mahrouss 2024-2026 all rights "
- "reserved.");
- printf("%s\n", "-cpp-working-dir <path>: set directory to working path.");
- printf("%s\n", "-cpp-include-dir <path>: add directory to include path.");
- printf("%s\n", "-cpp-def <name> <value>: define a macro.");
- printf("%s\n", "-cpp-ver: print the version.");
- printf("%s\n", "-cpp-help: show help (this current command).");
-
- return NECTAR_SUCCESS;
- }
-
- if (strcmp(argv[index], "-cpp-include-dir") == 0) {
- CompilerKit::STLString inc = argv[index + 1];
-
- skip = true;
-
- kIncludes.push_back(inc);
- }
-
- if (strcmp(argv[index], "-cpp-working-dir") == 0) {
- CompilerKit::STLString inc = argv[index + 1];
- skip = true;
- kWorkingDir = inc;
- }
-
- if (strcmp(argv[index], "-cpp-def") == 0 && argv[index + 1] != nullptr &&
- argv[index + 2] != nullptr) {
- CompilerKit::STLString macro_key = argv[index + 1];
-
- CompilerKit::STLString macro_value;
- bool is_string = false;
-
- for (int argv_find_len = 0; argv_find_len < strlen(argv[index + 2]); ++argv_find_len) {
- if (!isdigit(argv[index + 2][argv_find_len])) {
- is_string = true;
- macro_value += "\"";
-
- break;
- }
- }
-
- macro_value += argv[index + 2];
-
- if (is_string) macro_value += "\"";
-
- Detail::pp_macro macro;
- macro.fName = macro_key;
- macro.fValue = macro_value;
-
- kMacros.push_back(macro);
-
- double_skip = true;
- }
-
- continue;
- }
-
- kFiles.emplace_back(argv[index]);
- }
-
- if (kFiles.empty()) return NECTAR_EXEC_ERROR;
-
- for (auto& file : kFiles) {
- if (!std::filesystem::exists(file)) continue;
-
- std::ifstream file_descriptor(file);
- std::ofstream file_descriptor_pp(file + ".pp");
-
- pp_parse_file(file_descriptor, file_descriptor_pp);
- }
-
- return NECTAR_SUCCESS;
- } catch (const std::runtime_error& e) {
- std::cout << e.what() << '\n';
- }
-
- return NECTAR_EXEC_ERROR;
-}
-
-// Last rev 8-1-24
diff --git a/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp b/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp
index 581bfb8..e9632d9 100644
--- a/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp
+++ b/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp
@@ -11,11 +11,13 @@
TEST(CodegenTest, BasicCodegenTestGrep) {
// Compile C++ source to assembly
- auto compile_result = std::system("pef-amd64-necdrv ../../../../snippets/test_snippets/inner.nc > /dev/null 2>&1");
+ auto compile_result =
+ std::system("pef-amd64-necdrv ../../../../snippets/test_snippets/inner.nc > /dev/null 2>&1");
EXPECT_TRUE(compile_result == 0) << "C++ compiler driver failed to compile sample.cc";
}
TEST(CodegenTest, BasicCodegenTestAssemble) {
- auto expr = std::system("pef-amd64-asm ../../../../snippets/test_snippets/inner.masm > /dev/null 2>&1");
+ auto expr =
+ std::system("pef-amd64-asm ../../../../snippets/test_snippets/inner.masm > /dev/null 2>&1");
EXPECT_TRUE(expr == 0) << "ASM Driver did not compile the easy ASM unit.";
}
diff --git a/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cpp b/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cpp
index 8f3ff6b..50a6c21 100644
--- a/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cpp
+++ b/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cpp
@@ -8,8 +8,8 @@
#include <CompilerKit/Detail/Config.h>
#include <CompilerKit/ErrorID.h>
-#include <CompilerKit/Utilities/Compiler.h>
-#include <CompilerKit/Utilities/DLL.h>
+#include <CompilerKit/Utils/Compiler.h>
+#include <CompilerKit/Utils/DLL.h>
#include <gtest/gtest.h>
@@ -47,6 +47,8 @@ TEST(LinkerRunMachO, LinkerExitsCorrectly) {
return;
}
- auto ret =(entrypoint_cxx(argc, const_cast<const char**>(argv)) == NECTAR_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
+ auto ret = (entrypoint_cxx(argc, const_cast<const char**>(argv)) == NECTAR_SUCCESS)
+ ? EXIT_SUCCESS
+ : EXIT_FAILURE;
EXPECT_TRUE(ret == EXIT_SUCCESS);
}
diff --git a/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cpp b/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cpp
index b0b00fa..1af43d9 100644
--- a/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cpp
+++ b/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cpp
@@ -8,8 +8,8 @@
#include <CompilerKit/Detail/Config.h>
#include <CompilerKit/ErrorID.h>
-#include <CompilerKit/Utilities/Compiler.h>
-#include <CompilerKit/Utilities/DLL.h>
+#include <CompilerKit/Utils/Compiler.h>
+#include <CompilerKit/Utils/DLL.h>
#include <gtest/gtest.h>
@@ -47,6 +47,8 @@ TEST(LinkerRunMachO, LinkerExitsCorrectly) {
return;
}
- auto ret =(entrypoint_cxx(argc, const_cast<const char**>(argv)) == NECTAR_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
+ auto ret = (entrypoint_cxx(argc, const_cast<const char**>(argv)) == NECTAR_SUCCESS)
+ ? EXIT_SUCCESS
+ : EXIT_FAILURE;
EXPECT_TRUE(ret == EXIT_SUCCESS);
}