summaryrefslogtreecommitdiffhomepage
path: root/CompilerDriver
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-09 08:45:26 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-09 08:50:57 +0100
commitb16ae0960b396c8c20e4711eabfe4b826a039d7e (patch)
tree8e1688a956c98f3fee7218f5664ef1ac61100477 /CompilerDriver
parent8d7c9c7296e9b2e2afb79ce19d2560ab218d77aa (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/.gitignore1
-rw-r--r--CompilerDriver/bccl.cc48
-rw-r--r--CompilerDriver/bpp.cc (renamed from CompilerDriver/cpp.cc)171
-rw-r--r--CompilerDriver/ccplus.cc2
-rw-r--r--CompilerDriver/ld.cc8
-rw-r--r--CompilerDriver/makefile4
-rw-r--r--CompilerDriver/masm.cc17
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";
}
}
}