diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index db95b86..75c95d8 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -56,9 +56,7 @@ class Generator { llvm::InitializeNativeTargetAsmParser(); } - void compile() { - - llvm::LLVMContext context; + std::unique_ptr buildModule(llvm::LLVMContext& context) { std::unique_ptr module = std::make_unique("build", context); @@ -360,6 +358,7 @@ class Generator { } builder.store(builder.add(lhs, rhs, outName), outUint.getAlloc()); + break; } case StatementType::PRINT: { const PrintStatement& printStatement = @@ -408,8 +407,16 @@ class Generator { builder.createReturn(returnValue); } + return module; + } + + 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); @@ -422,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); diff --git a/src/main.cpp b/src/main.cpp index 8b85e2e..965be31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "./io/file_reader.hpp" #include "./lexer/lexer.hpp" @@ -17,6 +18,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 +34,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 diff --git a/src/syntax_analyser/abstract_syntax_tree.cpp b/src/syntax_analyser/abstract_syntax_tree.cpp index afcce01..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) { @@ -160,10 +155,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) { @@ -246,6 +239,5 @@ Program AbstractSyntaxTree::parse() { buffer.clear(); } } - std::cout << "program size: " << program.size() << "\n"; return program; } \ No newline at end of file diff --git a/tests/system.cpp b/tests/system.cpp new file mode 100644 index 0000000..b231b0b --- /dev/null +++ b/tests/system.cpp @@ -0,0 +1,81 @@ +#include + +#include "generation/generator.hpp" +#include "io/file_reader.hpp" +#include +#include +#include +#include +#include +#include +#include + +class CompilerBuildListener : public Catch::EventListenerBase { +public: + using Catch::EventListenerBase::EventListenerBase; + void testRunStarting(const Catch::TestRunInfo& testRunInfo) override { + if (std::filesystem::exists("./bin/main")) { + return; + } + std::cerr << "Compiler not found"; + std::exit(1); + } +}; + +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]") { + 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) == 0); +}; + +TEST_CASE("Run \"./examples/print.lang\"", "[system]") { + std::system("./bin/main ./examples/print.lang"); + std::string out = exec("./main.out"); + + 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); +}; + +TEST_CASE("Run \"./examples/variable_declaration.lang\"", "[system]") { + std::system("./bin/main ./examples/variable_declaration.lang"); + int out = std::system("./main.out"); + + REQUIRE(out != -1); + REQUIRE(WIFEXITED(out)); + REQUIRE(WEXITSTATUS(out) == 1); +};