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
25 changes: 23 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cmake_policy(SET CMP0135 NEW)
# _.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
# Library

## Coverage config
add_library(additional_config INTERFACE)

option(CODE_COVERAGE "Enable coverage reporting" OFF)
Expand All @@ -32,6 +33,7 @@ else ()
target_compile_options(additional_config INTERFACE -O3)
endif ()

## Cxxopts
FetchContent_Declare(
cxxopts
GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git
Expand All @@ -40,6 +42,7 @@ FetchContent_Declare(
FetchContent_MakeAvailable(cxxopts)
message(DEBUG cxxopts="${cxxopts_SOURCE_DIR}/include")

## Antlr4
add_definitions(-DANTLR4CPP_STATIC)
set(ANTLR4_WITH_STATIC_CRT OFF)
set(ANTLR4_TAG 4.13.2)
Expand All @@ -57,21 +60,39 @@ antlr_target(Parser ${PROJECT_SOURCE_DIR}/src/grammar/FilParser.g4 PARSER
DEPENDS_ANTLR Lexer
COMPILE_FLAGS -lib ${ANTLR_Lexer_OUTPUT_DIR})

## LLVM
find_package(LLVM REQUIRED CONFIG)

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

include_directories(${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS})

llvm_map_components_to_libnames(llvm_libs analysis support core object irreader executionengine scalaropts instcombine orcjit runtimedyld)

foreach(target ${LLVM_TARGETS_TO_BUILD})
list(APPEND llvm_targets "LLVM${target}CodeGen")
endforeach()

## filc lib
file(GLOB_RECURSE SRC_FILES
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/**/*.cpp"
)
message(DEBUG SRC_FILES=${SRC_FILES})

add_library(filc_lib ${SRC_FILES} ${ANTLR_Lexer_CXX_OUTPUTS} ${ANTLR_Parser_CXX_OUTPUTS})
target_link_libraries(filc_lib PRIVATE additional_config cxxopts::cxxopts antlr4_static)
target_link_libraries(filc_lib PRIVATE additional_config cxxopts::cxxopts antlr4_static ${llvm_libs} ${llvm_targets})

target_include_directories(filc_lib PUBLIC
"${PROJECT_SOURCE_DIR}/include"
"${cxxopts_SOURCE_DIR}/include"
${ANTLR4_INCLUDE_DIRS}
${ANTLR_Lexer_OUTPUT_DIR}
${ANTLR_Parser_OUTPUT_DIR})
${ANTLR_Parser_OUTPUT_DIR}
${LLVM_INCLUDE_DIRS})

target_compile_definitions(filc_lib
PUBLIC FILC_VERSION="${FILC_VERSION}"
Expand Down
1 change: 1 addition & 0 deletions include/filc/filc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "filc/options/OptionsParser.h"
#include "filc/grammar/DumpVisitor.h"
#include "filc/validation/ValidationVisitor.h"
#include "filc/llvm/IRGenerator.h"

namespace filc {
class FilCompiler final {
Expand Down
2 changes: 1 addition & 1 deletion include/filc/grammar/DumpVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <iostream>

namespace filc {
class DumpVisitor final: public Visitor {
class DumpVisitor final: public Visitor<void> {
public:
explicit DumpVisitor(std::ostream &out);

Expand Down
8 changes: 8 additions & 0 deletions include/filc/grammar/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <string>
#include <memory>
#include <llvm/IR/Type.h>

namespace filc {
class AbstractType {
Expand All @@ -36,8 +37,15 @@ class AbstractType {

[[nodiscard]] virtual auto toDisplay() const noexcept -> std::string = 0;

auto setLLVMType(llvm::Type *type) -> void;

[[nodiscard]] auto getLLVMType() const -> llvm::Type *;

protected:
AbstractType() = default;

private:
llvm::Type *_llvm_type = nullptr;
};

class Type final: public AbstractType {
Expand Down
26 changes: 15 additions & 11 deletions include/filc/grammar/Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,43 @@
#define FILC_VISITOR_H

#include "filc/grammar/ast.h"
#include "llvm/IR/Value.h"

namespace filc {
template<typename Return>
class Visitor {
public:
virtual ~Visitor() = default;

virtual auto visitProgram(Program *program) -> void = 0;
virtual auto visitProgram(Program *program) -> Return = 0;

virtual auto visitBooleanLiteral(BooleanLiteral *literal) -> void = 0;
virtual auto visitBooleanLiteral(BooleanLiteral *literal) -> Return = 0;

virtual auto visitIntegerLiteral(IntegerLiteral *literal) -> void = 0;
virtual auto visitIntegerLiteral(IntegerLiteral *literal) -> Return = 0;

virtual auto visitFloatLiteral(FloatLiteral *literal) -> void = 0;
virtual auto visitFloatLiteral(FloatLiteral *literal) -> Return = 0;

virtual auto visitCharacterLiteral(CharacterLiteral *literal) -> void = 0;
virtual auto visitCharacterLiteral(CharacterLiteral *literal) -> Return = 0;

virtual auto visitStringLiteral(StringLiteral *literal) -> void = 0;
virtual auto visitStringLiteral(StringLiteral *literal) -> Return = 0;

virtual auto visitVariableDeclaration(VariableDeclaration *variable) -> void = 0;
virtual auto visitVariableDeclaration(VariableDeclaration *variable) -> Return = 0;

virtual auto visitIdentifier(Identifier *identifier) -> void = 0;
virtual auto visitIdentifier(Identifier *identifier) -> Return = 0;

virtual auto visitBinaryCalcul(BinaryCalcul *calcul) -> void = 0;
virtual auto visitBinaryCalcul(BinaryCalcul *calcul) -> Return = 0;

virtual auto visitAssignation(Assignation *assignation) -> void = 0;
virtual auto visitAssignation(Assignation *assignation) -> Return = 0;

protected:
Visitor() = default;
};

class Visitable {
public:
virtual auto accept(Visitor *visitor) -> void = 0;
virtual auto acceptVoidVisitor(Visitor<void> *visitor) -> void = 0;

virtual auto acceptIRVisitor(Visitor<llvm::Value*> *visitor) -> llvm::Value * = 0;
};
}

Expand Down
4 changes: 3 additions & 1 deletion include/filc/grammar/assignation/Assignation.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class Assignation final: public Expression {

[[nodiscard]] auto getValue() const -> std::shared_ptr<Expression>;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
std::string _identifier;
Expand Down
4 changes: 3 additions & 1 deletion include/filc/grammar/calcul/Calcul.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ class BinaryCalcul final: public Expression {

[[nodiscard]] auto getRightExpression() const -> std::shared_ptr<Expression>;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
std::shared_ptr<Expression> _left_expression;
Expand Down
4 changes: 3 additions & 1 deletion include/filc/grammar/identifier/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class Identifier final: public Expression {

[[nodiscard]] auto getName() const -> std::string;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
std::string _name;
Expand Down
20 changes: 15 additions & 5 deletions include/filc/grammar/literal/Literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,27 @@ class BooleanLiteral final: public Literal<bool> {
public:
explicit BooleanLiteral(bool value);

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;
};

class IntegerLiteral final: public Literal<int> {
public:
explicit IntegerLiteral(int value);

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;
};

class FloatLiteral final: public Literal<double> {
public:
explicit FloatLiteral(double value);

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;
};

class CharacterLiteral final: public Literal<char> {
Expand All @@ -69,14 +75,18 @@ class CharacterLiteral final: public Literal<char> {

static auto stringToChar(const std::string &snippet) -> char;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;
};

class StringLiteral final: public Literal<std::string> {
public:
explicit StringLiteral(const std::string &value);

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;
};
}

Expand Down
4 changes: 3 additions & 1 deletion include/filc/grammar/program/Program.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class Program final: public Visitable {

[[nodiscard]] auto getExpressions() const -> const std::vector<std::shared_ptr<Expression>> &;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
std::vector<std::shared_ptr<Expression>> _expressions;
Expand Down
4 changes: 3 additions & 1 deletion include/filc/grammar/variable/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ class VariableDeclaration: public Expression {

[[nodiscard]] auto getValue() const -> std::shared_ptr<Expression>;

auto accept(Visitor *visitor) -> void override;
auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
bool _constant;
Expand Down
56 changes: 56 additions & 0 deletions include/filc/llvm/CalculBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* MIT License
*
* Copyright (c) 2024-Present Kevin Traini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef FILC_CALCULBUILDER_H
#define FILC_CALCULBUILDER_H

#include "filc/grammar/calcul/Calcul.h"
#include "filc/llvm/IRGenerator.h"
#include <llvm/IR/IRBuilder.h>

namespace filc {
class CalculBuilder final {
public:
explicit CalculBuilder(IRGenerator *generator, llvm::IRBuilder<> *builder);

auto buildCalculValue(BinaryCalcul *calcul) const -> llvm::Value *;

private:
IRGenerator *_generator;
llvm::IRBuilder<> *_builder;

auto buildSignedInteger(BinaryCalcul *calcul) const -> llvm::Value *;

auto buildUnsignedInteger(BinaryCalcul *calcul) const -> llvm::Value *;

auto buildFloat(BinaryCalcul *calcul) const -> llvm::Value *;

auto buildBool(BinaryCalcul *calcul) const -> llvm::Value *;

auto buildPointer(BinaryCalcul *calcul) const -> llvm::Value *;

auto static buildError(BinaryCalcul *calcul) -> std::logic_error;
};
}

#endif // FILC_CALCULBUILDER_H
71 changes: 71 additions & 0 deletions include/filc/llvm/IRGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* MIT License
*
* Copyright (c) 2024-Present Kevin Traini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef FILC_IRGENERATOR_H
#define FILC_IRGENERATOR_H

#include "filc/grammar/Visitor.h"
#include "filc/validation/Environment.h"
#include <llvm/IR/Module.h>
#include <llvm/IR/IRBuilder.h>
#include <memory>

namespace filc {
class IRGenerator final: public Visitor<llvm::Value *> {
public:
explicit IRGenerator(const std::string &filename, const Environment *environment);

~IRGenerator() override = default;

[[nodiscard]] auto dump() const -> std::string;

[[nodiscard]] auto toTarget(const std::string &output_file, const std::string &target_triple) const -> int;

auto visitProgram(Program *program) -> llvm::Value * override;

auto visitBooleanLiteral(BooleanLiteral *literal) -> llvm::Value * override;

auto visitIntegerLiteral(IntegerLiteral *literal) -> llvm::Value * override;

auto visitFloatLiteral(FloatLiteral *literal) -> llvm::Value * override;

auto visitCharacterLiteral(CharacterLiteral *literal) -> llvm::Value * override;

auto visitStringLiteral(StringLiteral *literal) -> llvm::Value * override;

auto visitVariableDeclaration(VariableDeclaration *variable) -> llvm::Value * override;

auto visitIdentifier(Identifier *identifier) -> llvm::Value * override;

auto visitBinaryCalcul(BinaryCalcul *calcul) -> llvm::Value * override;

auto visitAssignation(Assignation *assignation) -> llvm::Value * override;

private:
std::unique_ptr<llvm::LLVMContext> _llvm_context;
std::unique_ptr<llvm::Module> _module;
std::unique_ptr<llvm::IRBuilder<>> _builder;
};
}

#endif // FILC_IRGENERATOR_H
Loading