Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mcuelenaere committed Jun 25, 2014
0 parents commit 4b0b1eb
Show file tree
Hide file tree
Showing 76 changed files with 7,066 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/CMakeLists.txt.user
.DS_Store
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(b2 C CXX)

SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})

#add_definitions(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

add_subdirectory(tools)
add_subdirectory(lib)
add_subdirectory(src)
505 changes: 505 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
## About

b² is a [jinja](http://jinja.pocoo.org/)-inspired template engine which uses [LLVM](http://llvm.org/) to generate native code.

## Building the code

### Mac OS X

Requirements:
- `brew install cmake`
- `brew install llvm`
- `brew install bison`

Build steps:

```bash
mkdir build && cd build
cmake .. -DBISON_EXECUTABLE=/usr/local/opt/bison/bin/bison -DLLVM_CONFIG_EXECUTABLE=/usr/local/opt/llvm/bin/llvm-config
make
make install
```

### Linux

Requirements:
- `aptitude install cmake`
- `aptitude install llvm`

TODO

## Running tests

```bash
tests/runner.py build/
```

### Generate Xcode project

```bash
mkdir xcode && cd xcode
cmake .. -G Xcode
open b2.xcodeproj/
```

### Unofficial Homebrew formula

```ruby
require 'formula'

class B2 < Formula
head 'https://github.com/mcuelenaere/b2'
version '0.0.1'

option 'with-php-bindings', 'Enable PHP bindings.'

depends_on 'cmake' => :build
depends_on 'bison' => :build

# Standard packages
depends_on 'llvm'
depends_on 'php55' if build.with? 'php-bindings'

def install
args = [
"-DBISON_EXECUTABLE=#{Formula['bison'].opt_prefix}/bin/bison",
"-DLLVM_CONFIG_EXECUTABLE=#{Formula['llvm'].opt_prefix}/bin/llvm-config"
] + std_cmake_args

if build.with? 'php-bindings'
args << "-DPHP_CONFIG_EXECUTABLE=#{Formula['php55'].opt_prefix}/bin/php-config"
end

mkdir "build"
cd "build" do
system "cmake", "..", *args
system "make"
system "make install"
end

if build.with? 'php-bindings'
# TODO: install php.ini
end
end
end
```
80 changes: 80 additions & 0 deletions cmake/FindLLVM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
find_program(LLVM_CONFIG_EXECUTABLE llvm-config DOC "path to the llvm-config executable")
mark_as_advanced(LLVM_CONFIG_EXECUTABLE)

if(LLVM_CONFIG_EXECUTABLE)
execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --version
OUTPUT_VARIABLE LLVM_CONFIG_version_output
ERROR_VARIABLE LLVM_CONFIG_version_error
RESULT_VARIABLE LLVM_CONFIG_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT ${LLVM_CONFIG_version_result} EQUAL 0)
message(SEND_ERROR "Command \"${LLVM_CONFIG_EXECUTABLE} --version\" failed with output:\n${LLVM_CONFIG_version_error}")
else()
set(LLVM_VERSION ${LLVM_CONFIG_version_output})
endif()

execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --cppflags
RESULT_VARIABLE LLVM_CONFIG_cppflags_result
OUTPUT_VARIABLE LLVM_CONFIG_cppflags_output
ERROR_VARIABLE LLVM_CONFIG_cppflags_error
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ${LLVM_CONFIG_cppflags_result} EQUAL 0)
message(SEND_ERROR "Command \"${LLVM_CONFIG_EXECUTABLE} --cppflags\" failed with output: ${LLVM_CONFIG_cppflags_error}")
else()
set(LLVM_DEFINITIONS ${LLVM_CONFIG_cppflags_output})
endif()

execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --libs ${COMPONENTS}
RESULT_VARIABLE LLVM_CONFIG_libs_result
OUTPUT_VARIABLE LLVM_CONFIG_libs_output
ERROR_VARIABLE LLVM_CONFIG_libs_error
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ${LLVM_CONFIG_libs_result} EQUAL 0)
message(SEND_ERROR "Command \"${LLVM_CONFIG_EXECUTABLE} --libs\" failed with output: ${LLVM_CONFIG_libs_error}")
else()
set(LLVM_LIBS ${LLVM_CONFIG_libs_output})
endif()

execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir ${COMPONENTS}
RESULT_VARIABLE LLVM_CONFIG_libdir_result
OUTPUT_VARIABLE LLVM_CONFIG_libdir_output
ERROR_VARIABLE LLVM_CONFIG_libdir_error
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ${LLVM_CONFIG_libdir_result} EQUAL 0)
message(SEND_ERROR "Command \"${LLVM_CONFIG_EXECUTABLE} --libdir\" failed with output: ${LLVM_CONFIG_libdir_error}")
else()
set(LLVM_LIBS "-L${LLVM_CONFIG_libdir_output} ${LLVM_LIBS}")
endif()

execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --bindir ${COMPONENTS}
RESULT_VARIABLE LLVM_CONFIG_bindir_result
OUTPUT_VARIABLE LLVM_CONFIG_bindir_output
ERROR_VARIABLE LLVM_CONFIG_bindir_error
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ${LLVM_CONFIG_bindir_result} EQUAL 0)
message(SEND_ERROR "Command \"${LLVM_CONFIG_EXECUTABLE} --bindir\" failed with output: ${LLVM_CONFIG_bindir_error}")
else()
set(LLVM_BIN ${LLVM_CONFIG_bindir_output})
endif()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM REQUIRED_VARS LLVM_CONFIG_EXECUTABLE LLVM_DEFINITIONS LLVM_LIBS LLVM_BIN VERSION_VAR LLVM_VERSION)

macro(emit_llvm_target Input Output)
set(Definitions "${ARGV2}")
separate_arguments(Definitions)
add_custom_command(
OUTPUT ${Output}
COMMAND ${CMAKE_C_COMPILER} -emit-llvm -c ${Definitions} -o ${Output} ${Input}
DEPENDS ${Input}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
set_source_files_properties(${Input} PROPERTIES HEADER_FILE_ONLY TRUE)
endmacro()
70 changes: 70 additions & 0 deletions cmake/FindPHP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
find_program(PHP_CONFIG_EXECUTABLE php-config DOC "path to the php-config executable")
mark_as_advanced(PHP_CONFIG_EXECUTABLE)

if(PHP_CONFIG_EXECUTABLE)
execute_process(COMMAND ${PHP_CONFIG_EXECUTABLE} --version
OUTPUT_VARIABLE PHP_CONFIG_version_output
ERROR_VARIABLE PHP_CONFIG_version_error
RESULT_VARIABLE PHP_CONFIG_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT ${PHP_CONFIG_version_result} EQUAL 0)
message(SEND_ERROR "Command \"${PHP_CONFIG_EXECUTABLE} --version\" failed with output:\n${PHP_CONFIG_version_error}")
else()
set(PHP_VERSION ${PHP_CONFIG_version_output})
endif()

execute_process(COMMAND ${PHP_CONFIG_EXECUTABLE} --includes
RESULT_VARIABLE PHP_CONFIG_includes_result
OUTPUT_VARIABLE PHP_CONFIG_includes_output
ERROR_VARIABLE PHP_CONFIG_includes_error
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ${PHP_CONFIG_includes_result} EQUAL 0)
message(SEND_ERROR "Command \"${PHP_CONFIG_EXECUTABLE} --includes\" failed with output: ${PHP_CONFIG_includes_error}")
else()
set(PHP_DEFINITIONS ${PHP_CONFIG_includes_output})
endif()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PHP REQUIRED_VARS PHP_CONFIG_EXECUTABLE PHP_DEFINITIONS VERSION_VAR PHP_VERSION)

if(APPLE)
#set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -Wl,-flat_namespace -Wl,-undefined,dynamic_lookup")
#set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -Wl,-flat_namespace -Wl,-undefined,dynamic_lookup")

