diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-02 09:42:04 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-02 09:42:04 +0100 |
| commit | a00e0a5fb93c96460ddec264fc89a726004b94c2 (patch) | |
| tree | 5808921581ff0d68eebf134cc34ccb6d9c3f86e9 /CompilerDriver | |
| parent | cec81a16c9994b2a6188c17b7b849f165203006c (diff) | |
ccplus: now parsing using another strategy.
cc: fix: r15 used instead of r19 for jlr.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'CompilerDriver')
| -rw-r--r-- | CompilerDriver/.gitignore | 2 | ||||
| -rw-r--r-- | CompilerDriver/bin/README.txt | 2 | ||||
| -rw-r--r-- | CompilerDriver/cc.cxx | 25 | ||||
| -rw-r--r-- | CompilerDriver/ccplus.cxx | 804 | ||||
| -rw-r--r-- | CompilerDriver/makefile | 2 |
5 files changed, 248 insertions, 587 deletions
diff --git a/CompilerDriver/.gitignore b/CompilerDriver/.gitignore index 41e8394..ce5ef93 100644 --- a/CompilerDriver/.gitignore +++ b/CompilerDriver/.gitignore @@ -4,7 +4,7 @@ bin/cc bin/masm bin/mkcdfs bin/ccplus -bin/cpp2 +bin/cppfront bin/SourceUnitTest/*.c.pp bin/SourceUnitTest/*.c diff --git a/CompilerDriver/bin/README.txt b/CompilerDriver/bin/README.txt new file mode 100644 index 0000000..7530e5e --- /dev/null +++ b/CompilerDriver/bin/README.txt @@ -0,0 +1,2 @@ +The C compilers (ccplus, cc) are work in progress. +Use it at your own risk.
\ No newline at end of file diff --git a/CompilerDriver/cc.cxx b/CompilerDriver/cc.cxx index 87582e6..8fc35e6 100644 --- a/CompilerDriver/cc.cxx +++ b/CompilerDriver/cc.cxx @@ -141,7 +141,7 @@ public: CXXKIT_COPY_DEFAULT(CompilerBackendClang); std::string Check(const char* text, const char* file); - void Compile(const char* text, const char* file) override; + bool Compile(const std::string& text, const char* file) override; const char* Language() override { return "Optimized X64000 C"; } @@ -188,7 +188,7 @@ static std::string cc_parse_function_call(std::string& _text) } args += args_buffer; - args += "\n\tjlr __import "; + args += "\n\tjb __import "; } } @@ -218,7 +218,7 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// -void CompilerBackendClang::Compile(const char* text, const char* file) +bool CompilerBackendClang::Compile(const std::string& text, const char* file) { std::string _text = text; @@ -367,7 +367,7 @@ void CompilerBackendClang::Compile(const char* text, const char* file) value += tmp; } - syntax_tree.fUserValue = "\tldw r15, "; + syntax_tree.fUserValue = "\tldw r19, "; // make it pretty. if (value.find('\t') != std::string::npos) @@ -774,15 +774,20 @@ void CompilerBackendClang::Compile(const char* text, const char* file) args_buffer = args_buffer.erase(args_buffer.find('('), 1); if (!args_buffer.empty()) - args += "\tpsh "; + args += "\tldw r6, "; - while (args_buffer.find(',') != std::string::npos) + std::size_t index = 0UL; + + while (ParserKit::find_word(args_buffer, ",")) { - args_buffer.replace(args_buffer.find(','), 1, "\n\tpsh "); + std::string register_type = kRegisterPrefix; + register_type += std::to_string(index); + + args_buffer.replace(args_buffer.find(','), 1, "\n\tldw " + register_type + ","); } args += args_buffer; - args += "\n\tjlr __import "; + args += "\n\tjb __import "; } } @@ -1020,6 +1025,8 @@ void CompilerBackendClang::Compile(const char* text, const char* file) syntax_tree.fUserValue = "\n"; kState.fSyntaxTree->fLeafList.push_back(syntax_tree); + + return true; } static bool kShouldHaveBraces = false; @@ -1748,7 +1755,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// #define kPrintF printf -#define kSplashCxx() kPrintF(kWhite "%s\n", "X64000 C compiler, v1.13, (c) WestCo") +#define kSplashCxx() kPrintF(kWhite "%s\n", "X64000 Optimized C compiler, v1.13, (c) WestCo") static void cc_print_help() { diff --git a/CompilerDriver/ccplus.cxx b/CompilerDriver/ccplus.cxx index bdcd8d1..a6bd950 100644 --- a/CompilerDriver/ccplus.cxx +++ b/CompilerDriver/ccplus.cxx @@ -1,7 +1,7 @@ /* * ======================================================== * - * c++ + * ccplus * Copyright WestCo, all rights reserved. * * ======================================================== @@ -12,13 +12,15 @@ #include <string> #include <fstream> #include <iostream> +#include <stack> +#include <utility> #include <C++Kit/AsmKit/Arch/NewCPU.hpp> #include <C++Kit/ParserKit.hpp> #define kOk 0 -/* WestCo C++ driver */ -/* This is part of MP-UX C++ SDK. */ +/* WestCo C driver */ +/* This is part of MP-UX C SDK. */ /* (c) WestCo */ ///////////////////// @@ -33,7 +35,7 @@ ///////////////////////////////////// -// INTERNAL STUFF OF THE C++ COMPILER +// INTERNAL STUFF OF THE C COMPILER ///////////////////////////////////// @@ -76,14 +78,14 @@ namespace detail if (kState.fLastFile != file) { - std::cout << kRed << "[ c++ ] " << kWhite << ((file == "c++") ? "internal compiler error " : ("in file, " + file)) << kBlank << std::endl; - std::cout << kRed << "[ c++ ] " << kWhite << reason << kBlank << std::endl; + std::cout << kRed << "[ ccplus ] " << kWhite << ((file == "ccplus") ? "internal compiler error " : ("in file, " + file)) << kBlank << std::endl; + std::cout << kRed << "[ ccplus ] " << kWhite << reason << kBlank << std::endl; kState.fLastFile = file; } else { - std::cout << kRed << "[ c++ ] [ " << kState.fLastFile << " ] " << kWhite << reason << kBlank << std::endl; + std::cout << kRed << "[ ccplus ] [ " << kState.fLastFile << " ] " << kWhite << reason << kBlank << std::endl; } if (kAcceptableErrors > kErrorLimit) @@ -115,6 +117,7 @@ static size_t kStartUsable = 1; static size_t kUsableLimit = 14; static size_t kRegisterCounter = kStartUsable; static std::string kRegisterPrefix = kAsmRegisterPrefix; +static std::vector<std::string> kKeywords; ///////////////////////////////////////// @@ -130,7 +133,7 @@ static bool kOnForLoop = false; static bool kInBraces = false; static size_t kBracesCount = 0UL; -/* @brief C++ compiler backend for WestCo C++ */ +/* @brief C compiler backend for WestCo C */ class CompilerBackendClang final : public ParserKit::CompilerBackend { public: @@ -139,17 +142,15 @@ public: CXXKIT_COPY_DEFAULT(CompilerBackendClang); - std::string Check(const char* text, const char* file); - void Compile(const char* text, const char* file) override; + bool Compile(const std::string& text, const char* file) override; - const char* Language() override { return "C++"; } + const char* Language() override { return "Optimized 64x0 C"; } }; static CompilerBackendClang* kCompilerBackend = nullptr; static std::vector<detail::CompilerType> kCompilerVariables; static std::vector<std::string> kCompilerFunctions; -static std::vector<detail::CompilerType> kCompilerTypes; // @brief this hook code before the begin/end command. static std::string kAddIfAnyBegin; @@ -213,650 +214,253 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// // @name Compile -// @brief Generate MASM from a C++ source. +// @brief Generate MASM from a C source. ///////////////////////////////////////////////////////////////////////////////////////// -void CompilerBackendClang::Compile(const char* text, const char* file) -{ - -} - -static bool kShouldHaveBraces = false; -static std::string kFnName; - -std::string CompilerBackendClang::Check(const char* text, const char* file) -{ - std::string err_str; - std::string ln = text; +bool CompilerBackendClang::Compile(const std::string& text, const char* file) +{ + if (text.empty()) + return false; - if (ln.empty()) - { - return err_str; - } + // if (expr) + // int name = expr; + // expr; - bool non_ascii_found = false; + std::size_t index = 0UL; - for (int i = 0; i < ln.size(); ++i) { - if (isalnum(ln[i])) - { - non_ascii_found = true; - break; - } - } + auto syntax_tree = ParserKit::SyntaxLeafList::SyntaxLeaf(); - if (kShouldHaveBraces && - ln.find('{') != std::string::npos) { - kShouldHaveBraces = false; - } + syntax_tree.fUserData = text; + kState.fSyntaxTree->fLeafList.push_back(syntax_tree); - if (!non_ascii_found) - return err_str; + std::string text_cpy = text; - size_t string_index = 1UL; + std::vector<std::pair<std::string, std::size_t>> keywords_list; - if (ln.find('\'') != std::string::npos) + for (auto& keyword : kKeywords) { - string_index = ln.find('\'') + 1; - - for (; string_index < ln.size(); ++string_index) + while (text_cpy.find(keyword) != std::string::npos) { - if (ln[string_index] == '\'') - { - if (ln[string_index + 1] != ';') - { - ln.erase(string_index, 1); - } + keywords_list.push_back(std::make_pair(keyword, index)); + ++index; - return err_str; - } + text_cpy.erase(text_cpy.find(keyword), keyword.size()); } } - else if (ln.find('"') != std::string::npos) - { - string_index = ln.find('"') + 1; - for (; string_index < ln.size(); ++string_index) - { - if (ln[string_index] == '"') - { - if (ln[string_index + 1] != ';') - { - ln.erase(string_index, 1); - } - else - { - break; - } - } - } - } - else if (ln.find('"') == std::string::npos && - ln.find('\'') == std::string::npos) - { - std::vector<std::string> forbidden_words; + // TODO: sort keywords - forbidden_words.push_back("\\"); - forbidden_words.push_back("?"); - forbidden_words.push_back("@"); - forbidden_words.push_back("/*"); - forbidden_words.push_back("*/"); - - for (auto& forbidden : forbidden_words) - { - if (ParserKit::find_word(ln, forbidden)) - { - err_str += "\nForbidden character detected: "; - err_str += forbidden; - - return err_str; - } - } - } - - struct CompilerVariableRange final + for (auto& keyword : keywords_list) { - std::string fBegin; - std::string fEnd; - }; - - const std::vector<CompilerVariableRange> variables_list = { - { .fBegin = "static ", .fEnd = "="}, - { .fBegin = "=", .fEnd = ";"}, - { .fBegin = "if(", .fEnd = "="}, - { .fBegin = "if (", .fEnd = "="}, - { .fBegin = "if(", .fEnd = "<"}, - { .fBegin = "if (", .fEnd = "<"}, - { .fBegin = "if(", .fEnd = ">"}, - { .fBegin = "if (", .fEnd = ">"}, - { .fBegin = "if(", .fEnd = ")"}, - { .fBegin = "if (", .fEnd = ")"}, - - { .fBegin = "else(", .fEnd = "="}, - { .fBegin = "else (", .fEnd = "="}, - { .fBegin = "else(", .fEnd = "<"}, - { .fBegin = "else (", .fEnd = "<"}, - { .fBegin = "else(", .fEnd = ">"}, - { .fBegin = "else (", .fEnd = ">"}, - { .fBegin = "else(", .fEnd = ")"}, - { .fBegin = "else (", .fEnd = ")"}, - }; + syntax_tree.fUserData = keyword.first; + kState.fSyntaxTree->fLeafList.push_back(syntax_tree); - for (auto& variable : variables_list) - { - if (ln.find(variable.fBegin) != std::string::npos) - { - string_index = ln.find(variable.fBegin) + variable.fBegin.size(); - - while (ln[string_index] == ' ') - ++string_index; - - std::string keyword; - - for (; string_index < ln.size(); ++string_index) - { - if (ln[string_index] == variable.fEnd[0]) - { - std::string varname = ""; + std::cout << keyword.first << "\n"; + } - for (size_t index_keyword = ln.find(' '); ln[index_keyword] != variable.fBegin[0]; - ++index_keyword) - { - if (ln[index_keyword] == ' ') - { - continue; - } + return true; +} - if (isdigit(ln[index_keyword])) - { - goto cxx_next_loop; - } +///////////////////////////////////////////////////////////////////////////////////////// - varname += ln[index_keyword]; - } - - if (varname.find(' ') != std::string::npos) - { - varname.erase(0, varname.find(' ')); +/** + * @brief C To Assembly mount-point. + */ - if (variable.fBegin == "extern") - { - varname.erase(0, varname.find(' ')); - } - } +///////////////////////////////////////////////////////////////////////////////////////// - std::string reg = kAsmRegisterPrefix; - reg += std::to_string(kRegisterCounter); - - kCompilerVariables.push_back({ .fValue = varname }); - goto cxx_check_done; - } +class AssemblyMountpointClang final : public CxxKit::AssemblyMountpoint +{ +public: + explicit AssemblyMountpointClang() = default; + ~AssemblyMountpointClang() override = default; - keyword.push_back(ln[string_index]); - } - - goto cxx_next_loop; + CXXKIT_COPY_DEFAULT(AssemblyMountpointClang); - cxx_check_done: + [[maybe_unused]] static Int32 Arch() noexcept { return CxxKit::AssemblyFactory::kArchRISCV; } - // skip digit value. - if (isdigit(keyword[0]) || - keyword[0] == '"') - { - goto cxx_next_loop; - } + Int32 CompileToFormat(CxxKit::StringView& src, Int32 arch) override + { + if (arch != AssemblyMountpointClang::Arch()) + return -1; - while (keyword.find(' ') != std::string::npos) - keyword.erase(keyword.find(' '), 1); + if (kCompilerBackend == nullptr) + return -1; - for (auto& var : kCompilerVariables) - { - if (var.fValue.find(keyword) != std::string::npos) - { - err_str.clear(); - goto cxx_next; - } - } + /* @brief copy contents wihtout extension */ + std::string src_file = src.CData(); + std::ifstream src_fp = std::ifstream(src_file, std::ios::in); + std::string dest; - for (auto& fn : kCompilerFunctions) + for (auto& ch : src_file) + { + if (ch == '.') { - if (fn.find(keyword[0]) != std::string::npos) - { - auto where_begin = fn.find(keyword[0]); - auto keyword_begin = 0UL; - auto failed = false; - - for (; where_begin < keyword.size(); ++where_begin) - { - if (fn[where_begin] == '(' && - keyword[keyword_begin] == '(') - break; - - if (fn[where_begin] != keyword[keyword_begin]) - { - failed = true; - break; - } - - ++keyword_begin; - } - - if (!failed) - { - err_str.clear(); - goto cxx_next; - } - else - { - continue; - } - } + break; } -cxx_error_value: - if (keyword.find("->") != std::string::npos) - return err_str; - - if (keyword.find(".") != std::string::npos) - return err_str; - - if (isalnum(keyword[0])) - err_str += "\nUndefined value: " + keyword; - - return err_str; + dest += ch; } -cxx_next_loop: - continue; - } - -cxx_next: + /* According to pef abi. */ + dest += kAsmFileExt; - // extern doesnt declare anything, it imports a variable. - // so that's why it's not declare upper. - if (ParserKit::find_word(ln, "extern")) - { - auto substr = ln.substr(ln.find("extern") + strlen("extern")); - kCompilerVariables.push_back({ .fValue = substr }); - } + kState.fOutputAssembly = std::make_unique<std::ofstream>(dest); - if (kShouldHaveBraces && - ln.find('{') == std::string::npos) - { - err_str += "Missing '{' for function "; - err_str += kFnName; - err_str += "\n"; + auto fmt = CxxKit::current_date(); - kShouldHaveBraces = false; - kFnName.clear(); - } - else if (kShouldHaveBraces && - ln.find('{') != std::string::npos) - { - kShouldHaveBraces = false; - kFnName.clear(); - } + (*kState.fOutputAssembly) << "# Path: " << src_file << "\n"; + (*kState.fOutputAssembly) << "# Language: MP-UX Assembly\n"; + (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n"; - bool type_not_found = true; + ParserKit::SyntaxLeafList syntax; - if (ln.find('\'') != std::string::npos) - { - ln.replace(ln.find('\''), 3, "0"); - } + kState.fSyntaxTreeList.push_back(syntax); + kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1]; - auto first = ln.find('"'); - if (first != std::string::npos) - { - auto second = 0UL; - bool found_second_quote = false; + std::string source; - for (size_t i = first + 1; i < ln.size(); ++i) + while (std::getline(src_fp, source)) { - if (ln[i] == '\"') - { - found_second_quote = true; - second = i; - - break; - } + kCompilerBackend->Compile(source.c_str(), src.CData()); } - if (!found_second_quote) - { - err_str += "Missing terminating \"."; - err_str += " here -> " + ln.substr(ln.find('"'), second); - } - } + if (kAcceptableErrors > 0) + return -1; - if (ln.find(')') != std::string::npos && - ln.find(';') == std::string::npos) - { - if (ln.find('{') == std::string::npos) + std::vector<std::string> lines; + + struct scope_type { - kFnName = ln; - kShouldHaveBraces = true; + std::vector<std::string> vals; + int reg_cnt; + int id; - goto skip_braces_check; - } - else if (ln.find('{') != std::string::npos) - { - kShouldHaveBraces = false; - } - } + bool operator==(const scope_type& typ) { return typ.id == id; } + }; -skip_braces_check: + std::vector<scope_type> scope; + bool found_type = false; + bool is_pointer = false; + bool found_expr = false; + bool found_func = false; - for (auto& key : kCompilerTypes) - { - if (ParserKit::find_word(ln, key.fName)) + for (auto& leaf : kState.fSyntaxTree->fLeafList) { - if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1])) + if (leaf.fUserData == "{") { - err_str += "\nNumber cannot be set for "; - err_str += key.fName; - err_str += "'s name. here -> "; - err_str += ln; + scope.push_back({}); } - if (ln.find(key.fName) == 0 || - ln[ln.find(key.fName) - 1] == ' ' || - ln[ln.find(key.fName) - 1] == '\t') + if (leaf.fUserData == "{") { - type_not_found = false; - - if (ln[ln.find(key.fName) + key.fName.size()] != ' ') - { - type_not_found = true; - - if (ln[ln.find(key.fName) + key.fName.size()] == '\t') - type_not_found = false; - - goto next; - } - else if (ln[ln.find(key.fName) + key.fName.size()] != '\t') - { - type_not_found = true; - - if (ln[ln.find(key.fName) + key.fName.size()] == ' ') - type_not_found = false; - - } + scope.pop_back(); } -next: - - if (key.fName != "struct" || - key.fName != "enum" || - key.fName != "union") + if (leaf.fUserData == "int" || + leaf.fUserData == "long" || + leaf.fUserData == "unsigned" || + leaf.fUserData == "short" || + leaf.fUserData == "char" || + leaf.fUserData == "struct" || + leaf.fUserData == "class") { - if (ln.find(';') == std::string::npos) - { - if (ln.find('(') != std::string::npos) - { - if (ln.find('=') == std::string::npos) - continue; - } - - err_str += "\nMissing ';', here -> "; - err_str += ln; - } - else - { - continue; - } - - if (ln.find('=') != std::string::npos) - { - if (ln.find('(') != std::string::npos) - { - if (ln.find(')') == std::string::npos) - { - err_str += "\nMissing ')', after '(' here -> "; - err_str += ln.substr(ln.find('(')); - } - } - } + found_type = true; } - } - } - - if (kInBraces && - ln.find("struct") != std::string::npos && - ln.find("union") != std::string::npos && - ln.find("enum") != std::string::npos && - ln.find('=') != std::string::npos) - { - if (ln.find(';') == std::string::npos) - { - err_str += "\nMissing ';' after struct/union/enum declaration, here -> "; - err_str += ln; - } - } - if (ln.find(';') != std::string::npos && - ln.find("for") == std::string::npos) - { - if (ln.find(';') + 1 != ln.size()) - { - for (int i = 0; i < ln.substr(ln.find(';') + 1).size(); ++i) + if (leaf.fUserData == "(") { - if ((ln.substr(ln.find(';') + 1)[i] != ' ') || - (ln.substr(ln.find(';') + 1)[i] != '\t')) + if (found_type) { - if (auto err = this->Check(ln.substr(ln.find(';') + 1).c_str(), file); - !err.empty()) - { - err_str += "\nUnexpected text after ';' -> "; - err_str += ln.substr(ln.find(';')); - err_str += err; - } + found_expr = true; + found_type = false; + is_pointer = false; } } - } - } - - if (ln.find('(') != std::string::npos) - { - if (ln.find(';') == std::string::npos && - !ParserKit::find_word(ln, "|") && - !ParserKit::find_word(ln, "||") && - !ParserKit::find_word(ln, "&") && - !ParserKit::find_word(ln, "&&") && - !ParserKit::find_word(ln, "~")) - { - bool found_func = false; - size_t i = ln.find('('); - std::vector<char> opens; - std::vector<char> closes; - for (; i < ln.size(); ++i) + if (leaf.fUserData == ")") { - if (ln[i] == ')') + if (found_expr) { - closes.push_back(1); - } - - if (ln[i] == '(') - { - opens.push_back(1); + found_expr = false; + is_pointer = false; } } - if (closes.size() != opens.size()) - err_str += "Unterminated (), here -> " + ln; - - bool space_found = false; - - for (int i = 0; i < ln.size(); ++i) + if (leaf.fUserData == ",") { - if (ln[i] == ')' && - !space_found) + if (is_pointer) { - space_found = true; - continue; - } - - if (space_found) - { - if (ln[i] == ' ' && - isalnum(ln[i+1])) - { - err_str += "\nBad function format here -> "; - err_str += ln; - } + is_pointer = false; } } - } - if (ln.find('(') < 1) - { - err_str += "\nMissing identifier before '(' here -> "; - err_str += ln; - } - else - { - if (type_not_found && - ln.find(';') == std::string::npos && - ln.find("if") == std::string::npos && - ln.find("while") == std::string::npos && - ln.find("for") == std::string::npos && - ln.find("static") == std::string::npos && - ln.find("inline") == std::string::npos && - ln.find("|") == std::string::npos && - ln.find("&") == std::string::npos) + if (leaf.fUserData == "*") { - err_str += "\n Missing ';' or type, here -> "; - err_str += ln; + if (found_type && !found_expr) + is_pointer = true; } - } - - if (ln.find(')') == std::string::npos) - { - err_str += "\nMissing ')', after '(' here -> "; - err_str += ln.substr(ln.find('(')); - } - } - else - { - if (ln.find("for") != std::string::npos || - ln.find("while") != std::string::npos) - { - err_str += "\nMissing '(', after \"for\", here -> "; - err_str += ln; - } - } - - if (ln.find('}') != std::string::npos && - !kInBraces) - { - if (!kInStruct && - ln.find(';') == std::string::npos) - { - err_str += "\nMismatched '}', here -> "; - err_str += ln; - } - } - if (!ln.empty()) - { - if (ln.find(';') == std::string::npos && - ln.find("struct") == std::string::npos && - ln.find("enum") == std::string::npos && - ln.find("union") == std::string::npos && - ln.find("for") == std::string::npos && - ln.find("while") == std::string::npos && - ln.find('{') == std::string::npos && - ln.find('}') == std::string::npos && - ln.find(')') == std::string::npos && - ln.find('(') == std::string::npos && - ln.find(',') == std::string::npos && - ln.find("typedef") == std::string::npos) - { - if (ln.size() <= 2) - return err_str; - - err_str += "\nMissing ';', here -> "; - err_str += ln; - } - } - - return err_str; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -/** - * @brief C To Assembly mount-point. - */ - -///////////////////////////////////////////////////////////////////////////////////////// - -class AssemblyMountpointClang final : public CxxKit::AssemblyMountpoint -{ -public: - explicit AssemblyMountpointClang() = default; - ~AssemblyMountpointClang() override = default; - - CXXKIT_COPY_DEFAULT(AssemblyMountpointClang); - - [[maybe_unused]] static Int32 Arch() noexcept { return CxxKit::AssemblyFactory::kArchRISCV; } - - Int32 CompileToFormat(CxxKit::StringView& src, Int32 arch) override - { - if (arch != AssemblyMountpointClang::Arch()) - return -1; - - if (kCompilerBackend == nullptr) - return -1; - - /* @brief copy contents wihtout extension */ - std::string src_file = src.CData(); - std::ifstream src_fp = std::ifstream(src_file, std::ios::in); - std::string dest; - - for (auto& ch : src_file) - { - if (ch == '.') + if (leaf.fUserData == "=") { - break; - } + auto& front = scope.front(); - dest += ch; - } + if (found_type) + { + std::string reg = "r"; + reg += std::to_string(front.reg_cnt); + ++front.reg_cnt; + + leaf.fUserValue = !is_pointer ? "ldw %s, %s1\n" : "lda %s, %s1\n"; - /* According to pef abi. */ - dest += kAsmFileExt; + for (auto& ln : lines) + { + if (ln.find(leaf.fUserData) != std::string::npos && + ln.find(";") != std::string::npos) + { + auto val = ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size()); + val.erase(val.find(";"), 1); - kState.fOutputAssembly = std::make_unique<std::ofstream>(dest); + leaf.fUserValue.replace(leaf.fUserValue.find("%s1"), strlen("%s1"), val); + } + } - auto fmt = CxxKit::current_date(); + leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), reg); + } - (*kState.fOutputAssembly) << "# Path: " << src_file << "\n"; - (*kState.fOutputAssembly) << "# Language: MP-UX Assembly\n"; - (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n"; + is_pointer = false; + found_type = false; + } - ParserKit::SyntaxLeafList syntax; + if (leaf.fUserData == "return") + { + leaf.fUserValue = "ldw r19, %s\njlr"; - kState.fSyntaxTreeList.push_back(syntax); - kState.fSyntaxTree = &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1]; + if (!lines.empty()) + { + for (auto& ln : lines) + { + if (ln.find(leaf.fUserData) != std::string::npos && + ln.find(";") != std::string::npos) + { + auto val = ln.substr(ln.find(leaf.fUserData) + leaf.fUserData.size()); + val.erase(val.find(";"), 1); - std::string source; + leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), val); + } + } + } + else + { + leaf.fUserValue.replace(leaf.fUserValue.find("%s"), strlen("%s"), "0"); + } - while (std::getline(src_fp, source)) - { - if (auto err = kCompilerBackend->Check(source.c_str(), src.CData()); - err.empty()) - { - kCompilerBackend->Compile(source.c_str(), src.CData()); - } - else - { - detail::print_error(err, src.CData()); + continue; } - } - if (kAcceptableErrors > 0) - return -1; + lines.push_back(leaf.fUserData); + } for (auto& leaf : kState.fSyntaxTree->fLeafList) { @@ -876,13 +480,13 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// #define kPrintF printf -#define kSplashCxx() kPrintF(kWhite "%s\n", "X64000 C++ compiler, v1.13, (c) WestCo") +#define kSplashCxx() kPrintF(kWhite "%s\n", "X64000 C compiler, v1.13, (c) WestCo") static void cxx_print_help() { kSplashCxx(); kPrintF(kWhite "--asm={MACHINE}: %s\n", "Compile to a specific assembler syntax. (masm)"); - kPrintF(kWhite "--compiler={COMPILER}: %s\n", "Select compiler engine (builtin -> dolvik++)."); + kPrintF(kWhite "--compiler={COMPILER}: %s\n", "Select compiler engine (builtin -> vanhalen++)."); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -891,11 +495,59 @@ static void cxx_print_help() int main(int argc, char** argv) { - kCompilerTypes.push_back({ .fName = "void", .fValue = "void" }); - kCompilerTypes.push_back({ .fName = "char", .fValue = "byte" }); - kCompilerTypes.push_back({ .fName = "short", .fValue = "hword" }); - kCompilerTypes.push_back({ .fName = "int", .fValue = "dword" }); - kCompilerTypes.push_back({ .fName = "long", .fValue = "qword" }); + kKeywords.push_back("auto"); + kKeywords.push_back("else"); + kKeywords.push_back("break"); + kKeywords.push_back("switch"); + kKeywords.push_back("enum"); + kKeywords.push_back("register"); + kKeywords.push_back("do"); + kKeywords.push_back("return"); + kKeywords.push_back("if"); + kKeywords.push_back("default"); + kKeywords.push_back("struct"); + kKeywords.push_back("_Packed"); + kKeywords.push_back("extern"); + kKeywords.push_back("volatile"); + kKeywords.push_back("static"); + kKeywords.push_back("for"); + kKeywords.push_back("class"); + kKeywords.push_back("{"); + kKeywords.push_back("}"); + kKeywords.push_back("("); + kKeywords.push_back(")"); + kKeywords.push_back("char"); + kKeywords.push_back("int"); + kKeywords.push_back("short"); + kKeywords.push_back("long"); + kKeywords.push_back("float"); + kKeywords.push_back("double"); + kKeywords.push_back("unsigned"); + kKeywords.push_back("__export__"); + kKeywords.push_back("__packed__"); + kKeywords.push_back("namespace"); + kKeywords.push_back("while"); + kKeywords.push_back("sizeof"); + kKeywords.push_back("private"); + kKeywords.push_back("->"); + kKeywords.push_back("."); + kKeywords.push_back("::"); + kKeywords.push_back("*"); + kKeywords.push_back("+"); + kKeywords.push_back("-"); + kKeywords.push_back("/"); + kKeywords.push_back("="); + kKeywords.push_back("=="); + kKeywords.push_back("!="); + kKeywords.push_back(">="); + kKeywords.push_back("<="); + kKeywords.push_back(">"); + kKeywords.push_back("<"); + kKeywords.push_back(":"); + kKeywords.push_back(","); + kKeywords.push_back(";"); + kKeywords.push_back("public"); + kKeywords.push_back("protected"); bool skip = false; @@ -949,7 +601,7 @@ int main(int argc, char** argv) continue; } - if (strcmp(argv[index], "--compiler=dolvik") == 0) + if (strcmp(argv[index], "--compiler=vanhalen") == 0) { if (!kCompilerBackend) kCompilerBackend = new CompilerBackendClang(); @@ -977,7 +629,7 @@ int main(int argc, char** argv) std::string err = "Unknown command: "; err += argv[index]; - detail::print_error(err, "c++"); + detail::print_error(err, "ccplus"); continue; } @@ -990,7 +642,7 @@ int main(int argc, char** argv) { if (kState.kVerbose) { - std::cerr << argv[index] << " is not a valid C++ source.\n"; + std::cerr << argv[index] << " is not a valid C source.\n"; } return -1; diff --git a/CompilerDriver/makefile b/CompilerDriver/makefile index 91ab478..828f21a 100644 --- a/CompilerDriver/makefile +++ b/CompilerDriver/makefile @@ -15,7 +15,7 @@ LINK_OUTPUT=bin/ld PP_SRC=cpp.cxx PP_OUTPUT=bin/cpp -CC2_OUTPUT=bin/cpp2 +CC2_OUTPUT=bin/cppfront CC2_SRC=cc2/source/cppfront.cpp CC_SRC=ccplus.cxx ../C++Kit/StdKit/*.cpp ../C++Kit/AsmKit/*.cpp |
