diff options
Diffstat (limited to 'dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc')
| -rw-r--r-- | dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc | 888 |
1 files changed, 0 insertions, 888 deletions
diff --git a/dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc b/dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc deleted file mode 100644 index 1aaf091..0000000 --- a/dev/LibCompiler/src/Frontend/CompilerCPlusPlusAMD64.cc +++ /dev/null @@ -1,888 +0,0 @@ -/* - * ======================================================== - * - * C++ Compiler Driver - * Copyright (C) 2024-2025 Amlal El Mahrouss, all rights reserved. - * - * ======================================================== - */ - -/// BUGS: 1 - -#define kPrintF printf - -#define kExitOK (EXIT_SUCCESS) -#define kExitNO (EXIT_FAILURE) - -#include <LibCompiler/Backend/X64.h> -#include <LibCompiler/Frontend.h> -#include <LibCompiler/UUID.h> -#include <LibCompiler/Util/CompilerUtils.h> - -/* NeKernel C++ Compiler Driver */ -/* This is part of the LibCompiler. */ -/* (c) Amlal El Mahrouss 2024-2025 */ - -/// @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 { - LibCompiler::STLString fName; - LibCompiler::STLString fReg; -}; - -/// \brief Offset based struct/class -struct CompilerStructMap final { - LibCompiler::STLString fName; - LibCompiler::STLString fReg; - std::vector<std::pair<UInt32, LibCompiler::STLString>> fOffsets; -}; - -/// \brief Compiler state structure. -struct CompilerState final { - std::vector<CompilerRegisterMap> fStackMapVector; - std::vector<CompilerStructMap> fStructMapVector; - LibCompiler::STLString fLastFile; - LibCompiler::STLString fLastError; -}; -} // namespace Detail - -static Detail::CompilerState kState; - -static Int32 kOnClassScope = 0; - -///////////////////////////////////////////////////////////////////////////////////////// - -// Target architecture. -static Int32 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 CompilerFrontendCPlusPlusAMD64 final LC_COMPILER_FRONTEND { - public: - explicit CompilerFrontendCPlusPlusAMD64() = default; - ~CompilerFrontendCPlusPlusAMD64() override = default; - - LIBCOMPILER_COPY_DEFAULT(CompilerFrontendCPlusPlusAMD64); - - LibCompiler::SyntaxLeafList::SyntaxLeaf Compile(const LibCompiler::STLString text, - LibCompiler::STLString file) override; - - const char* Language() override; -}; - -/// @internal compiler variables - -static CompilerFrontendCPlusPlusAMD64* kCompilerFrontend = nullptr; - -static std::vector<LibCompiler::STLString> kRegisterMap; - -static std::vector<LibCompiler::STLString> kRegisterList = { - "rbx", "rsi", "r10", "r11", "r12", "r13", "r14", "r15", "xmm12", "xmm13", "xmm14", "xmm15", -}; - -/// @brief The PEF calling convention (caller must save rax, rbp) -/// @note callee must return via **rax**. -static std::vector<LibCompiler::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 = 0x1000000; -static std::vector<std::pair<LibCompiler::STLString, std::uintptr_t>> kOriginMap; - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @name Compile -/// @brief Generate assembly from a C++ source. - -///////////////////////////////////////////////////////////////////////////////////////// - -LibCompiler::SyntaxLeafList::SyntaxLeaf CompilerFrontendCPlusPlusAMD64::Compile( - LibCompiler::STLString text, LibCompiler::STLString file) { - LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree; - - if (text.length() < 1) return syntax_tree; - - std::size_t index = 0UL; - std::vector<std::pair<LibCompiler::CompilerKeyword, std::size_t>> keywords_list; - - 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; - } - } - - for (auto& keyword : keywords_list) { - if (text.find(keyword.first.keyword_name) == LibCompiler::STLString::npos) continue; - - switch (keyword.first.keyword_kind) { - case LibCompiler::KeywordKind::kKeywordKindClass: { - ++kOnClassScope; - break; - } - case LibCompiler::KeywordKind::kKeywordKindIf: { - std::size_t keywordPos = text.find(keyword.first.keyword_name); - std::size_t openParen = text.find("(", keywordPos); - std::size_t closeParen = text.find(")", openParen); - - if (keywordPos == LibCompiler::STLString::npos || - openParen == LibCompiler::STLString::npos || - closeParen == LibCompiler::STLString::npos || closeParen <= openParen) { - Detail::print_error("Malformed if expression: " + text, file); - break; - } - - auto expr = text.substr(openParen + 1, closeParen - openParen - 1); - - if (expr.find(">=") != LibCompiler::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); - - 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: - - LibCompiler::STLString 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: - break; - - accept: - LibCompiler::STLString 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 ") != LibCompiler::STLString::npos) { - text.erase(0, text.find("return ")); - break; - } - - if (text.ends_with(";") && text.find("return") == LibCompiler::STLString::npos) - goto lc_write_assembly; - else if (text.size() <= indexFnName) - Detail::print_error("Invalid function name: " + fnName, file); - - 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::STLString::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<LibCompiler::STLString, 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: { - LibCompiler::STLString 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(";") != LibCompiler::STLString::npos && - keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindEndInstr) { - valueOfVar.erase(valueOfVar.find(";")); - } - - LibCompiler::STLString 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) != LibCompiler::STLString::npos) { - if (text[text.find(keyword.keyword_name)] == ' ') { - typeFound = false; - continue; - } - - typeFound = true; - } - } - } - - LibCompiler::STLString instr = "mov "; - - std::vector<LibCompiler::STLString> newVars; - - 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(" ") != LibCompiler::STLString::npos) { - varName.erase(varName.find(" "), 1); - } - - while (varName.find("\t") != LibCompiler::STLString::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); - break; - } - - done: - for (auto& keyword : kKeywords) { - if (keyword.keyword_kind == LibCompiler::kKeywordKindType && - varName.find(keyword.keyword_name) != LibCompiler::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 == 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 "; - } - - LibCompiler::STLString varErrCpy = varName; - - while (varName.find(" ") != LibCompiler::STLString::npos) { - varName.erase(varName.find(" "), 1); - } - - while (varName.find("\t") != LibCompiler::STLString::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(" ") != LibCompiler::STLString::npos) { - valueOfVar.erase(valueOfVar.find(" "), 1); - } - - while (valueOfVar.find("\t") != LibCompiler::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 LibCompiler::KeywordKind::kKeywordKindReturn: { - try { - auto pos = text.find("return") + strlen("return") + 1; - LibCompiler::STLString subText = text.substr(pos); - subText = subText.erase(subText.find(";")); - size_t indxReg = 0UL; - - if (subText[0] != '\"' && subText[0] != '\'') { - if (!isdigit(subText[0])) { - 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("(") != LibCompiler::STLString::npos) { - subText.erase(subText.find("(")); - - auto it = std::find_if( - kOriginMap.begin(), kOriginMap.end(), - [&subText](std::pair<LibCompiler::STLString, std::uintptr_t> pair) -> bool { - return pair.first.find(subText) != LibCompiler::STLString::npos; - }); - - if (it == kOriginMap.end()) - Detail::print_error("Invalid return value: " + subText, file); - - 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; - } - } - } - - return syntax_tree; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -/** - * @brief C++ assembler class. - */ - -///////////////////////////////////////////////////////////////////////////////////////// - -class AssemblyCPlusPlusInterfaceAMD64 final LC_ASSEMBLY_INTERFACE { - public: - explicit AssemblyCPlusPlusInterfaceAMD64() = default; - ~AssemblyCPlusPlusInterfaceAMD64() override = default; - - LIBCOMPILER_COPY_DEFAULT(AssemblyCPlusPlusInterfaceAMD64); - - UInt32 Arch() noexcept override { return LibCompiler::AssemblyFactory::kArchAMD64; } - - Int32 CompileToFormat(LibCompiler::STLString src, Int32 arch) override { - if (kCompilerFrontend == nullptr) return kExitNO; - - LibCompiler::STLString dest = src; - dest += ".pp.masm"; - - std::ofstream out_fp(dest); - std::ifstream src_fp = std::ifstream(src + ".pp"); - - LibCompiler::STLString line_source; - - out_fp << "#bits 64\n"; - out_fp << "#org " << kOrigin << "\n\n"; - - while (std::getline(src_fp, line_source)) { - out_fp << kCompilerFrontend->Compile(line_source, src).fUserValue; - } - - return kExitOK; - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////////////////// - -#define kExtListCxx \ - { ".cpp", ".cxx", ".cc", ".c++", ".cp" } - -LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { - Boolean skip = false; - - kKeywords.emplace_back("if", LibCompiler::kKeywordKindIf); - kKeywords.emplace_back("else", LibCompiler::kKeywordKindElse); - kKeywords.emplace_back("else if", LibCompiler::kKeywordKindElseIf); - - kKeywords.emplace_back("class", LibCompiler::kKeywordKindClass); - kKeywords.emplace_back("struct", LibCompiler::kKeywordKindClass); - kKeywords.emplace_back("namespace", LibCompiler::kKeywordKindNamespace); - kKeywords.emplace_back("typedef", LibCompiler::kKeywordKindTypedef); - kKeywords.emplace_back("using", LibCompiler::kKeywordKindTypedef); - kKeywords.emplace_back("{", LibCompiler::kKeywordKindBodyStart); - kKeywords.emplace_back("}", LibCompiler::kKeywordKindBodyEnd); - kKeywords.emplace_back("auto", LibCompiler::kKeywordKindVariable); - kKeywords.emplace_back("int", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("bool", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("unsigned", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("short", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("char", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("long", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("float", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("double", LibCompiler::kKeywordKindType); - kKeywords.emplace_back("void", LibCompiler::kKeywordKindType); - - kKeywords.emplace_back("auto*", LibCompiler::kKeywordKindVariablePtr); - kKeywords.emplace_back("int*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("bool*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("unsigned*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("short*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("char*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("long*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("float*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("double*", LibCompiler::kKeywordKindTypePtr); - kKeywords.emplace_back("void*", LibCompiler::kKeywordKindTypePtr); - - kKeywords.emplace_back("(", LibCompiler::kKeywordKindFunctionStart); - kKeywords.emplace_back(")", LibCompiler::kKeywordKindFunctionEnd); - kKeywords.emplace_back("=", LibCompiler::kKeywordKindVariableAssign); - kKeywords.emplace_back("+=", LibCompiler::kKeywordKindVariableInc); - kKeywords.emplace_back("-=", LibCompiler::kKeywordKindVariableDec); - kKeywords.emplace_back("const", LibCompiler::kKeywordKindConstant); - kKeywords.emplace_back("*", LibCompiler::kKeywordKindPtr); - kKeywords.emplace_back("->", LibCompiler::kKeywordKindPtrAccess); - kKeywords.emplace_back(".", LibCompiler::kKeywordKindAccess); - kKeywords.emplace_back(",", LibCompiler::kKeywordKindArgSeparator); - kKeywords.emplace_back(";", LibCompiler::kKeywordKindEndInstr); - kKeywords.emplace_back(":", LibCompiler::kKeywordKindSpecifier); - kKeywords.emplace_back("public:", LibCompiler::kKeywordKindSpecifier); - kKeywords.emplace_back("private:", LibCompiler::kKeywordKindSpecifier); - kKeywords.emplace_back("protected:", LibCompiler::kKeywordKindSpecifier); - kKeywords.emplace_back("final", LibCompiler::kKeywordKindSpecifier); - kKeywords.emplace_back("return", LibCompiler::kKeywordKindReturn); - kKeywords.emplace_back("/*", LibCompiler::kKeywordKindCommentMultiLineStart); - kKeywords.emplace_back("*/", LibCompiler::kKeywordKindCommentMultiLineEnd); - kKeywords.emplace_back("//", LibCompiler::kKeywordKindCommentInline); - kKeywords.emplace_back("==", LibCompiler::kKeywordKindEq); - kKeywords.emplace_back("!=", LibCompiler::kKeywordKindNotEq); - kKeywords.emplace_back(">=", LibCompiler::kKeywordKindGreaterEq); - kKeywords.emplace_back("<=", LibCompiler::kKeywordKindLessEq); - - kErrorLimit = 0; - - kCompilerFrontend = new CompilerFrontendCPlusPlusAMD64(); - kFactory.Mount(new AssemblyCPlusPlusInterfaceAMD64()); - - LibCompiler::install_signal(SIGSEGV, Detail::drvi_crash_handler); - - for (auto index = 1UL; index < argc; ++index) { - if (!argv[index]) break; - - if (argv[index][0] == '-') { - if (skip) { - skip = false; - 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; - } - - LibCompiler::STLString err = "Unknown option: "; - err += argv[index]; - - Detail::print_error(err, "cxxdrv"); - - continue; - } - - LibCompiler::STLString argv_i = argv[index]; - - std::vector<LibCompiler::STLString> exts = kExtListCxx; - - for (LibCompiler::STLString ext : exts) { - if (argv_i.ends_with(ext)) { - if (kFactory.Compile(argv_i, kMachine) != kExitOK) { - return LIBCOMPILER_INVALID_DATA; - } - - break; - } - } - } - - kFactory.Unmount(); - - return LIBCOMPILER_SUCCESS; -} - -// -// Last rev 23-5-25 -// |
