From ab1d78b9b9a30316d4e57f112138f95222fed9c7 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Mon, 3 Aug 2026 18:01:10 +0100 Subject: [PATCH 01/16] Create build module method --- src/generation/generator.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index db95b86..a698633 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -56,8 +56,7 @@ class Generator { llvm::InitializeNativeTargetAsmParser(); } - void compile() { - + std::unique_ptr buildModule() { llvm::LLVMContext context; std::unique_ptr module = @@ -408,6 +407,11 @@ class Generator { builder.createReturn(returnValue); } + return std::move(module); + } + + void compile() { + std::unique_ptr module = this->buildModule(); std::cout << "-- LLVM IR --" << std::endl; module->print(llvm::outs(), nullptr); From 3f1560991986351f1fe20f8bb9e2f1b57be0e585 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Mon, 3 Aug 2026 18:01:22 +0100 Subject: [PATCH 02/16] Create template system test --- tests/system.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/system.cpp diff --git a/tests/system.cpp b/tests/system.cpp new file mode 100644 index 0000000..f8dd595 --- /dev/null +++ b/tests/system.cpp @@ -0,0 +1,24 @@ +#include + +#include "generation/generator.hpp" +#include "io/file_reader.hpp" +#include "lexer/lexer.hpp" +#include "lexer/token_container/token_container.hpp" +#include "syntax_analyser/abstract_syntax_tree.hpp" + +TEST_CASE("Run \"./examples/addition.lang\"", "[system]") { + FileReader fileReader("./examples/addition.lang"); + Lexer lexer = Lexer(fileReader.readAll()); + + TokenContainer tokens = lexer.makeTokenList(); + tokens.print(); + + AbstractSyntaxTree ast(tokens); + + Program program = ast.parse(); + program.print(); + + Generator generator(program); + generator.init(); + generator.compile(); +}; From 6042fc0f708275c727b170ed772b2369b9ac0b12 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Mon, 3 Aug 2026 22:55:17 +0100 Subject: [PATCH 03/16] Pas context as parameter --- src/generation/generator.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index a698633..a935b7b 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -56,8 +56,7 @@ class Generator { llvm::InitializeNativeTargetAsmParser(); } - std::unique_ptr buildModule() { - llvm::LLVMContext context; + std::unique_ptr buildModule(llvm::LLVMContext& context) { std::unique_ptr module = std::make_unique("build", context); @@ -407,11 +406,13 @@ class Generator { builder.createReturn(returnValue); } - return std::move(module); + return module; } void compile() { - std::unique_ptr module = this->buildModule(); + llvm::LLVMContext context; + std::unique_ptr module = this->buildModule(context); + std::cout << "-- LLVM IR --" << std::endl; module->print(llvm::outs(), nullptr); From cfb7d9f13fc58e86e1cbe5a1c89efdff571e4f01 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Mon, 3 Aug 2026 22:55:29 +0100 Subject: [PATCH 04/16] Remove console logs --- src/syntax_analyser/abstract_syntax_tree.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/syntax_analyser/abstract_syntax_tree.cpp b/src/syntax_analyser/abstract_syntax_tree.cpp index afcce01..2341d38 100644 --- a/src/syntax_analyser/abstract_syntax_tree.cpp +++ b/src/syntax_analyser/abstract_syntax_tree.cpp @@ -160,10 +160,8 @@ Program AbstractSyntaxTree::parse() { const Token& token = this->tokenContainer.view(i); buffer.push_back(token); - std::cout << "Reading " << token.tokenType << std::endl; if (token.tokenType == TokenType::END_OF_LINE) { - std::cout << "Reading end of line\n"; if (buffer[0].get().tokenType == TokenType::PRIMITIVE && buffer[1].get().tokenType == TokenType::IDENTIFIER && buffer[2].get().tokenType == TokenType::OPERATOR) { From dc16ead8d466572e8506568965ff1758e4e70e63 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:57:02 +0100 Subject: [PATCH 05/16] Remove print statements --- src/syntax_analyser/abstract_syntax_tree.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/syntax_analyser/abstract_syntax_tree.cpp b/src/syntax_analyser/abstract_syntax_tree.cpp index 2341d38..319ced6 100644 --- a/src/syntax_analyser/abstract_syntax_tree.cpp +++ b/src/syntax_analyser/abstract_syntax_tree.cpp @@ -118,8 +118,6 @@ std::vector> AbstractSyntaxTree::evaluateOperations( const Token& secondToken = static_cast(tokens[tokensIndex + 1].get()); - std::cout << secondToken.tokenType << "\n"; - if (secondToken.tokenType != TokenType::NUMBER && secondToken.tokenType != TokenType::IDENTIFIER) { throw std::runtime_error( @@ -132,9 +130,6 @@ std::vector> AbstractSyntaxTree::evaluateOperations( std::make_unique(outputIdentifier), std::make_unique( (static_cast(secondToken)).value))); - - std::cout << outputIdentifier << " + " - << (static_cast(secondToken)).value << "\n"; } if (secondToken.tokenType == TokenType::IDENTIFIER) { @@ -244,6 +239,5 @@ Program AbstractSyntaxTree::parse() { buffer.clear(); } } - std::cout << "program size: " << program.size() << "\n"; return program; } \ No newline at end of file From 55cf8e2cb7874d5590ce15c74b0f1c7abb4f580c Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:01:40 +0100 Subject: [PATCH 06/16] Seperate print method --- src/generation/generator.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index a935b7b..cc9da1c 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -409,12 +409,13 @@ class Generator { return module; } - void compile() { - llvm::LLVMContext context; - std::unique_ptr module = this->buildModule(context); - + void print_module(std::unique_ptr module) { std::cout << "-- LLVM IR --" << std::endl; module->print(llvm::outs(), nullptr); + } + + void compile(llvm::LLVMContext& context, + std::unique_ptr module) { auto targetTriple = llvm::Triple(llvm::sys::getDefaultTargetTriple()); module->setTargetTriple(targetTriple); From 1a4e067adef633df39b3e59b046582182793ef72 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:01:57 +0100 Subject: [PATCH 07/16] Create system tests on example files --- tests/system.cpp | 81 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/tests/system.cpp b/tests/system.cpp index f8dd595..c0bc778 100644 --- a/tests/system.cpp +++ b/tests/system.cpp @@ -2,23 +2,78 @@ #include "generation/generator.hpp" #include "io/file_reader.hpp" -#include "lexer/lexer.hpp" -#include "lexer/token_container/token_container.hpp" -#include "syntax_analyser/abstract_syntax_tree.hpp" +#include +#include +#include +#include +#include +#include + +class CompilerBuildListener : public Catch::EventListenerBase { +public: + using Catch::EventListenerBase::EventListenerBase; + + void testRunStarting(const Catch::TestRunInfo& testRunInfo) override { + std::cout << "Building compiler\n"; + + int result = std::system("cmake . && make && ./bin/main"); + } +}; + +CATCH_REGISTER_LISTENER(CompilerBuildListener) + +std::string exec(std::string cmd) { + std::array buffer; + std::string result; + + std::unique_ptr pipe(popen(cmd.c_str(), "r"), + pclose); + + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} + +void checkOutput(std::string filePath, std::string expectedOut) {} TEST_CASE("Run \"./examples/addition.lang\"", "[system]") { - FileReader fileReader("./examples/addition.lang"); - Lexer lexer = Lexer(fileReader.readAll()); + std::system("./bin/main ./examples/addition.lang"); + int out = std::system("./main.out"); + REQUIRE(out != -1); + REQUIRE(WIFEXITED(out)); + REQUIRE(WEXITSTATUS(out) == 5); +}; + +TEST_CASE("Run \"./examples/integer_primitives.lang\"", "[system]") { + std::system("./bin/main ./examples/integer_primitives.lang"); + int out = std::system("./main.out"); + REQUIRE(out != -1); + REQUIRE(WIFEXITED(out)); + REQUIRE(WEXITSTATUS(out) == 1); +}; - TokenContainer tokens = lexer.makeTokenList(); - tokens.print(); +TEST_CASE("Run \"./examples/print.lang\"", "[system]") { + std::system("./bin/main ./examples/print.lang"); + std::string out = exec("./main.out"); - AbstractSyntaxTree ast(tokens); + REQUIRE(out == "1\n2\n"); +}; + +TEST_CASE("Run \"./examples/transitive_assignment.lang\"", "[system]") { + std::system("./bin/main ./examples/transitive_assignment.lang"); + int out = std::system("./main.out"); + + REQUIRE(out != -1); + REQUIRE(WIFEXITED(out)); + REQUIRE(WEXITSTATUS(out) == 1); +}; - Program program = ast.parse(); - program.print(); +TEST_CASE("Run \"./examples/variable_declaration.lang\"", "[system]") { + std::system("./bin/main ./examples/variable_declaration.lang"); + int out = std::system("./main.out"); - Generator generator(program); - generator.init(); - generator.compile(); + REQUIRE(out != -1); + REQUIRE(WIFEXITED(out)); + REQUIRE(WEXITSTATUS(out) == 1); }; From d64afa0b6d09868a8793cb79062bcbff3c294d70 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:02:10 +0100 Subject: [PATCH 08/16] Include return to show successful run --- examples/integer_primitives.lang | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/integer_primitives.lang b/examples/integer_primitives.lang index cf839ce..7163088 100644 --- a/examples/integer_primitives.lang +++ b/examples/integer_primitives.lang @@ -1,4 +1,6 @@ uint8 a = 255; uint16 b = 65535; uint32 c = 4294967295; -uint64 d = 18446744073709551615; \ No newline at end of file +uint64 d = 18446744073709551615; + +return 1; \ No newline at end of file From 4503fe0b93bd82ba2e7169b706567a2ade7716bc Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:02:19 +0100 Subject: [PATCH 09/16] Create verbose option --- src/main.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8b85e2e..3a6a8e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,11 +4,13 @@ #include #include +#include #include "./io/file_reader.hpp" #include "./lexer/lexer.hpp" #include "./lexer/token_container/token_container.hpp" #include "generation/generator.hpp" +#include "generation/module.hpp" #include "syntax_analyser/abstract_syntax_tree.hpp" int main(const int argc, char* argv[]) { @@ -17,6 +19,14 @@ int main(const int argc, char* argv[]) { return 1; } + bool verbose = false; + + if (argc == 3) { + if (std::string(argv[2]) == "-v") { + verbose = true; + } + } + FileReader fileReader(argv[1]); if (!fileReader.isOpen()) { std::cerr << "Input file failed to open\n"; @@ -25,14 +35,26 @@ int main(const int argc, char* argv[]) { Lexer lexer(fileReader.readAll()); TokenContainer tokens = lexer.makeTokenList(); - tokens.print(); + if (verbose) { + tokens.print(); + } AbstractSyntaxTree ast(tokens); Program program = ast.parse(); - program.print(); + if (verbose) { + program.print(); + } Generator generator(program); generator.init(); - generator.compile(); + + llvm::LLVMContext context; + std::unique_ptr module = generator.buildModule(context); + + if (verbose) { + generator.print_module(std::move(module)); + } + + generator.compile(context, std::move(module)); } \ No newline at end of file From b14c4126944ef11b4bf821d9e99511f1089e8e4c Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:10:49 +0100 Subject: [PATCH 10/16] Simplify build command --- tests/system.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/system.cpp b/tests/system.cpp index c0bc778..733c7aa 100644 --- a/tests/system.cpp +++ b/tests/system.cpp @@ -6,17 +6,14 @@ #include #include #include +#include #include -#include class CompilerBuildListener : public Catch::EventListenerBase { public: using Catch::EventListenerBase::EventListenerBase; - void testRunStarting(const Catch::TestRunInfo& testRunInfo) override { - std::cout << "Building compiler\n"; - - int result = std::system("cmake . && make && ./bin/main"); + int result = std::system("cmake . && make"); } }; @@ -50,7 +47,7 @@ TEST_CASE("Run \"./examples/integer_primitives.lang\"", "[system]") { int out = std::system("./main.out"); REQUIRE(out != -1); REQUIRE(WIFEXITED(out)); - REQUIRE(WEXITSTATUS(out) == 1); + REQUIRE(WEXITSTATUS(out) == 0); }; TEST_CASE("Run \"./examples/print.lang\"", "[system]") { From 05a45f55469b453e09c4686e208c2e3aa5885836 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:10:54 +0100 Subject: [PATCH 11/16] Remove return --- examples/integer_primitives.lang | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/integer_primitives.lang b/examples/integer_primitives.lang index 7163088..cf839ce 100644 --- a/examples/integer_primitives.lang +++ b/examples/integer_primitives.lang @@ -1,6 +1,4 @@ uint8 a = 255; uint16 b = 65535; uint32 c = 4294967295; -uint64 d = 18446744073709551615; - -return 1; \ No newline at end of file +uint64 d = 18446744073709551615; \ No newline at end of file From 857e5674c0dd6334df827eecd49c5f3b4df4eab5 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:13:23 +0100 Subject: [PATCH 12/16] Remove unused import --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 3a6a8e5..965be31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,6 @@ #include "./lexer/lexer.hpp" #include "./lexer/token_container/token_container.hpp" #include "generation/generator.hpp" -#include "generation/module.hpp" #include "syntax_analyser/abstract_syntax_tree.hpp" int main(const int argc, char* argv[]) { From 488b307f214f3889cadbbb26cd53f98273e8bdfb Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:17:37 +0100 Subject: [PATCH 13/16] Require compiler --- tests/system.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/system.cpp b/tests/system.cpp index 733c7aa..f739fcf 100644 --- a/tests/system.cpp +++ b/tests/system.cpp @@ -13,7 +13,11 @@ class CompilerBuildListener : public Catch::EventListenerBase { public: using Catch::EventListenerBase::EventListenerBase; void testRunStarting(const Catch::TestRunInfo& testRunInfo) override { - int result = std::system("cmake . && make"); + if (std::filesystem::exists("./bin/main")) { + return; + } + std::cerr << "Compiler not found"; + std::exit(1); } }; From ee16c145d248670754e3f69f2fce851846252351 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:25:31 +0100 Subject: [PATCH 14/16] Include break --- src/generation/generator.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index cc9da1c..e595a88 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -358,6 +358,7 @@ class Generator { } builder.store(builder.add(lhs, rhs, outName), outUint.getAlloc()); + break; } case StatementType::PRINT: { const PrintStatement& printStatement = From 99d19d80ac37ca954067d697762721bda4984c1c Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:27:35 +0100 Subject: [PATCH 15/16] Include filesystem --- tests/system.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system.cpp b/tests/system.cpp index f739fcf..b231b0b 100644 --- a/tests/system.cpp +++ b/tests/system.cpp @@ -8,6 +8,7 @@ #include #include #include +#include class CompilerBuildListener : public Catch::EventListenerBase { public: From 259083f85707b5aec337567de98c687310de6322 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:29:35 +0100 Subject: [PATCH 16/16] Compile with PIC --- src/generation/generator.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index e595a88..75c95d8 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -429,7 +429,7 @@ class Generator { auto CPU = "generic"; auto features = ""; llvm::TargetOptions opt; - std::optional RM = std::nullopt; + std::optional RM = llvm::Reloc::PIC_; llvm::TargetMachine* targetMachine = target->createTargetMachine(targetTriple, CPU, features, opt, RM);