mirror of
https://github.com/PashaBibko/LX.git
synced 2026-04-04 01:49:05 +00:00
Improved compile times
Added A LOT of comments
This commit is contained in:
@@ -21,5 +21,5 @@
|
||||
#pragma warning(pop)
|
||||
|
||||
#else
|
||||
#error This code only works with MSVC / VS22
|
||||
#error This code is only designed to work with MSVC due to the use of vcpkg and other aspects
|
||||
#endif // _MSC_VER
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Foward declarations of STD classes to minimise includes //
|
||||
namespace std
|
||||
{
|
||||
template<typename T1 = char>
|
||||
template<typename T1>
|
||||
struct char_traits;
|
||||
|
||||
template<typename T1, typename T2>
|
||||
@@ -24,6 +24,7 @@ namespace std
|
||||
|
||||
namespace LX
|
||||
{
|
||||
// Error type with index and character to alert the user that LX does not understand that symbol //
|
||||
struct InvalidCharInSource
|
||||
{
|
||||
std::streamsize index;
|
||||
|
||||
@@ -2,25 +2,15 @@
|
||||
|
||||
// Lexer foward declares fstream components so we can use them here //
|
||||
#include <Lexer.h>
|
||||
#include <LLVM.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Foward declares all items of the llvm lib that we need //
|
||||
// Done to avoid including LLVM.h to shorten compile times //
|
||||
/*
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
namespace llvm { class Value; }
|
||||
|
||||
class ConstantFolder;
|
||||
class IRBuilderDefaultInserter;
|
||||
|
||||
template<typename T1 = ConstantFolder, typename T2 = IRBuilderDefaultInserter>
|
||||
class IRBuilder;
|
||||
}*/
|
||||
// Foward declares the wrapper around the LLVM objects we need to pass around //
|
||||
namespace LX { struct InfoLLVM; }
|
||||
|
||||
// The nodes of the abstract syntax tree constructed by the parser from the tokens //
|
||||
namespace LX::AST
|
||||
@@ -46,16 +36,14 @@ namespace LX::AST
|
||||
UNDEFINED = -1
|
||||
};
|
||||
|
||||
// Constructor to set the node type //
|
||||
Node(NodeType type)
|
||||
: m_Type(type)
|
||||
{}
|
||||
// Constructor to set the node type (no others provided) //
|
||||
Node(NodeType type);
|
||||
|
||||
// Virtual destructor because of polymorphism //
|
||||
virtual ~Node() = default;
|
||||
|
||||
// Function for generating LLVN IR (Intermediate representation) //
|
||||
virtual llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) = 0;
|
||||
virtual llvm::Value* GenIR(InfoLLVM& LLVM) = 0;
|
||||
|
||||
// Function for generating C/C++ code (Currently not implemented) //
|
||||
//virtual void GenC() = 0;
|
||||
@@ -63,81 +51,36 @@ namespace LX::AST
|
||||
// The type of the node //
|
||||
const NodeType m_Type;
|
||||
};
|
||||
|
||||
class NumberLiteral : public Node
|
||||
{
|
||||
public:
|
||||
// Constructor to set values and automatically set type
|
||||
NumberLiteral(std::string num);
|
||||
|
||||
// Function for generating LLVN IR (Intermediate representation) //
|
||||
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) override;
|
||||
|
||||
private:
|
||||
// The number it stores
|
||||
// Yes the number is stored as a string
|
||||
// It's horrible I know
|
||||
std::string m_Number;
|
||||
};
|
||||
|
||||
//
|
||||
class Operation : public Node
|
||||
{
|
||||
public:
|
||||
// Constructor to set values and automatically set type
|
||||
Operation(std::unique_ptr<Node> lhs, Token::TokenType op, std::unique_ptr<Node> rhs);
|
||||
|
||||
// Function for generating LLVN IR (Intermediate representation) //
|
||||
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) override;
|
||||
|
||||
private:
|
||||
// The sides of the operation
|
||||
// Unary operations are handled by a different class
|
||||
std::unique_ptr<Node> m_Lhs, m_Rhs;
|
||||
|
||||
// The operation to be applied to the two sides
|
||||
Token::TokenType m_Operand;
|
||||
};
|
||||
|
||||
//
|
||||
class ReturnStatement : public Node
|
||||
{
|
||||
public:
|
||||
// Constructor to set values and automatically set type
|
||||
ReturnStatement(std::unique_ptr<Node> val);
|
||||
|
||||
// Function for generating LLVN IR (Intermediate representation) //
|
||||
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) override;
|
||||
|
||||
private:
|
||||
// What it is returning (can be null)
|
||||
std::unique_ptr<Node> m_Val;
|
||||
};
|
||||
}
|
||||
|
||||
namespace LX
|
||||
{
|
||||
// Thrown if there was an error during IR Generation //
|
||||
struct IRGenerationError {};
|
||||
|
||||
// Holds all needed info about a function //
|
||||
// Currently only holds the body but in the future will hold: name, params, namespace/class-member
|
||||
struct FunctionDefinition
|
||||
{
|
||||
FunctionDefinition()
|
||||
: body{}
|
||||
{}
|
||||
// Defualt constructor (none other given) //
|
||||
FunctionDefinition();
|
||||
|
||||
// The instructions of the body of the function //
|
||||
std::vector<std::unique_ptr<AST::Node>> body;
|
||||
};
|
||||
|
||||
struct FileAST
|
||||
{
|
||||
FileAST()
|
||||
: functions{}
|
||||
{}
|
||||
// Default constructor (none other given) //
|
||||
FileAST();
|
||||
|
||||
// All the functions within this file //
|
||||
std::vector<FunctionDefinition> functions;
|
||||
};
|
||||
|
||||
// Turns the tokens of a file into it's abstract syntax tree equivalent //
|
||||
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens, std::ofstream* log);
|
||||
|
||||
// Turns an abstract binary tree into LLVM intermediate representation //
|
||||
void GenerateIR(FileAST& ast);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,19 @@
|
||||
namespace LX
|
||||
{
|
||||
template<typename T, typename... Args>
|
||||
// Helper function to throw given error if condition is true //
|
||||
// Also micro-optimises to predict there is no errors thrown //
|
||||
inline void ThrowIf(const bool condition, Args... args)
|
||||
{ if (condition) [[unlikely]] { throw T(args...); }}
|
||||
|
||||
template<typename... Args>
|
||||
// Helper function for logging //
|
||||
// Only logs the given args if the log is not null //
|
||||
inline void SafeLog(std::ofstream* log, Args... args)
|
||||
{
|
||||
if (log != nullptr) { (*log << ... << args); *log << "\n"; }
|
||||
}
|
||||
|
||||
// Gives a standard way to mark a change between different sections within the log output //
|
||||
constexpr const char* LOG_BREAK = "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user