180 lines
5.6 KiB
C++
180 lines
5.6 KiB
C++
#include "arctyx/compiler/Compiler.h"
|
|
|
|
#include <ehs/io/Console.h>
|
|
|
|
Compiler::Compiler()
|
|
: architecture(nullptr), language(nullptr)
|
|
{
|
|
}
|
|
|
|
Compiler::Compiler(const ehs::Str_8& arch, const ehs::Str_8& lang, ehs::Str_8 entryPoint)
|
|
{
|
|
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;
|
|
}
|
|
|
|
entryPointId = entryPoint.Hash_64();
|
|
entryPointName = (ehs::Str_8 &&)entryPoint;
|
|
|
|
EHS_LOG_SUCCESS();
|
|
}
|
|
|
|
Compiler::Compiler(Compiler&& other) noexcept
|
|
: architecture(other.architecture), language(other.language), entryPointId(other.entryPointId),
|
|
entryPointName((ehs::Str_8 &&)other.entryPointName), symbols((ehs::Array<Symbol> &&)other.symbols)
|
|
{
|
|
other.architecture = nullptr;
|
|
other.language = nullptr;
|
|
other.entryPointId = 0;
|
|
}
|
|
|
|
Compiler::Compiler(const Compiler& other)
|
|
: architecture(other.architecture), language(other.language), entryPointId(other.entryPointId),
|
|
entryPointName(other.entryPointName), symbols(other.symbols)
|
|
{
|
|
}
|
|
|
|
Compiler& Compiler::operator=(Compiler&& other) noexcept
|
|
{
|
|
if (this == &other)
|
|
return *this;
|
|
|
|
architecture = other.architecture;
|
|
language = other.language;
|
|
entryPointId = other.entryPointId;
|
|
entryPointName = (ehs::Str_8 &&)other.entryPointName;
|
|
symbols = (ehs::Array<Symbol> &&)other.symbols;
|
|
|
|
other.architecture = nullptr;
|
|
other.language = nullptr;
|
|
other.entryPointId = 0;
|
|
|
|
return *this;
|
|
}
|
|
|
|
Compiler& Compiler::operator=(const Compiler& other)
|
|
{
|
|
if (this == &other)
|
|
return *this;
|
|
|
|
architecture = other.architecture;
|
|
language = other.language;
|
|
entryPointId = other.entryPointId;
|
|
entryPointName = other.entryPointName;
|
|
symbols = other.symbols;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool Compiler::HasSymbol(const ehs::UInt_64 &id) const
|
|
{
|
|
for (ehs::UInt_64 i = 0; i < symbols.Size(); ++i)
|
|
if (symbols[i].GetId() == id)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool Compiler::HasSymbol(const ehs::Str_8 &name) const
|
|
{
|
|
return HasSymbol(name.Hash_64());
|
|
}
|
|
|
|
bool Compiler::AddSymbol(Symbol symbol)
|
|
{
|
|
if (HasSymbol(symbol.GetId()))
|
|
return false;
|
|
|
|
symbols.Push((Symbol &&)symbol);
|
|
|
|
return true;
|
|
}
|
|
|
|
Symbol *Compiler::GetSymbol(const ehs::UInt_64 &id) const
|
|
{
|
|
for (ehs::UInt_64 i = 0; i < symbols.Size(); ++i)
|
|
if (symbols[i].GetId() == id)
|
|
return &symbols[i];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Symbol *Compiler::GetSymbol(const ehs::Str_8 &name) const
|
|
{
|
|
return GetSymbol(name.Hash_64());
|
|
}
|
|
|
|
ehs::Vector<ehs::Byte> Compiler::Compile(const ehs::Str_8 &code)
|
|
{
|
|
ehs::Console::Write_8("Code:");
|
|
ehs::Console::Write_8(code);
|
|
|
|
ehs::Console::Write_8("Tokens:");
|
|
ehs::Vector<Token> tokens = language->CompileIntoTokens(this, code);
|
|
for (ehs::UInt_64 i = 0; i < tokens.Size(); ++i)
|
|
{
|
|
if (tokens[i].GetType() == TokenT::UNKNOWN)
|
|
ehs::Console::Write_8("UNKNOWN, ", false);
|
|
else if (tokens[i].GetType() == TokenT::SEPARATOR)
|
|
ehs::Console::Write_8("SEPARATOR, ", false);
|
|
else if (tokens[i].GetType() == TokenT::BOOLEAN)
|
|
ehs::Console::Write_8("BOOLEAN, ", false);
|
|
else if (tokens[i].GetType() == TokenT::NUMBER)
|
|
ehs::Console::Write_8("NUMBER, ", false);
|
|
else if (tokens[i].GetType() == TokenT::STRING)
|
|
ehs::Console::Write_8("STRING, ", false);
|
|
else if (tokens[i].GetType() == TokenT::CHARACTER)
|
|
ehs::Console::Write_8("CHARACTER, ", false);
|
|
else if (tokens[i].GetType() == TokenT::KEYWORD)
|
|
ehs::Console::Write_8("KEYWORD, ", false);
|
|
else if (tokens[i].GetType() == TokenT::TYPE)
|
|
ehs::Console::Write_8("TYPE, ", false);
|
|
else if (tokens[i].GetType() == TokenT::IDENTIFIER)
|
|
ehs::Console::Write_8("IDENTIFIER, ", false);
|
|
else if (tokens[i].GetType() == TokenT::UNARY_OPERATOR)
|
|
ehs::Console::Write_8("UNARY_OPERATOR, ", false);
|
|
else if (tokens[i].GetType() == TokenT::COMPOUND_OPERATOR)
|
|
ehs::Console::Write_8("COMPOUND_OPERATOR, ", false);
|
|
else if (tokens[i].GetType() == TokenT::ENCAPSULATOR)
|
|
ehs::Console::Write_8("ENCAPSULATOR, ", false);
|
|
else if (tokens[i].GetType() == TokenT::EOL)
|
|
ehs::Console::Write_8("EOL");
|
|
}
|
|
|
|
ehs::Vector<ehs::Byte> machineCode = language->CompileIntoMachineCode(this, tokens);
|
|
|
|
ehs::Console::Write_8("\nSymbols:");
|
|
for (ehs::UInt_64 i = 0; i < symbols.Size(); ++i)
|
|
{
|
|
if (symbols[i].GetType() == SymbolType::VARIABLE)
|
|
ehs::Console::Write_8("Variable ", false);
|
|
else if (symbols[i].GetType() == SymbolType::FUNCTION)
|
|
ehs::Console::Write_8("Function ", false);
|
|
else if (symbols[i].GetType() == SymbolType::CLASS)
|
|
ehs::Console::Write_8("Class ", false);
|
|
else if (symbols[i].GetType() == SymbolType::MEMBER)
|
|
ehs::Console::Write_8("Member ", false);
|
|
else if (symbols[i].GetType() == SymbolType::METHOD)
|
|
ehs::Console::Write_8("Method ", false);
|
|
else
|
|
ehs::Console::Write_8("Unknown ", false);
|
|
|
|
ehs::Console::Write_8(symbols[i].GetName());
|
|
}
|
|
|
|
Symbol *entryPoint = GetSymbol(entryPointId);
|
|
if (!entryPoint || entryPoint->GetType() != SymbolType::FUNCTION)
|
|
ehs::Console::Write_8("\nCompiler Error: Function symbol, \"" + entryPointName + "\", for the entry point was not found!");
|
|
|
|
return machineCode;
|
|
} |