Skip to content

Commit

Permalink
Support optree compilation backend in CLI (#169)
Browse files Browse the repository at this point in the history
* Refactor executor as a stage runner
* Extract command line arguments parsing into separate module
* Add Git-based versioning

Update argparse revision to f0759fd
p-ranav/argparse@f0759fd
  • Loading branch information
vla5924 authored May 25, 2024
1 parent f00cc8f commit 29d4c65
Show file tree
Hide file tree
Showing 13 changed files with 659 additions and 241 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
CC: gcc
CXX: g++
run: |
git config --global --add safe.directory $(pwd)
cmake -S compiler -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_CODEGEN='ast_to_llvmir;optree_to_llvmir'
cmake --build build --parallel
- name: Archive binaries
Expand Down
27 changes: 27 additions & 0 deletions compiler/cmake/version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.22)

if(NOT DEFINED VERSION_MAJOR)
set(VERSION_MAJOR 1)
endif()
if(NOT DEFINED VERSION_MINOR)
set(VERSION_MINOR 0)
endif()
if(NOT DEFINED VERSION_SUFFIX)
set(VERSION_SUFFIX "")
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE REVPARSE_RESULT
OUTPUT_VARIABLE REVPARSE_OUTPUT
ERROR_QUIET
)
if(REVPARSE_RESULT EQUAL 0)
string(STRIP "${REVPARSE_OUTPUT}" REVPARSE_OUTPUT)
set(VERSION_SUFFIX "-${REVPARSE_OUTPUT}")
else()
message(WARNING "Unable to detect version suffix from Git")
endif()
endif()
endif()
message(STATUS "Project version is ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_SUFFIX}")
50 changes: 47 additions & 3 deletions compiler/include/compiler/cli/compiler.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
#pragma once

#include <string_view>
#include <utility>
#include <vector>

#include "compiler/ast/syntax_tree.hpp"
#include "compiler/frontend/lexer/token.hpp"
#include "compiler/optree/program.hpp"
#include "compiler/utils/source_files.hpp"

#include "compiler/cli/options.hpp"

namespace cli {

class Compiler {
const Options &opt;
std::vector<std::pair<std::string_view, long long>> measuredTimes;

utils::SourceFile source;
lexer::TokenList tokens;
ast::SyntaxTree tree;
optree::Program program;

int readFiles();
int runPreprocessor();
int runLexer();
int runParser();
int runConverter();

int runAstSemantizer();
int runAstOptimizer();
#ifdef ENABLE_CODEGEN_AST_TO_LLVMIR
int runAstLLVMIRGenerator();
#endif

int runOptreeOptimizer();
#ifdef ENABLE_CODEGEN_OPTREE_TO_LLVMIR
int runOptreeLLVMIRGenerator();
#endif

public:
Compiler() = delete;
Compiler(const Options &options);
Compiler(const Compiler &) = delete;
Compiler(Compiler &&) = delete;
~Compiler() = delete;
~Compiler() = default;

static int exec(int argc, char *argv[]);
const auto &measurements() const {
return measuredTimes;
}

int run();
};

} // namespace cli
25 changes: 25 additions & 0 deletions compiler/include/compiler/cli/helpers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <filesystem>
#include <string>
#include <vector>

namespace cli {

class TemporaryDirectory {
std::filesystem::path dir;

public:
TemporaryDirectory();
TemporaryDirectory(const TemporaryDirectory &) = delete;
TemporaryDirectory(TemporaryDirectory &&) = delete;
~TemporaryDirectory();

const std::filesystem::path &path() const;
};

std::string wrapQuotes(const std::string &str);

std::string makeCommand(const std::vector<std::string> &args);

} // namespace cli
99 changes: 99 additions & 0 deletions compiler/include/compiler/cli/options.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#pragma once

#include <exception>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#if defined(ENABLE_CODEGEN_AST_TO_LLVMIR) || defined(ENABLE_CODEGEN_OPTREE_TO_LLVMIR)
#define LLVMIR_CODEGEN_ENABLED
#endif

namespace cli {

namespace arg {

constexpr std::string_view debug = "--debug";
constexpr std::string_view optimize = "--optimize";
constexpr std::string_view time = "--time";
constexpr std::string_view stopAfter = "--stop-after";
constexpr std::string_view backend = "--backend";
constexpr std::string_view files = "FILES";

#ifdef LLVMIR_CODEGEN_ENABLED
constexpr std::string_view codegen = "--codegen";
constexpr std::string_view compile = "--compile";
constexpr std::string_view clang = "--clang";
constexpr std::string_view llc = "--llc";
constexpr std::string_view output = "--output";
#endif

} // namespace arg

namespace stage {

constexpr std::string_view preprocessor = "preprocessor";
constexpr std::string_view lexer = "lexer";
constexpr std::string_view parser = "parser";
constexpr std::string_view converter = "converter";
constexpr std::string_view semantizer = "semantizer";
constexpr std::string_view optimizer = "optimizer";

#ifdef LLVMIR_CODEGEN_ENABLED
constexpr std::string_view codegen = "codegen";
#endif

} // namespace stage

namespace backend {

constexpr std::string_view ast = "ast";
constexpr std::string_view optree = "optree";

} // namespace backend

#ifdef LLVMIR_CODEGEN_ENABLED
namespace codegen {

constexpr std::string_view llvm = "llvm";

} // namespace codegen
#endif

struct Options {
bool debug;
std::string backend;
bool time;
bool optimize;
std::optional<std::string> stopAfter;
#ifdef LLVMIR_CODEGEN_ENABLED
std::string codegen;
bool compile;
std::string clang;
std::string llc;
std::string output;
#endif
std::vector<std::string> files;
std::string helpMessage;

void dump() const;
};

class OptionsError : public std::exception {
std::string message;

public:
OptionsError(const std::string &message) : message(message){};
~OptionsError() override = default;

OptionsError &operator=(const OptionsError &) noexcept = default;

const char *what() const noexcept override {
return message.c_str();
}
};

Options parseArguments(int argc, const char *const *argv);

} // namespace cli
10 changes: 10 additions & 0 deletions compiler/include/compiler/cli/version.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

namespace cli {

constexpr const char *version = "@VERSION_MAJOR@.@VERSION_MINOR@@VERSION_SUFFIX@";
constexpr const char *versionMajor = "@VERSION_MAJOR@";
constexpr const char *versionMinor = "@VERSION_MINOR@";
constexpr const char *versionSuffix = "@VERSION_SUFFIX@";

} // namespace cli
6 changes: 5 additions & 1 deletion compiler/lib/cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ set_target_include_dir(${TARGET_NAME})
file(GLOB_RECURSE TARGET_HEADERS ${TARGET_INCLUDE_DIR}/*.hpp)
file(GLOB_RECURSE TARGET_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

include(${COMPILER_CMAKE_DIR}/version.cmake)
configure_file(${TARGET_INCLUDE_DIR}/version.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/version.hpp @ONLY)

add_executable(${TARGET_NAME} ${TARGET_SRC} ${TARGET_HEADERS})
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME compiler)

target_include_directories(${TARGET_NAME}
PUBLIC ${COMPILER_INCLUDE_DIR}
PRIVATE ${TARGET_INCLUDE_DIR}
PRIVATE ${TARGET_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
)

target_link_libraries(${TARGET_NAME} PUBLIC
argparse
backend_ast
backend_optree
frontend
utils
)
Expand Down
Loading

0 comments on commit 29d4c65

Please sign in to comment.