From b3373a858cea7a8fe3cafdec09ad1513c7e6a579 Mon Sep 17 00:00:00 2001
From: Pasha Bibko <156938226+PashaBibko@users.noreply.github.com>
Date: Sat, 19 Apr 2025 11:41:52 +0100
Subject: [PATCH] Removed LLVM
---
LX-LLVM.vcxproj | 1 -
LX-LLVM.vcxproj.filters | 3 -
Main.cpp | 3 -
Parser/Parser.vcxproj | 2 -
Parser/Parser.vcxproj.filters | 6 -
Parser/src/AST-LLVM.cpp | 54 ---
Parser/src/GenIR.cpp | 64 ----
build-test/Log.txt | 17 +
build-test/tmp | 261 ++++++++++++++
build-test/x.cpp | 622 ++++++++++++++++++++++++++++++++++
common/LLVM.h | 25 --
common/Parser.h | 15 -
12 files changed, 900 insertions(+), 173 deletions(-)
delete mode 100644 Parser/src/AST-LLVM.cpp
delete mode 100644 Parser/src/GenIR.cpp
create mode 100644 build-test/tmp
create mode 100644 build-test/x.cpp
delete mode 100644 common/LLVM.h
diff --git a/LX-LLVM.vcxproj b/LX-LLVM.vcxproj
index 1fb1e60..b747bea 100644
--- a/LX-LLVM.vcxproj
+++ b/LX-LLVM.vcxproj
@@ -140,7 +140,6 @@
-
diff --git a/LX-LLVM.vcxproj.filters b/LX-LLVM.vcxproj.filters
index db15802..87e8a8f 100644
--- a/LX-LLVM.vcxproj.filters
+++ b/LX-LLVM.vcxproj.filters
@@ -16,9 +16,6 @@
Common
-
- Common
-
diff --git a/Main.cpp b/Main.cpp
index e0d91ef..2fcc0f2 100644
--- a/Main.cpp
+++ b/Main.cpp
@@ -56,9 +56,6 @@ int main(int argc, char** argv)
// Turns the tokens into an AST
LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens, log.get());
- // Turns the AST into something
- LX::GenerateIR(AST);
-
// Returns success
return 0;
}
diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj
index c5ffbbe..f78fa36 100644
--- a/Parser/Parser.vcxproj
+++ b/Parser/Parser.vcxproj
@@ -132,8 +132,6 @@
-
-
diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters
index 9159eb8..b9b222e 100644
--- a/Parser/Parser.vcxproj.filters
+++ b/Parser/Parser.vcxproj.filters
@@ -14,14 +14,8 @@
Source Files
-
- Source Files
-
Source Files
-
- Source Files
-
\ No newline at end of file
diff --git a/Parser/src/AST-LLVM.cpp b/Parser/src/AST-LLVM.cpp
deleted file mode 100644
index 0ba3f17..0000000
--- a/Parser/src/AST-LLVM.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include
-
-#include
-#include
-
-namespace LX::AST
-{
- llvm::Value* NumberLiteral::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
- {
- // Converts the string to it's int equivalent
- // Will eventually need to do floating point stuff here as well
- int number = std::stoi(m_Number);
-
- // Returns it as a llvm value (if valid)
- llvm::Value* out = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), number, true);
- ThrowIf(out == nullptr);
- return out;
- }
-
- llvm::Value* Operation::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
- {
- // Gets the IR for both sides of the operation
- llvm::Value* lhs = m_Lhs->GenIR(context, module, builder);
- llvm::Value* rhs = m_Rhs->GenIR(context, module, builder);
-
- // If either side is null then return null to prevent invalid IR //
- if (lhs == nullptr || rhs == nullptr)
- {
- ThrowIf(true);
- return nullptr;
- }
-
- // Will eventually get the correct operator but for now everything is add
- llvm::Value* out = builder.CreateAdd(lhs, rhs);
- ThrowIf(out == nullptr);
- return out;
- }
-
- llvm::Value* ReturnStatement::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
- {
- if (m_Val == nullptr)
- {
- ThrowIf(true);
- return nullptr;
- }
-
- else
- {
- llvm::Value* out = builder.CreateRet(m_Val->GenIR(context, module, builder));
- ThrowIf(out == nullptr);
- return out;
- }
- }
-}
diff --git a/Parser/src/GenIR.cpp b/Parser/src/GenIR.cpp
deleted file mode 100644
index ae8d646..0000000
--- a/Parser/src/GenIR.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include
-
-#include
-
-namespace LX
-{
- void GenerateIR(FileAST& ast)
- {
- // Generates stuff //
-
- llvm::LLVMContext context;
- llvm::IRBuilder<> builder(context);
-
- {
- std::unique_ptr module = std::make_unique("add_ints", context);
-
- // Defines main function //
-
- llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getInt32Ty(context), false);
- llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module.get());
- llvm::BasicBlock* entry = llvm::BasicBlock::Create(context, "entry", mainFunc);
- builder.SetInsertPoint(entry);
-
- // Loops over AST to generate IR //
-
- for (auto& node : ast.functions[0].body)
- {
- switch (node->m_Type)
- {
- case AST::Node::RETURN_STATEMENT:
- {
- node->GenIR(context, *module, builder);
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
-
- if (entry->getTerminator() == nullptr)
- {
- builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 0, true));
- }
-
- // Verification of the IR //
-
- if (llvm::verifyFunction(*mainFunc, &llvm::errs()) || llvm::verifyModule(*module, &llvm::errs()))
- {
- std::cerr << "Error: IR generation failed" << std::endl;
- return;
- }
-
- // Outputs the IR to the console //
-
- module->print(llvm::outs(), nullptr);
-
- } // <- Crashes here
-
- std::cout << "Finished generating IR" << std::endl;
- }
-}
diff --git a/build-test/Log.txt b/build-test/Log.txt
index e69de29..8e6fb47 100644
--- a/build-test/Log.txt
+++ b/build-test/Log.txt
@@ -0,0 +1,17 @@
+
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+Started lexing file
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+Token::FUNCTION
+Token::IDENTIFIER: main
+Unknown: 3
+Token::NUMBER_LITERAL: 3
+Token::ADD
+Token::NUMBER_LITERAL: 4
+
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+Started parsing tokens
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+AST length: 1
diff --git a/build-test/tmp b/build-test/tmp
new file mode 100644
index 0000000..0ef5127
--- /dev/null
+++ b/build-test/tmp
@@ -0,0 +1,261 @@
+/* File 0 */
+
+namespace LX::AST
+{
+ // Base node that everything else inherits from
+ 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:
+ // 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 lhs, Token::TokenType op, std::unique_ptr 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 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 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 m_Val;
+ };
+}
+
+namespace LX
+{
+ struct IRGenerationError {};
+
+ struct FunctionDefinition
+ {
+ FunctionDefinition()
+ : body{}
+ {}
+
+ std::vector> body;
+ };
+
+ struct FileAST
+ {
+ FileAST()
+ : functions{}
+ {}
+
+ std::vector functions;
+ };
+
+ FileAST TurnTokensIntoAbstractSyntaxTree(std::vector& tokens, std::ofstream* log);
+
+ void GenerateIR(FileAST& ast);
+}
+
+/* File 1 */
+
+#include
+
+#include
+#include
+
+namespace LX::AST
+{
+ llvm::Value* NumberLiteral::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
+ {
+ // Converts the string to it's int equivalent
+ // Will eventually need to do floating point stuff here as well
+ int number = std::stoi(m_Number);
+
+ // Returns it as a llvm value (if valid)
+ llvm::Value* out = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), number, true);
+ ThrowIf(out == nullptr);
+ return out;
+ }
+
+ llvm::Value* Operation::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
+ {
+ // Gets the IR for both sides of the operation
+ llvm::Value* lhs = m_Lhs->GenIR(context, module, builder);
+ llvm::Value* rhs = m_Rhs->GenIR(context, module, builder);
+
+ // If either side is null then return null to prevent invalid IR //
+ if (lhs == nullptr || rhs == nullptr)
+ {
+ ThrowIf(true);
+ return nullptr;
+ }
+
+ // Will eventually get the correct operator but for now everything is add
+ llvm::Value* out = builder.CreateAdd(lhs, rhs);
+ ThrowIf(out == nullptr);
+ return out;
+ }
+
+ llvm::Value* ReturnStatement::GenIR(llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder)
+ {
+ if (m_Val == nullptr)
+ {
+ ThrowIf(true);
+ return nullptr;
+ }
+
+ else
+ {
+ llvm::Value* out = builder.CreateRet(m_Val->GenIR(context, module, builder));
+ ThrowIf(out == nullptr);
+ return out;
+ }
+ }
+}
+
+/* File 2 */
+
+#include
+
+#include
+
+namespace LX
+{
+ void GenerateIR(FileAST& ast)
+ {
+ // Generates stuff //
+
+ llvm::LLVMContext context;
+ llvm::IRBuilder<> builder(context);
+
+ {
+ std::unique_ptr module = std::make_unique("add_ints", context);
+
+ // Defines main function //
+
+ llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getInt32Ty(context), false);
+ llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module.get());
+ llvm::BasicBlock* entry = llvm::BasicBlock::Create(context, "entry", mainFunc);
+ builder.SetInsertPoint(entry);
+
+ // Loops over AST to generate IR //
+
+ for (auto& node : ast.functions[0].body)
+ {
+ switch (node->m_Type)
+ {
+ case AST::Node::RETURN_STATEMENT:
+ {
+ node->GenIR(context, *module, builder);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if (entry->getTerminator() == nullptr)
+ {
+ builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 0, true));
+ }
+
+ // Verification of the IR //
+
+ if (llvm::verifyFunction(*mainFunc, &llvm::errs()) || llvm::verifyModule(*module, &llvm::errs()))
+ {
+ std::cerr << "Error: IR generation failed" << std::endl;
+ return;
+ }
+
+ // Outputs the IR to the console //
+
+ module->print(llvm::outs(), nullptr);
+
+ } // <- Crashes here
+
+ std::cout << "Finished generating IR" << std::endl;
+ }
+}
+
+
+/* Output */
+
+; ModuleID = 'add_ints'
+source_filename = "add_ints"
+
+define i32 @main() {
+entry:
+ ret i32 7
+}
+Finished generating IR
+
+/* AST */
+
+func main
+ return 3 + 4
diff --git a/build-test/x.cpp b/build-test/x.cpp
new file mode 100644
index 0000000..0356300
--- /dev/null
+++ b/build-test/x.cpp
@@ -0,0 +1,622 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include
+#include
+#include
+#include
+#include