Parser is held together by duck-tape and a wish

This commit is contained in:
Pasha Bibko
2025-04-17 14:47:19 +01:00
parent e1fce699da
commit 3017e70631
6 changed files with 216 additions and 33 deletions

View File

@@ -24,52 +24,122 @@ namespace llvm
namespace LX::AST
{
// Base node that everything else inherits from
class Node
struct Node
{
// Enum for storing the type of node //
// Used so a pointer to Node can be used and then turned into it's true type //
enum NodeType
{
// General Nodes //
IDENTIFIER,
NUMBER_LITERAL,
OPERATION,
// Control flow Nodes //
RETURN_STATEMENT,
// If an error happened somewhere //
UNDEFINED = -1
};
// Constructor to set the node type //
Node(NodeType type)
: m_Type(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;
// Function for generating C/C++ code (Currently not implemented) //
//virtual void GenC() = 0;
// The type of the node //
const NodeType m_Type;
};
class NumberLiteral : public Node
{
public:
// Enum for storing the type of node //
// Used so a pointer to Node can be used and then turned into it's true type //
enum NodeType
{
// General Nodes //
IDENTIFIER,
// Control flow Nodes //
// If an error happened somewhere //
UNDEFINED = -1
};
// Constructor to set the node type //
Node(NodeType type)
: m_Type(type)
NumberLiteral(std::string num)
: Node(Node::NUMBER_LITERAL), m_Number(num)
{}
// Virtual destructor because of polymorphism //
virtual ~Node() = default;
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
{
return nullptr;
}
// Function for generating LLVN IR (Intermediate representation) //
virtual llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) = 0;
private:
// The number it stores
// Yes the number is stored as a string
// It's horrible I know
std::string m_Number;
};
// Function for generating C/C++ code (Currently not implemented) //
virtual void GenC() = 0;
//
class Operation : public Node
{
public:
Operation(std::unique_ptr<Node> lhs, Token::TokenType op, std::unique_ptr<Node> rhs)
: Node(Node::OPERATION), m_Lhs(std::move(lhs)), m_Operand(op), m_Rhs(std::move(rhs))
{}
// The type of the node //
const NodeType m_Type;
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
{
return nullptr;
}
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:
ReturnStatement(std::unique_ptr<Node> val)
: Node(Node::RETURN_STATEMENT), m_Val(std::move(val))
{}
llvm::Value* GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
{
return nullptr;
}
private:
// What it is returning (can be null)
std::unique_ptr<Node> m_Val;
};
}
namespace LX
{
struct FunctionDeclaration
struct FunctionDefinition
{
FunctionDefinition()
: body{}
{}
std::vector<std::unique_ptr<AST::Node>> body;
};
struct FileAST
{
std::vector<FunctionDeclaration> functions;
FileAST()
: functions{}
{}
std::vector<FunctionDefinition> functions;
};
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens, std::ofstream* log);