summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-23 03:48:06 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-23 03:48:06 +0200
commit2eed4954c762bb8050e40798c3d9f1d3998324d1 (patch)
tree8848d4345fca4d62c23d1e7136eeff2978c9e6c5 /dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
parent8ad58a91a11380203c4a81fe4dc93e7734631b32 (diff)
feat!(LibCompiler): Codebase and diagram has been improved.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc')
-rw-r--r--dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc921
1 files changed, 0 insertions, 921 deletions
diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
deleted file mode 100644
index cc6fa67..0000000
--- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * ========================================================
- *
- * cxxdrv
- * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved.
- *
- * ========================================================
- */
-
-/// BUGS: 1
-
-#define kPrintF printf
-
-#define kExitOK (EXIT_SUCCESS)
-#define kExitNO (EXIT_FAILURE)
-
-// extern_segment, @autodelete { ... }, fn foo() -> auto { ... }
-
-#include <LibCompiler/Backend/Amd64.h>
-#include <LibCompiler/CompilerFrontend.h>
-#include <LibCompiler/Detail/ClUtils.h>
-#include <LibCompiler/UUID.h>
-
-/* NeKernel C++ Compiler Driver */
-/* This is part of the LibCompiler. */
-/* (c) Amlal El Mahrouss */
-
-/// @author EL Mahrouss Amlal (amlal@nekernel.org)
-/// @file CPlusPlusCompilerAMD64.cxx
-/// @brief Optimized C++ Compiler Driver.
-/// @todo Throw error for scoped inside scoped variables when they get referenced outside.
-/// @todo Add class/struct/enum support.
-
-///////////////////////
-
-// ANSI ESCAPE CODES //
-
-///////////////////////
-
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
-
-/////////////////////////////////////
-
-// INTERNALS OF THE C++ COMPILER
-
-/////////////////////////////////////
-
-/// @internal
-namespace Detail {
-std::filesystem::path expand_home(const std::filesystem::path& p) {
- if (!p.empty() && p.string()[0] == '~') {
- const char* home = std::getenv("HOME"); // For Unix-like systems
-
- if (!home) {
- home = std::getenv("USERPROFILE"); // For Windows
- }
-
- if (home) {
- return std::filesystem::path(home) / p.relative_path().string().substr(1);
- } else {
- throw std::runtime_error("Home directory not found in environment variables");
- }
- }
- return p;
-}
-
-struct CompilerRegisterMap final {
- std::string fName;
- std::string fReg;
-};
-
-// \brief Offset based struct/class
-struct CompilerStructMap final {
- std::string fName;
- std::string fReg;
-
- // offset counter
- std::size_t fOffsetsCnt;
-
- // offset array
- std::vector<std::pair<UInt32, std::string>> fOffsets;
-};
-
-struct CompilerState final {
- std::vector<CompilerRegisterMap> fStackMapVector;
- std::vector<CompilerStructMap> fStructMapVector;
- std::string fOutputValue;
- std::string fLastFile;
- std::string fLastError;
-};
-} // namespace Detail
-
-static Detail::CompilerState kState;
-
-static Int32 kOnClassScope = 0;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// Target architecture.
-static int kMachine = LibCompiler::AssemblyFactory::kArchAMD64;
-
-/////////////////////////////////////////
-
-// ARGUMENTS REGISTERS (R8, R15)
-
-/////////////////////////////////////////
-
-static std::vector<LibCompiler::CompilerKeyword> kKeywords;
-
-/////////////////////////////////////////
-
-// COMPILER PARSING UTILITIES/STATES.
-
-/////////////////////////////////////////
-
-static LibCompiler::AssemblyFactory kFactory;
-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 CompilerFrontendCPlusPlus final : public LibCompiler::CompilerFrontendInterface {
- public:
- explicit CompilerFrontendCPlusPlus() = default;
- ~CompilerFrontendCPlusPlus() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(CompilerFrontendCPlusPlus);
-
- Boolean Compile(const std::string text, std::string file) override;
-
- const char* Language() override;
-};
-
-/// @internal compiler variables
-
-static CompilerFrontendCPlusPlus* kCompilerFrontend = nullptr;
-
-static std::vector<std::string> kRegisterMap;
-
-static std::vector<std::string> kRegisterList = {
- "rbx", "rsi", "r10", "r11", "r12", "r13", "r14", "r15", "xmm12", "xmm13", "xmm14", "xmm15",
-};
-
-/// @brief The PEF calling convention (caller must save rax, rbp)
-/// @note callee must return via **rax**.
-static std::vector<std::string> kRegisterConventionCallList = {
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
-};
-
-static std::size_t kFunctionEmbedLevel = 0UL;
-
-/// detail namespaces
-
-const char* CompilerFrontendCPlusPlus::Language() {
- return "AMD64 C++";
-}
-
-static std::uintptr_t kOrigin = 0x1000000;
-static std::vector<std::pair<std::string, std::uintptr_t>> kOriginMap;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/// @name Compile
-/// @brief Generate assembly from a C++ source.
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) {
- if (text.length() < 1) return false;
-
- std::size_t index = 0UL;
- std::vector<std::pair<LibCompiler::CompilerKeyword, std::size_t>> keywords_list;
-
- for (auto& keyword : kKeywords) {
- if (text.find(keyword.keyword_name) != std::string::npos) {
- switch (keyword.keyword_kind) {
- case LibCompiler::kKeywordKindCommentInline: {
- break;
- }
- default:
- break;
- }
-
- std::size_t pos = text.find(keyword.keyword_name);
- if (pos == std::string::npos) continue;
-
- // Safe guard: can't go before start of string
- if (pos > 0 && text[pos - 1] == '+' &&
- keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
- continue;
-
- if (pos > 0 && text[pos - 1] == '-' &&
- keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
- continue;
-
- // Safe guard: don't go out of range
- if ((pos + keyword.keyword_name.size()) < text.size() &&
- text[pos + keyword.keyword_name.size()] == '=' &&
- keyword.keyword_kind == LibCompiler::kKeywordKindVariableAssign)
- continue;
-
- keywords_list.emplace_back(std::make_pair(keyword, index));
- ++index;
- }
- }
-
- LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree;
-
- for (auto& keyword : keywords_list) {
- if (text.find(keyword.first.keyword_name) == std::string::npos) continue;
-
- switch (keyword.first.keyword_kind) {
- case LibCompiler::KeywordKind::kKeywordKindClass: {
- ++kOnClassScope;
- break;
- }
- case LibCompiler::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 == std::string::npos || openParen == std::string::npos ||
- closeParen == std::string::npos || closeParen <= openParen) {
- Detail::print_error("Malformed if expression: " + text, file);
- return false;
- }
-
- auto expr = text.substr(openParen + 1, closeParen - openParen - 1);
-
- if (expr.find(">=") != std::string::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);
-
- size_t i = right.size() - 1;
-
- if (i < 1) break;
-
- try {
- while (!std::isalnum(right[i])) {
- right.erase(i, 1);
- --i;
- }
-
- right.erase(0, i);
- } catch (...) {
- right.erase(0, i);
- }
-
- i = left.size() - 1;
- try {
- while (!std::isalnum(left[i])) {
- left.erase(i, 1);
- --i;
- }
-
- left.erase(0, i);
- } catch (...) {
- left.erase(0, i);
- }
-
- if (!isdigit(left[0]) || !isdigit(right[0])) {
- auto indexRight = 0UL;
-
- auto& valueOfVar = !isdigit(left[0]) ? left : right;
-
- if (!valueOfVar.empty()) {
- for (auto pairRight : kRegisterMap) {
- ++indexRight;
-
- if (pairRight != valueOfVar) {
- auto& valueOfVarOpposite = isdigit(left[0]) ? left : right;
-
- syntax_tree.fUserValue +=
- "mov " + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + "," +
- kRegisterList[indexRight + 1] + "\n";
-
- goto done_iterarting_on_if;
- }
-
- auto& valueOfVarOpposite = isdigit(left[0]) ? left : right;
-
- syntax_tree.fUserValue +=
- "mov " + kRegisterList[indexRight + 1] + ", " + valueOfVarOpposite + "\n";
- syntax_tree.fUserValue += "cmp " + kRegisterList[kRegisterMap.size() - 1] + ", " +
- kRegisterList[indexRight + 1] + "\n";
-
- break;
- }
- }
- }
-
- done_iterarting_on_if:
-
- std::string fnName = text;
- fnName.erase(fnName.find(keyword.first.keyword_name));
-
- for (auto& ch : fnName) {
- if (ch == ' ') ch = '_';
- }
-
- syntax_tree.fUserValue +=
- "jge __OFFSET_ON_TRUE_LC\nsegment .code64 __OFFSET_ON_TRUE_LC:\n";
- }
-
- break;
- }
- case LibCompiler::KeywordKind::kKeywordKindFunctionStart: {
- for (auto& ch : text) {
- if (isdigit(ch)) {
- goto dont_accept;
- }
- }
-
- goto accept;
-
- dont_accept:
- return false;
-
- accept:
- std::string fnName = text;
- size_t indexFnName = 0;
-
- // this one is for the type.
- for (auto& ch : text) {
- ++indexFnName;
-
- if (ch == '\t') break;
- if (ch == ' ') break;
- }
-
- fnName = text.substr(indexFnName);
-
- if (text.find("return ") != std::string::npos) {
- text.erase(0, text.find("return "));
- break;
- }
-
- if (text.ends_with(";") && text.find("return") == std::string::npos)
- goto lc_write_assembly;
- else if (text.size() <= indexFnName)
- Detail::print_error("Invalid function name: " + fnName, file);
-
- indexFnName = 0;
-
- for (auto& ch : fnName) {
- if (ch == ' ' || ch == '\t') {
- if (fnName[indexFnName - 1] != ')')
- Detail::print_error("Invalid function name: " + fnName, file);
- }
-
- ++indexFnName;
- }
-
- if (fnName.find("(") != LibCompiler::String::npos) {
- fnName.erase(fnName.find("("));
- }
-
- syntax_tree.fUserValue = "public_segment .code64 __LIBCOMPILER_" + fnName + "\n";
- ++kFunctionEmbedLevel;
-
- kOriginMap.push_back({"__LIBCOMPILER_" + fnName, kOrigin});
-
- break;
-
- lc_write_assembly:
- auto it = std::find_if(kOriginMap.begin(), kOriginMap.end(),
- [&fnName](std::pair<std::string, std::uintptr_t> pair) -> bool {
- return fnName == pair.first;
- });
-
- if (it != kOriginMap.end()) {
- std::stringstream ss;
- ss << std::hex << it->second;
-
- syntax_tree.fUserValue = "jmp " + ss.str() + "\n";
- kOrigin += 1UL;
- }
- }
- case LibCompiler::KeywordKind::kKeywordKindFunctionEnd: {
- if (kOnClassScope) --kOnClassScope;
-
- if (text.ends_with(";")) break;
-
- --kFunctionEmbedLevel;
-
- if (kRegisterMap.size() > kRegisterList.size()) {
- --kFunctionEmbedLevel;
- }
-
- if (kFunctionEmbedLevel < 1) kRegisterMap.clear();
-
- break;
- }
- case LibCompiler::KeywordKind::kKeywordKindEndInstr:
- case LibCompiler::KeywordKind::kKeywordKindVariableInc:
- case LibCompiler::KeywordKind::kKeywordKindVariableDec:
- case LibCompiler::KeywordKind::kKeywordKindVariableAssign: {
- std::string valueOfVar = "";
-
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc) {
- valueOfVar = text.substr(text.find("+=") + 2);
- } else if (keyword.first.keyword_kind ==
- LibCompiler::KeywordKind::kKeywordKindVariableDec) {
- valueOfVar = text.substr(text.find("-=") + 2);
- } else if (keyword.first.keyword_kind ==
- LibCompiler::KeywordKind::kKeywordKindVariableAssign) {
- valueOfVar = text.substr(text.find("=") + 1);
- } else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr) {
- break;
- }
-
- while (valueOfVar.find(";") != std::string::npos &&
- keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindEndInstr) {
- valueOfVar.erase(valueOfVar.find(";"));
- }
-
- std::string varName = text;
-
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc) {
- varName.erase(varName.find("+="));
- } else if (keyword.first.keyword_kind ==
- LibCompiler::KeywordKind::kKeywordKindVariableDec) {
- varName.erase(varName.find("-="));
- } else if (keyword.first.keyword_kind ==
- LibCompiler::KeywordKind::kKeywordKindVariableAssign) {
- varName.erase(varName.find("="));
- } else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr) {
- varName.erase(varName.find(";"));
- }
-
- static Boolean typeFound = false;
-
- for (auto& keyword : kKeywords) {
- if (keyword.keyword_kind == LibCompiler::kKeywordKindType) {
- if (text.find(keyword.keyword_name) != std::string::npos) {
- if (text[text.find(keyword.keyword_name)] == ' ') {
- typeFound = false;
- continue;
- }
-
- typeFound = true;
- }
- }
- }
-
- std::string instr = "mov ";
-
- if (typeFound &&
- keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindVariableInc &&
- keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindVariableDec) {
- if (kRegisterMap.size() > kRegisterList.size()) {
- ++kFunctionEmbedLevel;
- }
-
- while (varName.find(" ") != std::string::npos) {
- varName.erase(varName.find(" "), 1);
- }
-
- while (varName.find("\t") != std::string::npos) {
- varName.erase(varName.find("\t"), 1);
- }
-
- for (size_t i = 0; !isalnum(valueOfVar[i]); i++) {
- if (i > valueOfVar.size()) break;
-
- valueOfVar.erase(i, 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 __LIBCOMPILER_LOCAL_VAR_" + varName +
- ": db " + valueOfVar + ", 0\n\n";
- syntax_tree.fUserValue += instr + kRegisterList[kRegisterMap.size() - 1] + ", " +
- "__LIBCOMPILER_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 __LIBCOMPILER_LOCAL_VAR_" + varName +
- ": db " + valueOfVar + ", 0\n";
- syntax_tree.fUserValue += instr + kRegisterList[kRegisterMap.size()] + ", " +
- "__LIBCOMPILER_LOCAL_VAR_" + varName + "\n";
- kOrigin += 1UL;
- } else {
- syntax_tree.fUserValue =
- instr + kRegisterList[kRegisterMap.size()] + ", " + valueOfVar + "\n";
- kOrigin += 1UL;
- }
-
- goto done;
- }
-
- if (valueOfVar[0] != '\"' && valueOfVar[0] != '\'' && !isdigit(valueOfVar[0])) {
- for (auto pair : kRegisterMap) {
- if (pair == valueOfVar) goto done;
- }
-
- Detail::print_error("Variable not declared: " + varName, file);
- return false;
- }
-
- done:
- for (auto& keyword : kKeywords) {
- if (keyword.keyword_kind == LibCompiler::kKeywordKindType &&
- varName.find(keyword.keyword_name) != std::string::npos) {
- varName.erase(varName.find(keyword.keyword_name), keyword.keyword_name.size());
- break;
- }
- }
-
- kRegisterMap.push_back(varName);
-
- break;
- }
-
- if (kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindType ||
- kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindTypePtr) {
- syntax_tree.fUserValue = "\n";
- continue;
- }
-
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr) {
- syntax_tree.fUserValue = "\n";
- continue;
- }
-
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc) {
- instr = "add ";
- } else if (keyword.first.keyword_kind ==
- LibCompiler::KeywordKind::kKeywordKindVariableDec) {
- instr = "sub ";
- }
-
- std::string varErrCpy = varName;
-
- while (varName.find(" ") != std::string::npos) {
- varName.erase(varName.find(" "), 1);
- }
-
- while (varName.find("\t") != std::string::npos) {
- varName.erase(varName.find("\t"), 1);
- }
-
- std::size_t indxReg = 0UL;
-
- for (size_t i = 0; !isalnum(valueOfVar[i]); i++) {
- if (i > valueOfVar.size()) break;
-
- valueOfVar.erase(i, 1);
- }
-
- while (valueOfVar.find(" ") != std::string::npos) {
- valueOfVar.erase(valueOfVar.find(" "), 1);
- }
-
- while (valueOfVar.find("\t") != std::string::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;
- }
-
- break;
- }
-
- if (syntax_tree.fUserValue.empty()) {
- Detail::print_error("Variable not declared: " + varName, file);
- }
-
- break;
- }
- case LibCompiler::KeywordKind::kKeywordKindReturn: {
- try {
- auto pos = text.find("return") + strlen("return") + 1;
- std::string subText = text.substr(pos);
- subText = subText.erase(subText.find(";"));
- size_t indxReg = 0UL;
-
- if (subText[0] != '\"' && subText[0] != '\'') {
- if (!isdigit(subText[0])) {
- for (auto pair : kRegisterMap) {
- ++indxReg;
-
- if (pair != subText) continue;
-
- 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 = "__LIBCOMPILER_LOCAL_RETURN_STRING: db " + subText +
- ", 0\nmov rcx, __LIBCOMPILER_LOCAL_RETURN_STRING\n";
- syntax_tree.fUserValue += "mov rax, rcx\nret\n";
- kOrigin += 1UL;
-
- break;
- }
-
- if (syntax_tree.fUserValue.empty()) {
- if (subText.find("(") != std::string::npos) {
- subText.erase(subText.find("("));
-
- auto it =
- std::find_if(kOriginMap.begin(), kOriginMap.end(),
- [&subText](std::pair<std::string, std::uintptr_t> pair) -> bool {
- return pair.first.find(subText) != std::string::npos;
- });
-
- 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;
- }
- }
-
- break;
- } catch (...) {
- syntax_tree.fUserValue = "ret\n";
- kOrigin += 1UL;
- }
- }
- default: {
- continue;
- }
- }
- }
-
- kState.fOutputValue = syntax_tree.fUserValue;
- return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief C++ assembler class.
- */
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class AssemblyCPlusPlusInterface final LC_ASSEMBLY_INTERFACE {
- public:
- explicit AssemblyCPlusPlusInterface() = default;
- ~AssemblyCPlusPlusInterface() override = default;
-
- LIBCOMPILER_COPY_DEFAULT(AssemblyCPlusPlusInterface);
-
- UInt32 Arch() noexcept override { return LibCompiler::AssemblyFactory::kArchAMD64; }
-
- Int32 CompileToFormat(std::string src, Int32 arch) override {
- if (kCompilerFrontend == nullptr) return kExitNO;
-
- std::string dest = src;
- dest += ".pp.masm";
-
- std::ofstream out_fp(dest);
-
- std::ifstream src_fp = std::ifstream(src);
-
- std::string line_source;
-
- while (std::getline(src_fp, line_source)) {
- if (kVerbose) {
- kStdOut << line_source << std::endl;
- kStdOut << line_source.length() << " bytes\n";
- }
-
- kCompilerFrontend->Compile(line_source, src);
-
- out_fp << kState.fOutputValue;
- kState.fOutputValue.clear();
- }
-
- if (kVerbose) {
- kStdOut << "Done compiling " << src << " to " << dest << "\n";
- }
-
- return kExitOK;
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define kExtListCxx \
- { ".cpp", ".cxx", ".cc", ".c++", ".cp" }
-
-LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) {
- Boolean skip = false;
-
- kKeywords.push_back({.keyword_name = "if", .keyword_kind = LibCompiler::kKeywordKindIf});
- kKeywords.push_back({.keyword_name = "else", .keyword_kind = LibCompiler::kKeywordKindElse});
- kKeywords.push_back({.keyword_name = "else if", .keyword_kind = LibCompiler::kKeywordKindElseIf});
-
- kKeywords.push_back({.keyword_name = "class", .keyword_kind = LibCompiler::kKeywordKindClass});
- kKeywords.push_back({.keyword_name = "struct", .keyword_kind = LibCompiler::kKeywordKindClass});
- kKeywords.push_back(
- {.keyword_name = "namespace", .keyword_kind = LibCompiler::kKeywordKindNamespace});
- kKeywords.push_back(
- {.keyword_name = "typedef", .keyword_kind = LibCompiler::kKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "using", .keyword_kind = LibCompiler::kKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "{", .keyword_kind = LibCompiler::kKeywordKindBodyStart});
- kKeywords.push_back({.keyword_name = "}", .keyword_kind = LibCompiler::kKeywordKindBodyEnd});
- kKeywords.push_back({.keyword_name = "auto", .keyword_kind = LibCompiler::kKeywordKindVariable});
- kKeywords.push_back({.keyword_name = "int", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "bool", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "short", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "char", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "long", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "float", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "double", .keyword_kind = LibCompiler::kKeywordKindType});
- kKeywords.push_back({.keyword_name = "void", .keyword_kind = LibCompiler::kKeywordKindType});
-
- kKeywords.push_back(
- {.keyword_name = "auto*", .keyword_kind = LibCompiler::kKeywordKindVariablePtr});
- kKeywords.push_back({.keyword_name = "int*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back(
- {.keyword_name = "unsigned*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "short*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "char*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "long*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "float*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back(
- {.keyword_name = "double*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "void*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
-
- kKeywords.push_back(
- {.keyword_name = "(", .keyword_kind = LibCompiler::kKeywordKindFunctionStart});
- kKeywords.push_back({.keyword_name = ")", .keyword_kind = LibCompiler::kKeywordKindFunctionEnd});
- kKeywords.push_back(
- {.keyword_name = "=", .keyword_kind = LibCompiler::kKeywordKindVariableAssign});
- kKeywords.push_back({.keyword_name = "+=", .keyword_kind = LibCompiler::kKeywordKindVariableInc});
- kKeywords.push_back({.keyword_name = "-=", .keyword_kind = LibCompiler::kKeywordKindVariableDec});
- kKeywords.push_back({.keyword_name = "const", .keyword_kind = LibCompiler::kKeywordKindConstant});
- kKeywords.push_back({.keyword_name = "*", .keyword_kind = LibCompiler::kKeywordKindPtr});
- kKeywords.push_back({.keyword_name = "->", .keyword_kind = LibCompiler::kKeywordKindPtrAccess});
- kKeywords.push_back({.keyword_name = ".", .keyword_kind = LibCompiler::kKeywordKindAccess});
- kKeywords.push_back({.keyword_name = ",", .keyword_kind = LibCompiler::kKeywordKindArgSeparator});
- kKeywords.push_back({.keyword_name = ";", .keyword_kind = LibCompiler::kKeywordKindEndInstr});
- kKeywords.push_back({.keyword_name = ":", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "public:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "private:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "protected:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back(
- {.keyword_name = "final", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "return", .keyword_kind = LibCompiler::kKeywordKindReturn});
- kKeywords.push_back(
- {.keyword_name = "/*", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineStart});
- kKeywords.push_back(
- {.keyword_name = "*/", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineEnd});
- kKeywords.push_back(
- {.keyword_name = "//", .keyword_kind = LibCompiler::kKeywordKindCommentInline});
- kKeywords.push_back({.keyword_name = "==", .keyword_kind = LibCompiler::kKeywordKindEq});
- kKeywords.push_back({.keyword_name = "!=", .keyword_kind = LibCompiler::kKeywordKindNotEq});
- kKeywords.push_back({.keyword_name = ">=", .keyword_kind = LibCompiler::kKeywordKindGreaterEq});
- kKeywords.push_back({.keyword_name = "<=", .keyword_kind = LibCompiler::kKeywordKindLessEq});
-
- kErrorLimit = 100;
-
- kCompilerFrontend = new CompilerFrontendCPlusPlus();
- kFactory.Mount(new AssemblyCPlusPlusInterface());
-
- ::signal(SIGSEGV, Detail::drv_segfault_handler);
-
- for (auto index = 1UL; index < argc; ++index) {
- 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 (kCompilerFrontend) std::cout << kCompilerFrontend->Language() << "\n";
-
- return LIBCOMPILER_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;
- }
-
- std::string err = "Unknown option: ";
- err += argv[index];
-
- Detail::print_error(err, "cxxdrv");
-
- continue;
- }
-
- std::string argv_i = argv[index];
-
- std::vector<std::string> exts = kExtListCxx;
- BOOL found = false;
-
- for (std::string ext : exts) {
- if (argv_i.ends_with(ext)) {
- found = true;
-
- if (kFactory.Compile(argv_i, kMachine) != kExitOK) {
- return LIBCOMPILER_INVALID_DATA;
- }
- }
- }
-
- if (!found) {
- if (kVerbose) {
- Detail::print_error(argv_i + " is not a valid C++ source.", "cxxdrv");
- }
-
- return LIBCOMPILER_INVALID_DATA;
- }
- }
-
- kFactory.Unmount();
-
- delete kCompilerFrontend;
- kCompilerFrontend = nullptr;
-
- kRegisterMap.clear();
- kOriginMap.clear();
-
- return LIBCOMPILER_SUCCESS;
-}
-
-//
-// Last rev 8-1-24
-//