Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/generation/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ class Generator {
llvm::InitializeNativeTargetAsmParser();
}

void compile() {

llvm::LLVMContext context;
std::unique_ptr<llvm::Module> buildModule(llvm::LLVMContext& context) {

std::unique_ptr<llvm::Module> module =
std::make_unique<llvm::Module>("build", context);
Expand Down Expand Up @@ -360,6 +358,7 @@ class Generator {
}

builder.store(builder.add(lhs, rhs, outName), outUint.getAlloc());
break;
}
case StatementType::PRINT: {
const PrintStatement& printStatement =
Expand Down Expand Up @@ -408,8 +407,16 @@ class Generator {
builder.createReturn(returnValue);
}

return module;
}

void print_module(std::unique_ptr<llvm::Module> module) {
std::cout << "-- LLVM IR --" << std::endl;
module->print(llvm::outs(), nullptr);
}

void compile(llvm::LLVMContext& context,
std::unique_ptr<llvm::Module> module) {

auto targetTriple = llvm::Triple(llvm::sys::getDefaultTargetTriple());
module->setTargetTriple(targetTriple);
Expand All @@ -422,7 +429,7 @@ class Generator {
auto CPU = "generic";
auto features = "";
llvm::TargetOptions opt;
std::optional<llvm::Reloc::Model> RM = std::nullopt;
std::optional<llvm::Reloc::Model> RM = llvm::Reloc::PIC_;

llvm::TargetMachine* targetMachine =
target->createTargetMachine(targetTriple, CPU, features, opt, RM);
Expand Down
27 changes: 24 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <llvm/Support/raw_ostream.h>

#include <iostream>
#include <memory>

#include "./io/file_reader.hpp"
#include "./lexer/lexer.hpp"
Expand All @@ -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";
Expand All @@ -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<llvm::Module> module = generator.buildModule(context);

if (verbose) {
generator.print_module(std::move(module));
}

generator.compile(context, std::move(module));
}
8 changes: 0 additions & 8 deletions src/syntax_analyser/abstract_syntax_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ std::vector<std::unique_ptr<Statement>> AbstractSyntaxTree::evaluateOperations(
const Token& secondToken =
static_cast<const Token&>(tokens[tokensIndex + 1].get());

std::cout << secondToken.tokenType << "\n";

if (secondToken.tokenType != TokenType::NUMBER &&
secondToken.tokenType != TokenType::IDENTIFIER) {
throw std::runtime_error(
Expand All @@ -132,9 +130,6 @@ std::vector<std::unique_ptr<Statement>> AbstractSyntaxTree::evaluateOperations(
std::make_unique<IdentifierValue>(outputIdentifier),
std::make_unique<NumberValue>(
(static_cast<const NumberToken&>(secondToken)).value)));

std::cout << outputIdentifier << " + "
<< (static_cast<const NumberToken&>(secondToken)).value << "\n";
}

if (secondToken.tokenType == TokenType::IDENTIFIER) {
Expand All @@ -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) {
Expand Down Expand Up @@ -246,6 +239,5 @@ Program AbstractSyntaxTree::parse() {
buffer.clear();
}
}
std::cout << "program size: " << program.size() << "\n";
return program;
}
81 changes: 81 additions & 0 deletions tests/system.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <catch2/catch_test_macros.hpp>

#include "generation/generator.hpp"
#include "io/file_reader.hpp"
#include <catch2/catch_test_macros.hpp>
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <csignal>
#include <cstdlib>
#include <filesystem>

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<char, 128> buffer;
std::string result;

std::unique_ptr<FILE, decltype(&pclose)> 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);
};
Loading