mirror of
https://github.com/PashaBibko/LX.git
synced 2026-04-03 17:39:02 +00:00
Refactored how logging works
Made it central reusable logic. No longer needs to be passed around, opened or closed.
This commit is contained in:
@@ -158,7 +158,9 @@
|
|||||||
<ClInclude Include="LX-Common.h" />
|
<ClInclude Include="LX-Common.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\Console.cpp" />
|
||||||
<ClCompile Include="src\dllmain.cpp" />
|
<ClCompile Include="src\dllmain.cpp" />
|
||||||
|
<ClCompile Include="src\Logger.cpp" />
|
||||||
<ClCompile Include="src\pch.cpp">
|
<ClCompile Include="src\pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
|||||||
@@ -37,5 +37,11 @@
|
|||||||
<ClCompile Include="src\pch.cpp">
|
<ClCompile Include="src\pch.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Logger.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Console.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#undef NOMINMAX
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
// Else alerts the user that their system is not supported //
|
// Else alerts the user that their system is not supported //
|
||||||
#else
|
#else
|
||||||
#error "This code is only designed to work on windows"
|
#error "This code is only designed to work on windows"
|
||||||
@@ -22,6 +23,17 @@
|
|||||||
#error "This code is only designed to work with Visual Studio"
|
#error "This code is only designed to work with Visual Studio"
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
// My commonly used macros //
|
||||||
|
|
||||||
|
#define RETURN_IF(condition) if (condition) { return; }
|
||||||
|
#define RETURN_V_IF(value, condition) if (condition) { return value; }
|
||||||
|
|
||||||
|
#ifdef COMMON_EXPORTS
|
||||||
|
#define COMMON_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define COMMON_API __declspec(dllimport)
|
||||||
|
#endif // COMMON_EXPORTS
|
||||||
|
|
||||||
// Includes commonly used STD files //
|
// Includes commonly used STD files //
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|||||||
@@ -1,41 +1,30 @@
|
|||||||
namespace LX
|
namespace LX
|
||||||
{
|
{
|
||||||
|
// Enum of colors with their Win32 equivalent value //
|
||||||
enum class Color
|
enum class Color
|
||||||
{
|
{
|
||||||
BLACK = 0,
|
BLACK = 0,
|
||||||
BLUE = 1,
|
BLUE = 1,
|
||||||
GREEN = 2,
|
GREEN = 2,
|
||||||
AQUA = 3,
|
AQUA = 3,
|
||||||
RED = 4,
|
RED = 4,
|
||||||
PURPLE = 5,
|
PURPLE = 5,
|
||||||
YELLOW = 6,
|
YELLOW = 6,
|
||||||
LIGHT_GRAY = 7,
|
LIGHT_GRAY = 7,
|
||||||
LIGHT_BLUE = 9,
|
LIGHT_BLUE = 9,
|
||||||
LIGHT_GREEN = 10,
|
LIGHT_GREEN = 10,
|
||||||
LIGHT_AQUA = 11,
|
LIGHT_AQUA = 11,
|
||||||
LIGHT_RED = 12,
|
LIGHT_RED = 12,
|
||||||
LIGHT_PURPLE = 13,
|
LIGHT_PURPLE = 13,
|
||||||
LIGHT_YELLOW = 14,
|
LIGHT_YELLOW = 14,
|
||||||
WHITE = 15
|
WHITE = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void PrintStringAsColor(const std::string& str, Color c)
|
// Prints a string to std::cout with a certain color using Win32 API //
|
||||||
{
|
extern "C" void COMMON_API PrintStringAsColor(const std::string& str, Color c);
|
||||||
// Gets a handle to the console //
|
|
||||||
static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
|
|
||||||
// Sets the color of the console to the desired color //
|
|
||||||
SetConsoleTextAttribute(hConsole, (WORD)c);
|
|
||||||
|
|
||||||
// Outputs the text //
|
|
||||||
std::cout << str;
|
|
||||||
|
|
||||||
// Resets the color //
|
|
||||||
SetConsoleTextAttribute(hConsole, (WORD)Color::LIGHT_GRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Util function for getting a line of the source at a given index (used for errors) //
|
// Util function for getting a line of the source at a given index (used for errors) //
|
||||||
inline std::string GetLineAtIndexOf(const std::string src, const std::streamsize index)
|
inline std::string GetLineAtIndexOf(const std::string& src, const std::streamsize index) // <- Has to be inline because of C++ types
|
||||||
{
|
{
|
||||||
// Finds the start of the line //
|
// Finds the start of the line //
|
||||||
size_t start = src.rfind('\n', index);
|
size_t start = src.rfind('\n', index);
|
||||||
|
|||||||
@@ -1,23 +1,51 @@
|
|||||||
namespace LX
|
namespace LX
|
||||||
{
|
{
|
||||||
template<typename... Args>
|
class COMMON_API Log
|
||||||
inline void SafeLog(std::ofstream* log, Args... args)
|
|
||||||
{
|
{
|
||||||
if (log != nullptr)
|
public:
|
||||||
{
|
// This class should never be constructed //
|
||||||
(*log << ... << args);
|
Log() = delete;
|
||||||
(*log << '\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SafeFlush(std::ofstream* log)
|
enum class Format
|
||||||
{
|
{
|
||||||
if (log != nullptr)
|
AUTO,
|
||||||
{
|
NONE
|
||||||
log->flush();
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gives a standard way to mark a change between different sections within the log output //
|
template<Format format = Format::AUTO, typename... Args>
|
||||||
constexpr const char* LOG_BREAK = "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
|
static void out(Args... args)
|
||||||
|
{
|
||||||
|
if constexpr (format == Format::AUTO)
|
||||||
|
{
|
||||||
|
((*s_LogFile << ... << args) << "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*s_LogFile << ... << args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static void LogNewSection(Args... args)
|
||||||
|
{
|
||||||
|
static const char* BREAK = "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
|
||||||
|
|
||||||
|
*s_LogFile << '\n' << BREAK << '\n';
|
||||||
|
(*s_LogFile << ... << args);
|
||||||
|
*s_LogFile << '\n' << BREAK << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Allows ProcAttach to manage the log //
|
||||||
|
friend bool ProcAttach(HMODULE hModule);
|
||||||
|
|
||||||
|
// Initalises the log (Called by DllMain) //
|
||||||
|
static void Init();
|
||||||
|
|
||||||
|
// Closes the log (Called by DllMain) //
|
||||||
|
static void Close();
|
||||||
|
|
||||||
|
static std::ofstream* s_LogFile;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
19
Common/src/Console.cpp
Normal file
19
Common/src/Console.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include <LX-Common.h>
|
||||||
|
|
||||||
|
namespace LX
|
||||||
|
{
|
||||||
|
void PrintStringAsColor(const std::string& str, Color c)
|
||||||
|
{
|
||||||
|
// Gets a handle to the console //
|
||||||
|
static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
// Sets the color of the console to the desired color //
|
||||||
|
SetConsoleTextAttribute(hConsole, (WORD)c);
|
||||||
|
|
||||||
|
// Outputs the text //
|
||||||
|
std::cout << str;
|
||||||
|
|
||||||
|
// Resets the color //
|
||||||
|
SetConsoleTextAttribute(hConsole, (WORD)Color::LIGHT_GRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Common/src/Logger.cpp
Normal file
26
Common/src/Logger.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include <LX-Common.h>
|
||||||
|
|
||||||
|
namespace LX
|
||||||
|
{
|
||||||
|
// Allocates memory for the log file pointer //
|
||||||
|
std::ofstream* Log::s_LogFile = nullptr;
|
||||||
|
|
||||||
|
void Log::Init()
|
||||||
|
{
|
||||||
|
// The actual object holding the log file //
|
||||||
|
// Has to be done like this to stop MSVC complaining //
|
||||||
|
static std::ofstream actualLog;
|
||||||
|
|
||||||
|
// Opens the log file and assigns it to the log pointer //
|
||||||
|
actualLog.open("log");
|
||||||
|
s_LogFile = &actualLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::Close()
|
||||||
|
{
|
||||||
|
// Flushes and closes the log //
|
||||||
|
// Yes I know closing automatically flushes but this function looked empty //
|
||||||
|
s_LogFile->flush();
|
||||||
|
s_LogFile->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,36 +3,38 @@
|
|||||||
|
|
||||||
namespace LX
|
namespace LX
|
||||||
{
|
{
|
||||||
|
// All the different functions that can be called by the system //
|
||||||
|
// Currently all empty but here for easier future development //
|
||||||
|
|
||||||
using DllFunc = bool(HMODULE);
|
using DllFunc = bool(HMODULE);
|
||||||
|
|
||||||
static bool ProcAttach(HMODULE hModule)
|
static bool ProcAttach(HMODULE hModule)
|
||||||
{
|
{
|
||||||
|
Log::Init(); // Initalises the log before the main process starts
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ProcDetach(HMODULE hModule)
|
static bool ProcDetach(HMODULE hModule)
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ThreadAttach(HMODULE hModule)
|
static bool ThreadAttach(HMODULE hModule) { return true; }
|
||||||
{
|
static bool ThreadDetach(HMODULE hModule) { return true; }
|
||||||
}
|
|
||||||
|
|
||||||
static bool ThreadDetach(HMODULE hModule)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL __stdcall DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
BOOL __stdcall DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
switch (ul_reason_for_call)
|
// All the functions that might be called with their relevant state //
|
||||||
|
static const std::unordered_map<DWORD, LX::DllFunc&> funcs =
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
{ DLL_PROCESS_ATTACH, LX::ProcAttach },
|
||||||
case DLL_THREAD_ATTACH:
|
{ DLL_PROCESS_DETACH, LX::ProcDetach },
|
||||||
case DLL_THREAD_DETACH:
|
{ DLL_THREAD_ATTACH , LX::ThreadAttach },
|
||||||
case DLL_PROCESS_DETACH:
|
{ DLL_THREAD_DETACH , LX::ThreadDetach }
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
// Returns the output of the relavant function //
|
||||||
|
return funcs.at(ul_reason_for_call)(hModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>Parser.lib;Lexer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Parser.lib;Lexer.lib;Common.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>Parser.lib;Lexer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Parser.lib;Lexer.lib;Common.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -158,6 +158,11 @@
|
|||||||
<ClInclude Include="inc\Lexer.h" />
|
<ClInclude Include="inc\Lexer.h" />
|
||||||
<ClInclude Include="inc\Parser.h" />
|
<ClInclude Include="inc\Parser.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Common\Common.vcxproj">
|
||||||
|
<Project>{0abb03b7-e61a-4040-a512-fc05aa35b2a6}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -128,5 +128,5 @@ namespace LX
|
|||||||
std::string ToString(Token::TokenType t);
|
std::string ToString(Token::TokenType t);
|
||||||
|
|
||||||
// Lexer function to take in a file and output a vector of tokens //
|
// Lexer function to take in a file and output a vector of tokens //
|
||||||
const std::vector<Token> LexicalAnalyze(const std::string& contents, const std::streamsize len, std::ofstream* log);
|
const std::vector<Token> LexicalAnalyze(const std::string& contents, const std::streamsize len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace LX::AST
|
|||||||
virtual llvm::Value* GenIR(InfoLLVM& LLVM) = 0;
|
virtual llvm::Value* GenIR(InfoLLVM& LLVM) = 0;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
virtual void Log(std::ofstream* log, unsigned depth) = 0;
|
virtual void Log(unsigned depth) = 0;
|
||||||
|
|
||||||
// Function for generating C/C++ code (Currently not implemented) //
|
// Function for generating C/C++ code (Currently not implemented) //
|
||||||
//virtual void GenC() = 0;
|
//virtual void GenC() = 0;
|
||||||
@@ -143,7 +143,7 @@ namespace LX
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Turns the tokens of a file into it's abstract syntax tree equivalent //
|
// Turns the tokens of a file into it's abstract syntax tree equivalent //
|
||||||
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens, std::ofstream* log);
|
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens);
|
||||||
|
|
||||||
// Turns an abstract binary tree into LLVM intermediate representation //
|
// Turns an abstract binary tree into LLVM intermediate representation //
|
||||||
void GenerateIR(FileAST& ast, const std::string& name, const std::filesystem::path& IRPath);
|
void GenerateIR(FileAST& ast, const std::string& name, const std::filesystem::path& IRPath);
|
||||||
|
|||||||
@@ -33,20 +33,16 @@ namespace LX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_outPath, const char* a_logPath)
|
extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_outPath)
|
||||||
{
|
{
|
||||||
// Creates the file paths outside of the try-catch so they can be used in errors //
|
// Creates the file paths outside of the try-catch so they can be used in errors //
|
||||||
std::filesystem::path inpPath;
|
std::filesystem::path inpPath;
|
||||||
std::filesystem::path outPath;
|
std::filesystem::path outPath;
|
||||||
std::filesystem::path logPath;
|
|
||||||
|
|
||||||
// Creates the contents string outside of the try-catch so they can be used in errors //
|
// Creates the contents string outside of the try-catch so they can be used in errors //
|
||||||
std::string contents;
|
std::string contents;
|
||||||
LX::Token::source = &contents;
|
LX::Token::source = &contents;
|
||||||
|
|
||||||
// Creates the log-file out of the try-catch so it can be closed propely if an error is thrown //
|
|
||||||
std::unique_ptr<std::ofstream> log = nullptr;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Turns the file paths into the C++ type for handling them //
|
// Turns the file paths into the C++ type for handling them //
|
||||||
@@ -69,33 +65,22 @@ extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_
|
|||||||
LX::ThrowIf<LX::InvalidFilePath>(outFile.is_open() == false, "output file path", outPath);
|
LX::ThrowIf<LX::InvalidFilePath>(outFile.is_open() == false, "output file path", outPath);
|
||||||
outFile.close(); // Opened just to check we can
|
outFile.close(); // Opened just to check we can
|
||||||
|
|
||||||
// Opens the log file (if there is one specified //
|
|
||||||
if (a_logPath != nullptr)
|
|
||||||
{
|
|
||||||
logPath = a_logPath;
|
|
||||||
log = std::make_unique<std::ofstream>(logPath);
|
|
||||||
LX::ThrowIf<LX::InvalidFilePath>(log->is_open() == false, "log file path", logPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prints the full paths to the console to let the user know compiling is being done //
|
// Prints the full paths to the console to let the user know compiling is being done //
|
||||||
std::cout << std::filesystem::absolute(inpPath) << " -> " << std::filesystem::absolute(outPath) << std::endl;
|
std::cout << std::filesystem::absolute(inpPath) << " -> " << std::filesystem::absolute(outPath) << std::endl;
|
||||||
|
|
||||||
// Create tokens out of the input file //
|
// Create tokens out of the input file //
|
||||||
LX::InvalidCharInSource::s_Source = &contents;
|
LX::InvalidCharInSource::s_Source = &contents;
|
||||||
LX::InvalidCharInSource::s_SourceFile = &inpPath;
|
LX::InvalidCharInSource::s_SourceFile = &inpPath;
|
||||||
std::vector<LX::Token>tokens = LX::LexicalAnalyze(contents, len, log.get());
|
std::vector<LX::Token>tokens = LX::LexicalAnalyze(contents, len);
|
||||||
LX::SafeFlush(log.get());
|
|
||||||
|
|
||||||
// Turns the tokens into an AST //
|
// Turns the tokens into an AST //
|
||||||
LX::UnexpectedToken::s_Source = &contents;
|
LX::UnexpectedToken::s_Source = &contents;
|
||||||
LX::UnexpectedToken::s_SourceFile = &inpPath;
|
LX::UnexpectedToken::s_SourceFile = &inpPath;
|
||||||
|
|
||||||
LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens, log.get());
|
LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens);
|
||||||
LX::SafeFlush(log.get());
|
|
||||||
|
|
||||||
// Turns the AST into LLVM IR //
|
// Turns the AST into LLVM IR //
|
||||||
LX::GenerateIR(AST, inpPath.filename().string(), outPath);
|
LX::GenerateIR(AST, inpPath.filename().string(), outPath);
|
||||||
LX::SafeFlush(log.get());
|
|
||||||
|
|
||||||
// Returns success
|
// Returns success
|
||||||
return 0;
|
return 0;
|
||||||
@@ -103,9 +88,8 @@ extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_
|
|||||||
|
|
||||||
catch(LX::RuntimeError& e)
|
catch(LX::RuntimeError& e)
|
||||||
{
|
{
|
||||||
// Closes the log to save everything outputted to it after logging the error //
|
// Logs the error. Does not need to close it as it is done after this function returns //
|
||||||
LX::SafeLog(log.get(), LX::LOG_BREAK, "Error thrown of type: ", e.ErrorType(), LX::LOG_BREAK);
|
LX::Log::LogNewSection("Error thrown of type: ", e.ErrorType());
|
||||||
if (log != nullptr) { log->close(); }
|
|
||||||
|
|
||||||
// Logs the errors type to the console if built as Debug //
|
// Logs the errors type to the console if built as Debug //
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -122,8 +106,8 @@ extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_
|
|||||||
// Catches any std errors, there should be none //
|
// Catches any std errors, there should be none //
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
// Closes the log if it is open to get as much info as possible //
|
// Logs the error. Does not need to close it as it is done after this function returns //
|
||||||
if (log != nullptr) { log->close(); }
|
LX::Log::LogNewSection("std::exception thrown: ", e.what());
|
||||||
|
|
||||||
// Prints the std exception to the console //
|
// Prints the std exception to the console //
|
||||||
// Any errors here are problems with the code //
|
// Any errors here are problems with the code //
|
||||||
@@ -134,24 +118,9 @@ extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catches errors that i was too lazy to code //
|
|
||||||
catch (int)
|
|
||||||
{
|
|
||||||
// Closes the log if it is open to get as much info as possible //
|
|
||||||
if (log != nullptr) { log->close(); }
|
|
||||||
|
|
||||||
std::cout << "An placeholder error occured. Maybe use a language that wasn't coded by a lazy person.\n" << std::endl;
|
|
||||||
|
|
||||||
// Exit code -1 means an undefined error //
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default catches any non-specified errors //
|
// Default catches any non-specified errors //
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// Closes the log if it is open to get as much info as possible //
|
|
||||||
if (log != nullptr) { log->close(); }
|
|
||||||
|
|
||||||
// Exit code -1 means an undefined error //
|
// Exit code -1 means an undefined error //
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace LX_Build
|
|||||||
[LibraryImport ("Generator.dll", StringMarshalling = StringMarshalling.Custom,
|
[LibraryImport ("Generator.dll", StringMarshalling = StringMarshalling.Custom,
|
||||||
StringMarshallingCustomType = typeof(System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller))]
|
StringMarshallingCustomType = typeof(System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller))]
|
||||||
[UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
|
[UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
|
||||||
public static partial int GenIR(string arg1, string arg2, string? arg3);
|
public static partial int GenIR(string arg1, string arg2);
|
||||||
|
|
||||||
// Sets the directory to import the DLLs from //
|
// Sets the directory to import the DLLs from //
|
||||||
public static void Init()
|
public static void Init()
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace LX_Build
|
|||||||
LX_API.Init();
|
LX_API.Init();
|
||||||
|
|
||||||
// Generates LLVM IR with the example files //
|
// Generates LLVM IR with the example files //
|
||||||
if (LX_API.GenIR("example/main.lx", "example/main.ll", "example/log") != 0)
|
if (LX_API.GenIR("example/main.lx", "example/main.ll") != 0)
|
||||||
{
|
{
|
||||||
// Quits if the IR Generation fails //
|
// Quits if the IR Generation fails //
|
||||||
// The C++ script handles all of the error message outputting //
|
// The C++ script handles all of the error message outputting //
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LX-Build", "LX-Build\LX-Bui
|
|||||||
{C88042E2-0E09-4383-93F8-C79F9EE1E897} = {C88042E2-0E09-4383-93F8-C79F9EE1E897}
|
{C88042E2-0E09-4383-93F8-C79F9EE1E897} = {C88042E2-0E09-4383-93F8-C79F9EE1E897}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{4AD62954-631A-4D0F-877E-E1C66E8CEC00}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Common\Common.vcxproj", "{0ABB03B7-E61A-4040-A512-FC05AA35B2A6}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Common\Common.vcxproj", "{0ABB03B7-E61A-4040-A512-FC05AA35B2A6}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
@@ -109,7 +107,6 @@ Global
|
|||||||
{4E4019F5-12E0-4EE2-9658-A0DD3038EEDA} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{4E4019F5-12E0-4EE2-9658-A0DD3038EEDA} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
{D6EAFB31-4AFD-4989-9522-D6609AC4ED64} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{D6EAFB31-4AFD-4989-9522-D6609AC4ED64} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
{C88042E2-0E09-4383-93F8-C79F9EE1E897} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{C88042E2-0E09-4383-93F8-C79F9EE1E897} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
{0ABB03B7-E61A-4040-A512-FC05AA35B2A6} = {4AD62954-631A-4D0F-877E-E1C66E8CEC00}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {411AFEC9-4075-4FCC-B95A-9288BC822E90}
|
SolutionGuid = {411AFEC9-4075-4FCC-B95A-9288BC822E90}
|
||||||
|
|||||||
@@ -175,10 +175,10 @@ namespace LX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Token> LX::LexicalAnalyze(const std::string& contents, std::streamsize len, std::ofstream* log)
|
const std::vector<Token> LX::LexicalAnalyze(const std::string& contents, std::streamsize len)
|
||||||
{
|
{
|
||||||
// Logs the start of the lexical analysis
|
// Logs the start of the lexical analysis
|
||||||
SafeLog(log, LOG_BREAK, "Started lexing file", LOG_BREAK);
|
Log::LogNewSection("Lexing file");
|
||||||
|
|
||||||
// Allocates a large ammount of memory to hold the output //
|
// Allocates a large ammount of memory to hold the output //
|
||||||
// Will shrink the size later on to stop excess memory being allocated //
|
// Will shrink the size later on to stop excess memory being allocated //
|
||||||
@@ -187,7 +187,7 @@ namespace LX
|
|||||||
|
|
||||||
// Trackers for when the program is iterating over the file //
|
// Trackers for when the program is iterating over the file //
|
||||||
LexerInfo info;
|
LexerInfo info;
|
||||||
|
|
||||||
// Iterates over the file and turns it into tokens //
|
// Iterates over the file and turns it into tokens //
|
||||||
while (info.index < len)
|
while (info.index < len)
|
||||||
{
|
{
|
||||||
@@ -344,11 +344,9 @@ namespace LX
|
|||||||
|
|
||||||
// Log dumps A LOT of info //
|
// Log dumps A LOT of info //
|
||||||
|
|
||||||
#ifdef LOG_EVERYTHING
|
Log::out
|
||||||
|
|
||||||
SafeLog
|
|
||||||
(
|
(
|
||||||
log, "Index: ", std::left, std::setw(3), info.index,
|
"Index: ", std::left, std::setw(3), info.index,
|
||||||
" Is Alpha: ", info.isAlpha,
|
" Is Alpha: ", info.isAlpha,
|
||||||
" Is Numeric: ", info.isNumeric,
|
" Is Numeric: ", info.isNumeric,
|
||||||
" In Comment: ", info.inComment,
|
" In Comment: ", info.inComment,
|
||||||
@@ -360,8 +358,6 @@ namespace LX
|
|||||||
" Current: {", PrintChar(current), "}"
|
" Current: {", PrintChar(current), "}"
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif // LOG_EVERYTHING
|
|
||||||
|
|
||||||
// Updates trackers to their default state of a new character //
|
// Updates trackers to their default state of a new character //
|
||||||
|
|
||||||
info.index++;
|
info.index++;
|
||||||
@@ -371,28 +367,22 @@ namespace LX
|
|||||||
info.wasLastCharNumeric = info.isNumeric;
|
info.wasLastCharNumeric = info.isNumeric;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logs the tokens if logging is on //
|
Log::out("\n"); // Puts a space to clean up the log
|
||||||
if (log != nullptr)
|
|
||||||
|
for (auto& token : tokens)
|
||||||
{
|
{
|
||||||
#ifdef LOG_EVERYTHING
|
Log::out
|
||||||
SafeLog(log, "\n"); // Puts a space when there is a lot in the log
|
(
|
||||||
#endif // LOG_EVERYTHING
|
std::left,
|
||||||
|
"{ Line: ", std::setw(3), token.line,
|
||||||
for (auto& token : tokens)
|
", Index: ", std::setw(3), token.index,
|
||||||
{
|
", Length: ", std::setw(2), token.length, " } ",
|
||||||
SafeLog
|
std::setw(30), ToStringNoFormat(token.type) + ":", "{", token.GetContents(), "}"
|
||||||
(
|
);
|
||||||
log, std::left,
|
|
||||||
"{ Line: ", std::setw(3), token.line,
|
|
||||||
", Index: ", std::setw(3), token.index,
|
|
||||||
", Length: ", std::setw(2), token.length, " } ",
|
|
||||||
std::setw(30), ToStringNoFormat(token.type) + ":", "{", token.GetContents(), "}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SafeLog(log, "\n END OF TOKENS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log::out("End of tokens");
|
||||||
|
|
||||||
// Shrinks the vector down to minimum size before returning to avoid excess memory being allocated
|
// Shrinks the vector down to minimum size before returning to avoid excess memory being allocated
|
||||||
tokens.shrink_to_fit();
|
tokens.shrink_to_fit();
|
||||||
return tokens;
|
return tokens;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file, will throw an error if called on this class //
|
// Function to log the node to a file, will throw an error if called on this class //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
// The nodes that are contained within this node //
|
// The nodes that are contained within this node //
|
||||||
std::vector<std::unique_ptr<Node>> nodes;
|
std::vector<std::unique_ptr<Node>> nodes;
|
||||||
@@ -48,7 +48,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The number it stores //
|
// The number it stores //
|
||||||
@@ -67,7 +67,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The sides of the operation //
|
// The sides of the operation //
|
||||||
@@ -89,7 +89,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// What it is returning (can be null) //
|
// What it is returning (can be null) //
|
||||||
@@ -107,7 +107,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Name of the variable //
|
// Name of the variable //
|
||||||
@@ -127,7 +127,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Name of the variable //
|
// Name of the variable //
|
||||||
@@ -148,7 +148,7 @@ namespace LX::AST
|
|||||||
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
llvm::Value* GenIR(InfoLLVM& LLVM) override;
|
||||||
|
|
||||||
// Function to log the node to a file //
|
// Function to log the node to a file //
|
||||||
void Log(std::ofstream* log, unsigned depth) override;
|
void Log(unsigned depth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The name of the variable //
|
// The name of the variable //
|
||||||
|
|||||||
@@ -4,61 +4,59 @@
|
|||||||
|
|
||||||
namespace LX::AST
|
namespace LX::AST
|
||||||
{
|
{
|
||||||
void MultiNode::Log(std::ofstream* log, unsigned depth)
|
void MultiNode::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
throw int(); // <- TODO: Make an error for this
|
throw int(); // <- TODO: Make an error for this
|
||||||
}
|
}
|
||||||
|
|
||||||
void NumberLiteral::Log(std::ofstream* log, unsigned depth)
|
void NumberLiteral::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out(std::string(depth, '\t'), "Number: ", m_Number);
|
||||||
(*log) << "Number: " << m_Number << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Operation::Log(std::ofstream* log, unsigned depth)
|
void Operation::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out(std::string(depth, '\t'), "Operation {", ToString(m_Operand), "}:");
|
||||||
(*log) << "Operation {" << ToString(m_Operand) << "}:\n";
|
|
||||||
(*log) << std::string(depth + 1, '\t') << "LHS:\n";
|
Log::out(std::string(depth + 1, '\t'), "LHS:");
|
||||||
m_Lhs.get()->Log(log, depth + 2);
|
m_Lhs->Log(depth + 2);
|
||||||
(*log) << std::string(depth + 1, '\t') << "RHS:\n";
|
|
||||||
m_Rhs.get()->Log(log, depth + 2);
|
Log::out(std::string(depth + 1, '\t'), "RHS:");
|
||||||
|
m_Rhs->Log(depth + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReturnStatement::Log(std::ofstream* log, unsigned depth)
|
void ReturnStatement::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out<Log::Format::NONE>(std::string(depth, '\t'), "Return");
|
||||||
|
|
||||||
if (m_Val == nullptr)
|
if (m_Val != nullptr)
|
||||||
{
|
{
|
||||||
(*log) << "Return\n";
|
Log::out(':');
|
||||||
|
m_Val->Log(depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*log) << "Return:\n";
|
Log::out<Log::Format::NONE>('\n');
|
||||||
m_Val->Log(log, depth + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableDeclaration::Log(std::ofstream* log, unsigned depth)
|
void VariableDeclaration::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out(std::string(depth, '\t'), "Variable declaration: ", m_Name);
|
||||||
(*log) << "Variable declaration: " << m_Name << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableAssignment::Log(std::ofstream* log, unsigned depth)
|
void VariableAssignment::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out(std::string(depth, '\t'), "Variable assignment:");
|
||||||
(*log) << "Variable assignment:\n";
|
|
||||||
(*log) << std::string(depth + 1, '\t') << "To: " << m_Name << "\n";
|
Log::out(std::string(depth + 1, '\t'), "To: ", m_Name);
|
||||||
(*log) << std::string(depth + 1, '\t') << "Value:\n";
|
Log::out(std::string(depth + 1, '\t'), "Value:");
|
||||||
m_Value.get()->Log(log, depth + 2);
|
m_Value->Log(depth + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableAccess::Log(std::ofstream* log, unsigned depth)
|
void VariableAccess::Log(unsigned depth)
|
||||||
{
|
{
|
||||||
(*log) << std::string(depth, '\t');
|
Log::out(std::string(depth, '\t'), "Variable: ", m_Name);
|
||||||
(*log) << "Variable: " << m_Name << '\n';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,16 +29,13 @@ namespace LX
|
|||||||
struct Parser
|
struct Parser
|
||||||
{
|
{
|
||||||
// Passes constructor args to members //
|
// Passes constructor args to members //
|
||||||
Parser(std::vector<Token>& _tokens, std::ofstream* _log)
|
Parser(std::vector<Token>& _tokens)
|
||||||
: tokens(_tokens), log(_log), index(0), len(_tokens.size()), scopeDepth(0)
|
: tokens(_tokens), index(0), len(_tokens.size()), scopeDepth(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Tokens created by the lexer //
|
// Tokens created by the lexer //
|
||||||
std::vector<Token>& tokens;
|
std::vector<Token>& tokens;
|
||||||
|
|
||||||
// Log to output to (can be null) //
|
|
||||||
std::ofstream* log;
|
|
||||||
|
|
||||||
// Length of the the token vector //
|
// Length of the the token vector //
|
||||||
const size_t len;
|
const size_t len;
|
||||||
|
|
||||||
@@ -203,14 +200,14 @@ namespace LX
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Turns the tokens of a file into it's abstract syntax tree equivalent //
|
// Turns the tokens of a file into it's abstract syntax tree equivalent //
|
||||||
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens, std::ofstream* log)
|
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens)
|
||||||
{
|
{
|
||||||
// Logs the start of the parsing
|
// Logs the start of the parsing
|
||||||
SafeLog(log, LOG_BREAK, "Started parsing tokens", LOG_BREAK);
|
Log::LogNewSection("Started parsing tokens");
|
||||||
|
|
||||||
// Creates the output storer and the parser //
|
// Creates the output storer and the parser //
|
||||||
FileAST output;
|
FileAST output;
|
||||||
Parser p(tokens, log);
|
Parser p(tokens);
|
||||||
|
|
||||||
// Loops over the tokens and calls the correct parsing function //
|
// Loops over the tokens and calls the correct parsing function //
|
||||||
// Which depends on their type and current state of the parser //
|
// Which depends on their type and current state of the parser //
|
||||||
@@ -261,7 +258,7 @@ namespace LX
|
|||||||
for (std::unique_ptr<AST::Node>& containedNode : ((AST::MultiNode*)node.get())->nodes)
|
for (std::unique_ptr<AST::Node>& containedNode : ((AST::MultiNode*)node.get())->nodes)
|
||||||
{
|
{
|
||||||
// Logs the node to the log //
|
// Logs the node to the log //
|
||||||
if (log != nullptr) { node->Log(log, 0); }
|
node->Log(0);
|
||||||
|
|
||||||
// Adds it to the vector //
|
// Adds it to the vector //
|
||||||
func.body.push_back(std::move(containedNode));
|
func.body.push_back(std::move(containedNode));
|
||||||
@@ -272,7 +269,7 @@ namespace LX
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Logs the node to the log //
|
// Logs the node to the log //
|
||||||
if (log != nullptr) { node->Log(log, 0); }
|
node->Log(0);
|
||||||
|
|
||||||
// Adds it to the vector //
|
// Adds it to the vector //
|
||||||
func.body.push_back(std::move(node));
|
func.body.push_back(std::move(node));
|
||||||
@@ -296,7 +293,7 @@ namespace LX
|
|||||||
|
|
||||||
// Logs that AST has finished parsing //
|
// Logs that AST has finished parsing //
|
||||||
// TODO: Make this output the AST in a human-readable form //
|
// TODO: Make this output the AST in a human-readable form //
|
||||||
SafeLog(log, "AST length: ", output.functions[0].body.size());
|
Log::out("AST length: ", output.functions[0].body.size());
|
||||||
|
|
||||||
// Returns the output and shrinks all uneccesarry allocated memory
|
// Returns the output and shrinks all uneccesarry allocated memory
|
||||||
output.functions.shrink_to_fit();
|
output.functions.shrink_to_fit();
|
||||||
|
|||||||
@@ -13,12 +13,10 @@ This is my custom compiled language written in C++ based off of the LLVM toolcha
|
|||||||
- Errors
|
- Errors
|
||||||
- All simple errors (no members) use the same type
|
- All simple errors (no members) use the same type
|
||||||
- Logging
|
- Logging
|
||||||
- Less templates
|
- Choose what is logged (if any)
|
||||||
- Standard for formatting
|
|
||||||
- Choose what is logged
|
|
||||||
- Refactor
|
- Refactor
|
||||||
- Use dynamic linking for debug builds (faster build times)
|
- Parser needs folders
|
||||||
- General clean up
|
- Better .h files
|
||||||
|
|
||||||
### Stuff I want to do later (unordered)
|
### Stuff I want to do later (unordered)
|
||||||
- I/O manager (Console, Files)
|
- I/O manager (Console, Files)
|
||||||
|
|||||||
BIN
example/Main.exe
BIN
example/Main.exe
Binary file not shown.
BIN
example/main.obj
BIN
example/main.obj
Binary file not shown.
Reference in New Issue
Block a user