diff --git a/CMakeLists.txt b/CMakeLists.txt index b3adb80..eb36860 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,29 @@ add_library(Arctyx SHARED include/arctyx/compiler/Keyword.h include/arctyx/compiler/Symbol.h src/compiler/Symbol.cpp + src/x64Arch.cpp + include/arctyx/compiler/Primitive.h + src/compiler/Primitive.cpp + include/arctyx/compiler/Register.h + src/compiler/Register.cpp + include/arctyx/compiler/Operator.h + src/compiler/Operator.cpp +) + +add_library(x64Arch SHARED + src/x64Arch.cpp +) + +set_target_properties(x64Arch PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins/architectures" +) + +add_library(ArctyxLang SHARED + src/ArctyxLang.cpp +) + +set_target_properties(ArctyxLang PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins/languages" ) add_executable(ArctyxTools @@ -72,4 +95,6 @@ elseif (IS_OS_WINDOWS) target_link_libraries(Arctyx PUBLIC EHS_Dyn) endif() +target_link_libraries(x64Arch PRIVATE Arctyx) +target_link_libraries(ArctyxLang PRIVATE Arctyx) target_link_libraries(ArctyxTools PRIVATE Arctyx) \ No newline at end of file diff --git a/include/arctyx/Arctyx.h b/include/arctyx/Arctyx.h index db3528d..6c958b5 100644 --- a/include/arctyx/Arctyx.h +++ b/include/arctyx/Arctyx.h @@ -1,10 +1,19 @@ #pragma once +#include #include +#include class EHS_LIB_IO Arctyx { private: + static ehs::Array plugins; + + static void LoadArchitecturePlugins(); + + static void LoadLanguagePlugins(); + +public: static void Initialize(); static void Uninitialize(); diff --git a/include/arctyx/compiler/Architecture.h b/include/arctyx/compiler/Architecture.h index e6f4cfd..162767c 100644 --- a/include/arctyx/compiler/Architecture.h +++ b/include/arctyx/compiler/Architecture.h @@ -2,6 +2,7 @@ #include +#include "Register.h" #include "Instruction.h" class EHS_LIB_IO Architecture @@ -11,6 +12,7 @@ private: ehs::UInt_64 id; ehs::Str_8 name; + ehs::Array registers; ehs::Array instructions; static ehs::Array architectures; @@ -32,6 +34,16 @@ public: ehs::Str_8 GetName() const; + bool HasRegister(const ehs::UInt_64 &id) const; + + bool HasRegister(const ehs::Str_8 &name) const; + + const Register *GetRegister(const ehs::UInt_64 &id) const; + + const Register *GetRegister(const ehs::Str_8 &name) const; + + bool AddRegister(Register reg); + bool HasInstruction(const ehs::UInt_64 &id) const; bool HasInstruction(const ehs::Str_8 &name) const; @@ -51,4 +63,4 @@ public: static const Architecture *Get(const ehs::Str_8 &name); static bool Add(Architecture arc); -}; \ No newline at end of file +}; diff --git a/include/arctyx/compiler/Compiler.h b/include/arctyx/compiler/Compiler.h index 34e2593..5df8c67 100644 --- a/include/arctyx/compiler/Compiler.h +++ b/include/arctyx/compiler/Compiler.h @@ -17,5 +17,28 @@ private: public: Compiler(); - Compiler(const Architecture *arch, const Language *lang); + Compiler(const ehs::Str_8 &arch, const ehs::Str_8 &lang); + + Compiler(Compiler &&other) noexcept; + + Compiler(const Compiler &other); + + Compiler &operator=(Compiler &&other) noexcept; + + Compiler &operator=(const Compiler &other); + + ehs::Array Compile(const ehs::Str_8 &code) const; + +private: + static bool IsSeparator(const ehs::Array &separators, const ehs::Char_8 *c); + + static bool IsPrimitive(const ehs::Array &primitives, const ehs::Str_8 &value); + + static bool IsKeyword(const ehs::Array &keywords, const ehs::Str_8 &value); + + static const Operator *IsOperator(const ehs::Array &operators, const ehs::Str_8 &value); + + Token ParseValue(const ehs::Array &primitives, const ehs::Array &keywords, const ehs::Array &operators, const ehs::Str_8 &value) const; + + ehs::Vector Parse(const ehs::Str_8 &code) const; }; \ No newline at end of file diff --git a/include/arctyx/compiler/Instruction.h b/include/arctyx/compiler/Instruction.h index 85014db..651a480 100644 --- a/include/arctyx/compiler/Instruction.h +++ b/include/arctyx/compiler/Instruction.h @@ -1,9 +1,18 @@ #pragma once +#include +#include #include #include +#include "Token.h" + +class Instruction; class Architecture; +class Compiler; +class Language; + +typedef ehs::Serializer (*TranslateIns)(const Instruction *, const ehs::Byte *); class EHS_LIB_IO Instruction { @@ -13,23 +22,12 @@ private: Architecture *arch; ehs::UInt_64 id; ehs::Str_8 name; - ehs::UInt_8 size; - ehs::Byte *code; + TranslateIns translation; public: - ~Instruction(); - Instruction(); - Instruction(ehs::Str_8 name, const ehs::UInt_8 &size, ehs::Byte *code); - - Instruction(ehs::Str_8 name, const ehs::UInt_64 &code); - - Instruction(ehs::Str_8 name, const ehs::UInt_32 &code); - - Instruction(ehs::Str_8 name, const ehs::UInt_16 &code); - - Instruction(ehs::Str_8 name, const ehs::UInt_8 &code); + Instruction(ehs::Str_8 name); Instruction(Instruction &&ins) noexcept; @@ -45,7 +43,32 @@ public: ehs::Str_8 GetName() const; - ehs::UInt_8 GetSize() const; + void SetTranslation(TranslateIns newTranslation); - ehs::Byte *GetCode() const; + ehs::Serializer Translate(const ehs::Byte *data) const; }; + +struct AssignBase +{ + const ehs::UInt_8 type = 0; +}; + +struct AssignRR +{ + AssignBase base = { + 1 + }; + bool isDstAddress = false; + ehs::UInt_64 dstReg = 0; + bool isSrcAddress = false; + ehs::UInt_64 srcReg = 0; +}; + +struct AssignRI +{ + AssignBase base = { + 2 + }; + ehs::UInt_64 dstReg = 0; + ehs::UInt_64 srcImm = 0; +}; \ No newline at end of file diff --git a/include/arctyx/compiler/Language.h b/include/arctyx/compiler/Language.h index c32aa0e..0f17a35 100644 --- a/include/arctyx/compiler/Language.h +++ b/include/arctyx/compiler/Language.h @@ -6,6 +6,8 @@ #include #include "Interpretation.h" +#include "Operator.h" +#include "Primitive.h" class EHS_LIB_IO Language { @@ -17,6 +19,9 @@ private: ehs::Version version; ehs::Char_8 eol; ehs::Array separators; + ehs::Array primitives; + ehs::Array keywords; + ehs::Array operators; ehs::Array interpretations; static ehs::Array languages; @@ -50,6 +55,33 @@ public: bool AddSeparator(const ehs::Char_8 &separator); + ehs::Array GetPrimitives() const; + + bool HasPrimitive(const ehs::UInt_64 &id) const; + + bool HasPrimitive(const ehs::Str_8 &name) const; + + const Primitive *GetPrimitive(const ehs::UInt_64 &id) const; + + const Primitive *GetPrimitive(const ehs::Str_8 &name) const; + + bool AddPrimitive(Primitive primitive); + + ehs::Array GetKeywords() const; + + bool HasKeyword(const ehs::Str_8 &keyword) const; + + bool AddKeyword(const ehs::Str_8 &keyword); + + ehs::Array GetOperators() const; + + bool HasOperator(const ehs::Str_8 &delimeter) const; + + + const Operator *GetOperator(const ehs::Str_8 &delimeter) const; + + bool AddOperator(Operator primitive); + ehs::Array GetInterpretations() const; bool HasInterpretation(const TokenT &type, const ehs::Str_8 &name) const; diff --git a/include/arctyx/compiler/Operator.h b/include/arctyx/compiler/Operator.h new file mode 100644 index 0000000..0f41d4a --- /dev/null +++ b/include/arctyx/compiler/Operator.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include + +class Operator +{ +private: + bool unary; + ehs::Str_8 delimeter; + ehs::UInt_64 instructionId; + ehs::Str_8 instructionName; + +public: + Operator(); + + Operator(ehs::Str_8 delimeter, ehs::Str_8 instructionName); + + Operator(Operator &&other) noexcept; + + Operator(const Operator &other); + + Operator &operator=(Operator &&other) noexcept; + + Operator &operator=(const Operator &other); + + bool IsUnary() const; + + ehs::Str_8 GetDelimeter() const; + + ehs::UInt_64 GetInstructionId() const; + + ehs::Str_8 GetInstructionName() const; +}; diff --git a/include/arctyx/compiler/Primitive.h b/include/arctyx/compiler/Primitive.h new file mode 100644 index 0000000..b1fa55d --- /dev/null +++ b/include/arctyx/compiler/Primitive.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +enum class Signedness : ehs::UInt_8 +{ + UNSIGNED, + SIGNED +}; + +class Primitive +{ +private: + ehs::UInt_64 id; + ehs::Str_8 name; + ehs::UInt_8 byteDepth; + Signedness signedness; + +public: + Primitive(); + + Primitive(ehs::Str_8 name, const ehs::UInt_8 &byteDepth, const Signedness &signedness); + + Primitive(Primitive &&other) noexcept; + + Primitive(const Primitive &other); + + Primitive &operator=(Primitive &&other) noexcept; + + Primitive &operator=(const Primitive &other); + + ehs::UInt_64 GetId() const; + + ehs::Str_8 GetName() const; + + ehs::UInt_8 GetByteDepth() const; + + Signedness GetSignedness() const; +}; diff --git a/include/arctyx/compiler/Register.h b/include/arctyx/compiler/Register.h new file mode 100644 index 0000000..2131ca7 --- /dev/null +++ b/include/arctyx/compiler/Register.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +class Register +{ +private: + ehs::UInt_64 id; + ehs::Str_8 name; + ehs::UInt_32 byteDepth; + ehs::UInt_64 code;; + +public: + Register(); + + Register(ehs::Str_8 name, const ehs::UInt_64 &byteDepth, const ehs::UInt_64 &code); + + Register(Register &&other) noexcept; + + Register(const Register &other); + + Register &operator=(Register &&other) noexcept; + + Register &operator=(const Register &other); + + bool operator==(const ehs::Str_8 &otherName) const; + + bool operator!=(const ehs::Str_8 &otherName) const; + + bool operator==(const ehs::UInt_64 &otherId) const; + + bool operator!=(const ehs::UInt_64 &otherId) const; + + ehs::UInt_64 GetId() const; + + ehs::Str_8 GetName() const; + + ehs::UInt_8 GetByteDepth() const; + + ehs::UInt_64 GetCode() const; +}; diff --git a/include/arctyx/compiler/Token.h b/include/arctyx/compiler/Token.h index 6526c62..d9be08c 100644 --- a/include/arctyx/compiler/Token.h +++ b/include/arctyx/compiler/Token.h @@ -7,9 +7,11 @@ enum class TokenT : ehs::UInt_8 UNKNOWN, VALUE, KEYWORD, + TYPE, IDENTIFIER, UNARY_OPERATOR, - COMPOUND_OPERATOR + COMPOUND_OPERATOR, + EOL }; class EHS_LIB_IO Token diff --git a/src/Arctyx.cpp b/src/Arctyx.cpp index d51037a..4d58eb7 100644 --- a/src/Arctyx.cpp +++ b/src/Arctyx.cpp @@ -1,19 +1,106 @@ #include "arctyx/Arctyx.h" #include +#include #include +#include +#include +#include #include "arctyx/compiler/Architecture.h" #include "arctyx/compiler/Language.h" #include "arctyx/compiler/Token.h" +ehs::Array Arctyx::plugins; + +typedef bool (*InitializePlugin)(); +typedef ehs::Str_8 (*GetPluginName)(); +typedef ehs::Version (*GetPluginVersion)(); +typedef bool (*ShutdownPlugin)(); + +void Arctyx::LoadArchitecturePlugins() +{ +#if defined(EHS_OS_LINUX) + const ehs::Str_8 delimeter = ".so"; +#elif defined(EHS_OS_WINDOWS) + const ehs::Str_8 delimeter = ".dll"; +#endif + + ehs::Array files = ehs::Directory::GetAllFiles("plugins/architectures"); + for (ehs::UInt_64 i = 0; i < files.Size(); ++i) + { + if (!files[i].Find(delimeter, nullptr, ehs::SearchPattern::RIGHT_LEFT)) + continue; + + ehs::Open plugin("plugins/architectures/" + files[i]); + InitializePlugin initFunc = (InitializePlugin)plugin.Retrieve("_Z16InitializePluginv"); + GetPluginName nameFunc = (GetPluginName)plugin.Retrieve("_Z13GetPluginNamev"); + GetPluginVersion verFunc = (GetPluginVersion)plugin.Retrieve("_Z16GetPluginVersionv"); + + ehs::Str_8 pluginName = nameFunc(); + ehs::Version pluginVersion = verFunc(); + + if (!initFunc()) + { + ehs::Console::Write_8("Failed to initialize plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + + continue; + } + + ehs::Console::Write_8("Successfully initialized plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + + plugins.Push((ehs::Open &&)plugin); + } +} + +void Arctyx::LoadLanguagePlugins() +{ + #if defined(EHS_OS_LINUX) + const ehs::Str_8 delimeter = ".so"; + #elif defined(EHS_OS_WINDOWS) + const ehs::Str_8 delimeter = ".dll"; + #endif + + ehs::Array files = ehs::Directory::GetAllFiles("plugins/languages"); + for (ehs::UInt_64 i = 0; i < files.Size(); ++i) + { + if (!files[i].Find(delimeter, nullptr, ehs::SearchPattern::RIGHT_LEFT)) + continue; + + ehs::Open plugin("plugins/languages/" + files[i]); + InitializePlugin initFunc = (InitializePlugin)plugin.Retrieve("_Z16InitializePluginv"); + GetPluginName nameFunc = (GetPluginName)plugin.Retrieve("_Z13GetPluginNamev"); + GetPluginVersion verFunc = (GetPluginVersion)plugin.Retrieve("_Z16GetPluginVersionv"); + + ehs::Str_8 pluginName = nameFunc(); + ehs::Version pluginVersion = verFunc(); + + if (!initFunc()) + { + ehs::Console::Write_8("Failed to initialize plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + + continue; + } + + ehs::Console::Write_8("Successfully initialized plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + + plugins.Push((ehs::Open &&)plugin); + } +} + void Arctyx::Initialize() { + LoadArchitecturePlugins(); + LoadLanguagePlugins(); } void Arctyx::Uninitialize() { - for (ehs::Size i = 0; Architecture::architectures.Size(); ++i) + for (ehs::Size i = 0; i < Architecture::architectures.Size(); ++i) delete Architecture::architectures[i]; Architecture::architectures.Clear(); @@ -22,4 +109,25 @@ void Arctyx::Uninitialize() delete Language::languages[i]; Language::languages.Clear(); + + for (ehs::UInt_64 i = 0; i < plugins.Size(); ++i) + { + GetPluginName nameFunc = (GetPluginName)plugins[i].Retrieve("_Z13GetPluginNamev"); + GetPluginVersion verFunc = (GetPluginVersion)plugins[i].Retrieve("_Z16GetPluginVersionv"); + ShutdownPlugin shutFunc = (ShutdownPlugin)plugins[i].Retrieve("_Z14ShutdownPluginv"); + + ehs::Str_8 pluginName = nameFunc(); + ehs::Version pluginVersion = verFunc(); + + if (!shutFunc) + { + ehs::Console::Write_8("Failed to shutdown plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + } + + ehs::Console::Write_8("successfully shutdown plugin " + pluginName + " v" + pluginVersion.major + "." + + pluginVersion.minor + "." + pluginVersion.patch); + } + + plugins.Clear(); } diff --git a/src/ArctyxLang.cpp b/src/ArctyxLang.cpp new file mode 100644 index 0000000..462d843 --- /dev/null +++ b/src/ArctyxLang.cpp @@ -0,0 +1,56 @@ +#include +#include + +#include "arctyx/Arctyx.h" +#include "arctyx/compiler/Architecture.h" +#include "arctyx/compiler/Language.h" + +ehs::Version GetPluginVersion(); + +bool InitializePlugin() +{ + const Architecture *x64 = Architecture::Get("x64"); + if (!x64) + return false; + + Language arctyx("Arctyx", GetPluginVersion()); + + arctyx.AddSeparator(' '); + arctyx.AddSeparator('\t'); + + arctyx.SetEOL('\n'); + + arctyx.AddPrimitive({"Byte", 1, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"Char_8", 1, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"Char_16", 2, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"Char_32", 4, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"UInt_8", 1, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"UInt_16", 2, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"UInt_32", 4, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"UInt_64", 8, Signedness::UNSIGNED}); + arctyx.AddPrimitive({"SInt_8", 1, Signedness::SIGNED}); + arctyx.AddPrimitive({"SInt_16", 2, Signedness::SIGNED}); + arctyx.AddPrimitive({"SInt_32", 4, Signedness::SIGNED}); + arctyx.AddPrimitive({"SInt_64", 8, Signedness::SIGNED}); + + arctyx.AddOperator({"=", "Assign"}); + + Language::Add((Language &&)arctyx); + + return true; +} + +ehs::Str_8 GetPluginName() +{ + return "Arctyx Language"; +} + +ehs::Version GetPluginVersion() +{ + return {1, 0, 0}; +} + +bool ShutdownPlugin() +{ + return true; +} \ No newline at end of file diff --git a/src/compiler/Architecture.cpp b/src/compiler/Architecture.cpp index 192c33f..9994a34 100644 --- a/src/compiler/Architecture.cpp +++ b/src/compiler/Architecture.cpp @@ -13,14 +13,15 @@ Architecture::Architecture(ehs::Str_8 name) } Architecture::Architecture(Architecture &&arch) noexcept - : id(arch.id), name((ehs::Str_8 &&)arch.name), instructions((ehs::Array &&)arch.instructions) + : id(arch.id), name((ehs::Str_8 &&)arch.name), registers((ehs::Array &&)arch.registers), + instructions((ehs::Array &&)arch.instructions) { for (ehs::Size i = 0; i < instructions.Size(); ++i) instructions[i].arch = this; } Architecture::Architecture(const Architecture &arc) - : id(arc.id), name(arc.name), instructions(arc.instructions) + : id(arc.id), name(arc.name), registers(arc.registers), instructions(arc.instructions) { for (ehs::Size i = 0; i < instructions.Size(); ++i) instructions[i].arch = this; @@ -33,6 +34,7 @@ Architecture & Architecture::operator=(Architecture &&arc) noexcept id = arc.id; name = (ehs::Str_8 &&)arc.name; + registers = (ehs::Array &&)arc.registers; instructions = (ehs::Array &&)arc.instructions; for (ehs::Size i = 0; i < instructions.Size(); ++i) @@ -50,6 +52,7 @@ Architecture & Architecture::operator=(const Architecture &arc) id = arc.id; name = arc.name; + registers = arc.registers; instructions = arc.instructions; for (ehs::Size i = 0; i < instructions.Size(); ++i) @@ -68,6 +71,44 @@ ehs::Str_8 Architecture::GetName() const return name; } +bool Architecture::HasRegister(const ehs::UInt_64& id) const +{ + for (ehs::UInt_64 i = 0; i < registers.Size(); ++i) + if (registers[i].GetId() == id) + return true; + + return false; +} + +bool Architecture::HasRegister(const ehs::Str_8& name) const +{ + return HasRegister(name.Hash_64()); +} + +const Register* Architecture::GetRegister(const ehs::UInt_64& id) const +{ + for (ehs::UInt_64 i = 0; i < registers.Size(); ++i) + if (registers[i].GetId() == id) + return ®isters[i]; + + return nullptr; +} + +const Register* Architecture::GetRegister(const ehs::Str_8& name) const +{ + return GetRegister(name.Hash_64()); +} + +bool Architecture::AddRegister(Register reg) +{ + if (HasRegister(reg.GetId())) + return false; + + registers.Push((Register &&)reg); + + return true; +} + bool Architecture::HasInstruction(const ehs::UInt_64 &id) const { for (ehs::UInt_64 i = 0; i < instructions.Size(); ++i) diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp index 85df818..c9a2c28 100644 --- a/src/compiler/Compiler.cpp +++ b/src/compiler/Compiler.cpp @@ -1 +1,186 @@ #include "arctyx/compiler/Compiler.h" + +Compiler::Compiler() + : architecture(nullptr), language(nullptr) +{ +} + +Compiler::Compiler(const ehs::Str_8& arch, const ehs::Str_8& lang) +{ + architecture = Architecture::Get(arch); + if (!architecture) + { + EHS_LOG(ehs::LogType::ERR, 0, "The Architecture, \"" + arch + "\" is not supported."); + return; + } + + language = Language::Get(lang); + if (!language) + { + EHS_LOG(ehs::LogType::ERR, 0, "The Language, \"" + lang + "\" is not supported."); + return; + } + + EHS_LOG_SUCCESS(); +} + +Compiler::Compiler(Compiler&& other) noexcept + : architecture(other.architecture), language(other.language), symbols((ehs::Array &&)other.symbols) +{ + other.architecture = nullptr; + other.language = nullptr; +} + +Compiler::Compiler(const Compiler& other) + : architecture(other.architecture), language(other.language), symbols(other.symbols) +{ +} + +Compiler& Compiler::operator=(Compiler&& other) noexcept +{ + if (this == &other) + return *this; + + architecture = other.architecture; + language = other.language; + symbols = (ehs::Array &&)other.symbols; + + other.architecture = nullptr; + other.language = nullptr; + + return *this; +} + +Compiler& Compiler::operator=(const Compiler& other) +{ + if (this == &other) + return *this; + + architecture = other.architecture; + language = other.language; + symbols = other.symbols; + + return *this; +} + +ehs::Array Compiler::Compile(const ehs::Str_8 &code) const +{ + ehs::Vector tokens = Parse(code); + + ehs::Array machineCode; + + return machineCode; +} + +bool Compiler::IsSeparator(const ehs::Array &separators, const ehs::Char_8 *c) +{ + for (ehs::UInt_64 s = 0; s < separators.Size(); ++s) + if (*c == separators[s]) + return true; + + return false; +} + +bool Compiler::IsPrimitive(const ehs::Array& primitives, const ehs::Str_8& value) +{ + for (ehs::UInt_64 i = 0; i < primitives.Size(); ++i) + if (value == primitives[i].GetName()) + return true; + + return false; +} + +bool Compiler::IsKeyword(const ehs::Array& keywords, const ehs::Str_8& value) +{ + for (ehs::UInt_64 i = 0; i < keywords.Size(); ++i) + if (value == keywords[i]) + return true; + + return false; +} + +const Operator *Compiler::IsOperator(const ehs::Array& operators, const ehs::Str_8& value) +{ + for (ehs::UInt_64 i = 0; i < operators.Size(); ++i) + if (value == operators[i].GetDelimeter()) + return &operators[i]; + + return nullptr; +} + +Token Compiler::ParseValue(const ehs::Array &primitives, const ehs::Array &keywords, const ehs::Array &operators, const ehs::Str_8& value) const +{ + if (IsPrimitive(primitives, value)) + return {TokenT::TYPE, value}; + + if (IsKeyword(keywords, value)) + return {TokenT::KEYWORD, value}; + + const Operator *op = IsOperator(operators, value); + if (op) + { + if (op->IsUnary()) + return {TokenT::UNARY_OPERATOR, value}; + else + return {TokenT::COMPOUND_OPERATOR, value}; + } + + if (value[0] >= '0' && value[0] <= '9') + return {TokenT::VALUE, value}; + + return {TokenT::IDENTIFIER, value}; +} + +ehs::Vector Compiler::Parse(const ehs::Str_8 &code) const +{ + ehs::Vector tokens; + + const ehs::Array separators = language->GetSeparators(); + const ehs::Array primitives = language->GetPrimitives(); + const ehs::Array keywords = language->GetKeywords(); + const ehs::Array operators = language->GetOperators(); + + for (ehs::Char_8 *i = &code[0], *start = i; i < &code[code.Size()]; ++i) + { + if (*i == language->GetEOL()) + { + if (start != i) + tokens.Push(ParseValue(primitives, keywords, operators, ehs::Str_8(start, i - start))); + + tokens.Push({TokenT::EOL, {i, 1}}); + + start = i + 1; + + continue; + } + + if (*start == '\"') + { + if (i != start && *i == '\"') + { + tokens.Push({TokenT::VALUE, {start, (ehs::UInt_64)(i - (start - 1))}}); + + start = i + 1; + + continue; + } + + continue; + } + + if (!IsSeparator(separators, i)) + continue; + + if (i - (start - 1) == 1 && IsSeparator(separators, start)) + { + start = i + 1; + continue; + } + + tokens.Push(ParseValue(primitives, keywords, operators, ehs::Str_8(start, i - start))); + + start = i + 1; + } + + return tokens; +} diff --git a/src/compiler/Instruction.cpp b/src/compiler/Instruction.cpp index 8922d8c..d4912d8 100644 --- a/src/compiler/Instruction.cpp +++ b/src/compiler/Instruction.cpp @@ -1,57 +1,26 @@ #include "arctyx/compiler/Instruction.h" -Instruction::~Instruction() -{ - delete code; -} - Instruction::Instruction() - : arch(nullptr), id(0), size(0), code(nullptr) + : arch(nullptr), id(0), translation(nullptr) { } -Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_8 &size, ehs::Byte *code) - : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(size), code(code) +Instruction::Instruction(ehs::Str_8 name) + : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), translation(nullptr) { } -Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_64 &code) - : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size]) -{ - *(ehs::UInt_64 *)this->code = code; -} - -Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_32 &code) - : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size]) -{ - *(ehs::UInt_32 *)this->code = code; -} - -Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_16 &code) - : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size]) -{ - *(ehs::UInt_16 *)this->code = code; -} - -Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_8 &code) - : arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size]) -{ - *this->code = code; -} - Instruction::Instruction(Instruction &&ins) noexcept - : arch(ins.arch), id(ins.id), name((ehs::Str_8 &&)ins.name), size(ins.size), code(ins.code) + : arch(ins.arch), id(ins.id), name((ehs::Str_8 &&)ins.name), translation(ins.translation) { ins.arch = nullptr; ins.id = 0; - ins.size = 0; - ins.code = nullptr; + ins.translation = nullptr; } Instruction::Instruction(const Instruction &ins) - : arch(nullptr), id(ins.id), name(ins.name), size(ins.size), code(new ehs::Byte[size]) + : arch(nullptr), id(ins.id), name(ins.name), translation(ins.translation) { - ehs::Util::Copy(code, ins.code, size); } Instruction &Instruction::operator=(Instruction &&ins) noexcept @@ -62,13 +31,11 @@ Instruction &Instruction::operator=(Instruction &&ins) noexcept arch = ins.arch; id = ins.id; name = (ehs::Str_8 &&)ins.name; - size = ins.size; - code = ins.code; + translation = ins.translation; ins.arch = nullptr; ins.id = 0; - ins.size = 0; - ins.code = nullptr; + ins.translation = nullptr; return *this; } @@ -81,10 +48,7 @@ Instruction &Instruction::operator=(const Instruction &ins) arch = nullptr; id = ins.id; name = ins.name; - size = ins.size; - code = new ehs::Byte[size]; - - ehs::Util::Copy(code, ins.code, size); + translation = ins.translation; return *this; } @@ -104,12 +68,15 @@ ehs::Str_8 Instruction::GetName() const return name; } -ehs::UInt_8 Instruction::GetSize() const +void Instruction::SetTranslation(TranslateIns newTranslation) { - return size; + translation = newTranslation; } -ehs::Byte *Instruction::GetCode() const +ehs::Serializer Instruction::Translate(const ehs::Byte* data) const { - return code; + if (!translation) + return {}; + + return translation(this, data); } diff --git a/src/compiler/Language.cpp b/src/compiler/Language.cpp index 5c11906..2881dbf 100644 --- a/src/compiler/Language.cpp +++ b/src/compiler/Language.cpp @@ -14,7 +14,8 @@ Language::Language(ehs::Str_8 name, const ehs::Version& version) Language::Language(Language&& lang) noexcept : id(lang.id), name((ehs::Str_8 &&)lang.name), version(lang.version), eol(lang.eol), - separators((ehs::Array &&)lang.separators), + separators((ehs::Array &&)lang.separators), primitives((ehs::Array &&)lang.primitives), + keywords((ehs::Array &&)lang.keywords), operators((ehs::Array &&)lang.operators), interpretations((ehs::Array &&)lang.interpretations) { lang.id = 0; @@ -24,6 +25,7 @@ Language::Language(Language&& lang) noexcept Language::Language(const Language& lang) : id(lang.id), name(lang.name), version(lang.version), eol(lang.eol), separators(lang.separators), + primitives(lang.primitives), keywords(lang.keywords), operators(lang.operators), interpretations(lang.interpretations) { } @@ -38,6 +40,9 @@ Language& Language::operator=(Language&& lang) noexcept version = lang.version; eol = lang.eol; separators = (ehs::Array &&)lang.separators; + primitives = (ehs::Array &&)lang.primitives; + keywords = (ehs::Array &&)lang.keywords; + operators = (ehs::Array &&)lang.operators; interpretations = (ehs::Array &&)lang.interpretations; lang.id = 0; @@ -57,6 +62,9 @@ Language& Language::operator=(const Language& lang) version = lang.version; eol = lang.eol; separators = lang.separators; + primitives = lang.primitives; + keywords = lang.keywords; + operators = lang.operators; interpretations = lang.interpretations; return *this; @@ -111,6 +119,106 @@ bool Language::AddSeparator(const ehs::Char_8& separator) return true; } +ehs::Array Language::GetPrimitives() const +{ + return primitives; +} + +bool Language::HasPrimitive(const ehs::UInt_64 &id) const +{ + for (ehs::Size i = 0; i < primitives.Size(); ++i) + if (primitives[i].GetId() == id) + return true; + + return false; +} + +bool Language::HasPrimitive(const ehs::Str_8 &name) const +{ + return HasPrimitive(name.Hash_64()); +} + +const Primitive *Language::GetPrimitive(const ehs::UInt_64 &id) const +{ + for (ehs::Size i = 0; i < primitives.Size(); ++i) + if (primitives[i].GetId() == id) + return &primitives[i]; + + return nullptr; +} + +const Primitive* Language::GetPrimitive(const ehs::Str_8 &name) const +{ + return GetPrimitive(name.Hash_64()); +} + +bool Language::AddPrimitive(Primitive primitive) +{ + if (HasPrimitive(primitive.GetId())) + return false; + + primitives.Push((Primitive &&)primitive); + + return true; +} + +ehs::Array Language::GetKeywords() const +{ + return keywords; +} + +bool Language::HasKeyword(const ehs::Str_8& keyword) const +{ + for (ehs::UInt_64 i = 0; i < keywords.Size(); ++i) + if (keywords[i] == keyword) + return true; + + return false; +} + +bool Language::AddKeyword(const ehs::Str_8& keyword) +{ + if (HasKeyword(keyword)) + return false; + + keywords.Push((ehs::Str_8 &&)keyword); + + return true; +} + +ehs::Array Language::GetOperators() const +{ + return operators; +} + +bool Language::HasOperator(const ehs::Str_8 &delimeter) const +{ + for (ehs::UInt_64 i = 0; i < operators.Size(); ++i) + if (operators[i].GetDelimeter() == delimeter) + return true; + + return false; +} + +const Operator* Language::GetOperator(const ehs::Str_8 &delimeter) const +{ + for (ehs::UInt_64 i = 0; i < operators.Size(); ++i) + if (operators[i].GetDelimeter() == delimeter) + return &operators[i]; + + return nullptr; +} + +bool Language::AddOperator(Operator primitive) +{ + if (HasOperator(primitive.GetDelimeter())) + return false; + + operators.Push((Operator &&)primitive); + + return true; +} + ehs::Array Language::GetInterpretations() const { return interpretations; diff --git a/src/compiler/Operator.cpp b/src/compiler/Operator.cpp new file mode 100644 index 0000000..9435faf --- /dev/null +++ b/src/compiler/Operator.cpp @@ -0,0 +1,75 @@ +#include "arctyx/compiler/Operator.h" + +Operator::Operator() + : instructionId(0) +{ +} + +Operator::Operator(ehs::Str_8 delimeter, ehs::Str_8 instructionName) + : unary(delimeter.Size() == 1), delimeter((ehs::Str_8 &&)delimeter), instructionId(instructionName.Hash_64()), + instructionName((ehs::Str_8 &&)instructionName) +{ +} + +Operator::Operator(Operator&& other) noexcept + : unary(other.unary), delimeter((ehs::Str_8 &&)other.delimeter), instructionId(other.instructionId), + instructionName((ehs::Str_8 &&)other.instructionName) +{ + other.unary = false; + other.instructionId = 0; +} + +Operator::Operator(const Operator& other) + : unary(other.unary), delimeter(other.delimeter), instructionId(other.instructionId), + instructionName(other.instructionName) +{ +} + +Operator& Operator::operator=(Operator&& other) noexcept +{ + if (this == &other) + return *this; + + unary = other.unary; + delimeter = (ehs::Str_8 &&)other.delimeter; + instructionId = other.instructionId; + instructionName = (ehs::Str_8 &&)other.instructionName; + + other.unary = false; + other.instructionId = 0; + + return *this; +} + +Operator& Operator::operator=(const Operator& other) +{ + if (this == &other) + return *this; + + unary = other.unary; + delimeter = other.delimeter; + instructionId = other.instructionId; + instructionName = other.instructionName; + + return *this; +} + +bool Operator::IsUnary() const +{ + return unary; +} + +ehs::Str_8 Operator::GetDelimeter() const +{ + return delimeter; +} + +ehs::UInt_64 Operator::GetInstructionId() const +{ + return instructionId; +} + +ehs::Str_8 Operator::GetInstructionName() const +{ + return instructionName; +} diff --git a/src/compiler/Primitive.cpp b/src/compiler/Primitive.cpp new file mode 100644 index 0000000..d7c414e --- /dev/null +++ b/src/compiler/Primitive.cpp @@ -0,0 +1,74 @@ +#include "arctyx/compiler/Primitive.h" + +Primitive::Primitive() + : id(0), byteDepth(0), signedness(Signedness::UNSIGNED) +{ +} + +Primitive::Primitive(ehs::Str_8 name, const ehs::UInt_8& byteDepth, const Signedness &signedness) + : id(name.Hash_64()), name((ehs::Str_8 &&)name), byteDepth(byteDepth), signedness(signedness) +{ +} + +Primitive::Primitive(Primitive&& other) noexcept + : id(other.id), name((ehs::Str_8 &&)other.name), byteDepth(other.byteDepth), signedness(other.signedness) +{ + other.id = 0; + other.byteDepth = 0; + other.signedness = Signedness::UNSIGNED; +} + +Primitive::Primitive(const Primitive& other) + : id(other.id), name(other.name), byteDepth(other.byteDepth), signedness(other.signedness) +{ +} + +Primitive& Primitive::operator=(Primitive&& other) noexcept +{ + if (this == &other) + return *this; + + id = other.id; + name = (ehs::Str_8 &&)other.name; + byteDepth = other.byteDepth; + signedness = other.signedness; + + other.id = 0; + other.byteDepth = 0; + other.signedness = Signedness::UNSIGNED; + + return *this; +} + +Primitive& Primitive::operator=(const Primitive& other) +{ + if (this == &other) + return *this; + + id = other.id; + name = other.name; + byteDepth = other.byteDepth; + signedness = other.signedness; + + return *this; +} + +ehs::UInt_64 Primitive::GetId() const +{ + return id; +} + +ehs::Str_8 Primitive::GetName() const +{ + return name; +} + +ehs::UInt_8 Primitive::GetByteDepth() const +{ + return byteDepth; +} + +Signedness Primitive::GetSignedness() const +{ + return signedness; +} diff --git a/src/compiler/Register.cpp b/src/compiler/Register.cpp new file mode 100644 index 0000000..35079c4 --- /dev/null +++ b/src/compiler/Register.cpp @@ -0,0 +1,94 @@ +#include "arctyx/compiler/Register.h" + +Register::Register() + : id(0), byteDepth(0) +{ +} + +Register::Register(ehs::Str_8 name, const ehs::UInt_64 &byteDepth, const ehs::UInt_64 &code) + : id(name.Hash_64()), name((ehs::Str_8 &&)name), byteDepth(byteDepth), code(code) +{ +} + +Register::Register(Register&& other) noexcept + : id(other.id), name((ehs::Str_8 &&)other.name), byteDepth(other.byteDepth), code(other.code) +{ + other.id = 0; + other.byteDepth = 0; + other.code = 0; +} + +Register::Register(const Register& other) + : id(other.id), name(other.name), byteDepth(other.byteDepth), code(other.code) +{ +} + +Register& Register::operator=(Register&& other) noexcept +{ + if (this == &other) + return *this; + + id = other.id; + name = (ehs::Str_8 &&)other.name; + byteDepth = other.byteDepth; + code = other.code; + + other.id = 0; + other.byteDepth = 0; + other.code = 0; + + return *this; +} + +Register& Register::operator=(const Register& other) +{ + if (this == &other) + return *this; + + id = other.id; + name = other.name; + byteDepth = other.byteDepth; + code = other.code; + + return *this; +} + +bool Register::operator==(const ehs::Str_8& otherName) const +{ + return name == otherName; +} + +bool Register::operator!=(const ehs::Str_8& otherName) const +{ + return name != otherName; +} + +bool Register::operator==(const ehs::UInt_64& otherId) const +{ + return id == otherId; +} + +bool Register::operator!=(const ehs::UInt_64& otherId) const +{ + return id != otherId; +} + +ehs::UInt_64 Register::GetId() const +{ + return id; +} + +ehs::Str_8 Register::GetName() const +{ + return name; +} + +ehs::UInt_8 Register::GetByteDepth() const +{ + return byteDepth; +} + +ehs::UInt_64 Register::GetCode() const +{ + return code; +} diff --git a/src/main.cpp b/src/main.cpp index ea3ad77..35e8d85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,20 +5,37 @@ #include #include +#include "arctyx/Arctyx.h" +#include "arctyx/compiler/Compiler.h" + int main() { ehs::Initialize("Arctyx", "Alpha", {1, 0, 0}); ehs::Log::EnableImmediateMode(true); + Arctyx::Initialize(); + + ehs::File file("../Main.arc", ehs::Mode::READ, ehs::Disposition::OPEN); + ehs::Str_8 code = file.ReadStr_8(file.Size()); + file.Release(); + + Compiler arctyxCompiler("x64", "Arctyx"); + arctyxCompiler.Compile(code); + + /* ehs::Vector args = ehs::Console::GetArgs_8(); if (args.Size() <= 1) { ehs::Console::Write_8(ehs::GetAppName_8() + " " + ehs::GetAppVersionId_8() + " v" + ehs::Str_8::FromNum(ehs::GetAppVersion().major) + "." + ehs::Str_8::FromNum(ehs::GetAppVersion().minor) + "." + ehs::Str_8::FromNum(ehs::GetAppVersion().patch)); + ehs::Uninitialize(); + return 0; } + Arctyx::Initialize(); + ehs::File codeFile(args[1].RemoveAll("\""), ehs::Mode::READ, ehs::Disposition::OPEN); ehs::Serializer code = codeFile.ReadSerializer_64(ehs::Endianness::LE, codeFile.Size()); codeFile.Release(); @@ -62,6 +79,9 @@ int main() ehs::File file(args[2].RemoveAll("\""), ehs::Mode::WRITE, ehs::Disposition::CREATE_PERSISTENT); file.WriteSerializer_64(executable.Serialize()); + */ + + Arctyx::Uninitialize(); ehs::Uninitialize(); diff --git a/src/x64Arch.cpp b/src/x64Arch.cpp new file mode 100644 index 0000000..c45de62 --- /dev/null +++ b/src/x64Arch.cpp @@ -0,0 +1,200 @@ +#include +#include +#include +#include + +#include "arctyx/Arctyx.h" +#include "arctyx/compiler/Architecture.h" +#include "arctyx/compiler/Language.h" + +bool StrContainsNum(const ehs::Str_8 &str) +{ + for (ehs::UInt_64 i = 0; i < str.Size(); ++i) + if (str[i] >= '0' && str[i] <= '9') + return true; + + return false; +} + +ehs::Serializer Assign(const Instruction *ins, const ehs::Byte *data) +{ + ehs::Serializer result; + + const Architecture *arch = ins->GetArchitecture(); + + const AssignBase *base = (AssignBase *)data; + if (base->type == 1) + { + constexpr ehs::UInt_16 moveRegister = 0b1000100000000000; + + const AssignRR *params = (AssignRR *)data; + const Register dst = *arch->GetRegister(params->dstReg); + const Register src = *arch->GetRegister(params->srcReg); + + if (dst.GetByteDepth() == 1) + { + result.Write(moveRegister | (params->isDstAddress ? 0b00000000 : 0b00000010) << 8 + | (params->isDstAddress || params->isSrcAddress ? 0b00000000 : 0b11000000) | dst.GetCode() << 3 | src.GetCode()); + } + else if (dst.GetByteDepth() >= 2 && dst.GetByteDepth() <= 4) + { + result.Write(moveRegister | (params->isDstAddress ? 0b00000001 : 0b00000011) << 8 + | (params->isDstAddress || params->isSrcAddress ? 0b00000000 : 0b11000000) | dst.GetCode() << 3 | src.GetCode()); + } + else if (dst.GetByteDepth() == 8) + { + ehs::UInt_16 rex = 0b01001000; + + if (StrContainsNum(dst.GetName())) + rex |= 0b00000001; + + if (StrContainsNum(src.GetName())) + rex |= 0b00000100; + + result.Write(rex); + + result.Write(moveRegister | (params->isDstAddress ? 0b00000001 : 0b00000011) << 8 + | (params->isDstAddress || params->isSrcAddress ? 0b00000000 : 0b11000000) | dst.GetCode() << 3 | src.GetCode()); + } + } + else if (base->type == 2) + { + const AssignRI *params = (AssignRI *)data; + const Register dst = *arch->GetRegister(params->dstReg); + + if (dst.GetByteDepth() == 1) + { + result.Write(0b1011000000000000 | dst.GetCode() << 8 | (ehs::UInt_8)params->srcImm); + } + else if (dst.GetByteDepth() == 2) + { + result.Write(0b0110011010110000); + result.Write(params->srcImm); + } + else if (dst.GetByteDepth() == 4) + { + result.Write(0b10111000 | dst.GetCode()); + result.Write(params->srcImm); + } + else if (dst.GetByteDepth() == 8) + { + result.Write(0b0100100010111000 | (StrContainsNum(dst.GetName()) ? 0b00000001 : 0b00000000) << 8 | dst.GetCode()); + result.Write(params->srcImm); + } + } + + return result; +} + +ehs::Version GetPluginVersion(); + +bool InitializePlugin() +{ + Architecture x64("x64"); + + x64.AddRegister({"RAX", 8, 0b000}); + x64.AddRegister({"EAX", 4, 0b000}); + x64.AddRegister({"AX", 2, 0b000}); + x64.AddRegister({"AH", 1, 0b000}); + x64.AddRegister({"AL", 1, 0b000}); + + x64.AddRegister({"RCX", 8, 0b001}); + x64.AddRegister({"ECX", 4, 0b001}); + x64.AddRegister({"CX", 2, 0b001}); + x64.AddRegister({"CH", 1, 0b001}); + x64.AddRegister({"CL", 1, 0b001}); + + x64.AddRegister({"RDX", 8, 0b010}); + x64.AddRegister({"EDX", 4, 0b010}); + x64.AddRegister({"DX", 2, 0b010}); + x64.AddRegister({"DH", 1, 0b010}); + x64.AddRegister({"DL", 1, 0b010}); + + x64.AddRegister({"RBX", 8, 0b011}); + x64.AddRegister({"EBX", 4, 0b011}); + x64.AddRegister({"BX", 2, 0b011}); + x64.AddRegister({"BH", 1, 0b011}); + x64.AddRegister({"BL", 1, 0b011}); + + x64.AddRegister({"RSP", 8, 0b100}); + x64.AddRegister({"ESP", 4, 0b100}); + x64.AddRegister({"SP", 2, 0b100}); + x64.AddRegister({"SPL", 1, 0b100}); + + x64.AddRegister({"RBP", 8, 0b101}); + x64.AddRegister({"EBP", 4, 0b101}); + x64.AddRegister({"BP", 2, 0b101}); + x64.AddRegister({"BPL", 1, 0b101}); + + x64.AddRegister({"RSI", 8, 0b110}); + x64.AddRegister({"ESI", 4, 0b110}); + x64.AddRegister({"SI", 2, 0b110}); + x64.AddRegister({"SIL", 1, 0b110}); + + x64.AddRegister({"RDI", 8, 0b111}); + x64.AddRegister({"EDI", 4, 0b111}); + x64.AddRegister({"DI", 2, 0b111}); + x64.AddRegister({"DIL", 1, 0b111}); + + x64.AddRegister({"R8", 8, 0b000}); + x64.AddRegister({"R8D", 4, 0b000}); + x64.AddRegister({"R8W", 2, 0b000}); + x64.AddRegister({"R8B", 1, 0b000}); + + x64.AddRegister({"R9", 8, 0b001}); + x64.AddRegister({"R9D", 4, 0b001}); + x64.AddRegister({"R9W", 2, 0b001}); + x64.AddRegister({"R9B", 1, 0b001}); + + x64.AddRegister({"R10", 8, 0b010}); + x64.AddRegister({"R10D", 4, 0b010}); + x64.AddRegister({"R10W", 2, 0b010}); + x64.AddRegister({"R10B", 1, 0b010}); + + x64.AddRegister({"R11", 8, 0b011}); + x64.AddRegister({"R11D", 4, 0b011}); + x64.AddRegister({"R11W", 2, 0b011}); + x64.AddRegister({"R11B", 1, 0b011}); + + x64.AddRegister({"R12", 8, 0b100}); + x64.AddRegister({"R12D", 4, 0b100}); + x64.AddRegister({"R12W", 2, 0b100}); + x64.AddRegister({"R12B", 1, 0b100}); + + x64.AddRegister({"R13", 8, 0b101}); + x64.AddRegister({"R13D", 4, 0b101}); + x64.AddRegister({"R13W", 2, 0b101}); + x64.AddRegister({"R13B", 1, 0b101}); + + x64.AddRegister({"R14", 8, 0b110}); + x64.AddRegister({"R14D", 4, 0b110}); + x64.AddRegister({"R14W", 2, 0b110}); + x64.AddRegister({"R14B", 1, 0b110}); + + x64.AddRegister({"R15", 8, 0b111}); + x64.AddRegister({"R15D", 4, 0b111}); + x64.AddRegister({"R15W", 2, 0b111}); + x64.AddRegister({"R15B", 1, 0b111}); + + Instruction assign("Assign"); + assign.SetTranslation(Assign); + + Architecture::Add((Architecture &&)x64); + + return true; +} + +ehs::Str_8 GetPluginName() +{ + return "x64 Architecture"; +} + +ehs::Version GetPluginVersion() +{ + return {1, 0, 0}; +} + +bool ShutdownPlugin() +{ + return true; +} \ No newline at end of file