From 5339df9b363f5036e62ec4f6cab22bb002c5b6e7 Mon Sep 17 00:00:00 2001
From: Pasha Bibko <156938226+PashaBibko@users.noreply.github.com>
Date: Mon, 5 May 2025 23:55:22 +0100
Subject: [PATCH] Refactored how logging works
Made it central reusable logic. No longer needs to be passed around, opened or closed.
---
Common/Common.vcxproj | 2 +
Common/Common.vcxproj.filters | 6 +++
Common/LX-Common.h | 14 ++++++-
Common/inc/Console.h | 49 +++++++++--------------
Common/inc/Logger.h | 62 ++++++++++++++++++++++--------
Common/src/Console.cpp | 19 +++++++++
Common/src/Logger.cpp | 26 +++++++++++++
Common/src/dllmain.cpp | 32 +++++++--------
IR-Generator/IR-Generator.vcxproj | 9 ++++-
IR-Generator/inc/Lexer.h | 2 +-
IR-Generator/inc/Parser.h | 4 +-
IR-Generator/src/Generator.cpp | 45 ++++------------------
LX-Build/LX-API.cs | 2 +-
LX-Build/Main.cs | 2 +-
LX-Compiler.sln | 3 --
Lexer/src/Lexer.cpp | 46 +++++++++-------------
Parser/inc/AST.h | 14 +++----
Parser/src/AST-Loggers.cpp | 60 ++++++++++++++---------------
Parser/src/Parser.cpp | 19 ++++-----
README.md | 8 ++--
example/Main.exe | Bin 2560 -> 0 bytes
example/main.obj | Bin 549 -> 0 bytes
22 files changed, 231 insertions(+), 193 deletions(-)
create mode 100644 Common/src/Console.cpp
create mode 100644 Common/src/Logger.cpp
delete mode 100644 example/Main.exe
delete mode 100644 example/main.obj
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index a410ccc..4d04ade 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -158,7 +158,9 @@
+
+
Create
Create
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index ec082b4..eb71ae7 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -37,5 +37,11 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
\ No newline at end of file
diff --git a/Common/LX-Common.h b/Common/LX-Common.h
index a6b1312..586efce 100644
--- a/Common/LX-Common.h
+++ b/Common/LX-Common.h
@@ -11,7 +11,8 @@
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include
-
+ #undef NOMINMAX
+ #undef WIN32_LEAN_AND_MEAN
// Else alerts the user that their system is not supported //
#else
#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"
#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 //
#include
diff --git a/Common/inc/Console.h b/Common/inc/Console.h
index f516810..ef93f52 100644
--- a/Common/inc/Console.h
+++ b/Common/inc/Console.h
@@ -1,41 +1,30 @@
namespace LX
{
+ // Enum of colors with their Win32 equivalent value //
enum class Color
{
- BLACK = 0,
- BLUE = 1,
- GREEN = 2,
- AQUA = 3,
- RED = 4,
- PURPLE = 5,
- YELLOW = 6,
- LIGHT_GRAY = 7,
- LIGHT_BLUE = 9,
- LIGHT_GREEN = 10,
- LIGHT_AQUA = 11,
- LIGHT_RED = 12,
- LIGHT_PURPLE = 13,
- LIGHT_YELLOW = 14,
- WHITE = 15
+ BLACK = 0,
+ BLUE = 1,
+ GREEN = 2,
+ AQUA = 3,
+ RED = 4,
+ PURPLE = 5,
+ YELLOW = 6,
+ LIGHT_GRAY = 7,
+ LIGHT_BLUE = 9,
+ LIGHT_GREEN = 10,
+ LIGHT_AQUA = 11,
+ LIGHT_RED = 12,
+ LIGHT_PURPLE = 13,
+ LIGHT_YELLOW = 14,
+ WHITE = 15
};
- inline 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);
- }
+ // 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);
// 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 //
size_t start = src.rfind('\n', index);
diff --git a/Common/inc/Logger.h b/Common/inc/Logger.h
index d7ceebe..2887d9a 100644
--- a/Common/inc/Logger.h
+++ b/Common/inc/Logger.h
@@ -1,23 +1,51 @@
namespace LX
{
- template
- inline void SafeLog(std::ofstream* log, Args... args)
+ class COMMON_API Log
{
- if (log != nullptr)
- {
- (*log << ... << args);
- (*log << '\n');
- }
- }
+ public:
+ // This class should never be constructed //
+ Log() = delete;
- inline void SafeFlush(std::ofstream* log)
- {
- if (log != nullptr)
- {
- log->flush();
- }
- }
+ enum class Format
+ {
+ AUTO,
+ NONE
+ };
- // Gives a standard way to mark a change between different sections within the log output //
- constexpr const char* LOG_BREAK = "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
+ template
+ static void out(Args... args)
+ {
+ if constexpr (format == Format::AUTO)
+ {
+ ((*s_LogFile << ... << args) << "\n");
+ }
+
+ else
+ {
+ (*s_LogFile << ... << args);
+ }
+ }
+
+ template
+ 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;
+ };
}
diff --git a/Common/src/Console.cpp b/Common/src/Console.cpp
new file mode 100644
index 0000000..c982f07
--- /dev/null
+++ b/Common/src/Console.cpp
@@ -0,0 +1,19 @@
+#include
+
+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);
+ }
+}
diff --git a/Common/src/Logger.cpp b/Common/src/Logger.cpp
new file mode 100644
index 0000000..d751907
--- /dev/null
+++ b/Common/src/Logger.cpp
@@ -0,0 +1,26 @@
+#include
+
+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();
+ }
+}
diff --git a/Common/src/dllmain.cpp b/Common/src/dllmain.cpp
index 91355f7..dbcd676 100644
--- a/Common/src/dllmain.cpp
+++ b/Common/src/dllmain.cpp
@@ -3,36 +3,38 @@
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);
static bool ProcAttach(HMODULE hModule)
{
+ Log::Init(); // Initalises the log before the main process starts
+ return true;
}
static bool ProcDetach(HMODULE hModule)
{
+ return true;
}
- static bool ThreadAttach(HMODULE hModule)
- {
- }
-
- static bool ThreadDetach(HMODULE hModule)
- {
- }
+ static bool ThreadAttach(HMODULE hModule) { return true; }
+ static bool ThreadDetach(HMODULE hModule) { return true; }
}
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 funcs =
{
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
+ { DLL_PROCESS_ATTACH, LX::ProcAttach },
+ { DLL_PROCESS_DETACH, LX::ProcDetach },
+ { DLL_THREAD_ATTACH , LX::ThreadAttach },
+ { DLL_THREAD_DETACH , LX::ThreadDetach }
+ };
- return true;
+ // Returns the output of the relavant function //
+ return funcs.at(ul_reason_for_call)(hModule);
}
diff --git a/IR-Generator/IR-Generator.vcxproj b/IR-Generator/IR-Generator.vcxproj
index 0e9e1d9..7d4f96d 100644
--- a/IR-Generator/IR-Generator.vcxproj
+++ b/IR-Generator/IR-Generator.vcxproj
@@ -122,7 +122,7 @@
Console
true
$(SolutionDir)bin\$(Platform)\$(Configuration)
- Parser.lib;Lexer.lib;ws2_32.lib;%(AdditionalDependencies)
+ Parser.lib;Lexer.lib;Common.lib;ws2_32.lib;%(AdditionalDependencies)
@@ -144,7 +144,7 @@
true
true
$(SolutionDir)bin\$(Platform)\$(Configuration)
- Parser.lib;Lexer.lib;ws2_32.lib;%(AdditionalDependencies)
+ Parser.lib;Lexer.lib;Common.lib;ws2_32.lib;%(AdditionalDependencies)
@@ -158,6 +158,11 @@
+
+
+ {0abb03b7-e61a-4040-a512-fc05aa35b2a6}
+
+
diff --git a/IR-Generator/inc/Lexer.h b/IR-Generator/inc/Lexer.h
index 2e610a0..2fdaa7e 100644
--- a/IR-Generator/inc/Lexer.h
+++ b/IR-Generator/inc/Lexer.h
@@ -128,5 +128,5 @@ namespace LX
std::string ToString(Token::TokenType t);
// Lexer function to take in a file and output a vector of tokens //
- const std::vector LexicalAnalyze(const std::string& contents, const std::streamsize len, std::ofstream* log);
+ const std::vector LexicalAnalyze(const std::string& contents, const std::streamsize len);
}
diff --git a/IR-Generator/inc/Parser.h b/IR-Generator/inc/Parser.h
index 0461c92..e816d4d 100644
--- a/IR-Generator/inc/Parser.h
+++ b/IR-Generator/inc/Parser.h
@@ -51,7 +51,7 @@ namespace LX::AST
virtual llvm::Value* GenIR(InfoLLVM& LLVM) = 0;
// 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) //
//virtual void GenC() = 0;
@@ -143,7 +143,7 @@ namespace LX
};
// Turns the tokens of a file into it's abstract syntax tree equivalent //
- FileAST TurnTokensIntoAbstractSyntaxTree(std::vector& tokens, std::ofstream* log);
+ FileAST TurnTokensIntoAbstractSyntaxTree(std::vector& tokens);
// Turns an abstract binary tree into LLVM intermediate representation //
void GenerateIR(FileAST& ast, const std::string& name, const std::filesystem::path& IRPath);
diff --git a/IR-Generator/src/Generator.cpp b/IR-Generator/src/Generator.cpp
index ccbc27e..c2a11a9 100644
--- a/IR-Generator/src/Generator.cpp
+++ b/IR-Generator/src/Generator.cpp
@@ -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 //
std::filesystem::path inpPath;
std::filesystem::path outPath;
- std::filesystem::path logPath;
// Creates the contents string outside of the try-catch so they can be used in errors //
std::string 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 log = nullptr;
-
try
{
// 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(outFile.is_open() == false, "output file path", outPath);
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(logPath);
- LX::ThrowIf(log->is_open() == false, "log file path", logPath);
- }
-
// 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;
// Create tokens out of the input file //
LX::InvalidCharInSource::s_Source = &contents;
LX::InvalidCharInSource::s_SourceFile = &inpPath;
- std::vectortokens = LX::LexicalAnalyze(contents, len, log.get());
- LX::SafeFlush(log.get());
+ std::vectortokens = LX::LexicalAnalyze(contents, len);
// Turns the tokens into an AST //
LX::UnexpectedToken::s_Source = &contents;
LX::UnexpectedToken::s_SourceFile = &inpPath;
- LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens, log.get());
- LX::SafeFlush(log.get());
+ LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens);
// Turns the AST into LLVM IR //
LX::GenerateIR(AST, inpPath.filename().string(), outPath);
- LX::SafeFlush(log.get());
// Returns success
return 0;
@@ -103,9 +88,8 @@ extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_
catch(LX::RuntimeError& e)
{
- // Closes the log to save everything outputted to it after logging the error //
- LX::SafeLog(log.get(), LX::LOG_BREAK, "Error thrown of type: ", e.ErrorType(), LX::LOG_BREAK);
- if (log != nullptr) { log->close(); }
+ // Logs the error. Does not need to close it as it is done after this function returns //
+ LX::Log::LogNewSection("Error thrown of type: ", e.ErrorType());
// Logs the errors type to the console if built as 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 //
catch (std::exception& e)
{
- // Closes the log if it is open to get as much info as possible //
- if (log != nullptr) { log->close(); }
+ // Logs the error. Does not need to close it as it is done after this function returns //
+ LX::Log::LogNewSection("std::exception thrown: ", e.what());
// Prints the std exception to the console //
// 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;
}
- // 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 //
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 //
return -1;
}
diff --git a/LX-Build/LX-API.cs b/LX-Build/LX-API.cs
index ec80b6b..c174ee4 100644
--- a/LX-Build/LX-API.cs
+++ b/LX-Build/LX-API.cs
@@ -14,7 +14,7 @@ namespace LX_Build
[LibraryImport ("Generator.dll", StringMarshalling = StringMarshalling.Custom,
StringMarshallingCustomType = typeof(System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller))]
[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 //
public static void Init()
diff --git a/LX-Build/Main.cs b/LX-Build/Main.cs
index 113b0c8..78c2d36 100644
--- a/LX-Build/Main.cs
+++ b/LX-Build/Main.cs
@@ -45,7 +45,7 @@ namespace LX_Build
LX_API.Init();
// 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 //
// The C++ script handles all of the error message outputting //
diff --git a/LX-Compiler.sln b/LX-Compiler.sln
index 79bfa9a..31b063f 100644
--- a/LX-Compiler.sln
+++ b/LX-Compiler.sln
@@ -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}
EndProjectSection
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}"
EndProject
Global
@@ -109,7 +107,6 @@ Global
{4E4019F5-12E0-4EE2-9658-A0DD3038EEDA} = {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}
- {0ABB03B7-E61A-4040-A512-FC05AA35B2A6} = {4AD62954-631A-4D0F-877E-E1C66E8CEC00}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {411AFEC9-4075-4FCC-B95A-9288BC822E90}
diff --git a/Lexer/src/Lexer.cpp b/Lexer/src/Lexer.cpp
index 6f2f1b7..043eed1 100644
--- a/Lexer/src/Lexer.cpp
+++ b/Lexer/src/Lexer.cpp
@@ -175,10 +175,10 @@ namespace LX
}
}
- const std::vector LX::LexicalAnalyze(const std::string& contents, std::streamsize len, std::ofstream* log)
+ const std::vector LX::LexicalAnalyze(const std::string& contents, std::streamsize len)
{
// 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 //
// 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 //
LexerInfo info;
-
+
// Iterates over the file and turns it into tokens //
while (info.index < len)
{
@@ -344,11 +344,9 @@ namespace LX
// Log dumps A LOT of info //
- #ifdef LOG_EVERYTHING
-
- SafeLog
+ Log::out
(
- log, "Index: ", std::left, std::setw(3), info.index,
+ "Index: ", std::left, std::setw(3), info.index,
" Is Alpha: ", info.isAlpha,
" Is Numeric: ", info.isNumeric,
" In Comment: ", info.inComment,
@@ -360,8 +358,6 @@ namespace LX
" Current: {", PrintChar(current), "}"
);
- #endif // LOG_EVERYTHING
-
// Updates trackers to their default state of a new character //
info.index++;
@@ -371,28 +367,22 @@ namespace LX
info.wasLastCharNumeric = info.isNumeric;
}
- // Logs the tokens if logging is on //
- if (log != nullptr)
+ Log::out("\n"); // Puts a space to clean up the log
+
+ for (auto& token : tokens)
{
- #ifdef LOG_EVERYTHING
- SafeLog(log, "\n"); // Puts a space when there is a lot in the log
- #endif // LOG_EVERYTHING
-
- for (auto& token : tokens)
- {
- SafeLog
- (
- 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
+ (
+ 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(), "}"
+ );
}
+ Log::out("End of tokens");
+
// Shrinks the vector down to minimum size before returning to avoid excess memory being allocated
tokens.shrink_to_fit();
return tokens;
diff --git a/Parser/inc/AST.h b/Parser/inc/AST.h
index ba41561..778f038 100644
--- a/Parser/inc/AST.h
+++ b/Parser/inc/AST.h
@@ -31,7 +31,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// 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 //
std::vector> nodes;
@@ -48,7 +48,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// The number it stores //
@@ -67,7 +67,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// The sides of the operation //
@@ -89,7 +89,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// What it is returning (can be null) //
@@ -107,7 +107,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// Name of the variable //
@@ -127,7 +127,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// Name of the variable //
@@ -148,7 +148,7 @@ namespace LX::AST
llvm::Value* GenIR(InfoLLVM& LLVM) override;
// Function to log the node to a file //
- void Log(std::ofstream* log, unsigned depth) override;
+ void Log(unsigned depth) override;
private:
// The name of the variable //
diff --git a/Parser/src/AST-Loggers.cpp b/Parser/src/AST-Loggers.cpp
index e689084..5c76688 100644
--- a/Parser/src/AST-Loggers.cpp
+++ b/Parser/src/AST-Loggers.cpp
@@ -4,61 +4,59 @@
namespace LX::AST
{
- void MultiNode::Log(std::ofstream* log, unsigned depth)
+ void MultiNode::Log(unsigned depth)
{
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) << "Number: " << m_Number << "\n";
+ Log::out(std::string(depth, '\t'), "Number: ", m_Number);
}
- void Operation::Log(std::ofstream* log, unsigned depth)
+ void Operation::Log(unsigned depth)
{
- (*log) << std::string(depth, '\t');
- (*log) << "Operation {" << ToString(m_Operand) << "}:\n";
- (*log) << std::string(depth + 1, '\t') << "LHS:\n";
- m_Lhs.get()->Log(log, depth + 2);
- (*log) << std::string(depth + 1, '\t') << "RHS:\n";
- m_Rhs.get()->Log(log, depth + 2);
+ Log::out(std::string(depth, '\t'), "Operation {", ToString(m_Operand), "}:");
+
+ Log::out(std::string(depth + 1, '\t'), "LHS:");
+ m_Lhs->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');
-
- if (m_Val == nullptr)
+ Log::out(std::string(depth, '\t'), "Return");
+
+ if (m_Val != nullptr)
{
- (*log) << "Return\n";
+ Log::out(':');
+ m_Val->Log(depth + 1);
}
-
+
else
{
- (*log) << "Return:\n";
- m_Val->Log(log, depth + 1);
+ Log::out('\n');
}
}
- void VariableDeclaration::Log(std::ofstream* log, unsigned depth)
+ void VariableDeclaration::Log(unsigned depth)
{
- (*log) << std::string(depth, '\t');
- (*log) << "Variable declaration: " << m_Name << "\n";
+ Log::out(std::string(depth, '\t'), "Variable declaration: ", m_Name);
}
- void VariableAssignment::Log(std::ofstream* log, unsigned depth)
+ void VariableAssignment::Log(unsigned depth)
{
- (*log) << std::string(depth, '\t');
- (*log) << "Variable assignment:\n";
- (*log) << std::string(depth + 1, '\t') << "To: " << m_Name << "\n";
- (*log) << std::string(depth + 1, '\t') << "Value:\n";
- m_Value.get()->Log(log, depth + 2);
+ Log::out(std::string(depth, '\t'), "Variable assignment:");
+
+ Log::out(std::string(depth + 1, '\t'), "To: ", m_Name);
+ Log::out(std::string(depth + 1, '\t'), "Value:");
+ m_Value->Log(depth + 2);
}
- void VariableAccess::Log(std::ofstream* log, unsigned depth)
+ void VariableAccess::Log(unsigned depth)
{
- (*log) << std::string(depth, '\t');
- (*log) << "Variable: " << m_Name << '\n';
+ Log::out(std::string(depth, '\t'), "Variable: ", m_Name);
}
}
diff --git a/Parser/src/Parser.cpp b/Parser/src/Parser.cpp
index e1af18f..fbd9fbf 100644
--- a/Parser/src/Parser.cpp
+++ b/Parser/src/Parser.cpp
@@ -29,16 +29,13 @@ namespace LX
struct Parser
{
// Passes constructor args to members //
- Parser(std::vector& _tokens, std::ofstream* _log)
- : tokens(_tokens), log(_log), index(0), len(_tokens.size()), scopeDepth(0)
+ Parser(std::vector& _tokens)
+ : tokens(_tokens), index(0), len(_tokens.size()), scopeDepth(0)
{}
// Tokens created by the lexer //
std::vector& tokens;
- // Log to output to (can be null) //
- std::ofstream* log;
-
// Length of the the token vector //
const size_t len;
@@ -203,14 +200,14 @@ namespace LX
}
// Turns the tokens of a file into it's abstract syntax tree equivalent //
- FileAST TurnTokensIntoAbstractSyntaxTree(std::vector& tokens, std::ofstream* log)
+ FileAST TurnTokensIntoAbstractSyntaxTree(std::vector& tokens)
{
// 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 //
FileAST output;
- Parser p(tokens, log);
+ Parser p(tokens);
// Loops over the tokens and calls the correct parsing function //
// Which depends on their type and current state of the parser //
@@ -261,7 +258,7 @@ namespace LX
for (std::unique_ptr& containedNode : ((AST::MultiNode*)node.get())->nodes)
{
// Logs the node to the log //
- if (log != nullptr) { node->Log(log, 0); }
+ node->Log(0);
// Adds it to the vector //
func.body.push_back(std::move(containedNode));
@@ -272,7 +269,7 @@ namespace LX
else
{
// Logs the node to the log //
- if (log != nullptr) { node->Log(log, 0); }
+ node->Log(0);
// Adds it to the vector //
func.body.push_back(std::move(node));
@@ -296,7 +293,7 @@ namespace LX
// Logs that AST has finished parsing //
// 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
output.functions.shrink_to_fit();
diff --git a/README.md b/README.md
index b577126..e9b50fa 100644
--- a/README.md
+++ b/README.md
@@ -13,12 +13,10 @@ This is my custom compiled language written in C++ based off of the LLVM toolcha
- Errors
- All simple errors (no members) use the same type
- Logging
- - Less templates
- - Standard for formatting
- - Choose what is logged
+ - Choose what is logged (if any)
- Refactor
- - Use dynamic linking for debug builds (faster build times)
- - General clean up
+ - Parser needs folders
+ - Better .h files
### Stuff I want to do later (unordered)
- I/O manager (Console, Files)
diff --git a/example/Main.exe b/example/Main.exe
deleted file mode 100644
index c57350fb985ca0c1abb22626255dab26fd542ca3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2560
zcmeZ`s$gJbU|?VYVr1Ze%)!B~0E+X;@8VY5PjpE#zJfZRw-h;99Ai>uocp#^CTAu`5=%ZTqP-jzsaiYyEBis^YM20dJfvH0N2L|aCuhbRm`hx{uSg5JLo^UVVb86{JW7Sh(FxZ
za@m0YrEBtvdcjL$ov4?%MV)tLydU$H?Lbp=>znkq_uZ&G0Nbd0Vc6Td#e+`~ft-=(
zSM!lS6;YKc*q+a{CJ1||P!d|X-#z%Qp%^T#)i6gIe7jHx4q4|AG4TTtIExDBplv4Q
zjh`+QfZwM=3Hbi5_pc)1tz7
GvEv_nM>wni