summaryrefslogtreecommitdiffhomepage
path: root/dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:05:29 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:05:29 +0100
commitbbe2c77243c541ca7e0075149f5be3262eb89523 (patch)
treeae5d59d299344fd19584a2c3642bacd788e841d4 /dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc
parentb5adf16a96b9cbb80c74cf30404ed5bcff03ac34 (diff)
feat! breaking changes on necti sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc')
-rw-r--r--dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc906
1 files changed, 0 insertions, 906 deletions
diff --git a/dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc b/dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc
deleted file mode 100644
index d715a3a..0000000
--- a/dev/CompilerKit/src/Frontend/CPlusPlusCompilerAMD64.cc
+++ /dev/null
@@ -1,906 +0,0 @@
-/*
- * ========================================================
- *
- * C++ Compiler Driver
- * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license.
- *
- * ========================================================
- */
-
-/// BUGS: 0
-
-///////////////////////
-
-// ANSI ESCAPE CODES //
-
-///////////////////////
-
-///////////////////////
-
-// MACROS //
-
-///////////////////////
-
-#define kPrintF printf
-#define kPrintErr std::cerr
-
-#define kExitOK (EXIT_SUCCESS)
-#define kExitNO (EXIT_FAILURE)
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-
-#include <CompilerKit/Frontend.h>
-#include <CompilerKit/PEF.h>
-#include <CompilerKit/UUID.h>
-#include <CompilerKit/impl/X64.h>
-#include <CompilerKit/utils/CompilerUtils.h>
-#include <csignal>
-#include <cstdlib>
-
-/* NeKernel C++ Compiler Driver */
-/* This is part of the CompilerKit. */
-/* (c) Amlal El Mahrouss 2024-2025 */
-
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/// @file CPlusPlusCompilerAMD64.cxx
-/// @brief Optimized C++ Compiler Driver.
-
-/////////////////////////////////////
-
-// INTERNALS OF THE C++ COMPILER
-
-/////////////////////////////////////
-
-/// @internal
-// Avoids relative_path which could discard parts of the original.
-std::filesystem::path necti_expand_home(const std::filesystem::path& input) {
- const std::string& raw = input.string();
-
- if (!raw.empty() && raw[0] == '~') {
- const char* home = std::getenv("HOME");
- 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);
- }
-
- return input;
-}
-
-struct CompilerRegisterMap final {
- CompilerKit::STLString fName{};
- CompilerKit::STLString fReg{};
-};
-
-/// \brief Offset based struct/class
-struct CompilerStructMap final {
- CompilerKit::STLString fName{};
- CompilerKit::STLString fReg{};
- std::vector<std::pair<UInt32, CompilerKit::STLString>> fOffsets;
-};
-
-/// \brief Compiler state structure.
-struct CompilerState final {
- std::vector<CompilerRegisterMap> fStackMapVector;
- std::vector<CompilerStructMap> fStructMapVector;
- CompilerKit::STLString fLastFile{};
- CompilerKit::STLString fLastError{};
-};
-
-static CompilerState kState;
-
-static Int32 kOnClassScope = 0;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// Target architecture.
-static Int32 kMachine = CompilerKit::AssemblyFactory::kArchAMD64;
-
-/////////////////////////////////////////
-
-// ARGUMENTS REGISTERS (R8, R15)
-
-/////////////////////////////////////////
-
-static std::vector<CompilerKit::CompilerKeyword> kKeywords;
-
-/////////////////////////////////////////
-
-// COMPILER PARSING UTILITIES/STATES.
-
-/////////////////////////////////////////
-
-static CompilerKit::AssemblyFactory kAssembler;
-static Boolean kInStruct = false;
-static Boolean kOnWhileLoop = false;
-static Boolean kOnForLoop = false;
-static Boolean kInBraces = false;
-static size_t kBracesCount = 0UL;
-
-/* @brief C++ compiler backend for the NeKernel C++ driver */
-class CompilerFrontendCPlusPlusAMD64 final CK_COMPILER_FRONTEND {
- public:
- explicit CompilerFrontendCPlusPlusAMD64() = default;
- ~CompilerFrontendCPlusPlusAMD64() override = default;
-
- NECTI_COPY_DEFAULT(CompilerFrontendCPlusPlusAMD64);
-
- CompilerKit::SyntaxLeafList::SyntaxLeaf Compile(const CompilerKit::STLString text,
- CompilerKit::STLString file) override;
-
- const char* Language() override;
-};
-
-/// @internal compiler variables
-
-static CompilerFrontendCPlusPlusAMD64* kFrontend = nullptr;
-
-static std::vector<CompilerKit::STLString> kRegisterMap;
-
-static std::vector<CompilerKit::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<CompilerKit::STLString> kRegisterConventionCallList = {
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
-};
-
-static std::size_t kFunctionEmbedLevel = 0UL;
-
-/// detail namespaces
-
-const char* CompilerFrontendCPlusPlusAMD64::Language() {
- return "AMD64 C++";
-}
-
-static std::uintptr_t kOrigin = kPefBaseOrigin;
-static std::vector<std::pair<CompilerKit::STLString, std::uintptr_t>> kOriginMap;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/// @name Compile
-/// @brief Generate assembly from a C++ source.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendCPlusPlusAMD64::Compile(
- CompilerKit::STLString text, CompilerKit::STLString file) {
- CompilerKit::SyntaxLeafList::SyntaxLeaf syntax_tree;
-
- if (text.empty()) return syntax_tree;
-
- std::size_t index = 0UL;
- std::vector<std::pair<CompilerKit::CompilerKeyword, std::size_t>> keywords_list;
-
- for (auto& keyword : kKeywords) {
- if (text.find(keyword.keyword_name) != std::string::npos) {
- switch (keyword.keyword_kind) {
- case CompilerKit::kKeywordKindCommentInline: {
- break;
- }
- default:
- break;
- }
-
- std::size_t pos = text.find(keyword.keyword_name);
- if (pos == std::string::npos) continue;
-
- // can't go before start of string
- if (pos > 0 && text[pos - 1] == '+' &&
- keyword.keyword_kind == CompilerKit::kKeywordKindVariableAssign)
- continue;
-
- if (pos > 0 && text[pos - 1] == '-' &&
- keyword.keyword_kind == CompilerKit::kKeywordKindVariableAssign)
- continue;
-
- // don't go out of range
- if ((pos + keyword.keyword_name.size()) < text.size() &&
- text[pos + keyword.keyword_name.size()] == '=' &&
- keyword.keyword_kind == CompilerKit::kKeywordKindVariableAssign)
- continue;
-
- keywords_list.emplace_back(std::make_pair(keyword, index));
- ++index;
- }
- }
-
- for (auto& keyword : keywords_list) {
- if (text.find(keyword.first.keyword_name) == CompilerKit::STLString::npos) continue;
-
- switch (keyword.first.keyword_kind) {
- case CompilerKit::KeywordKind::kKeywordKindClass: {
- ++kOnClassScope;
- break;
- }
- case CompilerKit::KeywordKind::kKeywordKindIf: {
- 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 == CompilerKit::STLString::npos ||
- openParen == CompilerKit::STLString::npos ||
- closeParen == CompilerKit::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(">=") != CompilerKit::STLString::npos) {
- auto left = text.substr(
- text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 2,
- expr.find("<=") + strlen("<="));
- auto right = text.substr(expr.find(">=") + strlen(">="), text.find(")") - 1);
-
- // Trim whitespace
- while (!right.empty() && (right.back() == ' ' || right.back() == '\t')) {
- right.pop_back();
- }
- while (!right.empty() && (right.front() == ' ' || right.front() == '\t')) {
- right.erase(0, 1);
- }
-
- while (!left.empty() && (left.back() == ' ' || left.back() == '\t')) {
- left.pop_back();
- }
- while (!left.empty() && (left.front() == ' ' || left.front() == '\t')) {
- left.erase(0, 1);
- }
-
- if ((!left.empty() && !isdigit(left[0])) || (!right.empty() && !isdigit(right[0]))) {
- auto indexRight = 0UL;
-
- auto& valueOfVar = (!left.empty() && !isdigit(left[0])) ? left : right;
-
- if (!valueOfVar.empty()) {
- for (auto pairRight : kRegisterMap) {
- ++indexRight;
-
- CompilerKit::STLString instr = "mov ";
-
- if (pairRight != valueOfVar) {
- auto& valueOfVarOpposite = (!left.empty() && isdigit(left[0])) ? left : right;
-
- syntax_tree.fUserValue +=
- instr + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + "," +
- kRegisterList[indexRight + 1] + "\n";
-
- goto lc_done_iterarting_on_if;
- }
-
- auto& valueOfVarOpposite = (!left.empty() && isdigit(left[0])) ? left : right;
-
- syntax_tree.fUserValue +=
- instr + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + ", " +
- kRegisterList[indexRight + 1] + "\n";
-
- break;
- }
- }
- }
-
- lc_done_iterarting_on_if:
-
- CompilerKit::STLString symbol_name_fn = text;
-
- symbol_name_fn.erase(symbol_name_fn.find(keyword.first.keyword_name));
-
- for (auto& ch : symbol_name_fn) {
- if (ch == ' ') ch = '_';
- }
-
- syntax_tree.fUserValue +=
- "jge __OFFSET_ON_TRUE_LC\nsegment .code64 __OFFSET_ON_TRUE_LC:\n";
- }
-
- break;
- }
- case CompilerKit::KeywordKind::kKeywordKindFunctionStart: {
- for (auto& ch : text) {
- if (isdigit(ch)) {
- goto dont_accept;
- }
- }
-
- goto accept;
-
- dont_accept:
- break;
-
- accept:
- CompilerKit::STLString symbol_name_fn = text;
- size_t indexFnName = 0;
-
- // this one is for the type.
- for (auto& ch : text) {
- ++indexFnName;
-
- if (ch == '\t') break;
- if (ch == ' ') break;
- }
-
- symbol_name_fn = text.substr(indexFnName);
-
- if (text.find("return ") != CompilerKit::STLString::npos) {
- text.erase(0, text.find("return "));
- break;
- }
-
- if (text.ends_with(";") && text.find("return") == CompilerKit::STLString::npos)
- goto lc_write_assembly;
- else if (text.size() <= indexFnName)
- Detail::print_error("Invalid function name: " + symbol_name_fn, file);
-
- indexFnName = 0;
-
- for (auto& ch : symbol_name_fn) {
- if (ch == ' ' || ch == '\t') {
- if (symbol_name_fn[indexFnName - 1] != ')')
- Detail::print_error("Invalid function name: " + symbol_name_fn, file);
- }
-
- ++indexFnName;
- }
-
- if (symbol_name_fn.find("(") != CompilerKit::STLString::npos) {
- symbol_name_fn.erase(symbol_name_fn.find("("));
- }
-
- syntax_tree.fUserValue = "public_segment .code64 __NECTI_" + symbol_name_fn + "\n";
- ++kFunctionEmbedLevel;
-
- kOriginMap.push_back({"__NECTI_" + symbol_name_fn, kOrigin});
-
- break;
-
- lc_write_assembly:
- auto it = std::find_if(
- kOriginMap.begin(), kOriginMap.end(),
- [&symbol_name_fn](std::pair<CompilerKit::STLString, std::uintptr_t> pair) -> bool {
- return symbol_name_fn == pair.first;
- });
-
- if (it != kOriginMap.end()) {
- std::stringstream ss;
- ss << std::hex << it->second;
-
- syntax_tree.fUserValue = "jmp " + ss.str() + "\n";
- kOrigin += 1UL;
- }
- }
- case CompilerKit::KeywordKind::kKeywordKindFunctionEnd: {
- if (kOnClassScope) --kOnClassScope;
-
- if (text.ends_with(";")) break;
-
- --kFunctionEmbedLevel;
-
- if (kRegisterMap.size() > kRegisterList.size()) {
- --kFunctionEmbedLevel;
- }
-
- if (kFunctionEmbedLevel < 1) kRegisterMap.clear();
-
- break;
- }
- case CompilerKit::KeywordKind::kKeywordKindEndInstr:
- case CompilerKit::KeywordKind::kKeywordKindVariableInc:
- case CompilerKit::KeywordKind::kKeywordKindVariableDec:
- case CompilerKit::KeywordKind::kKeywordKindVariableAssign: {
- CompilerKit::STLString valueOfVar = "";
-
- if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindVariableInc) {
- valueOfVar = text.substr(text.find("+=") + 2);
- } else if (keyword.first.keyword_kind ==
- CompilerKit::KeywordKind::kKeywordKindVariableDec) {
- valueOfVar = text.substr(text.find("-=") + 2);
- } else if (keyword.first.keyword_kind ==
- CompilerKit::KeywordKind::kKeywordKindVariableAssign) {
- valueOfVar = text.substr(text.find("=") + 1);
- } else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindEndInstr) {
- break;
- }
-
- while (valueOfVar.find(";") != CompilerKit::STLString::npos &&
- keyword.first.keyword_kind != CompilerKit::KeywordKind::kKeywordKindEndInstr) {
- valueOfVar.erase(valueOfVar.find(";"));
- }
-
- CompilerKit::STLString varName = text;
-
- if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindVariableInc) {
- varName.erase(varName.find("+="));
- } else if (keyword.first.keyword_kind ==
- CompilerKit::KeywordKind::kKeywordKindVariableDec) {
- varName.erase(varName.find("-="));
- } else if (keyword.first.keyword_kind ==
- CompilerKit::KeywordKind::kKeywordKindVariableAssign) {
- varName.erase(varName.find("="));
- } else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindEndInstr) {
- varName.erase(varName.find(";"));
- }
-
- static Boolean typeFound = false;
-
- for (auto& keyword : kKeywords) {
- if (keyword.keyword_kind == CompilerKit::kKeywordKindType) {
- if (text.find(keyword.keyword_name) != CompilerKit::STLString::npos) {
- if (text[text.find(keyword.keyword_name)] == ' ') {
- typeFound = false;
- continue;
- }
-
- typeFound = true;
- }
- }
- }
-
- CompilerKit::STLString instr = "mov ";
-
- std::vector<CompilerKit::STLString> newVars;
-
- if (typeFound &&
- keyword.first.keyword_kind != CompilerKit::KeywordKind::kKeywordKindVariableInc &&
- keyword.first.keyword_kind != CompilerKit::KeywordKind::kKeywordKindVariableDec) {
- if (kRegisterMap.size() > kRegisterList.size()) {
- ++kFunctionEmbedLevel;
- }
-
- while (varName.find(" ") != CompilerKit::STLString::npos) {
- varName.erase(varName.find(" "), 1);
- }
-
- while (varName.find("\t") != CompilerKit::STLString::npos) {
- varName.erase(varName.find("\t"), 1);
- }
-
- // Remove whitespace only (keep operators and quotes)
- while (!valueOfVar.empty() && (valueOfVar[0] == ' ' || valueOfVar[0] == '\t')) {
- valueOfVar.erase(0, 1);
- }
-
- constexpr auto kTrueVal = "true";
- constexpr auto kFalseVal = "false";
-
- if (valueOfVar == kTrueVal) {
- valueOfVar = "1";
- } else if (valueOfVar == kFalseVal) {
- valueOfVar = "0";
- }
-
- std::size_t indexRight = 0UL;
-
- for (auto pairRight : kRegisterMap) {
- ++indexRight;
-
- if (pairRight != valueOfVar) {
- if (valueOfVar[0] == '\"') {
- syntax_tree.fUserValue = "segment .data64 __NECTI_LOCAL_VAR_" + varName + ": db " +
- valueOfVar + ", 0\n\n";
- syntax_tree.fUserValue += instr + kRegisterList[kRegisterMap.size() - 1] + ", " +
- "__NECTI_LOCAL_VAR_" + varName + "\n";
- kOrigin += 1UL;
- } else {
- syntax_tree.fUserValue =
- instr + kRegisterList[kRegisterMap.size() - 1] + ", " + valueOfVar + "\n";
- kOrigin += 1UL;
- }
-
- goto done;
- }
- }
-
- if (((int) indexRight - 1) < 0) {
- if (valueOfVar[0] == '\"') {
- syntax_tree.fUserValue =
- "segment .data64 __NECTI_LOCAL_VAR_" + varName + ": db " + valueOfVar + ", 0\n";
- syntax_tree.fUserValue += instr + kRegisterList[kRegisterMap.size()] + ", " +
- "__NECTI_LOCAL_VAR_" + varName + "\n";
- kOrigin += 1UL;
- } else {
- auto mangled = valueOfVar;
-
- if (mangled.find("(") != std::string::npos) {
- auto ret = mangled.erase(mangled.find("("));
- mangled = "__NECTI_";
- mangled += ret;
-
- syntax_tree.fUserValue = "jmp " + mangled + "\n";
- syntax_tree.fUserValue +=
- instr + " rax, " + kRegisterList[kRegisterMap.size()] + "\n";
-
- goto done;
- }
-
- syntax_tree.fUserValue =
- instr + kRegisterList[kRegisterMap.size()] + ", " + mangled + "\n";
- kOrigin += 1UL;
- }
-
- goto done;
- }
-
- if (!valueOfVar.empty() && valueOfVar[0] != '\"' && valueOfVar[0] != '\'' &&
- !isdigit(valueOfVar[0])) {
- for (auto pair : kRegisterMap) {
- if (pair == valueOfVar) goto done;
- }
-
- Detail::print_error("Variable not declared: " + varName, file);
- break;
- }
-
- done:
- for (auto& keyword : kKeywords) {
- if (keyword.keyword_kind == CompilerKit::kKeywordKindType &&
- varName.find(keyword.keyword_name) != CompilerKit::STLString::npos) {
- varName.erase(varName.find(keyword.keyword_name), keyword.keyword_name.size());
- break;
- }
- }
-
- newVars.push_back(varName);
-
- break;
- }
-
- kRegisterMap.insert(kRegisterMap.end(), newVars.begin(), newVars.end());
-
- if (keyword.second > 0 &&
- kKeywords[keyword.second - 1].keyword_kind == CompilerKit::kKeywordKindType ||
- kKeywords[keyword.second - 1].keyword_kind == CompilerKit::kKeywordKindTypePtr) {
- syntax_tree.fUserValue = "\n";
- continue;
- }
-
- if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindEndInstr) {
- syntax_tree.fUserValue = "\n";
- continue;
- }
-
- if (keyword.first.keyword_kind == CompilerKit::KeywordKind::kKeywordKindVariableInc) {
- instr = "add ";
- } else if (keyword.first.keyword_kind ==
- CompilerKit::KeywordKind::kKeywordKindVariableDec) {
- instr = "sub ";
- }
-
- CompilerKit::STLString varErrCpy = varName;
-
- while (varName.find(" ") != CompilerKit::STLString::npos) {
- varName.erase(varName.find(" "), 1);
- }
-
- while (varName.find("\t") != CompilerKit::STLString::npos) {
- varName.erase(varName.find("\t"), 1);
- }
-
- std::size_t indxReg = 0UL;
-
- while (!valueOfVar.empty() && (valueOfVar[0] == ' ' || valueOfVar[0] == '\t')) {
- valueOfVar.erase(0, 1);
- }
-
- while (valueOfVar.find(" ") != CompilerKit::STLString::npos) {
- valueOfVar.erase(valueOfVar.find(" "), 1);
- }
-
- while (valueOfVar.find("\t") != CompilerKit::STLString::npos) {
- valueOfVar.erase(valueOfVar.find("\t"), 1);
- }
-
- constexpr auto kTrueVal = "true";
- constexpr auto kFalseVal = "false";
-
- /// interpet boolean values, since we're on C++
-
- if (valueOfVar == kTrueVal) {
- valueOfVar = "1";
- } else if (valueOfVar == kFalseVal) {
- valueOfVar = "0";
- }
-
- for (auto pair : kRegisterMap) {
- ++indxReg;
-
- if (pair != varName) continue;
-
- std::size_t indexRight = 0ul;
-
- for (auto pairRight : kRegisterMap) {
- ++indexRight;
-
- if (pairRight != varName) {
- syntax_tree.fUserValue =
- instr + kRegisterList[kRegisterMap.size()] + ", " + valueOfVar + "\n";
- kOrigin += 1UL;
- continue;
- }
-
- syntax_tree.fUserValue =
- instr + kRegisterList[indexRight - 1] + ", " + valueOfVar + "\n";
- kOrigin += 1UL;
- break;
- }
-
- newVars.push_back(varName);
- break;
- }
-
- if (syntax_tree.fUserValue.empty()) {
- Detail::print_error("Variable not declared: " + varName, file);
- }
-
- kRegisterMap.insert(kRegisterMap.end(), newVars.begin(), newVars.end());
-
- break;
- }
- case CompilerKit::KeywordKind::kKeywordKindReturn: {
- try {
- auto pos = text.find("return") + strlen("return") + 1;
- CompilerKit::STLString subText = text.substr(pos);
- if (subText.find(";") == CompilerKit::STLString::npos) break;
-
- subText = subText.erase(subText.find(";"));
- size_t indxReg = 0UL;
-
- if (!subText.empty() && subText[0] != '\"' && subText[0] != '\'') {
- if (!isdigit(subText[0])) {
- for (auto pair : kRegisterMap) {
- ++indxReg;
-
- syntax_tree.fUserValue = "mov rax, " + kRegisterList[indxReg - 1] + "\nret\n";
- kOrigin += 1UL;
-
- break;
- }
- } else {
- syntax_tree.fUserValue = "mov rax, " + subText + "\nret\n";
- kOrigin += 1UL;
-
- break;
- }
- } else {
- syntax_tree.fUserValue = "__NECTI_LOCAL_RETURN_STRING: db " + subText +
- ", 0\nmov rcx, __NECTI_LOCAL_RETURN_STRING\n";
- syntax_tree.fUserValue += "mov rax, rcx\nret\n";
- kOrigin += 1UL;
-
- break;
- }
-
- if (syntax_tree.fUserValue.empty()) {
- if (subText.find("(") != CompilerKit::STLString::npos) {
- subText.erase(subText.find("("));
-
- auto it = std::find_if(
- kOriginMap.begin(), kOriginMap.end(),
- [&subText](std::pair<CompilerKit::STLString, std::uintptr_t> pair) -> bool {
- return pair.first.find(subText) != CompilerKit::STLString::npos;
- });
-
- if (it == kOriginMap.end())
- Detail::print_error("Invalid return value: " + subText, file);
-
- std::stringstream ss;
- ss << it->second;
-
- syntax_tree.fUserValue = "jmp " + ss.str() + "\nret\n";
- kOrigin += 1UL;
- break;
- }
- }
-
- syntax_tree.fUserValue = "ret\n";
- kOrigin += 1UL;
-
- break;
- } catch (...) {
- syntax_tree.fUserValue = "ret\n";
- kOrigin += 1UL;
-
- break;
- }
- }
- default: {
- continue;
- }
- }
- }
-
- return syntax_tree;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief C++ assembler class.
- */
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class AssemblyCPlusPlusInterfaceAMD64 final CK_ASSEMBLY_INTERFACE {
- public:
- explicit AssemblyCPlusPlusInterfaceAMD64() = default;
- ~AssemblyCPlusPlusInterfaceAMD64() override = default;
-
- NECTI_COPY_DEFAULT(AssemblyCPlusPlusInterfaceAMD64);
-
- UInt32 Arch() noexcept override { return CompilerKit::AssemblyFactory::kArchAMD64; }
-
- Int32 CompileToFormat(CompilerKit::STLString src, Int32 arch) override {
- if (kFrontend == nullptr) return kExitNO;
-
- CompilerKit::STLString dest = src;
- dest += ".pp.masm";
-
- std::ofstream out_fp(dest);
- std::ifstream src_fp = std::ifstream(src + ".pp");
-
- CompilerKit::STLString line_source;
-
- out_fp << "%bits 64\n";
- out_fp << "%org " << kOrigin << "\n\n";
-
- while (std::getline(src_fp, line_source)) {
- out_fp << kFrontend->Compile(line_source, src).fUserValue;
- }
-
- return kExitOK;
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define kExtListCxx \
- { ".cpp", ".cxx", ".cc", ".c++", ".cp" }
-
-NECTI_MODULE(CompilerCPlusPlusAMD64) {
- Boolean skip = false;
-
- kKeywords.emplace_back("if", CompilerKit::kKeywordKindIf);
- kKeywords.emplace_back("else", CompilerKit::kKeywordKindElse);
- kKeywords.emplace_back("else if", CompilerKit::kKeywordKindElseIf);
-
- kKeywords.emplace_back("class", CompilerKit::kKeywordKindClass);
- kKeywords.emplace_back("struct", CompilerKit::kKeywordKindClass);
- kKeywords.emplace_back("namespace", CompilerKit::kKeywordKindNamespace);
- kKeywords.emplace_back("typedef", CompilerKit::kKeywordKindTypedef);
- kKeywords.emplace_back("using", CompilerKit::kKeywordKindTypedef);
- kKeywords.emplace_back("{", CompilerKit::kKeywordKindBodyStart);
- kKeywords.emplace_back("}", CompilerKit::kKeywordKindBodyEnd);
- kKeywords.emplace_back("auto", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("int", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("bool", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("unsigned", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("short", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("char", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("long", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("float", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("double", CompilerKit::kKeywordKindType);
- kKeywords.emplace_back("void", CompilerKit::kKeywordKindType);
-
- kKeywords.emplace_back("auto*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("int*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("bool*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("unsigned*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("short*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("char*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("long*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("float*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("double*", CompilerKit::kKeywordKindTypePtr);
- kKeywords.emplace_back("void*", CompilerKit::kKeywordKindTypePtr);
-
- kKeywords.emplace_back("(", CompilerKit::kKeywordKindFunctionStart);
- kKeywords.emplace_back(")", CompilerKit::kKeywordKindFunctionEnd);
- kKeywords.emplace_back("=", CompilerKit::kKeywordKindVariableAssign);
- kKeywords.emplace_back("+=", CompilerKit::kKeywordKindVariableInc);
- kKeywords.emplace_back("-=", CompilerKit::kKeywordKindVariableDec);
- kKeywords.emplace_back("const", CompilerKit::kKeywordKindConstant);
- kKeywords.emplace_back("*", CompilerKit::kKeywordKindPtr);
- kKeywords.emplace_back("->", CompilerKit::kKeywordKindPtrAccess);
- kKeywords.emplace_back(".", CompilerKit::kKeywordKindAccess);
- kKeywords.emplace_back(",", CompilerKit::kKeywordKindArgSeparator);
- kKeywords.emplace_back(";", CompilerKit::kKeywordKindEndInstr);
- kKeywords.emplace_back(":", CompilerKit::kKeywordKindSpecifier);
- kKeywords.emplace_back("public:", CompilerKit::kKeywordKindSpecifier);
- kKeywords.emplace_back("private:", CompilerKit::kKeywordKindSpecifier);
- kKeywords.emplace_back("protected:", CompilerKit::kKeywordKindSpecifier);
- kKeywords.emplace_back("final", CompilerKit::kKeywordKindSpecifier);
- kKeywords.emplace_back("return", CompilerKit::kKeywordKindReturn);
- kKeywords.emplace_back("/*", CompilerKit::kKeywordKindCommentMultiLineStart);
- kKeywords.emplace_back("*/", CompilerKit::kKeywordKindCommentMultiLineEnd);
- kKeywords.emplace_back("//", CompilerKit::kKeywordKindCommentInline);
- kKeywords.emplace_back("==", CompilerKit::kKeywordKindEq);
- kKeywords.emplace_back("!=", CompilerKit::kKeywordKindNotEq);
- kKeywords.emplace_back(">=", CompilerKit::kKeywordKindGreaterEq);
- kKeywords.emplace_back("<=", CompilerKit::kKeywordKindLessEq);
-
- kErrorLimit = 0;
-
- kFrontend = new CompilerFrontendCPlusPlusAMD64();
- kAssembler.Mount(new AssemblyCPlusPlusInterfaceAMD64());
-
- CompilerKit::install_signal(SIGSEGV, Detail::drvi_crash_handler);
-
- // Ensure cleanup on exit
- std::atexit([]() {
- delete kFrontend;
- kFrontend = nullptr;
- });
-
- for (auto index = 1UL; index < argc; ++index) {
- if (!argv[index]) break;
-
- if (argv[index][0] == '-') {
- if (skip) {
- skip = false;
- continue;
- }
-
- if (strcmp(argv[index], "-cxx-verbose") == 0) {
- kVerbose = true;
- continue;
- }
-
- if (strcmp(argv[index], "-cxx-dialect") == 0) {
- if (kFrontend) std::cout << kFrontend->Language() << "\n";
-
- return NECTI_SUCCESS;
- }
-
- if (strcmp(argv[index], "-cxx-max-err") == 0) {
- try {
- kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
- }
- // catch anything here
- catch (...) {
- kErrorLimit = 0;
- }
-
- skip = true;
-
- continue;
- }
-
- CompilerKit::STLString err = "Unknown option: ";
- err += argv[index];
-
- Detail::print_error(err, "cxxdrv");
-
- continue;
- }
-
- CompilerKit::STLString argv_i = argv[index];
-
- std::vector<CompilerKit::STLString> exts = kExtListCxx;
-
- for (CompilerKit::STLString ext : exts) {
- if (argv_i.ends_with(ext)) {
- if (kAssembler.Compile(argv_i, kMachine) != kExitOK) {
- return NECTI_INVALID_DATA;
- }
-
- break;
- }
- }
- }
-
- kAssembler.Unmount();
-
- return NECTI_SUCCESS;
-}
-
-//
-// Last rev 25-8-7
-//