diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-09 08:45:26 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-09 08:50:57 +0100 |
| commit | b16ae0960b396c8c20e4711eabfe4b826a039d7e (patch) | |
| tree | 8e1688a956c98f3fee7218f5664ef1ac61100477 /CompilerDriver | |
| parent | 8d7c9c7296e9b2e2afb79ce19d2560ab218d77aa (diff) | |
CompilerDriver: new preprocessor tool, bpp.
Syntax rules of bpp:
- prefixed with %
- looks like C preprocessor %ifdef, %if, %elif, %else, %endif
- #define is %def.
- can't call other defines in %def, so %define foo __false doesn't work.
bpp is a new preprocessor for masm and bccl.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'CompilerDriver')
| -rw-r--r-- | CompilerDriver/.gitignore | 1 | ||||
| -rw-r--r-- | CompilerDriver/bccl.cc | 48 | ||||
| -rw-r--r-- | CompilerDriver/bpp.cc (renamed from CompilerDriver/cpp.cc) | 171 | ||||
| -rw-r--r-- | CompilerDriver/ccplus.cc | 2 | ||||
| -rw-r--r-- | CompilerDriver/ld.cc | 8 | ||||
| -rw-r--r-- | CompilerDriver/makefile | 4 | ||||
| -rw-r--r-- | CompilerDriver/masm.cc | 17 |
7 files changed, 174 insertions, 77 deletions
diff --git a/CompilerDriver/.gitignore b/CompilerDriver/.gitignore index acd901f..69146c2 100644 --- a/CompilerDriver/.gitignore +++ b/CompilerDriver/.gitignore @@ -1,6 +1,7 @@ bin/ld bin/mld bin/cpp +bin/bpp bin/cc bin/masm bin/mkcdfs diff --git a/CompilerDriver/bccl.cc b/CompilerDriver/bccl.cc index c8cd88f..a522c79 100644 --- a/CompilerDriver/bccl.cc +++ b/CompilerDriver/bccl.cc @@ -20,13 +20,13 @@ // TODO: support structs and ., -> -/* Optimized C driver */ -/* This is part of MP-UX C SDK. */ +/* BCCL driver */ +/* This is part of MP-UX BCCL SDK. */ /* (c) Mahrouss Logic */ // @author Amlal El Mahrouss (amlel) // @file bccl.bccl -// @brief Optimized C Compiler. +// @brief BCCL Compiler. ///////////////////// @@ -40,7 +40,7 @@ ///////////////////////////////////// -// INTERNAL STUFF OF THE C COMPILER +// INTERNAL STUFF OF THE BCCL COMPILER ///////////////////////////////////// @@ -53,7 +53,7 @@ namespace detail std::string fReg; }; - // \brief Map for C structs + // \brief Map for BCCL structs // \author amlel struct CompilerStructMap final { @@ -156,22 +156,22 @@ static bool kOnForLoop = false; static bool kInBraces = false; static size_t kBracesCount = 0UL; -/* @brief C compiler backend for Optimized C */ -class CompilerBackendClang final : public ParserKit::CompilerBackend +/* @brief BCCL compiler backend for BCCL */ +class CompilerBackendBccl final : public ParserKit::CompilerBackend { public: - explicit CompilerBackendClang() = default; - ~CompilerBackendClang() override = default; + explicit CompilerBackendBccl() = default; + ~CompilerBackendBccl() override = default; - CXXKIT_COPY_DEFAULT(CompilerBackendClang); + CXXKIT_COPY_DEFAULT(CompilerBackendBccl); std::string Check(const char *text, const char *file); bool Compile(const std::string &text, const char *file) override; - const char *Language() override { return "MP-UX BCCL (64x0/32x0 target)"; } + const char *Language() override { return "MP-UX BCCL for 64x0/32x0"; } }; -static CompilerBackendClang *kCompilerBackend = nullptr; +static CompilerBackendBccl *kCompilerBackend = nullptr; static std::vector<detail::CompilerType> kCompilerVariables; static std::vector<std::string> kCompilerFunctions; static std::vector<detail::CompilerType> kCompilerTypes; @@ -207,11 +207,11 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// // @name Compile -// @brief Generate MASM from a C assignement. +// @brief Generate MASM from a BCCL assignement. ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerBackendClang::Compile(const std::string &text, const char *file) +bool CompilerBackendBccl::Compile(const std::string &text, const char *file) { std::string _text = text; @@ -705,7 +705,7 @@ bool CompilerBackendClang::Compile(const std::string &text, const char *file) static bool kShouldHaveBraces = false; static std::string kFnName; -std::string CompilerBackendClang::Check(const char *text, const char *file) +std::string CompilerBackendBccl::Check(const char *text, const char *file) { std::string err_str; std::string ln = text; @@ -1271,24 +1271,24 @@ skip_braces_check: ///////////////////////////////////////////////////////////////////////////////////////// /** - * @brief C To Assembly mount-point. + * @brief BCCL To Assembly mount-point. */ ///////////////////////////////////////////////////////////////////////////////////////// -class AssemblyMountpointClang final : public CompilerKit::AssemblyMountpoint +class AssemblyMountpointBccl final : public CompilerKit::AssemblyMountpoint { public: - explicit AssemblyMountpointClang() = default; - ~AssemblyMountpointClang() override = default; + explicit AssemblyMountpointBccl() = default; + ~AssemblyMountpointBccl() override = default; - CXXKIT_COPY_DEFAULT(AssemblyMountpointClang); + CXXKIT_COPY_DEFAULT(AssemblyMountpointBccl); [[maybe_unused]] static Int32 Arch() noexcept { return CompilerKit::AssemblyFactory::kArchRISCV; } Int32 CompileToFormat(CompilerKit::StringView &src, Int32 arch) override { - if (arch != AssemblyMountpointClang::Arch()) + if (arch != AssemblyMountpointBccl::Arch()) return -1; if (kCompilerBackend == nullptr) @@ -1509,7 +1509,7 @@ int main(int argc, char **argv) { delete kFactory.Unmount(); - kFactory.Mount(new AssemblyMountpointClang()); + kFactory.Mount(new AssemblyMountpointBccl()); kMachine = CompilerKit::AssemblyFactory::kArchRISCV; continue; @@ -1518,7 +1518,7 @@ int main(int argc, char **argv) if (strcmp(argv[index], "--compiler=dolvik") == 0) { if (!kCompilerBackend) - kCompilerBackend = new CompilerBackendClang(); + kCompilerBackend = new CompilerBackendBccl(); continue; } @@ -1556,7 +1556,7 @@ int main(int argc, char **argv) { if (kState.kVerbose) { - std::cerr << argv[index] << " is not a valid C line_src.\n"; + std::cerr << argv[index] << " is not a valid BCCL source.\n"; } return -1; diff --git a/CompilerDriver/cpp.cc b/CompilerDriver/bpp.cc index 6b33aeb..80b92ed 100644 --- a/CompilerDriver/cpp.cc +++ b/CompilerDriver/bpp.cc @@ -13,9 +13,11 @@ #include <iostream> #include <fstream> +#define kMacroPrefix '%' + // @author Amlal El Mahrouss (amlel) // @file cpp.cc -// @brief C Preprocessor. +// @brief MASM preprocessor. typedef Int32(*cpp_parser_fn_t)(std::string& line, std::ifstream& hdr_file, std::ofstream& pp_out); @@ -74,7 +76,7 @@ static std::vector<std::string> kKeywords = { "include", "if", "pragma", - "define", + "def", "elif", "ifdef", "ifndef", @@ -299,7 +301,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) hdr_line.erase(hdr_line.find("//")); } - if (hdr_line[0] == '#' && + if (hdr_line[0] == kMacroPrefix && hdr_line.find("endif") != std::string::npos) { if (!defined && @@ -331,14 +333,83 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) if (ParserKit::find_word(hdr_line, macro.fName) && hdr_line.find("#define") == std::string::npos) { - hdr_line = hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), macro.fValue); + auto substr = hdr_line.substr(hdr_line.find(macro.fName) + macro.fName.size() + 1); + + std::vector<std::string> sym_vec; + std::string sym_str; + + for (auto& subc : substr) + { + if (subc == ',' || + subc == ')') + { + if (sym_str.empty()) + continue; + + sym_vec.push_back(sym_str); + sym_str.clear(); + + continue; + } + + if (isalnum(subc)) + sym_str.push_back(subc); + } + + if (macro.fArgs.size() > 0) + { + + for (auto& item : sym_vec) + { + std::size_t cnt = 0; + + for (auto& arg : macro.fArgs) + { + if (item == arg) + ++cnt; + } + + if (cnt > 1) + { + auto it = std::find(macro.fArgs.begin(), macro.fArgs.end(), item); + + while (it != macro.fArgs.end()) + { + macro.fArgs.erase(it); + it = std::find(macro.fArgs.begin(), macro.fArgs.end(), item); + } + } + } + + if (sym_vec.size() != macro.fArgs.size()) + { + throw std::runtime_error("cpp: arguments count mismatch, except " + std::to_string(sym_vec.size()) + ", got: " + std::to_string(macro.fArgs.size())); + return; + } + + substr = macro.fValue; + + std::size_t cnt = 0UL; + + for (auto& val : macro.fArgs) + { + substr.replace(substr.find(val), val.size(), sym_vec[cnt]); + ++cnt; + } + + hdr_line = hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size() + macro.fValue.size(), substr); + } + else + { + hdr_line = hdr_line.replace(hdr_line.find(macro.fName), macro.fName.size(), macro.fValue); + } } } - if (hdr_line[0] == '#' && - hdr_line.find("define") != std::string::npos) + if (hdr_line[0] == kMacroPrefix && + hdr_line.find("def") != std::string::npos) { - auto line_after_define = hdr_line.substr(hdr_line.find("define") + strlen("define") + 1); + auto line_after_define = hdr_line.substr(hdr_line.find("def") + strlen("def") + 1); std::string macro_value; std::string macro_key; @@ -383,34 +454,52 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) macro_key += ch; } - for (auto& ch : line_after_define) - { - if (ch == '(') - { - std::string arg; + std::vector<std::string> dupls; + std::string str; - for (size_t i = pos+1; i < line_after_define.size(); i++) - { - if (line_after_define[i] == ')') - break; + line_after_define.erase(0, line_after_define.find("(") + 1); - if (line_after_define[i] == ' ') - continue; - - if (line_after_define[i] == ',') - { - args.push_back(arg); - arg.clear(); + for (auto& subc : line_after_define) + { + if (subc == ',' || + subc == ')') + { + if (str.empty()) + continue; - continue; - } + dupls.push_back(str); + args.push_back(str); - arg += line_after_define[i]; - } - - break; - } - } + str.clear(); + + continue; + } + + if (isalnum(subc)) + str.push_back(subc); + } + + for (auto& dupl : dupls) + { + std::size_t cnt = 0; + + for (auto& arg : args) + { + if (dupl == arg) + ++cnt; + } + + if (cnt > 1) + { + auto it = std::find(args.begin(), args.end(), dupl); + + while (it != args.end()) + { + args.erase(it); + it = std::find(args.begin(), args.end(), dupl); + } + } + } details::cpp_macro macro; @@ -423,7 +512,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) continue; } - if (hdr_line[0] != '#') + if (hdr_line[0] != kMacroPrefix) { if (inactive_code) { @@ -523,7 +612,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) continue; } - if (hdr_line[0] == '#' && + if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifndef") != std::string::npos) { auto line_after_ifndef = hdr_line.substr(hdr_line.find("ifndef") + strlen("ifndef") + 1); @@ -576,7 +665,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) continue; } } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("else") != std::string::npos) { if (!defined && @@ -595,7 +684,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) continue; } } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("ifdef") != std::string::npos) { auto line_after_ifdef = hdr_line.substr(hdr_line.find("ifdef") + strlen("ifdef") + 1); @@ -641,7 +730,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) } } } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("pragma") != std::string::npos) { line_after_include = hdr_line.substr(hdr_line.find("pragma once")); @@ -655,7 +744,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) goto kIncludeFile; } } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("if") != std::string::npos) { inactive_code = true; @@ -751,7 +840,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) } } } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("warning") != std::string::npos) { auto line_after_warning = hdr_line.substr(hdr_line.find("warning") + strlen("warning") + 1); @@ -770,7 +859,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) std::cout << "Warning: " << message << std::endl; } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("error") != std::string::npos) { auto line_after_warning = hdr_line.substr(hdr_line.find("error") + strlen("error") + 1); @@ -789,7 +878,7 @@ void cpp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) throw std::runtime_error("Error: " + message); } - else if (hdr_line[0] == '#' && + else if (hdr_line[0] == kMacroPrefix && hdr_line.find("include") != std::string::npos) { line_after_include = hdr_line.substr(hdr_line.find("include")); @@ -930,7 +1019,7 @@ int main(int argc, char** argv) if (strcmp(argv[index], "-v") == 0 || strcmp(argv[index], "--version") == 0) { - printf("%s\n", "cpp v1.11, (c) Mahrouss Logic"); + printf("%s\n", "bpp v1.11, (c) Mahrouss Logic"); return 0; } diff --git a/CompilerDriver/ccplus.cc b/CompilerDriver/ccplus.cc index e7b3347..8309145 100644 --- a/CompilerDriver/ccplus.cc +++ b/CompilerDriver/ccplus.cc @@ -163,7 +163,7 @@ public: bool Compile(const std::string& text, const char* file) override; - const char* Language() override { return "Optimized 64x0 C++"; } + const char* Language() override { return "64x0/32x0 C++"; } }; diff --git a/CompilerDriver/ld.cc b/CompilerDriver/ld.cc index 7620532..fbdf020 100644 --- a/CompilerDriver/ld.cc +++ b/CompilerDriver/ld.cc @@ -17,16 +17,16 @@ #include <CompilerKit/StdKit/ErrorID.hpp> -#include <fstream> -#include <iostream> -#include <uuid/uuid.h> - //! Portable Executable Format #include <CompilerKit/StdKit/PEF.hpp> //! Advanced Executable Object Format #include <CompilerKit/StdKit/AE.hpp> +#include <fstream> +#include <iostream> +#include <uuid/uuid.h> + //! @brief standard PEF entry. #define kPefStart "__start" diff --git a/CompilerDriver/makefile b/CompilerDriver/makefile index 4149005..8fe9c79 100644 --- a/CompilerDriver/makefile +++ b/CompilerDriver/makefile @@ -13,8 +13,8 @@ LINK_SRC=ld.cc LINK_OUTPUT=bin/ld LINK_ALT_OUTPUT=bin/mld -PP_SRC=cpp.cc -PP_OUTPUT=bin/cpp +PP_SRC=bpp.cc +PP_OUTPUT=bin/bpp CC2_OUTPUT=bin/cppfront CC2_SRC=cc2/source/cppfront.cpp diff --git a/CompilerDriver/masm.cc b/CompilerDriver/masm.cc index 582fce5..4d5f8d6 100644 --- a/CompilerDriver/masm.cc +++ b/CompilerDriver/masm.cc @@ -751,7 +751,7 @@ static bool masm_write_number(const std::size_t& pos, std::string& jump_label) ///////////////////////////////////////////////////////////////////////////////////////// -// @brief Read and write instruction to kBytes array. +// @brief Read and write an instruction to the output array. ///////////////////////////////////////////////////////////////////////////////////////// @@ -773,7 +773,7 @@ static void masm_read_instruction(std::string& line, const std::string& file) kBytes.emplace_back(opcode64x0.fFunct3); kBytes.emplace_back(opcode64x0.fFunct7); - // check funct7 + // check funct7 type. switch (opcode64x0.fFunct7) { // reg to reg means register to register transfer operation. @@ -800,6 +800,8 @@ static void masm_read_instruction(std::string& line, const std::string& file) if (isdigit(line[line_index + 2])) reg_str += line[line_index + 2]; + // it ranges from r0 to r19 + // something like r190 doesn't exist in the instruction set. if (kOutputArch == CompilerKit::kPefArch64000) { if (isdigit(line[line_index + 3]) && @@ -810,7 +812,8 @@ static void masm_read_instruction(std::string& line, const std::string& file) throw std::runtime_error("invalid_register_index"); } } - + + // finally cast to a size_t std::size_t reg_index = strtoq( reg_str.c_str(), nullptr, @@ -827,8 +830,12 @@ static void masm_read_instruction(std::string& line, const std::string& file) if (kVerbose) { - kStdOut << "masm: Found register: " << register_syntax << "\n"; - kStdOut << "masm: Register count: " << found_some << "\n"; + if (kOutputArch == CompilerKit::kPefArch64000) + kStdOut << "masm: 64x0 register found: " << register_syntax << "\n"; + else + kStdOut << "masm: register found: " << register_syntax << "\n"; + + kStdOut << "masm: Number of registers: " << found_some << "\n"; } } } |
