From 50573052f7331900f861404278f2e745ef7c1257 Mon Sep 17 00:00:00 2001 From: Philippe Tillet Date: Sun, 16 Dec 2018 16:15:40 -0500 Subject: [PATCH] TDL: restructured project directories --- CMakeLists.txt | 41 +++++++++++++-- cmake/FindLLVM.cmake | 88 +++++++++++++++++++++++++++++++++ examples/CMakeLists.txt | 6 +++ main.cpp => examples/matrix.cpp | 4 ++ ast.h => include/ast.h | 35 +++---------- parser.y => include/parser.y | 42 +++++++++++++--- scanner.l => include/scanner.l | 0 lib/codegen.cpp | 0 8 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 cmake/FindLLVM.cmake create mode 100644 examples/CMakeLists.txt rename main.cpp => examples/matrix.cpp (78%) rename ast.h => include/ast.h (84%) rename parser.y => include/parser.y (88%) rename scanner.l => include/scanner.l (100%) create mode 100644 lib/codegen.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 308a86ad1..256bbcf9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,42 @@ +cmake_minimum_required(VERSION 2.8.7) +project(TDL) +include(CTest) +include(cmake/FindLLVM.cmake) + +# FLEX/YACC find_package(BISON) -BISON_TARGET(Parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp) find_package(FLEX) -FLEX_TARGET(Lexer scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp) +BISON_TARGET(Parser ${CMAKE_CURRENT_SOURCE_DIR}/include/parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp) +FLEX_TARGET(Lexer ${CMAKE_CURRENT_SOURCE_DIR}/include/scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp) get_filename_component(BISON_Parser_INCLUDE_DIRECTORIES ${BISON_Parser_OUTPUT_HEADER} DIRECTORY) include_directories(${BISON_Parser_INCLUDE_DIRECTORIES}) -add_executable(test main.cpp ${BISON_Parser_OUTPUTS} ${FLEX_Lexer_OUTPUTS}) + +#Default build type +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Default build type: Release") + set(CMAKE_BUILD_TYPE "Release") +endif() + +# Gather headers for cmake-based IDEs +file( GLOB_RECURSE ALL_SRC *.cpp *.hpp *.h *.py) +add_custom_target( ALL SOURCES ${ALL_SRC} ) + +# Compiler flags +link_directories(/home/philippe/Development/llvm-tlvm/build/lib) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories(/home/philippe/Development/llvm-tlvm/include) +include_directories(/home/philippe/Development/llvm-tlvm/build/include) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +# Library +file(GLOB_RECURSE LIBTDL_SRC lib/*.cpp) +add_library(tdl SHARED ${LIBTDL_SRC} ${BISON_Parser_OUTPUTS} ${FLEX_Lexer_OUTPUTS}) +target_link_libraries(tdl "dl" ${LLVM_LIBRARIES}) + +# Examples +add_subdirectory(examples) + + + + + diff --git a/cmake/FindLLVM.cmake b/cmake/FindLLVM.cmake new file mode 100644 index 000000000..b3196d444 --- /dev/null +++ b/cmake/FindLLVM.cmake @@ -0,0 +1,88 @@ +# - Find LLVM +# This module can be used to find LLVM. +# It requires that the llvm-config executable be available on the system path. +# Once found, llvm-config is used for everything else. +# +# Typical usage could be: +# find_package(LLVM QUIET REQUIRED COMPONENTS jit native interpreter) +# +# If the QUIET flag is not set, the specified components and LLVM version are +# outputted. +# +# If the COMPONENTS are not set, the default set of "all" is used. +# +# The following variables are set: +# +# LLVM_FOUND - Set to YES if LLVM is found. +# LLVM_VERSION - Set to the decimal version of the LLVM library. +# LLVM_C_FLAGS - All flags that should be passed to a C compiler. +# LLVM_CXX_FLAGS - All flags that should be passed to a C++ compiler. +# LLVM_CPP_FLAGS - All flags that should be passed to the C pre-processor. +# LLVM_LD_FLAGS - Additional flags to pass to the linker. +# LLVM_LIBRARY_DIRS - A list of directories where the LLVM libraries are located. +# LLVM_INCLUDE_DIRS - A list of directories where the LLVM headers are located. +# LLVM_LIBRARIES - A list of libraries which should be linked against. + +# A macro to run llvm config +macro(_llvm_config _var_name) + # Firstly, locate the LLVM config executable + find_program(_llvm_config_exe + NAMES llvm-config + PATHS /home/philippe/Development/llvm-tlvm/build/bin/ + DOC "llvm-config executable location" + ) + + # If no llvm-config executable was found, set the output variable to not + # found. + if(NOT _llvm_config_exe) + set(${_var_name} "${_var_name}-NOTFOUND") + else(NOT _llvm_config_exe) + # Otherwise, run llvm-config + execute_process( + COMMAND ${_llvm_config_exe} ${ARGN} + OUTPUT_VARIABLE ${_var_name} + RESULT_VARIABLE _llvm_config_retval + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(RESULT_VARIABLE) + message(SEND_ERROR + "Error running llvm-config with arguments: ${ARGN}") + endif(RESULT_VARIABLE) + endif(NOT _llvm_config_exe) +endmacro(_llvm_config) + +# The default set of components +set(_llvm_components all) + +# If components have been specified via find_package, use them +if(LLVM_FIND_COMPONENTS) + set(_llvm_components ${LLVM_FIND_COMPONENTS}) +endif(LLVM_FIND_COMPONENTS) + +if(NOT LLVM_FIND_QUIETLY) + message(STATUS "Looking for LLVM components: ${_llvm_components}") +endif(NOT LLVM_FIND_QUIETLY) + +_llvm_config(LLVM_VERSION --version) +_llvm_config(LLVM_C_FLAGS --cflags) +_llvm_config(LLVM_CXX_FLAGS --cxxflags) +_llvm_config(LLVM_CPP_FLAGS --cppflags) +_llvm_config(LLVM_LD_FLAGS --ldflags) +_llvm_config(LLVM_LIBRARY_DIRS --libdir) +_llvm_config(LLVM_INCLUDE_DIRS --includedir) +_llvm_config(LLVM_LIBRARIES --libs) + +if(NOT LLVM_FIND_QUIETLY) + message(STATUS "Found LLVM version: ${LLVM_VERSION}") +endif(NOT LLVM_FIND_QUIETLY) + +# handle the QUIETLY and REQUIRED arguments and set LLVM_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVM + DEFAULT_MSG + LLVM_LIBRARIES + LLVM_INCLUDE_DIRS + LLVM_LIBRARY_DIRS) + +# vim:sw=4:ts=4:autoindent diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 000000000..53d780a94 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,6 @@ +foreach(PROG matrix) + add_executable(${PROG} ${PROG}.cpp) + set_target_properties(${PROG} PROPERTIES OUTPUT_NAME ${PROG}) + include_directories(/usr/local/cuda/include/) + target_link_libraries(${PROG} tdl) +endforeach(PROG) diff --git a/main.cpp b/examples/matrix.cpp similarity index 78% rename from main.cpp rename to examples/matrix.cpp index f4a67ddb4..cd46cc008 100644 --- a/main.cpp +++ b/examples/matrix.cpp @@ -1,10 +1,13 @@ #include #include +#include "ast.h" typedef struct yy_buffer_state * YY_BUFFER_STATE; extern int yyparse(); extern YY_BUFFER_STATE yy_scan_string(const char * str); extern void yy_delete_buffer(YY_BUFFER_STATE buffer); +using ast::translation_unit; +extern translation_unit *ast_root; const char src[] = "\ @@ -19,5 +22,6 @@ int main() { YY_BUFFER_STATE buffer = yy_scan_string(src); yyparse(); yy_delete_buffer(buffer); + translation_unit *program = ast_root; return 0; } diff --git a/ast.h b/include/ast.h similarity index 84% rename from ast.h rename to include/ast.h index da9bee095..3e1544264 100644 --- a/ast.h +++ b/include/ast.h @@ -43,20 +43,6 @@ enum TYPE_T{ // AST class node { }; -struct token: public node{ - token(ASSIGN_OP_T value): assign_op(value){ } - token(BIN_OP_T value): bin_op(value){ } - token(UNARY_OP_T value): unary_op(value){ } - token(TYPE_T value): type(value){ } - - union { - ASSIGN_OP_T assign_op; - BIN_OP_T bin_op; - UNARY_OP_T unary_op; - TYPE_T type; - }; -}; - template class list: public node { public: @@ -67,15 +53,8 @@ private: std::list values_; }; -template -node* append_ptr_list(node *result, node *in){ - return static_cast*>(result)->append((T*)in); -} - class binary_operator: public node{ public: - binary_operator(node *op, node *lhs, node *rhs) - : op_(((token*)op)->bin_op), lhs_(lhs), rhs_(rhs) { } binary_operator(BIN_OP_T op, node *lhs, node *rhs) : op_(op), lhs_(lhs), rhs_(rhs) { } @@ -112,8 +91,6 @@ public: class unary_operator: public node{ public: - unary_operator(node *op, node *arg) - : op_(((token*)op)->unary_op), arg_(arg) { } unary_operator(UNARY_OP_T op, node *arg) : op_(op), arg_(arg) { } @@ -144,8 +121,8 @@ public: class assignment_expression: public node{ public: - assignment_expression(node *lvalue, node *op, node *rvalue) - : lvalue_(lvalue), op_(((token*)op)->assign_op), rvalue_(rvalue) { } + assignment_expression(node *lvalue, ASSIGN_OP_T op, node *rvalue) + : lvalue_(lvalue), op_(op), rvalue_(rvalue) { } public: ASSIGN_OP_T op_; @@ -236,8 +213,8 @@ public: class parameter: public declarator { public: - parameter(node *spec, node *decl) - : spec_(((token*)spec)->type), decl_(decl) { } + parameter(TYPE_T spec, node *decl) + : spec_(spec), decl_(decl) { } public: const TYPE_T spec_; @@ -276,8 +253,8 @@ public: class type: public node{ public: - type(node *spec, node * decl) - : spec_(((token*)spec)->type), decl_(decl) { } + type(TYPE_T spec, node * decl) + : spec_(spec), decl_(decl) { } public: const TYPE_T spec_; diff --git a/parser.y b/include/parser.y similarity index 88% rename from parser.y rename to include/parser.y index 3fbed1113..40153c9c4 100644 --- a/parser.y +++ b/include/parser.y @@ -4,7 +4,7 @@ class node; } using namespace ast; #define YYSTYPE node* -#include "../ast.h" +#include "../include/ast.h" using namespace ast; extern char* yytext; @@ -13,6 +13,32 @@ int yylex(void); translation_unit *ast_root; +/* wrap token in AST node */ +struct token: public node{ + token(ASSIGN_OP_T value): assign_op(value){ } + token(BIN_OP_T value): bin_op(value){ } + token(UNARY_OP_T value): unary_op(value){ } + token(TYPE_T value): type(value){ } + + union { + ASSIGN_OP_T assign_op; + BIN_OP_T bin_op; + UNARY_OP_T unary_op; + TYPE_T type; + }; +}; + +/* shortcut to append in list */ +template +node* append_ptr_list(node *result, node *in){ + return static_cast*>(result)->append((T*)in); +} + +/* shortcut to access token value */ +ASSIGN_OP_T get_assign_op(node *op) { return ((token*)op)->assign_op; } +UNARY_OP_T get_unary_op(node *op) { return ((token*)op)->unary_op; } +TYPE_T get_type_spec(node *op) { return ((token*)op)->type; } + %} %token IDENTIFIER CONSTANT STRING_LITERAL @@ -69,8 +95,8 @@ constant_list ; type_name - : type_specifier { $$ = new type($1, nullptr); } - | type_specifier abstract_declarator { $$ = new type($1, $2); } + : type_specifier { $$ = new type(get_type_spec($1), nullptr); } + | type_specifier abstract_declarator { $$ = new type(get_type_spec($1), $2); } ; /* -------------------------- */ @@ -92,7 +118,7 @@ unary_expression : primary_expression { $$ = $1; } | INC_OP unary_expression { $$ = new unary_operator(INC, $2); } | DEC_OP unary_expression { $$ = new unary_operator(DEC, $2); } - | unary_operator cast_expression { $$ = new unary_operator($1, $2); } + | unary_operator cast_expression { $$ = new unary_operator(get_unary_op($1), $2); } ; unary_operator @@ -193,7 +219,7 @@ assignment_operator assignment_expression : conditional_expression { $$ = $1; } - | unary_expression assignment_operator assignment_expression { $$ = new assignment_expression($1, $2, $3); } + | unary_expression assignment_operator assignment_expression { $$ = new assignment_expression($1, get_assign_op($2), $3); } ; /* Expression */ @@ -269,9 +295,9 @@ parameter_list ; parameter_declaration - : declaration_specifiers declarator { $$ = new parameter($1, $2); } - | declaration_specifiers abstract_declarator { $$ = new parameter($1, $2); } - | declaration_specifiers { $$ = new parameter($1, nullptr); } + : declaration_specifiers declarator { $$ = new parameter(get_type_spec($1), $2); } + | declaration_specifiers abstract_declarator { $$ = new parameter(get_type_spec($1), $2); } + | declaration_specifiers { $$ = new parameter(get_type_spec($1), nullptr); } ; diff --git a/scanner.l b/include/scanner.l similarity index 100% rename from scanner.l rename to include/scanner.l diff --git a/lib/codegen.cpp b/lib/codegen.cpp new file mode 100644 index 000000000..e69de29bb