set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -Wl,-flat_namespace")
foreach(symbol
__efree
__emalloc
__estrdup
__object_init_ex
__zval_ptr_dtor
_display_ini_entries
_object_properties_init
_php_info_print_table_end
_php_info_print_table_row
_php_info_print_table_start
_php_output_write
_zend_declare_property_null
_zend_exception_get_default
_zend_get_std_object_handlers
_zend_new_interned_string
_zend_object_std_dtor
_zend_object_std_init
_zend_object_store_get_object
_zend_objects_new
_zend_objects_destroy_object
_zend_objects_store_put
_zend_parse_parameters
_zend_register_internal_class
_zend_register_internal_class_ex
_zend_strndup
_zend_throw_exception
_zend_update_property
)
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS},-U,${symbol}")
endforeach()
endif()
6 changes: 6 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include_directories("${PROJECT_SOURCE_DIR}/lib")

add_subdirectory(ast)
add_subdirectory(backends)
add_subdirectory(parser)
add_subdirectory(utils)
1 change: 1 addition & 0 deletions lib/ast/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(passes)
86 changes: 86 additions & 0 deletions lib/ast/ast.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef __AST_H_
#define __AST_H_

#include "expressions.hpp"
#include <list>
#include <memory>
#include <unordered_map>
#include <string>
#include "utils.hpp"

namespace b2 {

enum ASTType {
StatementsASTType,
RawBlockASTType,
PrintBlockASTType,
IfBlockASTType,
ForBlockASTType,
IncludeBlockASTType,
};

struct AST {
virtual ~AST() {}
virtual ASTType type() = 0;
};

template<ASTType T>
struct TypedAST : AST {
virtual ASTType type() override { return T; }
};

typedef std::list<std::unique_ptr<AST>> ASTList;
typedef unique_ptr_with_free_deleter<const char> UniquePtrString;
typedef std::unordered_map<std::string, std::unique_ptr<Expression>> StringExpressionMap;

struct StatementsAST : TypedAST<StatementsASTType> {
std::unique_ptr<ASTList> statements;

StatementsAST() : statements() {}
StatementsAST(ASTList* statements) : statements(statements) {}
};

struct RawBlockAST : TypedAST<RawBlockASTType> {
UniquePtrString text;

RawBlockAST(const char* text) : text(make_unique_ptr_with_free_deleter(text)) {}
RawBlockAST(UniquePtrString text) : text(std::move(text)) {}
};

struct PrintBlockAST : TypedAST<PrintBlockASTType> {
std::unique_ptr<Expression> expr;

PrintBlockAST(Expression *expr) : expr(expr) {}
};

struct IfBlockAST : TypedAST<IfBlockASTType> {
std::unique_ptr<Expression> condition;
std::unique_ptr<AST> thenBody;
std::unique_ptr<AST> elseBody;

IfBlockAST(Expression* condition, AST* thenBody, AST* elseBody = nullptr) : condition(condition), thenBody(thenBody), elseBody(elseBody) {}
};

struct ForBlockAST : TypedAST<ForBlockASTType> {
std::unique_ptr<VariableReferenceExpression> keyVariable;
std::unique_ptr<VariableReferenceExpression> valueVariable;
std::unique_ptr<Expression> iterable;
std::unique_ptr<AST> body;
std::unique_ptr<AST> elseBody;

ForBlockAST(VariableReferenceExpression* keyVariable, VariableReferenceExpression* valueVariable, Expression* iterable, AST* body, AST* elseBody) : keyVariable(keyVariable), valueVariable(valueVariable), iterable(iterable), body(body), elseBody(elseBody) {}
};

struct IncludeBlockAST : TypedAST<IncludeBlockASTType> {
UniquePtrString includeName;
std::unique_ptr<Expression> scope;
StringExpressionMap variableMapping;

IncludeBlockAST(const char* includeName) : includeName(make_unique_ptr_with_free_deleter(includeName)) {}
IncludeBlockAST(const char* includeName, Expression* scope) : includeName(make_unique_ptr_with_free_deleter(includeName)), scope(scope) {}
IncludeBlockAST(UniquePtrString includeName, std::unique_ptr<Expression> scope, StringExpressionMap &variableMapping) : includeName(std::move(includeName)), scope(std::move(scope)), variableMapping(std::move(variableMapping)) {}
};

} // namespace b2

#endif /* __AST_H_ */
Loading

0 comments on commit 4b0b1eb

Please sign in to comment.