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 c57350f..0000000 Binary files a/example/Main.exe and /dev/null differ diff --git a/example/main.obj b/example/main.obj deleted file mode 100644 index dd9ec5e..0000000 Binary files a/example/main.obj and /dev/null differ