diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-03-04 06:41:30 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-03-04 06:41:30 +0100 |
| commit | 4017e6408c162b0ab1b54a0427d443b56df5237e (patch) | |
| tree | 04d628712db204b984072e0bf5a5b6a10686e820 /dev/LibCompiler | |
| parent | a9d9538f9f5b6fedbf69086d66ad5452d7f67129 (diff) | |
ADD: C++ compiler improvements.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/LibCompiler')
| -rw-r--r-- | dev/LibCompiler/src/Assembler64x0.cc | 8 | ||||
| -rw-r--r-- | dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 103 |
2 files changed, 90 insertions, 21 deletions
diff --git a/dev/LibCompiler/src/Assembler64x0.cc b/dev/LibCompiler/src/Assembler64x0.cc index d7f4349..9ec57bb 100644 --- a/dev/LibCompiler/src/Assembler64x0.cc +++ b/dev/LibCompiler/src/Assembler64x0.cc @@ -79,11 +79,11 @@ namespace Detail if (reason[0] == '\n') reason.erase(0, 1); - kStdErr << kRed << "[ TQC++ ] " << kWhite + kStdErr << kRed << "[ asm ] " << kWhite << ((file == "LibCompiler") ? "InternalErrorException: " : ("FileException{ " + file + " }: ")) << kBlank << std::endl; - kStdErr << kRed << "[ TQC++ ] " << kWhite << reason << kBlank << std::endl; + kStdErr << kRed << "[ asm ] " << kWhite << reason << kBlank << std::endl; if (kAcceptableErrors > kErrorLimit) std::exit(3); @@ -98,10 +98,10 @@ namespace Detail if (!file.empty()) { - kStdOut << kYellow << "[ TQC++ ] " << kWhite << file << kBlank << std::endl; + kStdOut << kYellow << "[ asm ] " << kWhite << file << kBlank << std::endl; } - kStdOut << kYellow << "[ TQC++ ] " << kWhite << reason << kBlank << std::endl; + kStdOut << kYellow << "[ asm ] " << kWhite << reason << kBlank << std::endl; } } // namespace Detail diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 3a49327..580e646 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -109,6 +109,8 @@ namespace Detail static Detail::CompilerState kState; static SizeType kErrorLimit = 100; +static Int32 kOnClassScope = 0; + static Int32 kAcceptableErrors = 0; namespace Detail @@ -150,10 +152,10 @@ static std::vector<LibCompiler::CompilerKeyword> kKeywords; static std::vector<std::string> kFileList; static LibCompiler::AssemblyFactory kFactory; -static Boolean kInStruct = false; -static Boolean kOnWhileLoop = false; -static Boolean kOnForLoop = false; -static Boolean kInBraces = false; +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 NE C++ driver */ @@ -210,9 +212,13 @@ static std::size_t kFunctionEmbedLevel = 0UL; const char* CompilerFrontendCPlusPlus::Language() { - return "NE C++"; + return "NeOS C++"; } +static std::uintptr_t kOrigin = 0x1000000; + +std::vector<std::pair<std::string, std::uintptr_t>> kOriginMap; + ///////////////////////////////////////////////////////////////////////////////////////// /// @name Compile @@ -220,8 +226,8 @@ const char* CompilerFrontendCPlusPlus::Language() ///////////////////////////////////////////////////////////////////////////////////////// -Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, - const std::string file) +Boolean CompilerFrontendCPlusPlus::Compile(std::string text, + const std::string file) { if (text.empty()) return false; @@ -229,7 +235,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, std::size_t index = 0UL; std::vector<std::pair<LibCompiler::CompilerKeyword, std::size_t>> keywords_list; - Boolean found = false; + Boolean found = false; static Boolean commentBlock = false; for (auto& keyword : kKeywords) @@ -290,6 +296,10 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, switch (keyword.first.keyword_kind) { + case LibCompiler::KeywordKind::kKeywordKindClass: { + ++kOnClassScope; + break; + } case LibCompiler::KeywordKind::kKeywordKindIf: { auto expr = text.substr(text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 1, text.find(")") - 1); @@ -410,7 +420,13 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, fnName = text.substr(indexFnName); - if (text.ends_with(";")) + 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); @@ -435,12 +451,28 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, syntax_tree.fUserValue = "public_segment .code64 __LIBCOMPILER_" + fnName + "\n"; ++kFunctionEmbedLevel; + kOriginMap.push_back({"__LIBCOMPILER_" + fnName, kOrigin}); + break; LC_write_assembly: - syntax_tree.fUserValue = "jmp __LIBCOMPILER_" + fnName + "\n"; + auto it = std::find_if(kOriginMap.begin(), kOriginMap.end(), [&fnName](std::pair<std::string, std::uintptr_t> pair) -> bool { + return fnName == pair.first; + }); + + std::stringstream ss; + ss << std::hex << it->second; + + if (it != kOriginMap.end()) + { + syntax_tree.fUserValue = "jmp " + ss.str() + "\n"; + kOrigin += 1UL; + } } case LibCompiler::KeywordKind::kKeywordKindFunctionEnd: { + if (kOnClassScope) + --kOnClassScope; + if (text.ends_with(";")) break; @@ -453,6 +485,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, if (kFunctionEmbedLevel < 1) kRegisterMap.clear(); + break; } case LibCompiler::KeywordKind::kKeywordKindEndInstr: @@ -575,10 +608,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, 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; @@ -592,10 +627,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, 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; @@ -715,10 +752,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, 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; } @@ -727,7 +766,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, if (syntax_tree.fUserValue.empty()) { - Detail::print_error("Variable not declared: " + varErrCpy, file); + Detail::print_error("Variable not declared: " + varName, file); } break; @@ -753,23 +792,48 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, continue; syntax_tree.fUserValue = "mov rax, " + kRegisterList[indxReg - 1] + "\nret\n"; - break; - } + kOrigin += 1UL; - if (syntax_tree.fUserValue.empty()) - { - Detail::print_error("Variable not declared: " + subText, file); + 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 = "mov rax, " + ss.str() + "\nret\n"; + kOrigin += 1UL; + break; + } } break; @@ -777,6 +841,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(const std::string text, catch (...) { syntax_tree.fUserValue = "ret\n"; + kOrigin += 1UL; } } default: { @@ -871,10 +936,14 @@ public: break; } + std::stringstream stream; + stream << kOrigin; + std::string result(stream.str()); + (*kState.fOutputAssembly) << "; Assembler Dialect: AMD64 LibCompiler Assembler. (Generated from C++)\n"; (*kState.fOutputAssembly) << "; Date: " << fmt << "\n"; - (*kState.fOutputAssembly) << "#bits 64\n#org 0x1000000" + (*kState.fOutputAssembly) << "#bits 64\n#org " + result << "\n"; kState.fSyntaxTree = new LibCompiler::SyntaxLeafList(); |
