diff options
Diffstat (limited to 'Sources')
| -rw-r--r-- | Sources/64asm.cc | 2 | ||||
| -rw-r--r-- | Sources/64x0-cc.cc | 6 | ||||
| -rw-r--r-- | Sources/AssemblyFactory.cxx (renamed from Sources/AsmKit.cc) | 2 | ||||
| -rw-r--r-- | Sources/cplusplus.cc | 353 |
4 files changed, 327 insertions, 36 deletions
diff --git a/Sources/64asm.cc b/Sources/64asm.cc index 8f42ea2..96bdc90 100644 --- a/Sources/64asm.cc +++ b/Sources/64asm.cc @@ -763,7 +763,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, "invalid combination of opcode and registers.\nline: " + line, file); throw std::runtime_error("invalid_comb_op_reg"); - } else if (found_some == 1 && name == "dec") { + } else if (found_some == 1 && name == "sub") { detail::print_error( "invalid combination of opcode and registers.\nline: " + line, file); diff --git a/Sources/64x0-cc.cc b/Sources/64x0-cc.cc index b7ea908..d7b7491 100644 --- a/Sources/64x0-cc.cc +++ b/Sources/64x0-cc.cc @@ -736,7 +736,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) textBuffer.erase(_text_i, 1); } - syntaxLeaf.fUserValue += "dec "; + syntaxLeaf.fUserValue += "sub "; syntaxLeaf.fUserValue += textBuffer; kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); @@ -1399,7 +1399,7 @@ public: return -1; std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta", - "add", "dec", "mv"}; + "add", "sub", "mv"}; /// /// Replace, optimize, fix assembly output. @@ -1484,7 +1484,7 @@ public: } if (cnt > 1 && keyword != "mv" && keyword != "add" && - keyword != "dec") + keyword != "sub") { leaf.fUserValue.replace(leaf.fUserValue.find(keyword), keyword.size(), "mv"); diff --git a/Sources/AsmKit.cc b/Sources/AssemblyFactory.cxx index 38ca551..5a1475f 100644 --- a/Sources/AsmKit.cc +++ b/Sources/AssemblyFactory.cxx @@ -8,7 +8,7 @@ #include <Headers/StdKit/ErrorID.hpp> /** - * @file AsmKit.cc + * @file AssemblyFactory.cxx * @author Amlal El Mahrouss (amlal@mahrouss.com) * @brief Assembler Kit * @version 0.1 diff --git a/Sources/cplusplus.cc b/Sources/cplusplus.cc index b61b1d2..14a7af7 100644 --- a/Sources/cplusplus.cc +++ b/Sources/cplusplus.cc @@ -33,9 +33,11 @@ /* This is part of MPCC C++ compiler. */ /* (c) SoftwareLabs */ -// @author Amlal El Mahrouss (amlel) -// @file cc.cc -// @brief Optimized C++ Compiler. +/// @author Amlal El Mahrouss (amlel) +/// @file cc.cc +/// @brief Optimized C++ Compiler. +/// @todo Throw error for scoped inside scoped variables when they get referenced outside. +/// @todo Add class/struct/enum support. ///////////////////// @@ -110,8 +112,8 @@ namespace detail if (kState.fLastFile != file) { std::cout << kRed << "[ ccplus ] " << kWhite - << ((file == "ccplus") ? "internal compiler error " - : ("in file, " + file)) + << ((file == "cplusplus") ? "internal compiler error " + : ("in file, " + file)) << kBlank << std::endl; std::cout << kRed << "[ ccplus ] " << kWhite << reason << kBlank << std::endl; @@ -208,10 +210,25 @@ const char* CompilerBackendCPlusPlus::Language() return "ISO C++"; } +static std::vector<std::string> kRegisterMap; + +static size_t kLevelFunction = 0UL; + +static std::vector<std::string> cRegisters = { + "r8", + "r9", + "r10", + "r11", + "r12", + "r13", + "r14", + "r15", +}; + ///////////////////////////////////////////////////////////////////////////////////////// -// @name Compile -// @brief Generate MASM from a C++ source. +/// @name Compile +/// @brief Generate MASM from a C++ source. ///////////////////////////////////////////////////////////////////////////////////////// @@ -228,12 +245,39 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, std::size_t index = 0UL; std::vector<std::pair<ParserKit::CompilerKeyword, std::size_t>> keywords_list; - bool found = false; + bool found = false; + static bool commentBlock = false; for (auto& keyword : kKeywords) { if (text.find(keyword.keyword_name) != std::string::npos) { + switch (keyword.keyword_kind) + { + case ParserKit::eKeywordKindCommentMultiLineStart: { + commentBlock = true; + return true; + } + case ParserKit::eKeywordKindCommentMultiLineEnd: { + commentBlock = false; + break; + } + case ParserKit::eKeywordKindCommentInline: { + break; + } + default: + break; + } + + if (text[text.find(keyword.keyword_name) - 1] == '+' && + keyword.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableAssign) + continue; + + if ( + text[text.find(keyword.keyword_name) - 1] == '-' && + keyword.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableAssign) + continue; + keywords_list.emplace_back(std::make_pair(keyword, index)); ++index; @@ -241,7 +285,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, } } - if (!found) + if (!found && !commentBlock) { for (size_t i = 0; i < text.size(); i++) { @@ -253,39 +297,280 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, } } - static bool shouldEmitWarning = false; - for (auto& keyword : keywords_list) { - if (shouldEmitWarning) - { - if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindBodyEnd) - shouldEmitWarning = false; - - if (shouldEmitWarning) - { - detail::print_error("code after return: " + text, file); - } - } - auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf(); switch (keyword.first.keyword_kind) { - case ParserKit::KeywordKind::eKeywordKindAccess: - case ParserKit::KeywordKind::eKeywordKindPtrAccess: - kState.fSyntaxTree->fLeafList[kState.fSyntaxTree->fLeafList.size() - 1].fUserValue = "lea %LEFT+%OFFSET"; // MPCC assembly stipulates this. - break; case ParserKit::KeywordKind::eKeywordKindEndInstr: syntax_tree.fUserValue = "\r\n"; break; - case ParserKit::KeywordKind::eKeywordKindVariableAssign: - syntax_tree.fUserValue = "mov %LEFT, %RIGHT"; + case ParserKit::KeywordKind::eKeywordKindFunctionStart: { + ++kLevelFunction; break; - case ParserKit::KeywordKind::eKeywordKindReturn: - syntax_tree.fUserValue = "mov rax, %A0\r\nret"; - shouldEmitWarning = true; + } + case ParserKit::KeywordKind::eKeywordKindFunctionEnd: { + --kLevelFunction; + + if (kRegisterMap.size() > cRegisters.size()) + { + --kLevelFunction; + } + + if (kLevelFunction < 1) + kRegisterMap.clear(); break; + } + case ParserKit::KeywordKind::eKeywordKindVariableInc: + case ParserKit::KeywordKind::eKeywordKindVariableDec: + case ParserKit::KeywordKind::eKeywordKindVariableAssign: { + auto valueOfVar = text.substr(text.find("=") + 1); + + if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableInc) + { + valueOfVar = text.substr(text.find("+=") + 2); + } + else if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableDec) + { + valueOfVar = text.substr(text.find("-=") + 2); + } + + while (valueOfVar.find(";") != std::string::npos) + { + valueOfVar.erase(valueOfVar.find(";")); + } + + if (text.find("float ") != std::string::npos || + text.find("double ") != std::string::npos) + { + detail::print_error("Vector extensions not supported yet.", "cplusplus"); + } + + std::string varName = text; + + if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableInc) + { + varName.erase(varName.find("+=")); + } + else if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableDec) + { + varName.erase(varName.find("-=")); + } + else + { + varName.erase(varName.find("=")); + } + + bool typeFound = false; + + for (auto& keyword : kKeywords) + { + if (keyword.keyword_kind == ParserKit::eKeywordKindType) + { + if (varName.find(keyword.keyword_name) != std::string::npos) + { + typeFound = true; + varName.erase(varName.find(keyword.keyword_name), keyword.keyword_name.size()); + } + + /// in case we goot boolX or intX + if (text.find(keyword.keyword_name) != std::string::npos) + { + if (varName[text.find(keyword.keyword_name)] == ' ') + continue; + + typeFound = false; + } + } + } + + std::string instr = "mov "; + + if (typeFound) + { + if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableInc) + { + detail::print_error("Can't increment variable when it's being created.", file); + } + else if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableDec) + { + detail::print_error("Can't decrement variable when it's being created.", file); + } + + if (kRegisterMap.size() > cRegisters.size()) + { + ++kLevelFunction; + } + + 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); + } + + if (valueOfVar == "true") + { + valueOfVar = "1"; + } + else if (valueOfVar == "false") + { + valueOfVar = "0"; + } + + std::size_t indexRight = 0UL; + + for (auto pairRight : kRegisterMap) + { + ++indexRight; + + if (pairRight != valueOfVar) + { + syntax_tree.fUserValue = instr + cRegisters[kRegisterMap.size()] + ", " + valueOfVar; + continue; + } + + syntax_tree.fUserValue = instr + cRegisters[kRegisterMap.size()] + ", " + cRegisters[indexRight - 1]; + break; + } + + if (((int)indexRight - 1) < 0) + { + syntax_tree.fUserValue = instr + cRegisters[kRegisterMap.size()] + ", " + valueOfVar; + } + + kRegisterMap.push_back(varName); + } + else + { + if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableInc) + { + instr = "add "; + } + else if (keyword.first.keyword_kind == ParserKit::KeywordKind::eKeywordKindVariableDec) + { + 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); + } + + /// interpet boolean values. + + if (valueOfVar == "true") + { + valueOfVar = "1"; + } + else if (valueOfVar == "false") + { + valueOfVar = "0"; + } + + for (auto pair : kRegisterMap) + { + ++indxReg; + + if (pair != varName) + continue; + + std::size_t indexRight = 0ul; + + for (auto pairRight : kRegisterMap) + { + ++indexRight; + + if (pairRight != valueOfVar) + { + syntax_tree.fUserValue = instr + cRegisters[kRegisterMap.size() - 1] + ", " + valueOfVar; + continue; + } + + syntax_tree.fUserValue = instr + cRegisters[indxReg - 1] + ", " + cRegisters[indexRight - 1]; + break; + } + + break; + } + + if (syntax_tree.fUserValue.empty()) + { + detail::print_error("Variable not declared: " + varErrCpy, file); + } + } + + break; + } + case ParserKit::KeywordKind::eKeywordKindReturn: { + 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, " + cRegisters[indxReg - 1] + "\r\nret"; + break; + } + + if (syntax_tree.fUserValue.empty()) + { + detail::print_error("Variable not declared: " + subText, file); + } + } + else + { + syntax_tree.fUserValue = "mov rax, " + subText + "\r\nret"; + } + } + else + { + syntax_tree.fUserValue = "mov rcx, " + subText + "\r\n"; + syntax_tree.fUserValue = "mov rax, rcx\r\nret"; + } + + break; + } default: break; } @@ -411,6 +696,7 @@ MPCC_MODULE(CompilerCPlusPlus) kKeywords.push_back({.keyword_name = "}", .keyword_kind = ParserKit::eKeywordKindBodyEnd}); kKeywords.push_back({.keyword_name = "auto", .keyword_kind = ParserKit::eKeywordKindVariable}); kKeywords.push_back({.keyword_name = "int", .keyword_kind = ParserKit::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "bool", .keyword_kind = ParserKit::eKeywordKindType}); kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = ParserKit::eKeywordKindType}); kKeywords.push_back({.keyword_name = "short", .keyword_kind = ParserKit::eKeywordKindType}); kKeywords.push_back({.keyword_name = "(", .keyword_kind = ParserKit::eKeywordKindFunctionStart}); @@ -420,6 +706,8 @@ MPCC_MODULE(CompilerCPlusPlus) kKeywords.push_back({.keyword_name = "float", .keyword_kind = ParserKit::eKeywordKindType}); kKeywords.push_back({.keyword_name = "double", .keyword_kind = ParserKit::eKeywordKindType}); kKeywords.push_back({.keyword_name = "=", .keyword_kind = ParserKit::eKeywordKindVariableAssign}); + kKeywords.push_back({.keyword_name = "+=", .keyword_kind = ParserKit::eKeywordKindVariableInc}); + kKeywords.push_back({.keyword_name = "-=", .keyword_kind = ParserKit::eKeywordKindVariableDec}); kKeywords.push_back({.keyword_name = "const", .keyword_kind = ParserKit::eKeywordKindConstant}); kKeywords.push_back({.keyword_name = "->", .keyword_kind = ParserKit::eKeywordKindPtrAccess}); kKeywords.push_back({.keyword_name = ".", .keyword_kind = ParserKit::eKeywordKindAccess}); @@ -431,6 +719,9 @@ MPCC_MODULE(CompilerCPlusPlus) kKeywords.push_back({.keyword_name = "protected:", .keyword_kind = ParserKit::eKeywordKindSpecifier}); kKeywords.push_back({.keyword_name = "final", .keyword_kind = ParserKit::eKeywordKindSpecifier}); kKeywords.push_back({.keyword_name = "return", .keyword_kind = ParserKit::eKeywordKindReturn}); + kKeywords.push_back({.keyword_name = "/*", .keyword_kind = ParserKit::eKeywordKindCommentMultiLineStart}); + kKeywords.push_back({.keyword_name = "*/", .keyword_kind = ParserKit::eKeywordKindCommentMultiLineStart}); + kKeywords.push_back({.keyword_name = "//", .keyword_kind = ParserKit::eKeywordKindCommentInline}); kFactory.Mount(new AssemblyMountpointClang()); kCompilerBackend = new CompilerBackendCPlusPlus(); |
