This commit is contained in:
Arron Nelson 2025-04-27 10:34:53 -07:00
parent 70d35cf0e3
commit ba08245e02
25 changed files with 551 additions and 77 deletions

View File

@ -39,10 +39,12 @@ add_library(Arctyx SHARED
src/compiler/Language.cpp include/arctyx/compiler/Language.h
src/compiler/Token.cpp include/arctyx/compiler/Token.h
src/Arctyx.cpp include/arctyx/Arctyx.h
src/compiler/Combination.cpp
include/arctyx/compiler/Combination.h
src/compiler/Interpretation.cpp
include/arctyx/compiler/Interpretation.h
src/compiler/Keyword.cpp
include/arctyx/compiler/Keyword.h
include/arctyx/compiler/Symbol.h
src/compiler/Symbol.cpp
)
add_executable(ArctyxTools
@ -53,11 +55,21 @@ target_include_directories(Arctyx PUBLIC "${PROJECT_SOURCE_DIR}/include")
if (IS_OS_LINUX)
add_compile_definitions(LWE_WS_XCB)
endif()
target_link_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/.local/lib")
target_link_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/.local/bin")
target_include_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/.local/include")
target_link_libraries(Arctyx PUBLIC xcb xcb-cursor xcb-xfixes xcb-xinput z asound EHS_Dyn)
elseif (IS_OS_WINDOWS)
target_compile_definitions(Arctyx PRIVATE EHS_LIB_EXPORT)
target_compile_definitions(ArctyxTools PRIVATE EHS_LIB_IMPORT)
target_link_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/EHS/lib")
target_link_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/EHS/bin")
target_include_directories(Arctyx PUBLIC "${USER_HOME_DIRECTORY}/EHS/include")
target_link_libraries(Arctyx PUBLIC EHS_Dyn)
endif()
target_link_libraries(ArctyxTools PRIVATE Arctyx)

BIN
Main.bin

Binary file not shown.

View File

@ -1,7 +1,8 @@
#pragma once
#include <ehs/Types.h>
class Arctyx
class EHS_LIB_IO Arctyx
{
private:
static void Initialize();

View File

@ -4,14 +4,16 @@
#include "Instruction.h"
class Architecture
class EHS_LIB_IO Architecture
{
private:
friend class Arctyx;
ehs::UInt_64 id;
ehs::Str_8 name;
ehs::Array<Instruction> instructions;
static ehs::Array<Architecture> architectures;
static ehs::Array<const Architecture *> architectures;
public:
Architecture();

View File

@ -1,15 +0,0 @@
#pragma once
#include <ehs/Array.h>
#include "Token.h"
class Combination
{
private:
ehs::Array<TokenType> tokens;
public:
};

View File

@ -1 +1,21 @@
#pragma once
#include <ehs/Array.h>
#include <ehs/Serializer.h>
#include "Architecture.h"
#include "Language.h"
#include "Symbol.h"
class Compiler
{
private:
const Architecture *architecture;
const Language *language;
ehs::Array<Symbol> symbols;
public:
Compiler();
Compiler(const Architecture *arch, const Language *lang);
};

View File

@ -1,10 +1,16 @@
#pragma once
#include <ehs/Str.h>
#include <ehs/Types.h>
class Instruction
class Architecture;
class EHS_LIB_IO Instruction
{
private:
friend class Architecture;
Architecture *arch;
ehs::UInt_64 id;
ehs::Str_8 name;
ehs::UInt_8 size;
@ -33,6 +39,8 @@ public:
Instruction &operator=(const Instruction &ins);
const Architecture *GetArchitecture() const;
ehs::UInt_64 GetId() const;
ehs::Str_8 GetName() const;

View File

@ -0,0 +1,27 @@
#pragma once
#include <ehs/Array.h>
#include "Instruction.h"
#include "Token.h"
class EHS_LIB_IO Interpretation : public Token
{
private:
Instruction result;
public:
Interpretation() = default;
Interpretation(const TokenT &type, ehs::Str_8 value, Instruction result);
Interpretation(Interpretation &&other) noexcept;
Interpretation(const Interpretation &other);
Interpretation &operator=(Interpretation &&other) noexcept;
Interpretation &operator=(const Interpretation &other);
Instruction GetResult() const;
};

View File

@ -3,7 +3,7 @@
#include "Instruction.h"
class Keyword
class EHS_LIB_IO Keyword
{
private:
ehs::Str_8 identifier;

View File

@ -3,22 +3,28 @@
#include <ehs/Array.h>
#include <ehs/Str.h>
#include <ehs/Types.h>
#include <ehs/Version.h>
#include "Combination.h"
#include "Interpretation.h"
class Language
class EHS_LIB_IO Language
{
private:
friend class Arctyx;
ehs::UInt_64 id;
ehs::Str_8 name;
ehs::Array<ehs::Str_8> keywords;
ehs::Version version;
ehs::Char_8 eol;
ehs::Array<ehs::Char_8> separators;
ehs::Array<Combination> interpretations;
ehs::Array<Interpretation> interpretations;
static ehs::Array<const Language *> languages;
public:
Language();
Language(ehs::Str_8 name);
Language(ehs::Str_8 name, const ehs::Version &version);
Language(Language &&lang) noexcept;
@ -32,4 +38,34 @@ public:
ehs::Str_8 GetName() const;
ehs::Version GetVersion() const;
void SetEOL(const ehs::Char_8 &newEOL);
ehs::Char_8 GetEOL() const;
ehs::Array<ehs::Char_8> GetSeparators() const;
bool HasSeparator(const ehs::Char_8 &separator) const;
bool AddSeparator(const ehs::Char_8 &separator);
ehs::Array<Interpretation> GetInterpretations() const;
bool HasInterpretation(const TokenT &type, const ehs::Str_8 &name) const;
const Interpretation *GetInterpretation(const TokenT &type, const ehs::Str_8 &name) const;
bool AddInterpretation(Interpretation interpretation);
static bool Has(const ehs::UInt_64 &id);
static bool Has(const ehs::Str_8 &name);
static const Language *Get(const ehs::UInt_64 &id);
static const Language *Get(const ehs::Str_8 &name);
static bool Add(Language lang);
};

View File

@ -0,0 +1,44 @@
#pragma once
#include <ehs/Str.h>
#include <ehs/Types.h>
enum class SymbolType
{
UNKNOWN,
VARIABLE,
FUNCTION,
CLASS,
MEMBER,
METHOD
};
class Symbol
{
private:
SymbolType type;
ehs::UInt_64 id;
ehs::Str_8 name;
ehs::UInt_64 address;
public:
Symbol();
Symbol(const SymbolType &type, ehs::Str_8 name, const ehs::UInt_64 &address);
Symbol(Symbol &&other) noexcept;
Symbol(const Symbol &other);
Symbol &operator=(Symbol &&other) noexcept;
Symbol &operator=(const Symbol &other);
SymbolType GetType() const;
ehs::Str_8 GetName() const;
ehs::UInt_64 GetId() const;
ehs::UInt_64 GetAddress() const;
};

View File

@ -2,8 +2,9 @@
#include <ehs/Str.h>
enum class TokenType : ehs::UInt_8
enum class TokenT : ehs::UInt_8
{
UNKNOWN,
VALUE,
KEYWORD,
IDENTIFIER,
@ -11,16 +12,16 @@ enum class TokenType : ehs::UInt_8
COMPOUND_OPERATOR
};
class Token
class EHS_LIB_IO Token
{
private:
TokenType type;
TokenT type;
ehs::Str_8 value;
public:
Token();
Token(TokenType type, ehs::Str_8 value);
Token(const TokenT &type, ehs::Str_8 value);
Token(Token &&token) noexcept;
@ -30,7 +31,7 @@ public:
Token &operator=(const Token &token);
TokenType GetType() const;
TokenT GetType() const;
ehs::Str_8 GetValue() const;
};

View File

@ -17,7 +17,7 @@
#define ELF_64_BIT_HEADER_SIZE 64
#define ELF_32_BIT_HEADER_SIZE 52
class ELF
class EHS_LIB_IO ELF
{
private:
ehs::UInt_8 bitDepth;

View File

@ -14,7 +14,7 @@
class ELF;
class ELF_Program
class EHS_LIB_IO ELF_Program
{
private:
friend class ELF;

View File

@ -17,7 +17,7 @@
#define SECH_SIZE 64
class ELF_Section
class EHS_LIB_IO ELF_Section
{
private:
friend class ELF;

View File

@ -74,7 +74,7 @@
#define SYMH_SIZE 24
class ELF_Sym
class EHS_LIB_IO ELF_Sym
{
private:
ehs::UInt_32 nameOffset;

View File

@ -1,7 +1,10 @@
#include "arctyx/Arctyx.h"
#include <ehs/Vector.h>
#include <ehs/system/CPU.h>
#include "arctyx/compiler/Architecture.h"
#include "arctyx/compiler/Language.h"
#include "arctyx/compiler/Token.h"
void Arctyx::Initialize()
@ -10,4 +13,13 @@ void Arctyx::Initialize()
void Arctyx::Uninitialize()
{
for (ehs::Size i = 0; Architecture::architectures.Size(); ++i)
delete Architecture::architectures[i];
Architecture::architectures.Clear();
for (ehs::UInt_64 i = 0; i < Language::languages.Size(); ++i)
delete Language::languages[i];
Language::languages.Clear();
}

View File

@ -1,6 +1,6 @@
#include "arctyx/compiler/Architecture.h"
ehs::Array<Architecture> Architecture::architectures;
ehs::Array<const Architecture *> Architecture::architectures;
Architecture::Architecture()
: id(0)
@ -13,13 +13,17 @@ Architecture::Architecture(ehs::Str_8 name)
}
Architecture::Architecture(Architecture &&arch) noexcept
: id(arch.id), name((ehs::Str_8 &&)arch.name)
: id(arch.id), name((ehs::Str_8 &&)arch.name), instructions((ehs::Array<Instruction> &&)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)
: id(arc.id), name(arc.name), instructions(arc.instructions)
{
for (ehs::Size i = 0; i < instructions.Size(); ++i)
instructions[i].arch = this;
}
Architecture & Architecture::operator=(Architecture &&arc) noexcept
@ -29,6 +33,10 @@ Architecture & Architecture::operator=(Architecture &&arc) noexcept
id = arc.id;
name = (ehs::Str_8 &&)arc.name;
instructions = (ehs::Array<Instruction> &&)arc.instructions;
for (ehs::Size i = 0; i < instructions.Size(); ++i)
instructions[i].arch = this;
arc.id = 0;
@ -42,6 +50,10 @@ Architecture & Architecture::operator=(const Architecture &arc)
id = arc.id;
name = arc.name;
instructions = arc.instructions;
for (ehs::Size i = 0; i < instructions.Size(); ++i)
instructions[i].arch = this;
return *this;
}
@ -89,6 +101,8 @@ bool Architecture::AddInstruction(Instruction ins)
if (HasInstruction(ins.GetId()))
return false;
ins.arch = this;
instructions.Push((Instruction &&)ins);
return true;
@ -97,7 +111,7 @@ bool Architecture::AddInstruction(Instruction ins)
bool Architecture::Has(const ehs::UInt_64 &id)
{
for (ehs::UInt_64 i = 0; i < architectures.Size(); ++i)
if (architectures[i].GetId() == id)
if (architectures[i]->GetId() == id)
return true;
return false;
@ -111,8 +125,8 @@ bool Architecture::Has(const ehs::Str_8 &name)
const Architecture *Architecture::Get(const ehs::UInt_64 &id)
{
for (ehs::UInt_64 i = 0; i < architectures.Size(); ++i)
if (architectures[i].GetId() == id)
return &architectures[i];
if (architectures[i]->GetId() == id)
return architectures[i];
return nullptr;
}
@ -127,7 +141,7 @@ bool Architecture::Add(Architecture arc)
if (Has(arc.GetId()))
return false;
architectures.Push((Architecture &&)arc);
architectures.Push(new Architecture((Architecture &&)arc));
return true;
}

View File

@ -1 +0,0 @@
#include "arctyx/compiler/Combination.h"

View File

@ -6,49 +6,50 @@ Instruction::~Instruction()
}
Instruction::Instruction()
: id(0), size(0), code(nullptr)
: arch(nullptr), id(0), size(0), code(nullptr)
{
}
Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_8 &size, ehs::Byte *code)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), size(size), code(code)
: arch(nullptr), id(name.Hash_64()), name((ehs::Str_8 &&)name), size(size), code(code)
{
}
Instruction::Instruction(ehs::Str_8 name, const ehs::UInt_64 &code)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size])
: 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)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size])
: 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)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size])
: 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)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), size(sizeof(code)), code(new ehs::Byte[size])
: 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
: 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), size(ins.size), code(ins.code)
{
ins.arch = nullptr;
ins.id = 0;
ins.size = 0;
ins.code = nullptr;
}
Instruction::Instruction(const Instruction &ins)
: id(ins.id), name(ins.name), size(ins.size), code(new ehs::Byte[size])
: arch(nullptr), id(ins.id), name(ins.name), size(ins.size), code(new ehs::Byte[size])
{
ehs::Util::Copy(code, ins.code, size);
}
@ -58,11 +59,13 @@ Instruction &Instruction::operator=(Instruction &&ins) noexcept
if (this == &ins)
return *this;
arch = ins.arch;
id = ins.id;
name = (ehs::Str_8 &&)ins.name;
size = ins.size;
code = ins.code;
ins.arch = nullptr;
ins.id = 0;
ins.size = 0;
ins.code = nullptr;
@ -75,6 +78,7 @@ Instruction &Instruction::operator=(const Instruction &ins)
if (this == &ins)
return *this;
arch = nullptr;
id = ins.id;
name = ins.name;
size = ins.size;
@ -85,6 +89,11 @@ Instruction &Instruction::operator=(const Instruction &ins)
return *this;
}
const Architecture* Instruction::GetArchitecture() const
{
return arch;
}
ehs::UInt_64 Instruction::GetId() const
{
return id;

View File

@ -0,0 +1,45 @@
#include "arctyx/compiler/Interpretation.h"
Interpretation::Interpretation(const TokenT& type, ehs::Str_8 value, Instruction result)
: Token(type, (ehs::Str_8 &&)value), result((Instruction &&)result)
{
}
Interpretation::Interpretation(Interpretation&& other) noexcept
: Token((Token &&)other), result((Instruction &&)other.result)
{
}
Interpretation::Interpretation(const Interpretation& other)
: Token(other), result(other.result)
{
}
Interpretation& Interpretation::operator=(Interpretation&& other) noexcept
{
if (this == &other)
return *this;
Token::operator=((Token &&)other);
result = (Instruction &&)other.result;
return *this;
}
Interpretation& Interpretation::operator=(const Interpretation& other)
{
if (this == &other)
return *this;
Token::operator=(other);
result = other.result;
return *this;
}
Instruction Interpretation::GetResult() const
{
return result;
}

View File

@ -1 +1,183 @@
#include "arctyx/compiler/Language.h"
ehs::Array<const Language *> Language::languages;
Language::Language()
: id(0), eol('\n')
{
}
Language::Language(ehs::Str_8 name, const ehs::Version& version)
: id(name.Hash_64()), name((ehs::Str_8 &&)name), version(version), eol('\n')
{
}
Language::Language(Language&& lang) noexcept
: id(lang.id), name((ehs::Str_8 &&)lang.name), version(lang.version), eol(lang.eol),
separators((ehs::Array<ehs::Char_8> &&)lang.separators),
interpretations((ehs::Array<Interpretation> &&)lang.interpretations)
{
lang.id = 0;
lang.version = {};
lang.eol = '\n';
}
Language::Language(const Language& lang)
: id(lang.id), name(lang.name), version(lang.version), eol(lang.eol), separators(lang.separators),
interpretations(lang.interpretations)
{
}
Language& Language::operator=(Language&& lang) noexcept
{
if (this == &lang)
return *this;
id = lang.id;
name = (ehs::Str_8 &&)lang.name;
version = lang.version;
eol = lang.eol;
separators = (ehs::Array<ehs::Char_8> &&)lang.separators;
interpretations = (ehs::Array<Interpretation> &&)lang.interpretations;
lang.id = 0;
lang.version = {};
lang.eol = '\n';
return *this;
}
Language& Language::operator=(const Language& lang)
{
if (this == &lang)
return *this;
id = lang.id;
name = lang.name;
version = lang.version;
eol = lang.eol;
separators = lang.separators;
interpretations = lang.interpretations;
return *this;
}
ehs::UInt_64 Language::GetId() const
{
return id;
}
ehs::Str_8 Language::GetName() const
{
return name;
}
ehs::Version Language::GetVersion() const
{
return version;
}
void Language::SetEOL(const ehs::Char_8& newEOL)
{
eol = newEOL;
}
ehs::Char_8 Language::GetEOL() const
{
return eol;
}
ehs::Array<ehs::Char_8> Language::GetSeparators() const
{
return separators;
}
bool Language::HasSeparator(const ehs::Char_8& separator) const
{
for (ehs::Size i = 0; i < separators.Size(); ++i)
if (separators[i] == separator)
return true;
return false;
}
bool Language::AddSeparator(const ehs::Char_8& separator)
{
if (HasSeparator(separator))
return false;
separators.Push(separator);
return true;
}
ehs::Array<Interpretation> Language::GetInterpretations() const
{
return interpretations;
}
bool Language::HasInterpretation(const TokenT &type, const ehs::Str_8& name) const
{
for (ehs::Size i = 0; i < interpretations.Size(); ++i)
if (interpretations[i].GetType() == type && interpretations[i].GetValue() == name)
return true;
return false;
}
const Interpretation *Language::GetInterpretation(const TokenT &type, const ehs::Str_8& name) const
{
for (ehs::Size i = 0; i < interpretations.Size(); ++i)
if (interpretations[i].GetType() == type && interpretations[i].GetValue() == name)
return &interpretations[i];
return nullptr;
}
bool Language::AddInterpretation(Interpretation interpretation)
{
if (HasInterpretation(interpretation.GetType(), interpretation.GetValue()))
return false;
interpretations.Push((Interpretation &&)interpretation);
return true;
}
bool Language::Has(const ehs::UInt_64& id)
{
for (ehs::UInt_64 i = 0; i < languages.Size(); ++i)
if (languages[i]->GetId() == id)
return true;
return false;
}
bool Language::Has(const ehs::Str_8& name)
{
return Has(name.Hash_64());
}
const Language* Language::Get(const ehs::UInt_64& id)
{
for (ehs::UInt_64 i = 0; i < languages.Size(); ++i)
if (languages[i]->GetId() == id)
return languages[i];
return nullptr;
}
const Language* Language::Get(const ehs::Str_8& name)
{
return Get(name.Hash_64());
}
bool Language::Add(Language lang)
{
if (Has(lang.GetId()))
return false;
languages.Push(new Language((Language &&)lang));
return true;
}

71
src/compiler/Symbol.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "arctyx/compiler/Symbol.h"
Symbol::Symbol()
: type(SymbolType::UNKNOWN), id(0), address(0)
{
}
Symbol::Symbol(const SymbolType& type, ehs::Str_8 name, const ehs::UInt_64& address)
: type(type), id(name.Hash_64()), name((ehs::Str_8 &&)name), address(address)
{
}
Symbol::Symbol(Symbol&& other) noexcept
: type(other.type), id(other.id), name((ehs::Str_8 &&)other.name), address(other.address)
{
}
Symbol::Symbol(const Symbol &other)
: type(other.type), id(other.id), name(other.name), address(other.address)
{
}
Symbol &Symbol::operator=(Symbol &&other) noexcept
{
if (this == &other)
return *this;
type = other.type;
name = (ehs::Str_8 &&)other.name;
id = other.id;
address = other.address;
other.type = SymbolType::UNKNOWN;
other.id = 0;
other.address = 0;
return *this;
}
Symbol &Symbol::operator=(const Symbol& other)
{
if (this == &other)
return *this;
type = other.type;
name = other.name;
id = other.id;
address = other.address;
return *this;
}
SymbolType Symbol::GetType() const
{
return type;
}
ehs::Str_8 Symbol::GetName() const
{
return name;
}
ehs::UInt_64 Symbol::GetId() const
{
return id;
}
ehs::UInt_64 Symbol::GetAddress() const
{
return address;
}

View File

@ -1,37 +1,56 @@
#include "arctyx/compiler/Token.h"
Token::Token()
: type(TokenT::UNKNOWN)
{
}
Token::Token(TokenType type, ehs::Str_8 value)
Token::Token(const TokenT &type, ehs::Str_8 value)
: type(type), value((ehs::Str_8 &&)value)
{
}
Token::Token(Token &&token) noexcept
: type(token.type), value((ehs::Str_8 &&)token.value)
{
token.type = TokenT::UNKNOWN;
}
Token::Token(const Token &token)
: type(token.type), value(token.value)
{
}
Token & Token::operator=(Token &&token) noexcept
{
if (this == &token)
return *this;
type = token.type;
value = (ehs::Str_8 &&)token.value;
token.type = TokenT::UNKNOWN;
return *this;
}
Token & Token::operator=(const Token &token)
{
if (this == &token)
return *this;
type = token.type;
value = token.value;
return *this;
}
TokenType Token::GetType() const
TokenT Token::GetType() const
{
return type;
}
ehs::Str_8 Token::GetValue() const
{
return {};
return value;
}

View File

@ -5,19 +5,6 @@
#include <ehs/io/Console.h>
#include <ehs/io/File.h>
struct Foo
{
bool a;
ehs::UInt_64 b;
ehs::UInt_16 c;
};
struct Bar
{
Foo a;
ehs::Char_8 b[128];
};
int main()
{
ehs::Initialize("Arctyx", "Alpha", {1, 0, 0});
@ -26,8 +13,8 @@ int main()
ehs::Vector<ehs::Str_8> 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::GetVersion().major) + "." +
ehs::Str_8::FromNum(ehs::GetVersion().minor) + "." + ehs::Str_8::FromNum(ehs::GetVersion().patch));
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));
return 0;
}