summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-05 11:10:54 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-05 11:14:57 +0100
commitc3b10ee1e28737375d65c3811f390d77a84fc165 (patch)
tree898acd05db58943e7b9203232c00445c17ce4836 /dev/LibCompiler/src
parentb6f625090109568d4bfd9f5fc6bc5c88682795b8 (diff)
WIP: ARM64 support is coming soon.
WIP: Prototyping ELF linker for ZkaOS. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/LibCompiler/src')
-rw-r--r--dev/LibCompiler/src/AssemblerARM64.cc0
-rw-r--r--dev/LibCompiler/src/CCompiler64x0.cc2
-rw-r--r--dev/LibCompiler/src/CCompilerARM64.cc1596
-rw-r--r--dev/LibCompiler/src/CCompilerPower64.cc2
-rw-r--r--dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc178
-rw-r--r--dev/LibCompiler/src/CPlusPlusLinkerELF.cc92
-rw-r--r--dev/LibCompiler/src/CPlusPlusLinkerPEF.cc (renamed from dev/LibCompiler/src/DynamicLinker64PEF.cc)2
-rw-r--r--dev/LibCompiler/src/Detail/ClUtils.h4
8 files changed, 1784 insertions, 92 deletions
diff --git a/dev/LibCompiler/src/AssemblerARM64.cc b/dev/LibCompiler/src/AssemblerARM64.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dev/LibCompiler/src/AssemblerARM64.cc
diff --git a/dev/LibCompiler/src/CCompiler64x0.cc b/dev/LibCompiler/src/CCompiler64x0.cc
index 657c2f9..8888a72 100644
--- a/dev/LibCompiler/src/CCompiler64x0.cc
+++ b/dev/LibCompiler/src/CCompiler64x0.cc
@@ -1493,7 +1493,7 @@ static void cc_print_help()
#define kExt ".c"
-TOOLCHAINKIT_MODULE(NewOSCompilerCLang64x0)
+TOOLCHAINKIT_MODULE(ZkaOSCompilerCLang64x0)
{
kCompilerTypes.push_back({.fName = "void", .fValue = "void"});
kCompilerTypes.push_back({.fName = "char", .fValue = "byte"});
diff --git a/dev/LibCompiler/src/CCompilerARM64.cc b/dev/LibCompiler/src/CCompilerARM64.cc
new file mode 100644
index 0000000..d985b2e
--- /dev/null
+++ b/dev/LibCompiler/src/CCompilerARM64.cc
@@ -0,0 +1,1596 @@
+/*
+ * ========================================================
+ *
+ * cc
+ * Copyright (C) 2024 Theater Quality Corp, all rights reserved.
+ *
+ * ========================================================
+ */
+
+/// BUGS: 0
+/// TODO: none
+
+#include <LibCompiler/AAL/CPU/arm64.h>
+#include <LibCompiler/Parser.h>
+#include <LibCompiler/UUID.h>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <random>
+#include <string>
+#include <utility>
+#include <vector>
+
+/* C driver */
+/* This is part of the LibCompiler. */
+/* (c) Theater Quality Corp. */
+
+/// @author EL Mahrouss Amlal (amlel)
+/// @file ARM64-cc.cxx
+/// @brief ARM64 C Compiler.
+
+/// TODO: support structures, else if, else, . and ->
+
+/////////////////////
+
+// ANSI ESCAPE CODES
+
+/////////////////////
+
+#define kExitOK (0)
+
+#define kBlank "\e[0;30m"
+#define kRed "\e[0;31m"
+#define kWhite "\e[0;97m"
+
+/////////////////////////////////////
+
+// INTERNAL STUFF OF THE C COMPILER
+
+/////////////////////////////////////
+
+namespace Details
+{
+ // \brief Register map structure, used to keep track of each variable's registers.
+ struct CompilerRegisterMap final
+ {
+ std::string fName;
+ std::string fReg;
+ };
+
+ // \brief Map for C structs
+ // \author amlel
+ struct CompilerStructMap final
+ {
+ // 'my_foo'
+ std::string fName;
+
+ // if instance: stores a valid register.
+ std::string fReg;
+
+ // offset count
+ std::size_t fOffsetsCnt;
+
+ // offset array.
+ std::vector<std::pair<Int32, std::string>> fOffsets;
+ };
+
+ struct CompilerState final
+ {
+ std::vector<LibCompiler::SyntaxLeafList> fSyntaxTreeList;
+ std::vector<CompilerRegisterMap> kStackFrame;
+ std::vector<CompilerStructMap> kStructMap;
+ LibCompiler::SyntaxLeafList* fSyntaxTree{nullptr};
+ std::unique_ptr<std::ofstream> fOutputAssembly;
+ std::string fLastFile;
+ std::string fLastError;
+ bool fVerbose;
+ };
+} // namespace Details
+
+static Details::CompilerState kState;
+static SizeType kErrorLimit = 100;
+static std::string kIfFunction = "";
+static Int32 kAcceptableErrors = 0;
+
+namespace Details
+{
+ /// @brief prints an error into stdout.
+ /// @param reason the reason of the error.
+ /// @param file where does it originate from?
+ void print_error(std::string reason, std::string file) noexcept;
+
+ struct CompilerType final
+ {
+ std::string fName;
+ std::string fValue;
+ };
+} // namespace Details
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+// Target architecture.
+static int kMachine = 0;
+
+/////////////////////////////////////////
+
+// REGISTERS ACCORDING TO USED ASSEMBLER
+
+/////////////////////////////////////////
+
+static size_t kRegisterCnt = kAsmRegisterLimit;
+static size_t kStartUsable = 8;
+static size_t kUsableLimit = 15;
+static size_t kRegisterCounter = kStartUsable;
+static std::string kRegisterPrefix = kAsmRegisterPrefix;
+
+/////////////////////////////////////////
+
+// COMPILER PARSING UTILITIES/STATES.
+
+/////////////////////////////////////////
+
+static std::vector<std::string> kFileList;
+static LibCompiler::AssemblyFactory kFactory;
+static bool kInStruct = false;
+static bool kOnWhileLoop = false;
+static bool kOnForLoop = false;
+static bool kInBraces = false;
+static bool kIfFound = false;
+static size_t kBracesCount = 0UL;
+
+/* @brief C compiler backend for C */
+class CompilerFrontendARM64 final : public LibCompiler::ICompilerFrontend
+{
+public:
+ explicit CompilerFrontendARM64() = default;
+ ~CompilerFrontendARM64() override = default;
+
+ TOOLCHAINKIT_COPY_DEFAULT(CompilerFrontendARM64);
+
+ std::string Check(const char* text, const char* file);
+ bool Compile(const std::string text, const std::string file) override;
+
+ const char* Language() override
+ {
+ return "64k C";
+ }
+};
+
+static CompilerFrontendARM64* kCompilerFrontend = nullptr;
+static std::vector<Details::CompilerType> kCompilerVariables;
+static std::vector<std::string> kCompilerFunctions;
+static std::vector<Details::CompilerType> kCompilerTypes;
+
+namespace Details
+{
+ union number_cast final {
+ public:
+ number_cast(UInt64 _Raw)
+ : _Raw(_Raw)
+ {
+ }
+
+ public:
+ char _Num[8];
+ UInt64 _Raw;
+ };
+
+ union double_cast final {
+ public:
+ double_cast(float _Raw)
+ : _Raw(_Raw)
+ {
+ }
+
+ public:
+ char _Sign;
+ char _Lh[8];
+ char _Rh[23];
+
+ float _Raw;
+ };
+} // namespace Details
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+// @name Compile
+// @brief Generate MASM from a C assignement.
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+bool CompilerFrontendARM64::Compile(const std::string text, const std::string file)
+{
+ std::string textBuffer = text;
+
+ bool typeFound = false;
+ bool fnFound = false;
+
+ // setup generator.
+ std::random_device rd;
+
+ auto seed_data = std::array<int, std::mt19937::state_size>{};
+ std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd));
+ std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
+ std::mt19937 generator(seq);
+
+ // start parsing
+ for (size_t text_index = 0; text_index < textBuffer.size(); ++text_index)
+ {
+ auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
+
+ auto gen = uuids::uuid_random_generator{generator};
+ uuids::uuid out = gen();
+
+ Details::number_cast time_off = (UInt64)out.as_bytes().data();
+
+ if (!typeFound)
+ {
+ auto substr = textBuffer.substr(text_index);
+ std::string match_type;
+
+ for (size_t y = 0; y < substr.size(); ++y)
+ {
+ if (substr[y] == ' ')
+ {
+ while (match_type.find(' ') != std::string::npos)
+ {
+ match_type.erase(match_type.find(' '));
+ }
+
+ for (auto& clType : kCompilerTypes)
+ {
+ if (clType.fName == match_type)
+ {
+ match_type.clear();
+
+ std::string buf;
+
+ buf += clType.fValue;
+ buf += ' ';
+
+ if (substr.find('=') != std::string::npos)
+ {
+ break;
+ }
+
+ if (textBuffer.find('(') != std::string::npos)
+ {
+ syntaxLeaf.fUserValue = buf;
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+ }
+
+ typeFound = true;
+ break;
+ }
+ }
+
+ break;
+ }
+
+ match_type += substr[y];
+ }
+ }
+
+ if (textBuffer[text_index] == '{')
+ {
+ if (kInStruct)
+ {
+ continue;
+ }
+
+ kInBraces = true;
+ ++kBracesCount;
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+ }
+
+ // return keyword handler
+ if (textBuffer[text_index] == 'r')
+ {
+ std::string return_keyword;
+ return_keyword += "return";
+
+ std::size_t index = 0UL;
+
+ std::string value;
+
+ for (size_t return_index = text_index; return_index < textBuffer.size();
+ ++return_index)
+ {
+ if (textBuffer[return_index] != return_keyword[index])
+ {
+ for (size_t value_index = return_index;
+ value_index < textBuffer.size(); ++value_index)
+ {
+ if (textBuffer[value_index] == ';')
+ break;
+
+ value += textBuffer[value_index];
+ }
+
+ break;
+ }
+
+ ++index;
+ }
+
+ if (index == return_keyword.size())
+ {
+ if (!value.empty())
+ {
+ if (value.find('(') != std::string::npos)
+ {
+ value.erase(value.find('('));
+ }
+
+ if (!isdigit(value[value.find('(') + 2]))
+ {
+ std::string tmp = value;
+ bool reg_to_reg = false;
+
+ value.clear();
+
+ value += " extern_segment";
+ value += tmp;
+ }
+
+ syntaxLeaf.fUserValue = "\tldw r19, ";
+
+ // make it pretty.
+ if (value.find('\t') != std::string::npos)
+ value.erase(value.find('\t'), 1);
+
+ syntaxLeaf.fUserValue += value + "\n";
+ }
+
+ syntaxLeaf.fUserValue += "\tjlr";
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ break;
+ }
+ }
+
+ if (textBuffer[text_index] == 'i' && textBuffer[text_index + 1] == 'f')
+ {
+ auto expr = textBuffer.substr(text_index + 2);
+ textBuffer.erase(text_index, 2);
+
+ if (expr.find("{") != std::string::npos)
+ {
+ expr.erase(expr.find("{"));
+ }
+
+ if (expr.find("(") != std::string::npos)
+ expr.erase(expr.find("("));
+
+ if (expr.find(")") != std::string::npos)
+ expr.erase(expr.find(")"));
+
+ kIfFunction = "__TOOLCHAINKIT_IF_PROC_";
+ kIfFunction += std::to_string(time_off._Raw);
+
+ syntaxLeaf.fUserValue = "\tlda r12, extern_segment ";
+ syntaxLeaf.fUserValue +=
+ kIfFunction +
+ "\n\t#r12 = Code to jump on, r11 right cond, r10 left cond.\n\tbeq "
+ "r10, r11, r12\ndword public_segment .code64 " +
+ kIfFunction + "\n";
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ kIfFound = true;
+ }
+
+ // Parse expressions and instructions here.
+ // what does this mean?
+ // we encounter an assignment, or we reached the end of an expression.
+ if (textBuffer[text_index] == '=' || textBuffer[text_index] == ';')
+ {
+ if (fnFound)
+ continue;
+ if (kIfFound)
+ continue;
+
+ if (textBuffer[text_index] == ';' && kInStruct)
+ continue;
+
+ if (textBuffer.find("typedef ") != std::string::npos)
+ continue;
+
+ if (textBuffer[text_index] == '=' && kInStruct)
+ {
+ Details::print_error("assignement of value in struct " + textBuffer,
+ file);
+ continue;
+ }
+
+ if (textBuffer[text_index] == ';' && kInStruct)
+ {
+ bool space_found_ = false;
+ std::string sym;
+
+ for (auto& ch : textBuffer)
+ {
+ if (ch == ' ')
+ {
+ space_found_ = true;
+ }
+
+ if (ch == ';')
+ break;
+
+ if (space_found_)
+ sym.push_back(ch);
+ }
+
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsets.push_back(
+ std::make_pair(
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4,
+ sym));
+
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt =
+ kState.kStructMap[kState.kStructMap.size() - 1].fOffsetsCnt + 4;
+
+ continue;
+ }
+
+ if (textBuffer[text_index] == '=' && kInStruct)
+ {
+ continue;
+ }
+
+ if (textBuffer[text_index + 1] == '=' ||
+ textBuffer[text_index - 1] == '!' ||
+ textBuffer[text_index - 1] == '<' ||
+ textBuffer[text_index - 1] == '>')
+ {
+ continue;
+ }
+
+ std::string substr;
+
+ if (textBuffer.find('=') != std::string::npos && kInBraces && !kIfFound)
+ {
+ if (textBuffer.find("*") != std::string::npos)
+ {
+ if (textBuffer.find("=") > textBuffer.find("*"))
+ substr += "\tlda ";
+ else
+ substr += "\tldw ";
+ }
+ else
+ {
+ substr += "\tldw ";
+ }
+ }
+ else if (textBuffer.find('=') != std::string::npos && !kInBraces)
+ {
+ substr += "stw public_segment .data64 ";
+ }
+
+ int first_encountered = 0;
+
+ std::string str_name;
+
+ for (size_t text_index_2 = 0; text_index_2 < textBuffer.size();
+ ++text_index_2)
+ {
+ if (textBuffer[text_index_2] == '\"')
+ {
+ ++text_index_2;
+
+ // want to add this, so that the parser recognizes that this is a
+ // string.
+ substr += '"';
+
+ for (; text_index_2 < textBuffer.size(); ++text_index_2)
+ {
+ if (textBuffer[text_index_2] == '\"')
+ break;
+
+ substr += textBuffer[text_index_2];
+ }
+ }
+
+ if (textBuffer[text_index_2] == '{' || textBuffer[text_index_2] == '}')
+ continue;
+
+ if (textBuffer[text_index_2] == ';')
+ {
+ break;
+ }
+
+ if (textBuffer[text_index_2] == ' ' ||
+ textBuffer[text_index_2] == '\t')
+ {
+ if (first_encountered != 2)
+ {
+ if (textBuffer[text_index] != '=' &&
+ substr.find("public_segment .data64") == std::string::npos &&
+ !kInStruct)
+ substr += "public_segment .data64 ";
+ }
+
+ ++first_encountered;
+
+ continue;
+ }
+
+ if (textBuffer[text_index_2] == '=')
+ {
+ if (!kInBraces)
+ {
+ substr.replace(substr.find("public_segment .data64"),
+ strlen("public_segment .data64"), "public_segment .zero64 ");
+ }
+
+ substr += ",";
+ continue;
+ }
+
+ substr += textBuffer[text_index_2];
+ }
+
+ for (auto& clType : kCompilerTypes)
+ {
+ if (substr.find(clType.fName) != std::string::npos)
+ {
+ if (substr.find(clType.fName) > substr.find('"'))
+ continue;
+
+ substr.erase(substr.find(clType.fName), clType.fName.size());
+ }
+ else if (substr.find(clType.fValue) != std::string::npos)
+ {
+ if (substr.find(clType.fValue) > substr.find('"'))
+ continue;
+
+ if (clType.fName == "const")
+ continue;
+
+ substr.erase(substr.find(clType.fValue), clType.fValue.size());
+ }
+ }
+
+ if (substr.find("extern") != std::string::npos)
+ {
+ substr.replace(substr.find("extern"), strlen("extern"), "extern_segment ");
+
+ if (substr.find("public_segment .data64") != std::string::npos)
+ substr.erase(substr.find("public_segment .data64"), strlen("public_segment .data64"));
+ }
+
+ auto var_to_find =
+ std::find_if(kCompilerVariables.cbegin(), kCompilerVariables.cend(),
+ [&](Details::CompilerType type) {
+ return type.fName.find(substr) != std::string::npos;
+ });
+
+ if (kRegisterCounter == 5 || kRegisterCounter == 6)
+ ++kRegisterCounter;
+
+ std::string reg = kAsmRegisterPrefix;
+ reg += std::to_string(kRegisterCounter);
+
+ if (var_to_find == kCompilerVariables.cend())
+ {
+ ++kRegisterCounter;
+
+ kState.kStackFrame.push_back({.fName = substr, .fReg = reg});
+ kCompilerVariables.push_back({.fName = substr});
+ }
+
+ syntaxLeaf.fUserValue += substr;
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ if (textBuffer[text_index] == '=')
+ break;
+ }
+
+ // function handler.
+
+ if (textBuffer[text_index] == '(' && !fnFound && !kIfFound)
+ {
+ std::string substr;
+ std::string args_buffer;
+ std::string args;
+
+ bool type_crossed = false;
+
+ for (size_t idx = textBuffer.find('(') + 1; idx < textBuffer.size();
+ ++idx)
+ {
+ if (textBuffer[idx] == ',')
+ continue;
+
+ if (textBuffer[idx] == ' ')
+ continue;
+
+ if (textBuffer[idx] == ')')
+ break;
+ }
+
+ for (char substr_first_index : textBuffer)
+ {
+ if (substr_first_index != ',')
+ args_buffer += substr_first_index;
+ else
+ args_buffer += '$';
+
+ if (substr_first_index == ';')
+ {
+ args_buffer = args_buffer.erase(0, args_buffer.find('('));
+ args_buffer = args_buffer.erase(args_buffer.find(';'), 1);
+ args_buffer = args_buffer.erase(args_buffer.find(')'), 1);
+ args_buffer = args_buffer.erase(args_buffer.find('('), 1);
+
+ if (!args_buffer.empty())
+ args += "\tldw r6, ";
+
+ std::string register_type;
+ std::size_t index = 7UL;
+
+ while (args_buffer.find("$") != std::string::npos)
+ {
+ register_type = kRegisterPrefix;
+ register_type += std::to_string(index);
+
+ ++index;
+
+ args_buffer.replace(args_buffer.find('$'), 1,
+ "\n\tldw " + register_type + ",");
+ }
+
+ args += args_buffer;
+ args += "\n\tlda r19, ";
+ }
+ }
+
+ for (char _text_i : textBuffer)
+ {
+ if (_text_i == '\t' || _text_i == ' ')
+ {
+ if (!type_crossed)
+ {
+ substr.clear();
+ type_crossed = true;
+ }
+
+ continue;
+ }
+
+ if (_text_i == '(')
+ break;
+
+ substr += _text_i;
+ }
+
+ if (kInBraces)
+ {
+ syntaxLeaf.fUserValue = args;
+ syntaxLeaf.fUserValue += substr;
+ syntaxLeaf.fUserValue += "\n\tjrl\n";
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ fnFound = true;
+ }
+ else
+ {
+ syntaxLeaf.fUserValue.clear();
+
+ syntaxLeaf.fUserValue += "public_segment .code64 ";
+
+ syntaxLeaf.fUserValue += substr;
+ syntaxLeaf.fUserValue += "\n";
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ fnFound = true;
+ }
+
+ kCompilerFunctions.push_back(textBuffer);
+ }
+
+ if (textBuffer[text_index] == '-' && textBuffer[text_index + 1] == '-')
+ {
+ textBuffer = textBuffer.replace(textBuffer.find("--"), strlen("--"), "");
+
+ for (int _text_i = 0; _text_i < textBuffer.size(); ++_text_i)
+ {
+ if (textBuffer[_text_i] == '\t' || textBuffer[_text_i] == ' ')
+ textBuffer.erase(_text_i, 1);
+ }
+
+ syntaxLeaf.fUserValue += "sub ";
+ syntaxLeaf.fUserValue += textBuffer;
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+ break;
+ }
+
+ if (textBuffer[text_index] == '}')
+ {
+ kRegisterCounter = kStartUsable;
+
+ --kBracesCount;
+
+ if (kBracesCount < 1)
+ {
+ kInBraces = false;
+ kBracesCount = 0;
+ }
+
+ if (kIfFound)
+ kIfFound = false;
+
+ if (kInStruct)
+ kInStruct = false;
+
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+ }
+
+ syntaxLeaf.fUserValue.clear();
+ }
+
+ auto syntaxLeaf = LibCompiler::SyntaxLeafList::SyntaxLeaf();
+ syntaxLeaf.fUserValue = "\n";
+ kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf);
+
+ return true;
+}
+
+static bool kShouldHaveBraces = false;
+static std::string kFnName;
+
+std::string CompilerFrontendARM64::Check(const char* text, const char* file)
+{
+ std::string err_str;
+ std::string ln = text;
+
+ if (ln.empty())
+ {
+ return err_str;
+ }
+
+ bool non_ascii_found = false;
+
+ for (int i = 0; i < ln.size(); ++i)
+ {
+ if (isalnum(ln[i]))
+ {
+ non_ascii_found = true;
+ break;
+ }
+ }
+
+ if (kShouldHaveBraces && ln.find('{') != std::string::npos)
+ {
+ kShouldHaveBraces = false;
+ }
+
+ if (!non_ascii_found)
+ return err_str;
+
+ size_t string_index = 1UL;
+
+ 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);
+ }
+
+ return err_str;
+ }
+ }
+ }
+ 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;
+
+ forbidden_words.push_back("\\");
+ forbidden_words.push_back("?");
+ forbidden_words.push_back("@");
+ forbidden_words.push_back("~");
+ forbidden_words.push_back("::");
+ forbidden_words.push_back("--*");
+ forbidden_words.push_back("*/");
+
+ // add them to avoid stupid mistakes.
+ forbidden_words.push_back("namespace");
+ forbidden_words.push_back("class");
+ forbidden_words.push_back("extern \"C\"");
+
+ for (auto& forbidden : forbidden_words)
+ {
+ if (ln.find(forbidden) != std::string::npos)
+ {
+ err_str += "\nForbidden character detected: ";
+ err_str += forbidden;
+
+ return err_str;
+ }
+ }
+ }
+
+ struct CompilerVariableRange final
+ {
+ 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 = ")"},
+ };
+
+ 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 = "";
+
+ for (size_t index_keyword = ln.find(' ');
+ ln[index_keyword] != variable.fBegin[0]; ++index_keyword)
+ {
+ if (ln[index_keyword] == ' ')
+ {
+ continue;
+ }
+
+ if (isdigit(ln[index_keyword]))
+ {
+ goto cc_next_loop;
+ }
+
+ varname += ln[index_keyword];
+ }
+
+ if (varname.find(' ') != std::string::npos)
+ {
+ varname.erase(0, varname.find(' '));
+
+ if (variable.fBegin == "extern")
+ {
+ varname.erase(0, varname.find(' '));
+ }
+ }
+
+ if (kRegisterCounter == 5 || kRegisterCounter == 6)
+ ++kRegisterCounter;
+
+ std::string reg = kAsmRegisterPrefix;
+ reg += std::to_string(kRegisterCounter);
+
+ kCompilerVariables.push_back({.fValue = varname});
+ goto cc_check_done;
+ }
+
+ keyword.push_back(ln[string_index]);
+ }
+
+ goto cc_next_loop;
+
+ cc_check_done:
+
+ // skip digit value.
+ if (isdigit(keyword[0]) || keyword[0] == '"')
+ {
+ goto cc_next_loop;
+ }
+
+ while (keyword.find(' ') != std::string::npos)
+ keyword.erase(keyword.find(' '), 1);
+
+ for (auto& var : kCompilerVariables)
+ {
+ if (var.fValue.find(keyword) != std::string::npos)
+ {
+ err_str.clear();
+ goto cc_next;
+ }
+ }
+
+ for (auto& fn : kCompilerFunctions)
+ {
+ 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 cc_next;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ cc_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;
+ }
+
+ cc_next_loop:
+ continue;
+ }
+
+cc_next:
+
+ // extern does not declare anything, it extern_segments a variable.
+ // so that's why it's not declare upper.
+ if (LibCompiler::find_word(ln, "extern"))
+ {
+ auto substr = ln.substr(ln.find("extern") + strlen("extern"));
+ kCompilerVariables.push_back({.fValue = substr});
+ }
+
+ if (kShouldHaveBraces && ln.find('{') == std::string::npos)
+ {
+ err_str += "Missing '{' for function ";
+ err_str += kFnName;
+ err_str += "\n";
+
+ kShouldHaveBraces = false;
+ kFnName.clear();
+ }
+ else if (kShouldHaveBraces && ln.find('{') != std::string::npos)
+ {
+ kShouldHaveBraces = false;
+ kFnName.clear();
+ }
+
+ bool type_not_found = true;
+
+ if (ln.find('\'') != std::string::npos)
+ {
+ ln.replace(ln.find('\''), 3, "0");
+ }
+
+ auto first = ln.find('"');
+ if (first != std::string::npos)
+ {
+ auto second = 0UL;
+ bool found_second_quote = false;
+
+ for (size_t i = first + 1; i < ln.size(); ++i)
+ {
+ if (ln[i] == '\"')
+ {
+ found_second_quote = true;
+ second = i;
+
+ break;
+ }
+ }
+
+ if (!found_second_quote)
+ {
+ err_str += "Missing terminating \".";
+ err_str += " here -> " + ln.substr(ln.find('"'), second);
+ }
+ }
+
+ if (ln.find(')') != std::string::npos && ln.find(';') == std::string::npos)
+ {
+ if (ln.find('{') == std::string::npos)
+ {
+ kFnName = ln;
+ kShouldHaveBraces = true;
+
+ goto skip_braces_check;
+ }
+ else if (ln.find('{') != std::string::npos)
+ {
+ kShouldHaveBraces = false;
+ }
+ }
+
+skip_braces_check:
+
+ for (auto& key : kCompilerTypes)
+ {
+ if (LibCompiler::find_word(ln, key.fName))
+ {
+ if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1]))
+ {
+ err_str += "\nNumber cannot be set for ";
+ err_str += key.fName;
+ err_str += "'s name. here -> ";
+ err_str += ln;
+ }
+
+ if (ln.find(key.fName) == 0 || ln[ln.find(key.fName) - 1] == ' ' ||
+ ln[ln.find(key.fName) - 1] == '\t')
+ {
+ 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;
+ }
+ }
+
+ next:
+
+ 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('('));
+ }
+ }
+ }
+ }
+ }
+
+ 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 ((ln.substr(ln.find(';') + 1)[i] != ' ') ||
+ (ln.substr(ln.find(';') + 1)[i] != '\t'))
+ {
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+ if (ln.find('(') != std::string::npos)
+ {
+ if (ln.find(';') == std::string::npos && !LibCompiler::find_word(ln, "|") &&
+ !LibCompiler::find_word(ln, "||") && !LibCompiler::find_word(ln, "&") &&
+ !LibCompiler::find_word(ln, "&&") && !LibCompiler::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 (ln[i] == ')')
+ {
+ closes.push_back(1);
+ }
+
+ if (ln[i] == '(')
+ {
+ opens.push_back(1);
+ }
+ }
+
+ if (closes.size() != opens.size())
+ err_str += "Unterminated (), here -> " + ln;
+
+ bool space_found = false;
+
+ for (int i = 0; i < ln.size(); ++i)
+ {
+ if (ln[i] == ')' && !space_found)
+ {
+ space_found = true;
+ continue;
+ }
+
+ if (space_found)
+ {
+ if (ln[i] == ' ' && isalnum(ln[i + 1]))
+ {
+ err_str += "\nBad function format here -> ";
+ err_str += ln;
+ }
+ }
+ }
+ }
+
+ 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("|") == std::string::npos &&
+ ln.find("&") == std::string::npos &&
+ ln.find("(") == std::string::npos &&
+ ln.find(")") == std::string::npos)
+ {
+ err_str += "\n Missing ';' or type, here -> ";
+ err_str += ln;
+ }
+ }
+
+ 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('{') == std::string::npos &&
+ ln.find('}') == std::string::npos &&
+ ln.find(')') == std::string::npos &&
+ ln.find('(') == std::string::npos &&
+ ln.find(',') == 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 AssemblyCCInterface final ASSEMBLY_INTERFACE
+{
+public:
+ explicit AssemblyCCInterface() = default;
+ ~AssemblyCCInterface() override = default;
+
+ TOOLCHAINKIT_COPY_DEFAULT(AssemblyCCInterface);
+
+ [[maybe_unused]] static Int32 Arch() noexcept
+ {
+ return LibCompiler::AssemblyFactory::kArchARM64;
+ }
+
+ Int32 CompileToFormat(std::string& src, Int32 arch) override
+ {
+ if (arch != AssemblyCCInterface::Arch())
+ return 1;
+
+ if (kCompilerFrontend == nullptr)
+ return 1;
+
+ /* @brief copy contents wihtout extension */
+ std::string src_file = src.data();
+ std::ifstream src_fp = std::ifstream(src_file, std::ios::in);
+ std::string dest;
+
+ for (auto& ch : src_file)
+ {
+ if (ch == '.')
+ {
+ break;
+ }
+
+ dest += ch;
+ }
+
+ /* According to PEF ABI. */
+ std::vector<const char*> exts = kAsmFileExts;
+ dest += exts[4];
+
+ kState.fOutputAssembly = std::make_unique<std::ofstream>(dest);
+
+ auto fmt = LibCompiler::current_date();
+
+ (*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
+ (*kState.fOutputAssembly)
+ << "# Language: ARM64 Assembly (Generated from ANSI C)\n";
+ (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n";
+
+ LibCompiler::SyntaxLeafList syntax;
+
+ kState.fSyntaxTreeList.push_back(syntax);
+ kState.fSyntaxTree =
+ &kState.fSyntaxTreeList[kState.fSyntaxTreeList.size() - 1];
+
+ std::string line_src;
+
+ while (std::getline(src_fp, line_src))
+ {
+ if (auto err = kCompilerFrontend->Check(line_src.c_str(), src.data());
+ err.empty())
+ {
+ kCompilerFrontend->Compile(line_src, src.data());
+ }
+ else
+ {
+ Details::print_error(err, src.data());
+ }
+ }
+
+ if (kAcceptableErrors > 0)
+ return 1;
+
+ std::vector<std::string> keywords = {"ldw", "stw", "lda", "sta",
+ "add", "sub", "mv"};
+
+ ///
+ /// Replace, optimize, fix assembly output.
+ ///
+
+ for (auto& leaf : kState.fSyntaxTree->fLeafList)
+ {
+ std::vector<std::string> access_keywords = {"->", "."};
+
+ for (auto& access_ident : access_keywords)
+ {
+ if (LibCompiler::find_word(leaf.fUserValue, access_ident))
+ {
+ for (auto& struc : kState.kStructMap)
+ {
+ /// TODO:
+ }
+ }
+ }
+
+ for (auto& keyword : keywords)
+ {
+ if (LibCompiler::find_word(leaf.fUserValue, keyword))
+ {
+ std::size_t cnt = 0UL;
+
+ for (auto& reg : kState.kStackFrame)
+ {
+ std::string needle;
+
+ for (size_t i = 0; i < reg.fName.size(); i++)
+ {
+ if (reg.fName[i] == ' ')
+ {
+ ++i;
+
+ for (; i < reg.fName.size(); i++)
+ {
+ if (reg.fName[i] == ',')
+ {
+ break;
+ }
+
+ if (reg.fName[i] == ' ')
+ continue;
+
+ needle += reg.fName[i];
+ }
+
+ break;
+ }
+ }
+
+ if (LibCompiler::find_word(leaf.fUserValue, needle))
+ {
+ if (leaf.fUserValue.find("extern_segment " + needle) !=
+ std::string::npos)
+ {
+ std::string range = "extern_segment " + needle;
+ leaf.fUserValue.replace(
+ leaf.fUserValue.find("extern_segment " + needle), range.size(),
+ needle);
+ }
+
+ if (leaf.fUserValue.find("ldw r6") != std::string::npos)
+ {
+ std::string::difference_type countComma = std::count(
+ leaf.fUserValue.begin(), leaf.fUserValue.end(), ',');
+
+ if (countComma == 1)
+ {
+ leaf.fUserValue.replace(leaf.fUserValue.find("ldw"),
+ strlen("ldw"), "mv");
+ }
+ }
+
+ leaf.fUserValue.replace(leaf.fUserValue.find(needle),
+ needle.size(), reg.fReg);
+
+ ++cnt;
+ }
+ }
+
+ if (cnt > 1 && keyword != "mv" && keyword != "add" &&
+ keyword != "sub")
+ {
+ leaf.fUserValue.replace(leaf.fUserValue.find(keyword),
+ keyword.size(), "mv");
+ }
+ }
+ }
+ }
+
+ for (auto& leaf : kState.fSyntaxTree->fLeafList)
+ {
+ (*kState.fOutputAssembly) << leaf.fUserValue;
+ }
+
+ kState.fSyntaxTree = nullptr;
+
+ kState.fOutputAssembly->flush();
+ kState.fOutputAssembly.reset();
+
+ return kExitOK;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#include <Version.h>
+
+#define kPrintF printf
+#define kSplashCxx() \
+ kPrintF(kWhite "ZKA C Driver, %s, (c) Theater Quality Corp.\n", kDistVersion)
+
+static void cc_print_help()
+{
+ kSplashCxx();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define kCExtension ".c"
+
+TOOLCHAINKIT_MODULE(ZkaOSCompilerCLangARM64)
+{
+ 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"});
+ kCompilerTypes.push_back({.fName = "*", .fValue = "offset"});
+
+ bool skip = false;
+
+ kFactory.Mount(new AssemblyCCInterface());
+ kMachine = LibCompiler::AssemblyFactory::kArchARM64;
+ kCompilerFrontend = new CompilerFrontendARM64();
+
+ for (auto index = 1UL; index < argc; ++index)
+ {
+ if (skip)
+ {
+ skip = false;
+ continue;
+ }
+
+ if (argv[index][0] == '-')
+ {
+ if (strcmp(argv[index], "--v") == 0 ||
+ strcmp(argv[index], "--version") == 0)
+ {
+ kSplashCxx();
+ return kExitOK;
+ }
+
+ if (strcmp(argv[index], "--verbose") == 0)
+ {
+ kState.fVerbose = true;
+
+ continue;
+ }
+
+ if (strcmp(argv[index], "--h") == 0 || strcmp(argv[index], "--help") == 0)
+ {
+ cc_print_help();
+
+ return kExitOK;
+ }
+
+ if (strcmp(argv[index], "--dialect") == 0)
+ {
+ if (kCompilerFrontend)
+ std::cout << kCompilerFrontend->Language() << "\n";
+
+ return kExitOK;
+ }
+
+ if (strcmp(argv[index], "--fmax-exceptions") == 0)
+ {
+ try
+ {
+ kErrorLimit = std::strtol(argv[index + 1], nullptr, 10);
+ }
+ // catch anything here
+ catch (...)
+ {
+ kErrorLimit = 0;
+ }
+
+ skip = true;
+
+ continue;
+ }
+
+ std::string err = "Unknown command: ";
+ err += argv[index];
+
+ Details::print_error(err, "cc");
+
+ continue;
+ }
+
+ kFileList.emplace_back(argv[index]);
+
+ std::string srcFile = argv[index];
+
+ if (strstr(argv[index], kCExtension) == nullptr)
+ {
+ if (kState.fVerbose)
+ {
+ Details::print_error(srcFile + " is not a valid C source.\n", "cc");
+ }
+
+ return 1;
+ }
+
+ if (kFactory.Compile(srcFile, kMachine) != kExitOK)
+ return 1;
+ }
+
+ return kExitOK;
+}
+
+// Last rev 8-1-24
diff --git a/dev/LibCompiler/src/CCompilerPower64.cc b/dev/LibCompiler/src/CCompilerPower64.cc
index dca96b3..328c429 100644
--- a/dev/LibCompiler/src/CCompilerPower64.cc
+++ b/dev/LibCompiler/src/CCompilerPower64.cc
@@ -1513,7 +1513,7 @@ static void cc_print_help()
#define kExt ".c"
-TOOLCHAINKIT_MODULE(NewOSCompilerCLangPowerPC)
+TOOLCHAINKIT_MODULE(ZkaOSCompilerCLangPowerPC)
{
kCompilerTypes.push_back({.fName = "void", .fValue = "void"});
kCompilerTypes.push_back({.fName = "char", .fValue = "byte"});
diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
index 4994644..ba805bd 100644
--- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
+++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc
@@ -237,15 +237,15 @@ bool CompilerFrontendCPlusPlus::Compile(const std::string text,
{
switch (keyword.keyword_kind)
{
- case LibCompiler::eKeywordKindCommentMultiLineStart: {
+ case LibCompiler::kKeywordKindCommentMultiLineStart: {
commentBlock = true;
return true;
}
- case LibCompiler::eKeywordKindCommentMultiLineEnd: {
+ case LibCompiler::kKeywordKindCommentMultiLineEnd: {
commentBlock = false;
break;
}
- case LibCompiler::eKeywordKindCommentInline: {
+ case LibCompiler::kKeywordKindCommentInline: {
break;
}
default:
@@ -253,15 +253,15 @@ bool CompilerFrontendCPlusPlus::Compile(const std::string text,
}
if (text[text.find(keyword.keyword_name) - 1] == '+' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableAssign)
+ keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
continue;
if (text[text.find(keyword.keyword_name) - 1] == '-' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableAssign)
+ keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
continue;
if (text[text.find(keyword.keyword_name) + 1] == '=' &&
- keyword.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableAssign)
+ keyword.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
continue;
keywords_list.emplace_back(std::make_pair(keyword, index));
@@ -289,7 +289,7 @@ bool CompilerFrontendCPlusPlus::Compile(const std::string text,
switch (keyword.first.keyword_kind)
{
- case LibCompiler::KeywordKind::eKeywordKindIf: {
+ case LibCompiler::KeywordKind::kKeywordKindIf: {
auto expr = text.substr(text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 1, text.find(")") - 1);
if (expr.find(">=") != std::string::npos)
@@ -377,7 +377,7 @@ bool CompilerFrontendCPlusPlus::Compile(const std::string text,
break;
}
- case LibCompiler::KeywordKind::eKeywordKindFunctionStart: {
+ case LibCompiler::KeywordKind::kKeywordKindFunctionStart: {
for (auto& ch : text)
{
if (isdigit(ch))
@@ -439,7 +439,7 @@ bool CompilerFrontendCPlusPlus::Compile(const std::string text,
tk_write_assembly:
syntax_tree.fUserValue = "jmp __TOOLCHAINKIT_" + fnName + "\n";
}
- case LibCompiler::KeywordKind::eKeywordKindFunctionEnd: {
+ case LibCompiler::KeywordKind::kKeywordKindFunctionEnd: {
if (text.ends_with(";"))
break;
@@ -454,50 +454,50 @@ tk_write_assembly:
kRegisterMap.clear();
break;
}
- case LibCompiler::KeywordKind::eKeywordKindEndInstr:
- case LibCompiler::KeywordKind::eKeywordKindVariableInc:
- case LibCompiler::KeywordKind::eKeywordKindVariableDec:
- case LibCompiler::KeywordKind::eKeywordKindVariableAssign: {
+ case LibCompiler::KeywordKind::kKeywordKindEndInstr:
+ case LibCompiler::KeywordKind::kKeywordKindVariableInc:
+ case LibCompiler::KeywordKind::kKeywordKindVariableDec:
+ case LibCompiler::KeywordKind::kKeywordKindVariableAssign: {
std::string valueOfVar = "";
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableInc)
+ if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc)
{
valueOfVar = text.substr(text.find("+=") + 2);
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableDec)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableDec)
{
valueOfVar = text.substr(text.find("-=") + 2);
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableAssign)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
{
valueOfVar = text.substr(text.find("=") + 1);
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindEndInstr)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr)
{
break;
}
while (valueOfVar.find(";") != std::string::npos &&
- keyword.first.keyword_kind != LibCompiler::KeywordKind::eKeywordKindEndInstr)
+ keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindEndInstr)
{
valueOfVar.erase(valueOfVar.find(";"));
}
std::string varName = text;
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableInc)
+ if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc)
{
varName.erase(varName.find("+="));
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableDec)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableDec)
{
varName.erase(varName.find("-="));
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableAssign)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableAssign)
{
varName.erase(varName.find("="));
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindEndInstr)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr)
{
varName.erase(varName.find(";"));
}
@@ -506,7 +506,7 @@ tk_write_assembly:
for (auto& keyword : kKeywords)
{
- if (keyword.keyword_kind == LibCompiler::eKeywordKindType)
+ if (keyword.keyword_kind == LibCompiler::kKeywordKindType)
{
if (text.find(keyword.keyword_name) != std::string::npos)
{
@@ -523,8 +523,8 @@ tk_write_assembly:
std::string instr = "mov ";
- if (typeFound && keyword.first.keyword_kind != LibCompiler::KeywordKind::eKeywordKindVariableInc &&
- keyword.first.keyword_kind != LibCompiler::KeywordKind::eKeywordKindVariableDec)
+ if (typeFound && keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindVariableInc &&
+ keyword.first.keyword_kind != LibCompiler::KeywordKind::kKeywordKindVariableDec)
{
if (kRegisterMap.size() > kRegisterList.size())
{
@@ -617,7 +617,7 @@ tk_write_assembly:
done:
for (auto& keyword : kKeywords)
{
- if (keyword.keyword_kind == LibCompiler::eKeywordKindType &&
+ if (keyword.keyword_kind == LibCompiler::kKeywordKindType &&
varName.find(keyword.keyword_name) != std::string::npos)
{
varName.erase(varName.find(keyword.keyword_name), keyword.keyword_name.size());
@@ -630,24 +630,24 @@ tk_write_assembly:
break;
}
- if (kKeywords[keyword.second - 1].keyword_kind == LibCompiler::eKeywordKindType ||
- kKeywords[keyword.second - 1].keyword_kind == LibCompiler::eKeywordKindTypePtr)
+ if (kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindType ||
+ kKeywords[keyword.second - 1].keyword_kind == LibCompiler::kKeywordKindTypePtr)
{
syntax_tree.fUserValue = "\n";
continue;
}
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindEndInstr)
+ if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindEndInstr)
{
syntax_tree.fUserValue = "\n";
continue;
}
- if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableInc)
+ if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableInc)
{
instr = "add ";
}
- else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::eKeywordKindVariableDec)
+ else if (keyword.first.keyword_kind == LibCompiler::KeywordKind::kKeywordKindVariableDec)
{
instr = "sub ";
}
@@ -731,7 +731,7 @@ tk_write_assembly:
break;
}
- case LibCompiler::KeywordKind::eKeywordKindReturn: {
+ case LibCompiler::KeywordKind::kKeywordKindReturn: {
try
{
auto pos = text.find("return") + strlen("return") + 1;
@@ -928,63 +928,63 @@ TOOLCHAINKIT_MODULE(CompilerCPlusPlusX8664)
{
bool skip = false;
- kKeywords.push_back({.keyword_name = "if", .keyword_kind = LibCompiler::eKeywordKindIf});
- kKeywords.push_back({.keyword_name = "else", .keyword_kind = LibCompiler::eKeywordKindElse});
- kKeywords.push_back({.keyword_name = "else if", .keyword_kind = LibCompiler::eKeywordKindElseIf});
-
- kKeywords.push_back({.keyword_name = "class", .keyword_kind = LibCompiler::eKeywordKindClass});
- kKeywords.push_back({.keyword_name = "struct", .keyword_kind = LibCompiler::eKeywordKindClass});
- kKeywords.push_back({.keyword_name = "namespace", .keyword_kind = LibCompiler::eKeywordKindNamespace});
- kKeywords.push_back({.keyword_name = "typedef", .keyword_kind = LibCompiler::eKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "using", .keyword_kind = LibCompiler::eKeywordKindTypedef});
- kKeywords.push_back({.keyword_name = "{", .keyword_kind = LibCompiler::eKeywordKindBodyStart});
- kKeywords.push_back({.keyword_name = "}", .keyword_kind = LibCompiler::eKeywordKindBodyEnd});
- kKeywords.push_back({.keyword_name = "auto", .keyword_kind = LibCompiler::eKeywordKindVariable});
- kKeywords.push_back({.keyword_name = "int", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "bool", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "short", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "char", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "long", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "float", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "double", .keyword_kind = LibCompiler::eKeywordKindType});
- kKeywords.push_back({.keyword_name = "void", .keyword_kind = LibCompiler::eKeywordKindType});
-
- kKeywords.push_back({.keyword_name = "auto*", .keyword_kind = LibCompiler::eKeywordKindVariablePtr});
- kKeywords.push_back({.keyword_name = "int*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "unsigned*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "short*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "char*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "long*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "float*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "double*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
- kKeywords.push_back({.keyword_name = "void*", .keyword_kind = LibCompiler::eKeywordKindTypePtr});
-
- kKeywords.push_back({.keyword_name = "(", .keyword_kind = LibCompiler::eKeywordKindFunctionStart});
- kKeywords.push_back({.keyword_name = ")", .keyword_kind = LibCompiler::eKeywordKindFunctionEnd});
- kKeywords.push_back({.keyword_name = "=", .keyword_kind = LibCompiler::eKeywordKindVariableAssign});
- kKeywords.push_back({.keyword_name = "+=", .keyword_kind = LibCompiler::eKeywordKindVariableInc});
- kKeywords.push_back({.keyword_name = "-=", .keyword_kind = LibCompiler::eKeywordKindVariableDec});
- kKeywords.push_back({.keyword_name = "const", .keyword_kind = LibCompiler::eKeywordKindConstant});
- kKeywords.push_back({.keyword_name = "*", .keyword_kind = LibCompiler::eKeywordKindPtr});
- kKeywords.push_back({.keyword_name = "->", .keyword_kind = LibCompiler::eKeywordKindPtrAccess});
- kKeywords.push_back({.keyword_name = ".", .keyword_kind = LibCompiler::eKeywordKindAccess});
- kKeywords.push_back({.keyword_name = ",", .keyword_kind = LibCompiler::eKeywordKindArgSeparator});
- kKeywords.push_back({.keyword_name = ";", .keyword_kind = LibCompiler::eKeywordKindEndInstr});
- kKeywords.push_back({.keyword_name = ":", .keyword_kind = LibCompiler::eKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "public:", .keyword_kind = LibCompiler::eKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "private:", .keyword_kind = LibCompiler::eKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "protected:", .keyword_kind = LibCompiler::eKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "final", .keyword_kind = LibCompiler::eKeywordKindSpecifier});
- kKeywords.push_back({.keyword_name = "return", .keyword_kind = LibCompiler::eKeywordKindReturn});
- kKeywords.push_back({.keyword_name = "--*", .keyword_kind = LibCompiler::eKeywordKindCommentMultiLineStart});
- kKeywords.push_back({.keyword_name = "*/", .keyword_kind = LibCompiler::eKeywordKindCommentMultiLineStart});
- kKeywords.push_back({.keyword_name = "--/", .keyword_kind = LibCompiler::eKeywordKindCommentInline});
- kKeywords.push_back({.keyword_name = "==", .keyword_kind = LibCompiler::eKeywordKindEq});
- kKeywords.push_back({.keyword_name = "!=", .keyword_kind = LibCompiler::eKeywordKindNotEq});
- kKeywords.push_back({.keyword_name = ">=", .keyword_kind = LibCompiler::eKeywordKindGreaterEq});
- kKeywords.push_back({.keyword_name = "<=", .keyword_kind = LibCompiler::eKeywordKindLessEq});
+ kKeywords.push_back({.keyword_name = "if", .keyword_kind = LibCompiler::kKeywordKindIf});
+ kKeywords.push_back({.keyword_name = "else", .keyword_kind = LibCompiler::kKeywordKindElse});
+ kKeywords.push_back({.keyword_name = "else if", .keyword_kind = LibCompiler::kKeywordKindElseIf});
+
+ kKeywords.push_back({.keyword_name = "class", .keyword_kind = LibCompiler::kKeywordKindClass});
+ kKeywords.push_back({.keyword_name = "struct", .keyword_kind = LibCompiler::kKeywordKindClass});
+ kKeywords.push_back({.keyword_name = "namespace", .keyword_kind = LibCompiler::kKeywordKindNamespace});
+ kKeywords.push_back({.keyword_name = "typedef", .keyword_kind = LibCompiler::kKeywordKindTypedef});
+ kKeywords.push_back({.keyword_name = "using", .keyword_kind = LibCompiler::kKeywordKindTypedef});
+ kKeywords.push_back({.keyword_name = "{", .keyword_kind = LibCompiler::kKeywordKindBodyStart});
+ kKeywords.push_back({.keyword_name = "}", .keyword_kind = LibCompiler::kKeywordKindBodyEnd});
+ kKeywords.push_back({.keyword_name = "auto", .keyword_kind = LibCompiler::kKeywordKindVariable});
+ kKeywords.push_back({.keyword_name = "int", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "bool", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "short", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "char", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "long", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "float", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "double", .keyword_kind = LibCompiler::kKeywordKindType});
+ kKeywords.push_back({.keyword_name = "void", .keyword_kind = LibCompiler::kKeywordKindType});
+
+ kKeywords.push_back({.keyword_name = "auto*", .keyword_kind = LibCompiler::kKeywordKindVariablePtr});
+ kKeywords.push_back({.keyword_name = "int*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "unsigned*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "short*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "char*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "long*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "float*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "double*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+ kKeywords.push_back({.keyword_name = "void*", .keyword_kind = LibCompiler::kKeywordKindTypePtr});
+
+ kKeywords.push_back({.keyword_name = "(", .keyword_kind = LibCompiler::kKeywordKindFunctionStart});
+ kKeywords.push_back({.keyword_name = ")", .keyword_kind = LibCompiler::kKeywordKindFunctionEnd});
+ kKeywords.push_back({.keyword_name = "=", .keyword_kind = LibCompiler::kKeywordKindVariableAssign});
+ kKeywords.push_back({.keyword_name = "+=", .keyword_kind = LibCompiler::kKeywordKindVariableInc});
+ kKeywords.push_back({.keyword_name = "-=", .keyword_kind = LibCompiler::kKeywordKindVariableDec});
+ kKeywords.push_back({.keyword_name = "const", .keyword_kind = LibCompiler::kKeywordKindConstant});
+ kKeywords.push_back({.keyword_name = "*", .keyword_kind = LibCompiler::kKeywordKindPtr});
+ kKeywords.push_back({.keyword_name = "->", .keyword_kind = LibCompiler::kKeywordKindPtrAccess});
+ kKeywords.push_back({.keyword_name = ".", .keyword_kind = LibCompiler::kKeywordKindAccess});
+ kKeywords.push_back({.keyword_name = ",", .keyword_kind = LibCompiler::kKeywordKindArgSeparator});
+ kKeywords.push_back({.keyword_name = ";", .keyword_kind = LibCompiler::kKeywordKindEndInstr});
+ kKeywords.push_back({.keyword_name = ":", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
+ kKeywords.push_back({.keyword_name = "public:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
+ kKeywords.push_back({.keyword_name = "private:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
+ kKeywords.push_back({.keyword_name = "protected:", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
+ kKeywords.push_back({.keyword_name = "final", .keyword_kind = LibCompiler::kKeywordKindSpecifier});
+ kKeywords.push_back({.keyword_name = "return", .keyword_kind = LibCompiler::kKeywordKindReturn});
+ kKeywords.push_back({.keyword_name = "--*", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineStart});
+ kKeywords.push_back({.keyword_name = "*/", .keyword_kind = LibCompiler::kKeywordKindCommentMultiLineStart});
+ kKeywords.push_back({.keyword_name = "--/", .keyword_kind = LibCompiler::kKeywordKindCommentInline});
+ kKeywords.push_back({.keyword_name = "==", .keyword_kind = LibCompiler::kKeywordKindEq});
+ kKeywords.push_back({.keyword_name = "!=", .keyword_kind = LibCompiler::kKeywordKindNotEq});
+ kKeywords.push_back({.keyword_name = ">=", .keyword_kind = LibCompiler::kKeywordKindGreaterEq});
+ kKeywords.push_back({.keyword_name = "<=", .keyword_kind = LibCompiler::kKeywordKindLessEq});
kFactory.Mount(new AssemblyCPlusPlusInterface());
kCompilerFrontend = new CompilerFrontendCPlusPlus();
diff --git a/dev/LibCompiler/src/CPlusPlusLinkerELF.cc b/dev/LibCompiler/src/CPlusPlusLinkerELF.cc
new file mode 100644
index 0000000..5b85afc
--- /dev/null
+++ b/dev/LibCompiler/src/CPlusPlusLinkerELF.cc
@@ -0,0 +1,92 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024 Theater Quality Corp, all rights reserved
+
+ @file DynamicLinker64PEF.cc
+ @brief: C++ 64-Bit PEF Linker.
+
+------------------------------------------- */
+
+/// @author EL Mahrouss Amlal (amlel)
+/// @brief TQ 64-bit PEF Linker.
+/// Last Rev: Sat Feb 24 CET 2024
+/// @note Do not look up for anything with .code64/.data64/.zero64!
+/// It will be loaded when the program loader will start the image.
+
+//! Toolchain Kit.
+#include <LibCompiler/Defines.h>
+
+#include <LibCompiler/NFC/ErrorID.h>
+
+//! Assembler Kit
+#include <LibCompiler/AAL/AssemblyInterface.h>
+
+//! Preferred Executable Format
+#include <LibCompiler/NFC/XCOFF.h>
+#include <LibCompiler/UUID.h>
+
+//! Release macros.
+#include <LibCompiler/Version.h>
+
+//! Advanced Executable Object Format.
+#include <LibCompiler/NFC/AE.h>
+#include <cstdint>
+
+#define kLinkerVersionStr "TQ 64-Bit Linker (ELF) %s, (c) Theater Quality Corp. 2024, all rights reserved.\n"
+
+#define MemoryCopy(DST, SRC, SZ) memcpy(DST, SRC, SZ)
+#define StringCompare(DST, SRC) strcmp(DST, SRC)
+
+#define kPefNoCpu 0U
+#define kPefNoSubCpu 0U
+
+#define kWhite "\e[0;97m"
+
+#define kStdOut (std::cout << kWhite << "ld64: ")
+
+#define kLinkerDefaultOrigin kPefBaseOrigin
+#define kLinkerId (0x5046FF)
+#define kLinkerAbiContainer "Container:ABI:"
+
+/// @brief PEF stack size symbol.
+#define kLinkerStackSizeSymbol "SizeOfReserveStack"
+
+namespace Details
+{
+struct DynamicLinkerBlob final
+{
+ std::vector<CharType> fPefBlob; // PEF code/bss/data blob.
+ std::uintptr_t fAEOffset; // the offset of the PEF container header..
+};
+}
+
+enum
+{
+ kABITypeStart = 0x1010, /* Invalid ABI start of ABI list. */
+ kABITypeZKA = 0x5046, /* PF (ZKA PEF ABI) */
+ kABITypeInvalid = 0xFFFF,
+};
+
+static Bool kFatBinaryEnable = false;
+static Bool kStartFound = false;
+static Bool kDuplicateSymbols = false;
+static Bool kVerbose = false;
+
+/* object code and list. */
+static std::vector<LibCompiler::String> kObjectList;
+static std::vector<Details::DynamicLinkerBlob> kObjectBytes;
+
+static uintptr_t kMIBCount = 8;
+static uintptr_t kByteCount = 1024;
+
+#define kPrintF printf
+#define kLinkerSplash() kPrintF(kWhite kLinkerVersionStr, kDistVersion)
+
+/// @brief ZKA 64-bit Linker.
+/// @note This linker is made for XCOFF executable, thus ZKA based OSes.
+TOOLCHAINKIT_MODULE(DynamicLinker64XCOFF)
+{
+ return EXIT_SUCCESS;
+}
+
+// Last rev 13-1-24
diff --git a/dev/LibCompiler/src/DynamicLinker64PEF.cc b/dev/LibCompiler/src/CPlusPlusLinkerPEF.cc
index aaab9b6..2e5e40b 100644
--- a/dev/LibCompiler/src/DynamicLinker64PEF.cc
+++ b/dev/LibCompiler/src/CPlusPlusLinkerPEF.cc
@@ -32,7 +32,7 @@
#include <LibCompiler/NFC/AE.h>
#include <cstdint>
-#define kLinkerVersionStr "TQ 64-Bit Linker %s, (c) Theater Quality Corp. 2024, all rights reserved.\n"
+#define kLinkerVersionStr "TQ 64-Bit Linker (Preferred Executable) %s, (c) Theater Quality Corp. 2024, all rights reserved.\n"
#define MemoryCopy(DST, SRC, SZ) memcpy(DST, SRC, SZ)
#define StringCompare(DST, SRC) strcmp(DST, SRC)
diff --git a/dev/LibCompiler/src/Detail/ClUtils.h b/dev/LibCompiler/src/Detail/ClUtils.h
index 5d3ff79..393a3cc 100644
--- a/dev/LibCompiler/src/Detail/ClUtils.h
+++ b/dev/LibCompiler/src/Detail/ClUtils.h
@@ -12,3 +12,7 @@
#define kZero64Section ".zero64"
#define kCode64Section ".code64"
#define kData64Section ".data64"
+
+#define kZero128Section ".zero128"
+#define kCode128Section ".code128"
+#define kData128Section ".data128"