Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Sameer Rahmani | 6e6c8d8897 | |
Sameer Rahmani | 462074faa6 |
|
@ -16,7 +16,7 @@ AlignEscapedNewlines: Left
|
|||
AlwaysBreakTemplateDeclarations: Yes
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^"'
|
||||
- Regex: '^"(serene)/'
|
||||
Priority: 1
|
||||
SortPriority: 1
|
||||
CaseSensitive: true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
Checks: '-*,clang-diagnostic-*,clang-analyzer-*,cert-*,-cert-err58-cpp,concurrency-*,llvm-*,performance-*,readability-*,-readability-identifier-length*'
|
||||
WarningsAsErrors: '-*,clang-diagnostic-*,clang-analyzer-*,cert-*,-cert-err58-cpp,concurrency-*,llvm-*,performance-*,readability-*,-readability-identifier-length*'
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-*,cert-*,-cert-err58-cpp,concurrency-*,llvm-*,performance-*,readability-*'
|
||||
WarningsAsErrors: 'clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-*,cert-*,-cert-err58-cpp,concurrency-*,llvm-*,performance-*,readability-*'
|
||||
HeaderFilterRegex: ''
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: file
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
./resources/
|
|
@ -23,14 +23,4 @@ bin/serenec_CXX_cotire.cmake
|
|||
/config.h
|
||||
|
||||
docs/Doxyfile.docs
|
||||
.ccache/
|
||||
docs/spec.tex
|
||||
docs/spec.pdf
|
||||
.tmp
|
||||
.env
|
||||
.tex
|
||||
.pdf
|
||||
docs/overall_picture.png
|
||||
.direnv/
|
||||
.pre-commit-config.yaml
|
||||
.envrc
|
||||
.ccache/
|
|
@ -1 +1 @@
|
|||
#leak:mlir::Region::emplaceBlock
|
||||
#leak:mlir::Region::emplaceBlock
|
|
@ -1,55 +0,0 @@
|
|||
pipeline:
|
||||
Linters:
|
||||
group: build
|
||||
image: lxsameer/serene_ci:13
|
||||
commands:
|
||||
- export SERENE_CI=true
|
||||
- ./builder setup
|
||||
- export FILES="$(git diff --name-only HEAD HEAD~1)"
|
||||
- pre-commit run --files "$FILES"
|
||||
|
||||
Build:
|
||||
group: build
|
||||
image: lxsameer/serene_ci:13
|
||||
commands:
|
||||
# Uncomment this when running with a new toolchain for the
|
||||
# first time to save up space
|
||||
# - rm -rf /root/.serene/*
|
||||
- ./builder build -DSERENE_DISABLE_CCACHE=ON
|
||||
|
||||
volumes:
|
||||
- serene_config:/root/.serene/
|
||||
|
||||
ChatNotify:
|
||||
image: lxsameer/notify:3
|
||||
settings:
|
||||
matrix_room_id:
|
||||
from_secret: matrix_room
|
||||
matrix_access_token:
|
||||
from_secret: matrix_token
|
||||
|
||||
matrix_user:
|
||||
from_secret: matrix_user
|
||||
|
||||
matrix_msg: "[${CI_REPO}][Build] Job #${CI_BUILD_NUMBER} <b>failed</b> for branch <b>${CI_COMMIT_BRANCH}</b>. ${CI_BUILD_LINK}"
|
||||
secrets: [ matrix_room, matrix_token, matrix_user ]
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
MailNotify:
|
||||
image: lxsameer/woodpecker_mailer:4
|
||||
settings:
|
||||
from: ci@serene-lang.org
|
||||
user:
|
||||
from_secret: mailer_user
|
||||
password:
|
||||
from_secret: mailer_password
|
||||
to: ${CI_COMMIT_AUTHOR_EMAIL}
|
||||
subject: "[${CI_REPO}][Build] JOB #${CI_BUILD_NUMBER} failed for branch '${CI_COMMIT_BRANCH}'."
|
||||
text: |
|
||||
BUILD: ${CI_BUILD_LINK}
|
||||
COMMIT: ${CI_COMMIT_LINK}
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
secrets: [ mail_pass, mail_user ]
|
|
@ -1,64 +0,0 @@
|
|||
pipeline:
|
||||
build:
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
secrets: [docker_username, docker_password]
|
||||
settings:
|
||||
repo: serenelang/serene-docs
|
||||
registry: docker.io
|
||||
dockerfile: docs/Dockerfile
|
||||
tags: latest
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
when:
|
||||
- path:
|
||||
include: [ 'mkdocs.yml', 'docs/**' ]
|
||||
- branch: master
|
||||
|
||||
deploy:
|
||||
image: docker:24.0.2-cli-alpine3.18
|
||||
commands:
|
||||
- docker stack deploy -c docs/service.yml serene-docs --prune
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
when:
|
||||
- path:
|
||||
include: [ 'mkdocs.yml', 'docs/**' ]
|
||||
# ignore_message: "[ALL]"
|
||||
- branch: master
|
||||
|
||||
ChatNotify:
|
||||
image: lxsameer/notify:3
|
||||
settings:
|
||||
matrix_room_id:
|
||||
from_secret: matrix_room
|
||||
matrix_access_token:
|
||||
from_secret: matrix_token
|
||||
|
||||
matrix_user:
|
||||
from_secret: matrix_user
|
||||
|
||||
matrix_msg: "[${CI_REPO}][Docs] Job #${CI_BUILD_NUMBER} <b>failed</b> for branch <b>${CI_COMMIT_BRANCH}</b>. ${CI_BUILD_LINK}"
|
||||
secrets: [ matrix_room, matrix_token, matrix_user ]
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
MailNotify:
|
||||
image: lxsameer/woodpecker_mailer:4
|
||||
settings:
|
||||
from: ci@serene-lang.org
|
||||
user:
|
||||
from_secret: mailer_user
|
||||
password:
|
||||
from_secret: mailer_password
|
||||
to: ${CI_COMMIT_AUTHOR_EMAIL}
|
||||
subject: "[${CI_REPO}][Docs] JOB #${CI_BUILD_NUMBER} failed for branch '${CI_COMMIT_BRANCH}'."
|
||||
text: |
|
||||
BUILD: ${CI_BUILD_LINK}
|
||||
COMMIT: ${CI_COMMIT_LINK}
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
secrets: [ mail_pass, mail_user ]
|
246
CMakeLists.txt
246
CMakeLists.txt
|
@ -1,61 +1,55 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
# Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, version 2.
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
project(
|
||||
Serene
|
||||
VERSION 1.0.0
|
||||
DESCRIPTION "A modern typed Lisp."
|
||||
# Project name and a few useful settings. Other commands can pick up the results
|
||||
project(Serene
|
||||
VERSION 0.1.0
|
||||
DESCRIPTION "Serene language is a modern Lisp."
|
||||
LANGUAGES CXX C)
|
||||
|
||||
# Clangd command file
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
|
||||
# =============================================================================
|
||||
# Policies
|
||||
# =============================================================================
|
||||
cmake_policy(SET CMP0116 OLD)
|
||||
# Policies ==========================
|
||||
cmake_policy(SET CMP0116 NEW)
|
||||
|
||||
# =============================================================================
|
||||
# User Options
|
||||
# =============================================================================
|
||||
option(CPP_20_SUPPORT "C++20 Support" ON)
|
||||
option(SERENE_BUILD_TESTING "Enable tests" ON)
|
||||
# User Options ======================
|
||||
option(CPP_20_SUPPORT "C++20 Support" OFF)
|
||||
option(SERENE_BUILD_TESTING "Enable tests" OFF)
|
||||
option(SERENE_ENABLE_BUILDID "Enable build id." OFF)
|
||||
option(SERENE_ENABLE_THINLTO "Enable ThisLTO." ON)
|
||||
option(SERENE_ENABLE_DOCS "Enable document generation" OFF)
|
||||
option(SERENE_ENABLE_TIDY "Enable clang tidy check" OFF)
|
||||
option(SERENE_DISABLE_CCACHE "Disable automatic ccache integration" OFF)
|
||||
option(SERENE_ENABLE_DEVTOOLS "Enable the devtools build" OFF)
|
||||
option(SERENE_DISABLE_MUSL "Disable musl libc (Musl is recommended)." OFF)
|
||||
option(SERENE_DISABLE_LIBCXX "Disable libc++ (libc++ is recommended)." OFF)
|
||||
option(SERENE_DISABLE_COMPILER_RT
|
||||
"Disable compiler-rt (compiler-rt is recommended)." OFF)
|
||||
|
||||
# LLVM Info about the target llvm build
|
||||
option(LLVM_USE_PERF "If the target LLVM build is built with LLVM_USE_PERF" OFF)
|
||||
# libserene
|
||||
option(SERENE_SHARED_LIB "Build libserene as a shared library" ON)
|
||||
option(SERENE_SHOW_MLIR_DIALECTS "Print out a list of MLIR dialect libs" OFF)
|
||||
option(SERENE_SHOW_MLIR_TRANSFORMERS "Print out a list of MLIR dialect transformer libs" OFF)
|
||||
option(SERENE_SHOW_LLVM_LIBS "Print all the llvm libs available" OFF)
|
||||
|
||||
# Only do these if this is the main project, and not if it is included through
|
||||
# add_subdirectory
|
||||
|
||||
option(SERENE_WITH_MLIR_CL_OPTION "Add support for controlling MLIR via command line options" OFF)
|
||||
|
||||
# Only do these if this is the main project, and not if it is included through add_subdirectory
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
# Settings =======================
|
||||
|
||||
set(C_STANDARD 17)
|
||||
## Settings =======================
|
||||
# specify the C++ standard
|
||||
if(CPP_20_SUPPORT)
|
||||
if (CPP_20_SUPPORT)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
@ -63,21 +57,22 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
|||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Setup the source locations
|
||||
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||
set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
if(SERENE_ENABLE_TIDY)
|
||||
find_program(CLANG_TIDY_PATH NAMES clang-tidy REQUIRED)
|
||||
endif()
|
||||
|
||||
# We use iwyu intensively. For the version details check out the submodule at
|
||||
# `deps/include-what-you-use`
|
||||
find_program(iwyu NAMES include-what-you-use iwyu REQUIRED)
|
||||
set(iwyu_path ${iwyu})
|
||||
|
||||
# Let's ensure -std=c++xx instead of -std=g++xx
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/scripts/cmake")
|
||||
set(MemoryCheckCommand "valgrind")
|
||||
|
||||
configure_file(${INCLUDE_DIR}/serene/config.h.in include/serene/config.h)
|
||||
|
||||
# Let's nicely support folders in IDEs
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
|
@ -86,122 +81,149 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
|||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-Wpedantic
|
||||
-Wabstract-final-class
|
||||
-Walloca
|
||||
-Warray-bounds-pointer-arithmetic
|
||||
-Warray-parameter
|
||||
-Wassign-enum
|
||||
-Wsign-conversion
|
||||
-Wnon-virtual-dtor
|
||||
-Wold-style-cast
|
||||
-Wcast-align
|
||||
-Wunused
|
||||
-Woverloaded-virtual
|
||||
-Wdouble-promotion
|
||||
-Wformat=2)
|
||||
-fno-rtti
|
||||
-fno-builtin-strlen
|
||||
|
||||
# Dedicate a section to each function, so the linker
|
||||
# can do a better job on dead code elimination
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
|
||||
$<$<CONFIG:DEBUG>:-g3>
|
||||
$<$<CONFIG:DEBUG>:-ggdb>
|
||||
# For the sake of debugging
|
||||
$<$<CONFIG:DEBUG>:-fno-inline>
|
||||
# To make the local ccache happy
|
||||
$<$<CONFIG:DEBUG>:-fdebug-prefix-map=${PROJECT_SOURCE_DIR}=.>
|
||||
|
||||
$<$<CONFIG:DEBUG>:-fno-omit-frame-pointer>
|
||||
$<$<CONFIG:RELEASE>:-fomit-frame-pointer>
|
||||
$<$<CONFIG:DEBUG>:-fsanitize=address>
|
||||
|
||||
$<$<CONFIG:RELEASE>:-O3>
|
||||
$<$<CONFIG:RELEASE>:-fmerge-all-constants>
|
||||
$<$<CONFIG:RELEASE>:-flto=thin>
|
||||
$<$<CONFIG:DEBUG>:-shared-libsan>
|
||||
)
|
||||
|
||||
add_link_options(
|
||||
# We enforce the lld linker
|
||||
-fuse-ld=lld
|
||||
-Wl,-gc-sections
|
||||
$<$<CONFIG:DEBUG>:-shared-libsan>
|
||||
$<$<CONFIG:RELEASE>:-fsanitize-address-globals-dead-stripping>
|
||||
$<$<CONFIG:DEBUG>:-fsanitize=address>
|
||||
$<$<CONFIG:RELEASE>:-flto=thin>
|
||||
$<$<CONFIG:RELEASE>:-s>
|
||||
# Do not link against shared libraries
|
||||
#--static
|
||||
)
|
||||
|
||||
# Do we need to build serene as a shared lib? default is "yes"
|
||||
if(SERENE_SHARED_LIB)
|
||||
set(BUILD_SHARED_LIBS "${SERENE_SHARED_LIB}")
|
||||
endif()
|
||||
|
||||
find_program(LLD_PROGRAM REQUIRED NAMES lld)
|
||||
find_program(MLIRTBLGEN_PROGRAM REQUIRED NAMES mlir-tblgen)
|
||||
|
||||
if(SERENE_ENABLE_BUILDID)
|
||||
add_link_options(-Wl,--build-id)
|
||||
endif()
|
||||
|
||||
#TODO: Setup the THINLTO on release
|
||||
if(SERENE_ENABLE_THINLTO)
|
||||
endif()
|
||||
|
||||
|
||||
# CCache support ==============================
|
||||
if(SERENE_DISABLE_CCACHE)
|
||||
message(STATUS "CCache support is disabled")
|
||||
else()
|
||||
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
|
||||
if(CCACHE_PROGRAM)
|
||||
message(STATUS "Found CCache")
|
||||
set(SERENE_CCACHE_MAXSIZE
|
||||
""
|
||||
CACHE STRING "Size of ccache")
|
||||
set(SERENE_CCACHE_DIR
|
||||
""
|
||||
CACHE STRING "Directory to keep ccached data")
|
||||
set(SERENE_CCACHE_PARAMS
|
||||
"CCACHE_CPP2=yes CCACHE_HASHDIR=yes"
|
||||
CACHE STRING "Parameters to pass through to ccache")
|
||||
set(SERENE_CCACHE_MAXSIZE "" CACHE STRING "Size of ccache")
|
||||
set(SERENE_CCACHE_DIR "" CACHE STRING "Directory to keep ccached data")
|
||||
set(SERENE_CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes"
|
||||
CACHE STRING "Parameters to pass through to ccache")
|
||||
|
||||
set(CCACHE_PROGRAM "${SERENE_CCACHE_PARAMS} ${CCACHE_PROGRAM}")
|
||||
|
||||
if(SERENE_CCACHE_MAXSIZE)
|
||||
set(CCACHE_PROGRAM
|
||||
"CCACHE_MAXSIZE=${SERENE_CCACHE_MAXSIZE} ${CCACHE_PROGRAM}")
|
||||
if (SERENE_CCACHE_MAXSIZE)
|
||||
set(CCACHE_PROGRAM "CCACHE_MAXSIZE=${SERENE_CCACHE_MAXSIZE} ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
if(SERENE_CCACHE_DIR)
|
||||
if (SERENE_CCACHE_DIR)
|
||||
set(CCACHE_PROGRAM "CCACHE_DIR=${SERENE_CCACHE_DIR} ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
message(STATUS "Using CCACHE: ${CCACHE_PROGRAM}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Unable to find the program ccache. Set SERENE_DISABLE_CCACHE to ON")
|
||||
message(FATAL_ERROR "Unable to find the program ccache. Set SERENE_DISABLE_CCACHE to ON")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SERENE_BUILD_TESTING)
|
||||
enable_testing()
|
||||
find_package(GTest REQUIRED)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker
|
||||
# settings
|
||||
set(gtest_force_shared_crt
|
||||
ON
|
||||
CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
add_link_options(-Wl,-Map=output.map)
|
||||
# LLVM setup
|
||||
# ================================================================== Why not
|
||||
# specify the version? Since we use the development version of the LLVM all
|
||||
# the time it doesn't make sense to use a version here
|
||||
# LLVM setup =========================================
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
find_package(MLIR REQUIRED CONFIG)
|
||||
find_package(LLD REQUIRED CONFIG)
|
||||
find_program(LLD_PROGRAM REQUIRED NAMES lld)
|
||||
|
||||
find_program(MLIRTBLGEN_PROGRAM REQUIRED NAMES mlir-tblgen)
|
||||
find_package(Clang REQUIRED CONFIG)
|
||||
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
|
||||
message(STATUS "Using LLDConfig.cmake in: ${LLD_DIR}")
|
||||
message(STATUS "Using CLANGConfig.cmake in: ${Clang_DIR}")
|
||||
|
||||
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
|
||||
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
|
||||
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Make cmake modules available to load
|
||||
list(APPEND CMAKE_MODULE_PATH "${MLIR_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLD_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${Clang_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLD_CMAKE_DIR}")
|
||||
|
||||
include(TableGen)
|
||||
include(AddLLVM)
|
||||
include(AddMLIR)
|
||||
include(HandleLLVMOptions)
|
||||
include(AddClang)
|
||||
|
||||
# This goes against the CMake's best practices to add these kind of settings
|
||||
# to the targets only. But this is what LLVM recommends and we will stick to
|
||||
# their recommendation.
|
||||
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
|
||||
|
||||
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
|
||||
add_definitions(${LLVM_DEFINITIONS_LIST})
|
||||
|
||||
link_directories(${LLVM_BUILD_LIBRARY_DIR})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
|
||||
# /LLVM setup
|
||||
# =================================================================
|
||||
# add_subdirectory(serene-tblgen)
|
||||
add_subdirectory(serene)
|
||||
# include(tablegen-serene) Create the tools we use to compile Serene
|
||||
llvm_map_components_to_libnames(llvm_libs support)
|
||||
|
||||
# The compiled library code is here add_subdirectory(libserene) The static
|
||||
# library containing builtin special forms and functions
|
||||
# add_subdirectory(core) Binary tools of the compiler
|
||||
# add_subdirectory(serenec) add_subdirectory(serene-repl)
|
||||
|
||||
# add_subdirectory(devtools)
|
||||
|
||||
if(SERENE_ENABLE_DOCS)
|
||||
add_subdirectory(docs)
|
||||
# Serene Setup ===================================
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
# We don't want the generated files from table gen
|
||||
# to be treated as local since the contain warnings
|
||||
include_directories(SYSTEM ${PROJECT_BINARY_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
|
||||
# The compiled library code is here
|
||||
add_subdirectory(src)
|
||||
# The executable code is here
|
||||
add_subdirectory(include)
|
||||
|
||||
if (SERENE_ENABLE_DOCS)
|
||||
# Docs only available if this is the main app
|
||||
find_package(Doxygen
|
||||
REQUIRED dot
|
||||
OPTIONAL_COMPONENTS dia)
|
||||
|
||||
if(Doxygen_FOUND)
|
||||
add_subdirectory(docs)
|
||||
else()
|
||||
message(STATUS "Doxygen not found, not building docs")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
33
README.md
33
README.md
|
@ -1,33 +0,0 @@
|
|||
# Serene lang
|
||||
[![Please don't upload to GitHub](https://nogithub.codeberg.page/badge.svg)](https://nogithub.codeberg.page)
|
||||
[![status-badge](https://ci.devheroes.codes/api/badges/Serene/serene/status.svg)](https://ci.devheroes.codes/Serene/serene)
|
||||
|
||||
Serene is a modern typed lisp. It's not done yet, and it's heavily under development. Don't
|
||||
expect anything stable for now.
|
||||
|
||||
## More Info
|
||||
- Website: https://serene-lang.org
|
||||
- Documentation: https://serene-lang.org/getting_started/
|
||||
- CI: https://ci.devheroes.codes/Serene/serene
|
||||
|
||||
# Get Help
|
||||
If you need help, or you just want to hang out, you can find us at:
|
||||
|
||||
- *IRC*: *#serene-lang* on the libera chat server
|
||||
- *Matrix*: https://app.element.io/#/room/#serene:matrix.org
|
||||
- *MailingList*: https://www.freelists.org/list/serene
|
||||
|
||||
# License
|
||||
Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
|
||||
*Serene* is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 2.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,101 @@
|
|||
* Serene lang
|
||||
|
||||
** Setup development environment
|
||||
Setup the githook and install dependencies using the following commands:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
./builder setup
|
||||
#+END_SRC
|
||||
|
||||
*** Dependencies
|
||||
You would need the following dependencies to start get started with *Serene* development
|
||||
|
||||
- LLVM (LLVM Instructions coming up.)
|
||||
- cmake
|
||||
- ninja
|
||||
- doxygen (If you want to build the docs as well)
|
||||
- Valgrind
|
||||
- CCache (If you want faster builds specially with the LLVM)
|
||||
|
||||
** LLVM Installation
|
||||
MLIR is a part of the [[https://llvm.org][LLVM]] project and in order to build it we need to build the LLVM itself as well.
|
||||
Here is a quick guide to build the latest version of the LLVM and MLIR.
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
## YES we're using the development version of MLIR
|
||||
git clone https://github.com/llvm/llvm-project.git
|
||||
|
||||
mkdir llvm-project/build
|
||||
cd llvm-project/build
|
||||
|
||||
cmake -G Ninja ../llvm \
|
||||
-DCMAKE_INSTALL_PREFIX=/your/target/path \
|
||||
-DLLVM_PARALLEL_COMPILE_JOBS=7 \
|
||||
-DLLVM_PARALLEL_LINK_JOBS=1 \
|
||||
-DLLVM_BUILD_EXAMPLES=ON \
|
||||
-DLLVM_TARGETS_TO_BUILD="X86" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DLLVM_ENABLE_ASSERTIONS=ON \
|
||||
-DLLVM_CCACHE_BUILD=ON \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DLLVM_ENABLE_PROJECTS='clang;lldb;lld;mlir;clang-tools-extra;compiler-rt' \
|
||||
-DCMAKE_C_COMPILER=clang \ # If you have clang installed already
|
||||
-DCMAKE_CXX_COMPILER=clang++ \ # If you have clang installed already
|
||||
-DLLVM_ENABLE_LLD=ON
|
||||
|
||||
cmake --build .
|
||||
|
||||
cmake --build . --target check-mlir
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/your/target/location -P cmake_install.cmake
|
||||
#+END_SRC
|
||||
|
||||
You need to have =clang= and =lld= installed to compile the LLVM with the above command. Also if you
|
||||
are not using =ccache= just remove the option related to it from the above command.
|
||||
|
||||
*** Emacs
|
||||
If you're using Emacs as your development environment just install =clangd= and =lsp=.
|
||||
|
||||
** Heads up for devs
|
||||
While you're working on *Serene* be mindful of:
|
||||
- In =DEBUG= mode we dynamically link against =libsan= due to the fact that we build the =libserene=
|
||||
as a shared lib by default. This means we need to =LD_PRELOAD= the =libclang_rt= before we run
|
||||
any executable. If you're using the =builder= script you're all set otherwise you can run an
|
||||
executable like:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) /path/to/executable
|
||||
#+END_SRC
|
||||
|
||||
* How to build
|
||||
In order to build for development (Debug mode) just use =./builder build= to setup the build and build
|
||||
the project once and then you can just use =./builder compile= to build the changed files only.
|
||||
|
||||
Check out the =builder= script for more subcommands and details.
|
||||
|
||||
* Cheatsheets
|
||||
- [[https://github.com/muqsitnawaz/modern-cpp-cheatsheet][Modern C++ Cheatsheet]]
|
||||
|
||||
* License
|
||||
Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
|
||||
*Serene* is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 2.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
* Get Help
|
||||
If you need help or you just want to hangout, you can find us at:
|
||||
|
||||
- *IRC*: *#serene-lang* on the freenode server
|
||||
|
||||
- *Matrix Network*: https://matrix.to/#/#serene:matrix.org?via=matrix.org&via=gitter.im
|
||||
|
||||
- *MailingList*: https://www.freelists.org/list/serene
|
|
@ -0,0 +1,232 @@
|
|||
#! /bin/bash
|
||||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
command=$1
|
||||
|
||||
export CC=$(which clang)
|
||||
export CXX=$(which clang++)
|
||||
|
||||
# TODO: Add sloppiness to the cmake list file as well
|
||||
export CCACHE_SLOPPINESS="pch_defines,time_macros"
|
||||
|
||||
export ASAN_OPTIONS=check_initialization_order=1
|
||||
LSAN_OPTIONS=suppressions=$(pwd)/.ignore_sanitize
|
||||
export LSAN_OPTIONS
|
||||
export LDFLAGS="-fuse-ld=lld"
|
||||
|
||||
# The `builder` script is supposed to be run from the
|
||||
# root of the source tree
|
||||
ROOT_DIR=$(pwd)
|
||||
BUILD_DIR=$ROOT_DIR/build
|
||||
ME=$(cd "$(dirname "$0")/." >/dev/null 2>&1 ; pwd -P)
|
||||
|
||||
CMAKEARGS_DEBUG=" -DCMAKE_BUILD_TYPE=Debug -DSERENE_WITH_MLIR_CL_OPTION=ON"
|
||||
CMAKEARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DSERENE_CCACHE_DIR=$HOME/.ccache"
|
||||
|
||||
# The scan-build utility scans the build for bugs checkout the man page
|
||||
scanbuild="scan-build --force-analyze-debug-code --use-analyzer=$(which clang)"
|
||||
|
||||
|
||||
function gen_precompile_header_index() {
|
||||
echo "// DO NOT EDIT THIS FILE: It is aute generated by './builder gen_precompile_index'" > ./include/serene_precompiles.h
|
||||
echo "#ifndef SERENE_PRECOMPIL_H" >> ./include/serene_precompiles.h
|
||||
echo "#define SERENE_PRECOMPIL_H" >> ./include/serene_precompiles.h
|
||||
grep -oP "#include .llvm/.*" . -R|cut -d':' -f2|tail +2 >> ./include/serene_precompiles.h
|
||||
grep -oP "#include .mlir/.*" . -R|cut -d':' -f2|tail +2 >> ./include/serene_precompiles.h
|
||||
echo "#endif" >> ./include/serene_precompiles.h
|
||||
}
|
||||
|
||||
function pushed_build() {
|
||||
pushd "$BUILD_DIR" > /dev/null || return
|
||||
}
|
||||
|
||||
function popd_build() {
|
||||
popd > /dev/null || return
|
||||
}
|
||||
|
||||
function build-gen() {
|
||||
pushed_build
|
||||
echo "Running: "
|
||||
echo "cmake -G Ninja $CMAKEARGS $CMAKEARGS_DEBUG \"$@\" \"$ROOT_DIR\""
|
||||
cmake -G Ninja $CMAKEARGS $CMAKEARGS_DEBUG "$@" "$ROOT_DIR"
|
||||
popd_build
|
||||
}
|
||||
function compile() {
|
||||
pushed_build
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build() {
|
||||
build-gen "$@"
|
||||
pushed_build
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build-20() {
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCPP_20_SUPPORT=ON "$@" "$ROOT_DIR"
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build-release() {
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release "$ROOT_DIR"
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build-docs() {
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Docs "$ROOT_DIR"
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
function clean() {
|
||||
rm -rf "$BUILD_DIR"
|
||||
}
|
||||
|
||||
function run() {
|
||||
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) "$BUILD_DIR"/src/serenec/serenec "$@"
|
||||
}
|
||||
|
||||
function repl() {
|
||||
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) "$BUILD_DIR"/src/serene-repl/serene-repl "$@"
|
||||
}
|
||||
|
||||
function memcheck() {
|
||||
export ASAN_FLAG=""
|
||||
build
|
||||
pushed_build
|
||||
valgrind --tool=memcheck --leak-check=yes --trace-children=yes "$BUILD_DIR"/bin/serenec "$@"
|
||||
popd_build
|
||||
}
|
||||
|
||||
function run-tests() {
|
||||
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) "$BUILD_DIR"/src/tests/tests
|
||||
}
|
||||
|
||||
function tests() {
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON "$ROOT_DIR"
|
||||
cmake --build .
|
||||
popd_build
|
||||
}
|
||||
|
||||
|
||||
case "$command" in
|
||||
"setup")
|
||||
rm -rfv $ME/.git/hooks/pre-commit
|
||||
ln -s $ME/scripts/pre-commit $ME/.git/hooks/pre-commit
|
||||
;;
|
||||
"build")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build "${@:2}"
|
||||
;;
|
||||
"build-tidy")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build "-DSERENE_ENABLE_TIDY=ON" "${@:2}"
|
||||
;;
|
||||
|
||||
"build-20")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build-20 "${@:2}"
|
||||
;;
|
||||
|
||||
"build-docs")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build-docs "${@:2}"
|
||||
;;
|
||||
|
||||
"build-release")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build-release "${@:2}"
|
||||
;;
|
||||
"compile")
|
||||
compile
|
||||
;;
|
||||
"compile-and-tests")
|
||||
compile
|
||||
run-tests
|
||||
;;
|
||||
|
||||
"run")
|
||||
run "${@:2}"
|
||||
;;
|
||||
|
||||
"repl")
|
||||
repl "${@:2}"
|
||||
;;
|
||||
|
||||
"run-tests")
|
||||
run-tests "${@:2}"
|
||||
;;
|
||||
|
||||
"scan-build")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build-gen
|
||||
pushed_build
|
||||
exec $scanbuild cmake --build .
|
||||
popd_build
|
||||
;;
|
||||
"memcheck")
|
||||
memcheck "${@:2}"
|
||||
;;
|
||||
"tests")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
tests
|
||||
run-tests
|
||||
;;
|
||||
"clean")
|
||||
rm -rf "$BUILD_DIR"
|
||||
;;
|
||||
"gen_precompile_index")
|
||||
gen_precompile_header_index
|
||||
;;
|
||||
"full-build")
|
||||
clean
|
||||
mkdir -p "$BUILD_DIR"
|
||||
build
|
||||
tests
|
||||
run-tests
|
||||
memcheck
|
||||
;;
|
||||
*)
|
||||
echo "Commands: "
|
||||
echo "setup - Setup the githooks for devs"
|
||||
echo "full-build - Build and test Serene."
|
||||
echo "build - Build Serene from scratch in DEBUG mode."
|
||||
echo "build-release - Build Serene from scratch in RELEASE mode."
|
||||
echo "compile - reCompiles the project using the already exist cmake configuration"
|
||||
echo "compile-and-tests - reCompiles the project using the already exist cmake configuration and runs the tests"
|
||||
echo "run - Runs the serene executable"
|
||||
echo "scan-build - Compiles serene with static analyzer"
|
||||
echo "tests - Runs the test cases"
|
||||
echo "memcheck - Runs the memcheck(valgrind) tool."
|
||||
echo "clean - :D"
|
||||
;;
|
||||
esac
|
|
@ -1,29 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file sets up a CMakeCache to build serene for development. In this
|
||||
# cache file we assume that you are using the toolchain and musl that are
|
||||
# built by the `builder` script. For example: `builder deps build llvm`
|
||||
# You still can just build everything yourself but the builder script and
|
||||
# this file make the process easier.
|
||||
|
||||
# Where to find the packages. Packages can be built from source
|
||||
# or downloaded via the builder script.
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "")
|
||||
|
||||
set(SERENE_CCACHE_DIR "$ENV{HOME}/.ccache" CACHE STRING "")
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
|
@ -1,29 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file sets up a CMakeCache to build serene for development. In this
|
||||
# cache file we assume that you are using the toolchain and musl that are
|
||||
# built by the `builder` script. For example: `builder deps build llvm`
|
||||
# You still can just build everything yourself but the builder script and
|
||||
# this file make the process easier.
|
||||
|
||||
# Where to find the packages. Packages can be built from source
|
||||
# or downloaded via the builder script.
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL "")
|
||||
|
||||
set(SERENE_CCACHE_DIR "$ENV{HOME}/.ccache" CACHE STRING "")
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
|
@ -1,11 +0,0 @@
|
|||
#Look for an executable called sphinx-build
|
||||
find_program(SPHINX_EXECUTABLE
|
||||
NAMES sphinx-build
|
||||
DOC "Path to sphinx-build executable")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
#Handle standard arguments to find_package like REQUIRED and QUIET
|
||||
find_package_handle_standard_args(Sphinx
|
||||
"Failed to find sphinx-build executable"
|
||||
SPHINX_EXECUTABLE)
|
|
@ -1,22 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
function(serene_tablegen ofn)
|
||||
tablegen(SERENE ${ARGV})
|
||||
set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
|
||||
PARENT_SCOPE)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
endfunction()
|
|
@ -1,49 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file sets up a CMakeCache to build serene for development. In this
|
||||
# cache file we assume that you are using the toolchain and musl that are
|
||||
# built by the `builder` script. For example: `builder deps build llvm`
|
||||
# You still can just build everything yourself but the builder script and
|
||||
# this file make the process easier.
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
|
||||
set(triple x86_64-pc-linux-musl)
|
||||
|
||||
set(CMAKE_SYSROOT ${SERENE_TOOLCHAIN_PATH})
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
|
||||
|
||||
set(CMAKE_C_COMPILER "clang")
|
||||
set(CMAKE_C_COMPILER_AR "llvm-ar")
|
||||
set(CMAKE_C_COMPILER_RANLIB "llvm-ranlib")
|
||||
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
set(CMAKE_CXX_COMPILER_AR "llvm-ar")
|
||||
set(CMAKE_CXX_COMPILER_RANLIB "llvm-ranlib")
|
||||
|
||||
set(CMAKE_ASM_COMPILER "clang")
|
||||
set(CMAKE_ASM_COMPILER_AR "llvm-ar")
|
||||
set(CMAKE_ASM_COMPILER_RANLIB "llvm-ranlib")
|
||||
|
||||
set(CMAKE_C_COMPILER_TARGET ${triple})
|
||||
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
||||
set(CMAKE_ASM_COMPILER_TARGET ${triple})
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
|
@ -1,85 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
include_directories(${LIBSERENE_INCLUDE_DIR})
|
||||
|
||||
add_subdirectory(lib/serene)
|
||||
|
||||
|
||||
get_target_property(LIBNAME Serene::core CMAKE_PKG_NAME)
|
||||
|
||||
# Install rules for libserene target
|
||||
install(TARGETS core
|
||||
EXPORT CoreExports
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
||||
# Install rules for the public header files.
|
||||
install(DIRECTORY ${INCLUDE_DIR}/serene
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN *.h
|
||||
PATTERN *.td
|
||||
PATTERN "CMake*" EXCLUDE)
|
||||
|
||||
# Install rule for the public generated header files
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN *.h
|
||||
PATTERN *.td
|
||||
PATTERN *.h.inc
|
||||
PATTERN "CMake*" EXCLUDE)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# Package config file let us use find_package with serene
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/${LIBNAME}Config.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}Config.cmake"
|
||||
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/serene-core-${PROJECT_VERSION}
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"CoreConfigVersion.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}ConfigVersion.cmake"
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/serene-core-${PROJECT_VERSION}
|
||||
)
|
||||
|
||||
# Install the package exports
|
||||
install(EXPORT CoreExports
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/serene-core-${PROJECT_VERSION}
|
||||
NAMESPACE serene::)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
|
||||
if(SERENE_BUILD_TESTING)
|
||||
message("Build the test binary")
|
||||
add_subdirectory(tests)
|
||||
endif()
|
|
@ -1,21 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Exports.cmake")
|
||||
|
||||
check_required_components("@PROJECT_NAME@")
|
|
@ -1,70 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#TODO: To support MacOS look into cmake's public headers
|
||||
# https://cmake.org/cmake/help/latest/prop_tgt/PUBLIC_HEADER.html
|
||||
|
||||
# Prevent any future RPATH issue on Posix
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_INSTALL_RPATH $ORIGIN)
|
||||
endif()
|
||||
|
||||
set(SOURCES core.cpp)
|
||||
add_library(core OBJECT
|
||||
${SOURCES})
|
||||
|
||||
#add_custom_target(serene.core)
|
||||
# Create an ALIAS target. This way if we mess up the name
|
||||
# there will be an cmake error inseat of a linker error which is harder
|
||||
# to understand. So any binary that wants to use serene has to
|
||||
# use `Serene::core` alias instead
|
||||
add_library(Serene::core ALIAS core)
|
||||
|
||||
set_target_properties(core PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
CMAKE_PKG_NAME SereneCore
|
||||
# Warn on unused libs
|
||||
LINK_WHAT_YOU_USE TRUE
|
||||
CXX_INCLUDE_WHAT_YOU_USE "${iwyu_path}"
|
||||
C_INCLUDE_WHAT_YOU_USE "${iwyu_path}"
|
||||
# LTO support we need the actual object file
|
||||
# LTO will export them to llvm IR
|
||||
INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||
|
||||
target_compile_options(core PRIVATE --static)
|
||||
target_link_options(core PRIVATE --static)
|
||||
|
||||
if(SERENE_ENABLE_TIDY)
|
||||
set_target_properties(core PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_PATH})
|
||||
endif()
|
||||
|
||||
if (CPP_20_SUPPORT)
|
||||
target_compile_features(core PUBLIC cxx_std_20)
|
||||
else()
|
||||
target_compile_features(core PUBLIC cxx_std_17)
|
||||
endif()
|
||||
|
||||
# We need this directory, and users of our library will need it too
|
||||
target_include_directories(core PUBLIC "$<BUILD_INTERFACE:${INCLUDE_DIR}>")
|
||||
target_include_directories(core PUBLIC "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>")
|
||||
|
||||
# Generate the export.h
|
||||
include(GenerateExportHeader)
|
||||
|
||||
generate_export_header(core EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/serene/core/export.h)
|
||||
|
||||
target_link_libraries(core PRIVATE)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <compiler.cpp.inc>
|
||||
#include <reader.cpp.inc>
|
154
dev.org
154
dev.org
|
@ -1,7 +1,7 @@
|
|||
#+TITLE: Serene Development
|
||||
#+AUTHOR: Sameer Rahmani
|
||||
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) WONT_DO(c@/!) FAILED(f@/!)
|
||||
#+TAGS: DOCS(d) EXAMPLES(e) serenecli(c) reader(r) context(x) Misc(m) JIT(j) GC(g) Tool(t)
|
||||
#+TAGS: DOCS(d) EXAMPLES(e) serenecli(c) reader(r) context(x) Misc(m)
|
||||
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty nolatexpreview
|
||||
#+OPTIONS: tex:t
|
||||
#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Eule
|
||||
|
@ -36,8 +36,6 @@ Then here is the list or parsers that we have considered
|
|||
- [[http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm][Backquote in CL]]
|
||||
- [[https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node367.html][Backquote spec in Common Lisp the Language, 2nd Edition]]
|
||||
- [[http://christophe.rhodes.io/notes/blog/posts/2014/backquote_and_pretty_printing/][Backquote and pretty printing]]
|
||||
*** Compilers
|
||||
- https://bernsteinbear.com/blog/compiling-a-lisp-0/
|
||||
** Rust
|
||||
- [[https://doc.rust-lang.org/book/][The Rust book]] (in [[https://www.reddit.com/r/rust/comments/2s1zj2/the_rust_programming_language_book_as_epub/][EPUB]] format)
|
||||
** LLVM
|
||||
|
@ -57,13 +55,6 @@ Then here is the list or parsers that we have considered
|
|||
- [[https://julialang.org/research/julia-fresh-approach-BEKS.pdf][Julia: A Fresh Approach toNumerical Computing]]
|
||||
** Cranelift
|
||||
- [[https://github.com/bytecodealliance/wasmtime/tree/master/cranelift][Source tree]]
|
||||
** Type Systems
|
||||
- [[https://www.cs.cmu.edu/~rwh/courses/hott/][Homotopy Type Theory]]
|
||||
- No, dynamic type systems are not inherently more open:
|
||||
https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-type-systems-are-not-inherently-more-open/
|
||||
- Type theory resources:
|
||||
https://github.com/jozefg/learn-tt
|
||||
|
||||
** Memory management
|
||||
- [[https://deepu.tech/memory-management-in-golang/][Visualizing memory management in Golang]]
|
||||
- [[http://goog-perftools.sourceforge.net/doc/tcmalloc.html][TCMalloc : Thread-Caching Malloc]]
|
||||
|
@ -71,19 +62,12 @@ Then here is the list or parsers that we have considered
|
|||
** Concurrency
|
||||
- [[https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html][Scheduling In Go (Series)]]
|
||||
|
||||
** Garbage collection :GC:
|
||||
** Garbage collection
|
||||
- [[https://v8.dev/blog/high-performance-cpp-gc][GC on V8]]
|
||||
- [[https://www.microsoft.com/en-us/research/uploads/prod/2020/11/perceus-tr-v1.pdf][Perceus: Garbage Free Reference Counting with Reuse]]
|
||||
*** [[https://www.hboehm.info/gc/][Boehm GC]] :Tool:
|
||||
*** [[https://www.ravenbrook.com/project/mps/][MPS]] :Tool:
|
||||
*** [[https://www.mmtk.io/code][MMTK]] :Tool:
|
||||
*** [[https://github.com/JWesleySM/Whiro][Whiro]] :Tool:
|
||||
This is not GC but a tool to debug GC and memory allocation.
|
||||
|
||||
- [[https://www.hboehm.info/gc/][Boehm GC]]
|
||||
** JIT
|
||||
- [[https://asmjit.com/][Machine code generator for C++]]
|
||||
- https://www.youtube.com/watch?v=hILdR8XRvdQ&t=1511s
|
||||
|
||||
** Optimizations
|
||||
- [[https://sunfishcode.github.io/blog/2018/10/22/Canonicalization.html][Canonicalization]]
|
||||
|
||||
|
@ -93,10 +77,6 @@ This is not GC but a tool to debug GC and memory allocation.
|
|||
It would be cool to have macro to instruct the compiler about the likelyhood
|
||||
of a branch in a conditional. Something similar to kernel's *likely* and *unlikely*
|
||||
macros
|
||||
*** How to learn compilers: LLVM Edition
|
||||
https://lowlevelbits.org/how-to-learn-compilers-llvm-edition/
|
||||
*** Pointers Are Complicated III, or: Pointer-integer casts exposed
|
||||
https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html
|
||||
*** Execution Instrumentation
|
||||
The compiler should be able to embed some code in the program to collect data about
|
||||
the different execution paths or function instrumentation and other useful data the
|
||||
|
@ -116,83 +96,25 @@ on ADF
|
|||
*** Emacs mode
|
||||
- [[https://www.wilfred.me.uk/blog/2015/03/19/adding-a-new-language-to-emacs/][Adding A New Language to Emacs]]
|
||||
- [[https://www.wilfred.me.uk/blog/2014/09/27/the-definitive-guide-to-syntax-highlighting/][The Definitive Guide To Syntax Highlighting]]
|
||||
|
||||
** Linker
|
||||
- [[https://lwn.net/Articles/276782/][20 part linker essay]]
|
||||
- [[https://lld.llvm.org/index.html][LLD Usage]]
|
||||
** LLVM
|
||||
- [[https://blog.yossarian.net/2021/07/19/LLVM-internals-part-1-bitcode-format][LLVM Internals]]
|
||||
*** TableGen
|
||||
- [[https://llvm.org/docs/TableGen/BackGuide.html#creating-a-new-backend][Create a backend]]
|
||||
** Toolchain
|
||||
- https://llvm.org/docs/BuildingADistribution.html
|
||||
|
||||
** Cross compilation
|
||||
|
||||
- https://blog.gibson.sh/2017/11/26/creating-portable-linux-binaries/#some-general-suggestions
|
||||
A nice to read article on some of the common problems when linking statically
|
||||
with none default libc or libc++
|
||||
|
||||
** Useful courses and resources
|
||||
- https://www.cs.cornell.edu/courses/cs6120/2020fa/lesson/
|
||||
- https://cs.lmu.edu/~ray/notes/languagedesignnotes/
|
||||
* Considerations
|
||||
** Hashmaps
|
||||
*** DOS attack
|
||||
- https://www.anchor.com.au/blog/2012/12/how-to-explain-hash-dos-to-your-parents-by-using-cats/
|
||||
- https://en.wikipedia.org/wiki/Collision_attack
|
||||
* Ideas
|
||||
** Destructure types
|
||||
Imagine a type that is a subset of a Coll, and when we
|
||||
pass a Coll to its type constructor in destructs the input and
|
||||
construct the type base on the data that it needs only and
|
||||
leave the rest untouched
|
||||
** Hot function optimization
|
||||
it would be nice for the JIT to add instrumentation to the compiled
|
||||
functions and detect hot functions similar to how javascript jits do it
|
||||
and recompile those functions with more optimization passes
|
||||
* Conversations
|
||||
** Solutions to link other ~libc~ rather than the default
|
||||
From my discassion with ~lhames~
|
||||
#+BEGIN_QUOTE
|
||||
I can think of a few approaches with different trade-offs:
|
||||
- Link your whole JIT (including LLVM) against musl rather than the default -- JIT'd
|
||||
code uses the desired libc, there's only one libc in the JIT'd process, but the
|
||||
cost is high (perhaps prohibitive, depending on your constraints)
|
||||
- JIT out-of-process -- JIT (including LLVM) uses default libc and is compiled only once,
|
||||
executor links the (alternative) desired libc at compile time and must be compiled each
|
||||
time that you want to change it -- JIT'd code uses the desired libc, there's only one libc
|
||||
in the JIT'd process, but the config is involved (requires a cross-process setup)
|
||||
- JIT in process, link desired libc via JIT -- Easy to set up, but now you've got two
|
||||
libcs in the process. I've never tested that config. It might just work, it might
|
||||
fail at link or runtime in weird ways.
|
||||
#+END_QUOTE
|
||||
* TODOs
|
||||
** Strings
|
||||
*** TODO How to concat to strings in a functional and immutable way?
|
||||
Should we include an pointer to another string???
|
||||
** TODO Create =Catch2= generators to be used in tests. Specially for the =reader= tests
|
||||
** TODO Investigate possible implementanion for Internal Errors
|
||||
- An option is to use llvm registry functionality like the one used in =clang-doc= instead of
|
||||
=errorVariants= var.
|
||||
|
||||
** TODO In =SereneContext::getLatestJITDylib= function, make sure that the JITDylib is still valid
|
||||
Make sure that the returning Dylib still exists in the JIT
|
||||
by calling =jit->engine->getJITDylibByName(dylib_name);=
|
||||
** TODO Provide the CLI arguments to pass the =createTargetMachine=.
|
||||
We need a way to tweak the target machine object. It's better to provide cli tools
|
||||
to do so.
|
||||
** TODO Walk the module and register the symbols with the engine (lazy and nonlazy) :JIT:
|
||||
** TODO Change the compilation layer to accept MLIR modules instead of LLVM IR :JIT:
|
||||
This way we can fine tune MLIR's passes based on the JIT settings as well
|
||||
** TODO Create a pass to rename functions to include the ns name
|
||||
** TODO Use =const= where ever it makes sense
|
||||
** TODO Create different pass pipeline for different compilation phases
|
||||
* TODOs
|
||||
** Bootstrap*
|
||||
*** TODO Use =const= where ever it makes sense
|
||||
*** TODO Create different pass pipeline for different compilation phases
|
||||
So we can use them directly via command line, like -O1 for example
|
||||
|
||||
** TODO Investigate the huge size of serenec
|
||||
*** TODO Investigate the huge size of serenec
|
||||
So far it seems that the static linking and the lack of tree shaking is the issue
|
||||
** DONE Add the support for =ns-paths= :serenecli:context:
|
||||
*** DONE Add the support for =ns-paths= :serenecli:context:
|
||||
CLOSED: [2021-09-25 Sat 19:22]
|
||||
:LOGBOOK:
|
||||
- State "DONE" from "TODO" [2021-09-25 Sat 19:22]
|
||||
|
@ -206,39 +128,39 @@ in python.
|
|||
- [ ] Add the support to *Namespace*.
|
||||
- [ ] Add the cli argument to the =bin/serene.cpp=
|
||||
|
||||
** TODO Error handling
|
||||
*** TODO Error handling
|
||||
Create proper error handling for the internal infra
|
||||
** TODO Replace =llvm::outs()= with debug statements
|
||||
** TODO Move the generatable logic out of its files and remove them
|
||||
** TODO Add a CLI option to get any extra pass
|
||||
** TODO Add support for =sourcemgr= for input files
|
||||
** TODO Language Spec :DOCS:
|
||||
** TODO A proper List implementation
|
||||
** TODO Vector implementation
|
||||
** TODO Hashmap implementation
|
||||
** TODO Meta data support
|
||||
** TODO Docstring support :DOCS:
|
||||
*** TODO Replace =llvm::outs()= with debug statements
|
||||
*** TODO Move the generatable logic out of its files and remove them
|
||||
*** TODO Add a CLI option to get any extra pass
|
||||
*** TODO Add support for =sourcemgr= for input files
|
||||
*** TODO Language Spec :DOCS:
|
||||
*** TODO A proper List implementation
|
||||
*** TODO Vector implementation
|
||||
*** TODO Hashmap implementation
|
||||
*** TODO Meta data support
|
||||
*** TODO Docstring support :DOCS:
|
||||
- [ ] For functions and macros
|
||||
- [ ] For namespaces and projects
|
||||
- [ ] API to interact with docstrings and helps
|
||||
** TODO FFI interface
|
||||
** TODO nREPL
|
||||
** TODO Emacs mode :Misc:
|
||||
** TODO Number implementation
|
||||
** TODO String implementation
|
||||
** TODO Enum implementation
|
||||
** TODO Protocol
|
||||
** TODO Struct implementation
|
||||
** TODO Multi arity functions
|
||||
** TODO QuasiQuotation
|
||||
** TODO Linter :Misc:
|
||||
** TODO Document generator :DOCS:Misc:
|
||||
** TODO Spec like functionality
|
||||
** TODO Laziness implementation
|
||||
** TODO Investigate the Semantic Error tree and tracking
|
||||
*** TODO FFI interface
|
||||
*** TODO nREPL
|
||||
*** TODO Emacs mode :Misc:
|
||||
*** TODO Number implementation
|
||||
*** TODO String implementation
|
||||
*** TODO Enum implementation
|
||||
*** TODO Protocol
|
||||
*** TODO Struct implementation
|
||||
*** TODO Multi arity functions
|
||||
*** TODO QuasiQuotation
|
||||
*** TODO Linter :Misc:
|
||||
*** TODO Document generator :DOCS:Misc:
|
||||
*** TODO Spec like functionality
|
||||
*** TODO Laziness implementation
|
||||
*** TODO Investigate the Semantic Error tree and tracking
|
||||
Basically we should be able to create an error tree on semantic analysis
|
||||
time and trace semantic errors on different layers and intensively.
|
||||
Is it a good idea ?
|
||||
** Standard libraries
|
||||
*** TODO IO library
|
||||
*** TODO Test library
|
||||
*** Standard libraries
|
||||
**** TODO IO library
|
||||
**** TODO Test library
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if (SERENE_ENABLE_DEVTOOLS)
|
||||
|
||||
add_executable(slir-lsp-server slir-lsp-server.cpp)
|
||||
add_executable(Serene::SLIR::LSP ALIAS slir-lsp-server)
|
||||
|
||||
set_target_properties(slir-lsp-server PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
# Warn on unused libs
|
||||
LINK_WHAT_YOU_USE TRUE
|
||||
|
||||
# LTO support
|
||||
INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
|
||||
if(SERENE_ENABLE_TIDY)
|
||||
set_target_properties(slir-lsp-server PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_PATH})
|
||||
endif()
|
||||
|
||||
if (CPP_20_SUPPORT)
|
||||
target_compile_features(slir-lsp-server PRIVATE cxx_std_20)
|
||||
else()
|
||||
target_compile_features(slir-lsp-server PRIVATE cxx_std_17)
|
||||
endif()
|
||||
|
||||
|
||||
target_link_libraries(slir-lsp-server
|
||||
PRIVATE
|
||||
Serene::lib
|
||||
MLIRLspServerLib
|
||||
)
|
||||
|
||||
target_include_directories(slir-lsp-server PRIVATE ${PROJECT_BINARY_DIR})
|
||||
target_include_directories(slir-lsp-server PRIVATE ${INCLUDE_DIR})
|
||||
|
||||
install(TARGETS slir-lsp-server
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
||||
# ========
|
||||
# slir-opt
|
||||
# ========
|
||||
add_executable(slir-opt slir-opt.cpp)
|
||||
add_executable(Serene::SLIR::Opt ALIAS slir-opt)
|
||||
|
||||
set_target_properties(slir-opt PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
# Warn on unused libs
|
||||
LINK_WHAT_YOU_USE TRUE
|
||||
|
||||
# LTO support
|
||||
INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
|
||||
if(SERENE_ENABLE_TIDY)
|
||||
set_target_properties(slir-opt PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_PATH})
|
||||
endif()
|
||||
|
||||
if (CPP_20_SUPPORT)
|
||||
target_compile_features(slir-opt PRIVATE cxx_std_20)
|
||||
else()
|
||||
target_compile_features(slir-opt PRIVATE cxx_std_17)
|
||||
endif()
|
||||
|
||||
|
||||
target_link_libraries(slir-opt
|
||||
PRIVATE
|
||||
Serene::lib
|
||||
MLIROptLib
|
||||
)
|
||||
|
||||
target_include_directories(slir-opt PRIVATE ${PROJECT_BINARY_DIR})
|
||||
target_include_directories(slir-opt PRIVATE ${INCLUDE_DIR})
|
||||
|
||||
install(TARGETS slir-opt
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
endif()
|
|
@ -1,39 +0,0 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "serene/passes.h"
|
||||
#include "serene/slir/dialect.h"
|
||||
|
||||
#include <mlir/Dialect/Arithmetic/IR/Arithmetic.h>
|
||||
#include <mlir/Dialect/Func/IR/FuncOps.h>
|
||||
#include <mlir/Dialect/LLVMIR/LLVMDialect.h>
|
||||
#include <mlir/IR/Dialect.h>
|
||||
#include <mlir/Tools/mlir-opt/MlirOptMain.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
mlir::DialectRegistry registry;
|
||||
|
||||
serene::slir::registerTo(registry);
|
||||
registry.insert<mlir::arith::ArithmeticDialect, mlir::func::FuncDialect,
|
||||
mlir::LLVM::LLVMDialect>();
|
||||
|
||||
serene::passes::registerAllPasses();
|
||||
|
||||
return static_cast<int>(
|
||||
mlir::failed(mlir::MlirOptMain(argc, argv, "slir-opt", registry)));
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
set(DOXYGEN_GENERATE_HTML YES)
|
||||
set(DOXYGEN_GENERATE_MAN YES)
|
||||
set(DOXYGEN_EXTRACT_ALL YES)
|
||||
set(DOXYGEN_BUILTIN_STL_SUPPORT YES)
|
||||
|
||||
set(DOXYGEN_PROJECT_BRIEF "Just another Lisp")
|
||||
|
||||
message("<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
||||
message(${PROJECT_SOURCE_DIR})
|
||||
message(${INCLUDE_DIR})
|
||||
doxygen_add_docs(docs
|
||||
#"${CMAKE_CURRENT_SOURCE_DIR}/index.md"
|
||||
"${PROJECT_SOURCE_DIR}/src/"
|
||||
${INCLUDE_DIR})
|
||||
|
||||
add_dependencies(serenec docs)
|
|
@ -1,14 +0,0 @@
|
|||
FROM docker.io/python
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install -r docs/requirements.txt
|
||||
RUN mkdocs build
|
||||
|
||||
|
||||
FROM docker.io/busybox
|
||||
|
||||
COPY --from=0 /app/build/docs /app
|
||||
|
||||
WORKDIR /app
|
||||
CMD ["busybox", "httpd", "-f", "-v", "-p", "3000"]
|
|
@ -1,2 +1,4 @@
|
|||
(def main (fn () 4))
|
||||
(def main
|
||||
(fn () 4))
|
||||
|
||||
(def main1 (fn (v y n) 3))
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
module @some.ns {
|
||||
// Value operator ----
|
||||
%0 = "serene.value"(){value= 3} : () -> i64
|
||||
// compact form
|
||||
%1 = serene.value 3 : i32
|
||||
|
||||
%x = serene.symbol "some.ns" "x"
|
||||
// Def operator ----
|
||||
%foo = "serene.define"(%0){sym_name = "foo"}: (i64) -> !serene.symbol
|
||||
// compact form
|
||||
%bar = serene.define "bar", %0 : i64
|
||||
|
||||
// Fn operator ----
|
||||
%f1 = "serene.fn"()({
|
||||
^entry(%fnarg1 : i1, %fnarg2 : !serene.symbol):
|
||||
%2 = serene.value 3 : i32
|
||||
|
||||
// Def operator ----
|
||||
%baz = "serene.define"(%fnarg1){sym_name = "baz"}: (i1) -> !serene.symbol
|
||||
serene.ret %baz : !serene.symbol
|
||||
},
|
||||
{
|
||||
^b1(%f1 : i1):
|
||||
%3 = serene.value 4 : i32
|
||||
|
||||
// Def operator ----
|
||||
%baz1 = "serene.define"(%3){sym_name = "baz"}: (i32) -> !serene.symbol
|
||||
serene.ret %baz1 : !serene.symbol
|
||||
^b2:
|
||||
%baz2 = "serene.define"(%3){sym_name = "baz"}: (i32) -> !serene.symbol
|
||||
serene.ret %baz2 : !serene.symbol
|
||||
}){name = "some-fn", return_type = i32} : () -> !serene.fn
|
||||
|
||||
%a1 = serene.value 1 : i1
|
||||
%a2 = serene.value "x" : !serene.symbol
|
||||
|
||||
%result = serene.call %f1(%a1, %a2){} : (i1, !serene.symbol) -> i32
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
---
|
||||
title: Getting Started
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
Serene is under heavy development. This guide is dedicated to help you to get started with
|
||||
Serene development.
|
||||
|
||||
This guide assumes that you are familiar with C/C++ development and ecosystem.
|
||||
|
||||
## Are you a Linux user?
|
||||
If you are using Linux (x86_64 only), then you're in luck. The `builder` script
|
||||
will download the required toolchain automatically for you and set it up. So,
|
||||
you can just use `builder` subcommands to develop serene (you still need to
|
||||
install `cmake` and `ninja`).
|
||||
|
||||
You can disable this behaviour by setting the `USE_SERENE_TOOLCHAIN` env variable to
|
||||
anything beside "true".
|
||||
|
||||
## Dependencies
|
||||
Here is the list of dependencies that need to be present:
|
||||
- `LLVM` (You can find the exact version in the `builder` script)
|
||||
- `CMake` `>= 3.19`
|
||||
- `Ninja`
|
||||
- `include-what-you-use`
|
||||
- `Valgrind` (Optional and only for development)
|
||||
- `CCache` (If you want faster builds, specially with the LLVM)
|
||||
- `Boehm GC` `v8.2.2`
|
||||
make sure to build in statically with `-fPIC` flag.
|
||||
- `zstd` (Only if you want to use prebuilt dependencies on Linux)
|
||||
- Musl libc `v1.2.3` (It's not required but highly recommended)
|
||||
- `libc++` (same version as LLVM abviously. It's not required but highly recommended)
|
||||
- `compiler-rt` (same version as LLVM abviously. It's not required but highly recommended)
|
||||
|
||||
Serene build system uses Musl, libc++, and compiler-rt to generate a static binary.
|
||||
You can use glibc, libgcc, and libstdc++ instead. But you might not be able to
|
||||
cross compiler with Serene and also if anything happen to you, I might not be able
|
||||
to help (I'll try for sure).
|
||||
|
||||
## Setup development environment
|
||||
Before, you have to set up the necessary git hooks as follows:
|
||||
|
||||
```bash
|
||||
./builder setup
|
||||
```
|
||||
|
||||
## Build and installing dependencies (Other platforms)
|
||||
Currently, the `builder` script does not support any platform beside GNU/Linux. So, you
|
||||
need to build the dependencies yourself and make them available to the builder.
|
||||
|
||||
By the way, If you are interested, you can just hack the builder script and accommodate your
|
||||
platform and contribute your changes to the project.
|
||||
|
||||
To build the dependencies in your platform, you can use the https://devheroes.codes/Serene/bootstrap-toolchain
|
||||
repo as a reference or even modify it to support other platforms. Any contribution will be appreciated.
|
||||
|
||||
After all, it's just a cmake project. So, don't be afraid.
|
||||
|
||||
## How to build
|
||||
To build for development (Debug mode) just use `./builder build` to setup the build system,
|
||||
and build the project once, and then you can just use `./builder compile` to build the changed files
|
||||
only.
|
||||
|
||||
Check out the `builder` script for more subcommands and details.
|
||||
|
||||
## How to debug
|
||||
Since we're using the Boehm GC, to use a debugger, we need to turn off some of the signal
|
||||
handlers that the debugger sets. To run the debugger (by default, lldb) with `serene`
|
||||
just use the `lldb-run` subcommand of the builder script. In the debugger, after setting the
|
||||
break point on the `main` function (`b main`) then use the following commands on:
|
||||
|
||||
```
|
||||
process handle -p yes -s no -n no SIGPWR
|
||||
process handle -p yes -s no -n no SIGXCPU
|
||||
process handle -p yes -s no -n no SIGSEGV
|
||||
```
|
||||
|
||||
## Cheatsheets
|
||||
- [Modern C++ Cheatsheet](https://github.com/muqsitnawaz/modern-cpp-cheatsheet)
|
||||
- [Modern CMake](https://cliutils.gitlab.io/modern-cmake/)
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
hide:
|
||||
- navigation
|
||||
- toc
|
||||
title: Home
|
||||
---
|
||||
# “What I cannot create, I do not understand”
|
||||
-- Richard Feynman
|
||||
|
||||
## Serene is ...
|
||||
A modern lisp, and it is to be born. It started out of the curiosity of the author and his journey
|
||||
through computer science and mathematics. We are at the early stages of the development process
|
||||
and there is a long way to go. If you're interested, contact us by joining our mailing list and
|
||||
checkout the git repository. Furthermore, we document our progress in development via some video
|
||||
tutorials and code walkthrough that can be a good guide for the developers who are eager to join
|
||||
the team. You can find the videos on [my :fontawesome-brands-youtube:{ .youtube } YouTube channel](https://www.youtube.com/c/lxsameer).
|
||||
|
||||
|
||||
## Announcements:
|
||||
|
||||
### * How to build a compiler with LLVM and MLIR
|
||||
I have decided to make a video series as a guide and walk through the Serene’s code base. This
|
||||
way, anyone who is interested in Serene but never done language development will have an easier
|
||||
time getting started with Serene. It will also serve as a historical documentary for some
|
||||
decisions and implementations that we made throughout the development process. The video series
|
||||
in accessible via my YouTube channel and How to build a compiler with LLVM and MLIR playlist.
|
||||
Looking forward to your feedback. :smile:
|
||||
|
||||
Date: `2021-08-15`
|
|
@ -1,18 +0,0 @@
|
|||
window.MathJax = {
|
||||
tex: {
|
||||
inlineMath: [["\\(", "\\)"]],
|
||||
displayMath: [["\\[", "\\]"]],
|
||||
processEscapes: true,
|
||||
processEnvironments: true
|
||||
},
|
||||
options: {
|
||||
ignoreHtmlClass: ".*|",
|
||||
processHtmlClass: "arithmatex"
|
||||
}
|
||||
};
|
||||
|
||||
document$.subscribe(() => {
|
||||
|
||||
|
||||
MathJax.typesetPromise()
|
||||
})
|
|
@ -1,192 +0,0 @@
|
|||
---
|
||||
title: Resources
|
||||
---
|
||||
# Development Resource
|
||||
|
||||
## LLVM
|
||||
- [Brief Overview of LLVM](https://www.infoworld.com/article/3247799/what-is-llvm-the-power-behind-swift-rust-clang-and-more.html)
|
||||
- [A bit in depth details on LLVM](https://aosabook.org/en/llvm.html)
|
||||
- [Official LLVM tutorial C++](https://llvm.org/docs/tutorial/)
|
||||
- [Interactive C++ with Cling](https://blog.llvm.org/posts/2020-11-30-interactive-cpp-with-cling/)
|
||||
- [My First LLVM Compiler](https://www.wilfred.me.uk/blog/2015/02/21/my-first-llvm-compiler/)
|
||||
- [A Complete Guide to LLVM for Programming Language Creators](https://mukulrathi.co.uk/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/)
|
||||
- [LLVM Internals](https://blog.yossarian.net/2021/07/19/LLVM-internals-part-1-bitcode-format)
|
||||
- [How to learn about compilers (LLVM Version)](https://lowlevelbits.org/how-to-learn-compilers-llvm-edition/)
|
||||
|
||||
### TableGen
|
||||
- [Create a backend](https://llvm.org/docs/TableGen/BackGuide.html#creating-a-new-backend)
|
||||
|
||||
## Data Structures
|
||||
- [Pure functional datastructures papaer](https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf)
|
||||
- [Dynamic typing: syntax and proof theory](https://reader.elsevier.com/reader/sd/pii/0167642394000042?token=CEFF5C5D1B03FD680762FC4889A14C0CA2BB28FE390EC51099984536E12AC358F3D28A5C25C274296ACBBC32E5AE23CD)
|
||||
- [Representing Type Information in Dynamically Typed Languages](https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.4394)
|
||||
- [An empirical study on the impact of static typing on software maintainability](https://www.researchgate.net/publication/259634489_An_empirical_study_on_the_impact_of_static_typing_on_software_maintainability)
|
||||
|
||||
## Other languages
|
||||
- [Julia: A Fresh Approach toNumerical Computing](https://julialang.org/research/julia-fresh-approach-BEKS.pdf)
|
||||
|
||||
|
||||
|
||||
## Memory management
|
||||
- [Visualizing memory management in Golang](https://deepu.tech/memory-management-in-golang/)
|
||||
- [TCMalloc : Thread-Caching Malloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html)
|
||||
- [A visual guide to Go Memory Allocator from scratch (Golang)](https://medium.com/@ankur_anand/a-visual-guide-to-golang-memory-allocator-from-ground-up-e132258453ed)
|
||||
|
||||
## Concurrency
|
||||
- [Scheduling In Go (Series)](https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html)
|
||||
|
||||
## Garbage collection
|
||||
- [GC on V8](https://v8.dev/blog/high-performance-cpp-gc)
|
||||
- [Perceus: Garbage Free Reference Counting with Reuse](https://www.microsoft.com/en-us/research/uploads/prod/2020/11/perceus-tr-v1.pdf)
|
||||
- [Boehm GC](https://www.hboehm.info/gc/)
|
||||
- [MPS](https://www.ravenbrook.com/project/mps/)
|
||||
- [MMTK](https://www.mmtk.io/code)
|
||||
- [Whiro](https://github.com/JWesleySM/Whiro)<br/>
|
||||
This is not GC but a tool to debug GC and memory allocation.
|
||||
|
||||
## JIT
|
||||
- [Machine code generator for C++](https://asmjit.com/)
|
||||
- [LLVM's Next Generation of JIT API](https://www.youtube.com/watch?v=hILdR8XRvdQ)
|
||||
|
||||
## Optimizations
|
||||
- [Canonicalization](https://sunfishcode.github.io/blog/2018/10/22/Canonicalization.html)
|
||||
|
||||
## Compiler
|
||||
- [Stack frame layout on x86-64](https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64)
|
||||
- [Pointers Are Complicated](https://www.ralfj.de/blog/2020/12/14/provenance.html)
|
||||
- [Pointers Are Complicated III, or: Pointer-integer casts exposed](https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html)
|
||||
- [A compiler writting journal](https://github.com/DoctorWkt/acwj)
|
||||
|
||||
## Linker
|
||||
- [20 part linker essay](https://lwn.net/Articles/276782/)
|
||||
- [LLD Usage](https://lld.llvm.org/index.html)
|
||||
|
||||
## Toolchain
|
||||
- [Building LLVM Distribution](https://llvm.org/docs/BuildingADistribution.html)
|
||||
|
||||
## Cross compilation
|
||||
|
||||
- [Creating portable Linux binaries](https://blog.gibson.sh/2017/11/26/creating-portable-linux-binaries/#some-general-suggestions)<br/>
|
||||
A nice to read article on some of the common problems when linking statically
|
||||
with none default libc or libc++
|
||||
|
||||
## Lang
|
||||
- Scheme
|
||||
* [Chicken Scheme - Easy-to-use compiler and interpreter, with lots of libraries](https://call-cc.org)
|
||||
* [Stalin - Brutally optimizing Scheme compiler, with lots of optimization flags](https://github.com/barak/stalin)
|
||||
* [Crafting Interpreters](https://craftinginterpreters.com/contents.html)
|
||||
|
||||
## Emacs mode
|
||||
- [Adding A New Language to Emacs](https://www.wilfred.me.uk/blog/2015/03/19/adding-a-new-language-to-emacs/)
|
||||
- [The Definitive Guide To Syntax Highlighting](https://www.wilfred.me.uk/blog/2014/09/27/the-definitive-guide-to-syntax-highlighting/)
|
||||
|
||||
|
||||
## Mathematics
|
||||
- [CS410 course: Advance Functional Programming](https://github.com/pigworker/CS410-18)<br/>
|
||||
If you need to learn Agda (We use it for the mathematics side of Serene, to proof certain features)
|
||||
check out
|
||||
|
||||
- [Programming Language Foundations in Agda](https://plfa.github.io/)<br/>
|
||||
This book is an introduction to programming language theory using the proof assistant Agda.
|
||||
|
||||
### Curry-Howard correspondence
|
||||
- [The formulae-as-types notion of construction](https://www.dcc.fc.up.pt/~acm/howard2.pdf)
|
||||
- [Propositions as Types](https://www.youtube.com/watch?v=IOiZatlZtGU)
|
||||
|
||||
### Type Theory
|
||||
- [Homotopy Type Theory](https://www.cs.cmu.edu/~rwh/courses/hott/)
|
||||
- [No, dynamic type systems are not inherently more open](https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-type-systems-are-not-inherently-more-open/)
|
||||
|
||||
- Practical Foundations of Programming Languages
|
||||
+ [Online copy (2nd Edition Preview)](http://www.cs.cmu.edu/~rwh/pfpl/2nded.pdf)
|
||||
+ [Dead-tree copy (2nd Edition)](https://www.amazon.com/Practical-Foundations-Programming-Languages-Robert/dp/1107150302)
|
||||
|
||||
|
||||
- Types and Programming Languages
|
||||
+ [Online supplements](http://www.cis.upenn.edu/~bcpierce/tapl/)
|
||||
+ [Dead-tree copy](https://mitpress.mit.edu/books/types-and-programming-languages)
|
||||
|
||||
- Advanced Topics in Types and Programming Languages
|
||||
+ [Online supplements](http://www.cis.upenn.edu/~bcpierce/attapl/)
|
||||
+ [Dead-tree copy](http://www.amazon.com/exec/obidos/ASIN/0262162288/benjamcpierce)
|
||||
|
||||
|
||||
- The Works of Per Martin-Löf:
|
||||
+ [1972](https://github.com/michaelt/martin-lof/blob/master/pdfs/An-Intuitionistic-Theory-of-Types-1972.pdf?raw=true)
|
||||
+ [1979](https://github.com/michaelt/martin-lof/blob/master/pdfs/Constructive-mathematics-and-computer-programming-1982.pdf?raw=true)
|
||||
+ [1984](https://github.com/michaelt/martin-lof/blob/master/pdfs/Bibliopolis-Book-retypeset-1984.pdf?raw=true)
|
||||
+ [The Complete Works of Per Martin-Löf](https://github.com/michaelt/martin-lof)
|
||||
|
||||
|
||||
- [Programming In Martin-Löf's Type Theory](http://www.cse.chalmers.se/research/group/logic/book/book.pdf)
|
||||
|
||||
- The Works of John Reynolds
|
||||
* [Types, Abstraction and Parametric Polymorphism](http://www.cse.chalmers.se/edu/year/2010/course/DAT140_Types/Reynolds_typesabpara.pdf) (Parametricity for
|
||||
System F)
|
||||
* [A Logic For Shared Mutable State](http://www.cs.cmu.edu/~jcr/seplogic.pdf)
|
||||
* [Course notes on separation logic](http://www.cs.cmu.edu/afs/cs.cmu.edu/project/fox-19/member/jcr/www15818As2011/cs818A3-11.html)
|
||||
* [Course notes on denotational semantics](http://www.cs.cmu.edu/~jcr/cs819-00.html)
|
||||
|
||||
- [The HoTT book](http://homotopytypetheory.org/book/)
|
||||
- [Student's Notes on HoTT](https://github.com/RobertHarper/hott-notes)
|
||||
- [Materials for the Schools and Workshops on UniMath](https://github.com/UniMath/Schools)
|
||||
|
||||
### Proof Theory
|
||||
|
||||
- Frank Pfenning's Lecture Notes
|
||||
* [Introductory Course](http://www.cs.cmu.edu/~fp/courses/15317-f09/)
|
||||
* [Linear Logic](http://www.cs.cmu.edu/~fp/courses/15816-s12/)
|
||||
* [Modal Logic](http://www.cs.cmu.edu/~fp/courses/15816-s10/)
|
||||
|
||||
- [Proofs and Types](http://www.paultaylor.eu/stable/prot.pdf)
|
||||
- [The Blind Spot: Lectures on Logic](http://www.ems-ph.org/books/book.php?proj_nr=136&srch=browse_authors%7CGirard%2C+Jean-Yves)
|
||||
- [Mustard Watches: An Integrated Approach to Time and Food](http://girard.perso.math.cnrs.fr/mustard/page1.html)
|
||||
|
||||
### Category Theory
|
||||
|
||||
- Category Theory in Context
|
||||
* [Online version](http://www.math.jhu.edu/~eriehl/context.pdf)
|
||||
* [Dead-tree version](http://store.doverpublications.com/048680903x.html)
|
||||
* [The author's post on the book](https://golem.ph.utexas.edu/category/2016/11/category_theory_in_context.html)
|
||||
|
||||
- Practical Foundations of Mathematics
|
||||
* [HTML version](http://www.paultaylor.eu/~pt/prafm/)
|
||||
* [Dead-tree version](https://www.amazon.com/gp/product/0521631076)
|
||||
|
||||
- [Category Theory](http://www.amazon.com/Category-Theory-Oxford-Logic-Guides/dp/0199237182/ref=sr_1_1?ie=UTF8&qid=1439348930&sr=8-1&keywords=awodey+category+theory)
|
||||
|
||||
- [Ed Morehouse's Category Theory Lecture Notes](https://emorehouse.wescreates.wesleyan.edu/research/notes/intro_categorical_semantics.pdf)
|
||||
|
||||
- Categorical Logic and Type Theory
|
||||
* [Jacob's thesis, containing much of what went into the book](http://www.cs.ru.nl/B.Jacobs/PAPERS/PhD.ps)
|
||||
* [A definitely not suspicious online copy](https://people.mpi-sws.org/~dreyer/courses/catlogic/jacobs.pdf)
|
||||
* [Dead-tree copy](https://www.amazon.com/exec/obidos/ASIN/0444501703/qid%3D922441598/002-9790597-0750031)
|
||||
|
||||
- [Introduction to Higher-Order Categorical Logic](https://www.amazon.com/Introduction-Higher-Order-Categorical-Cambridge-Mathematics/dp/0521356539/ref=pd_sim_14_5?_encoding=UTF8&psc=1&refRID=V4H286NSZWK4MWDPV17R)
|
||||
|
||||
- [Sheaves in Geometry and Logic](https://www.amazon.com/Sheaves-Geometry-Logic-Introduction-Universitext/dp/0387977104)
|
||||
|
||||
|
||||
### Others
|
||||
|
||||
- [Gunter's "Semantics of Programming Language"](http://www.amazon.com/Semantics-Programming-Languages-Structures-Foundations/dp/0262071436/ref=sr_1_1?ie=UTF8&qid=1439349219&sr=8-1&keywords=gunter+semantics+of+programming+languages)
|
||||
|
||||
- [Abramsky and Jung's "Domain Theory"](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.8851)
|
||||
|
||||
- [Realizability: An Introduction to Its Categorical Side](https://www.amazon.com/Realizability-Introduction-its-Categorical-Side/dp/0444550208)
|
||||
|
||||
|
||||
- OPLSS:<br/>
|
||||
The Oregon Programming Languages Summer School is a 2 week long
|
||||
bootcamp on PLs held annually at the university of Oregon. It's a
|
||||
wonderful event to attend but if you can't make it they record all
|
||||
their lectures anyways! They're taught be a variety of lecturers
|
||||
but they're all world class researchers.
|
||||
|
||||
* [2012](https://www.cs.uoregon.edu/research/summerschool/summer12/curriculum.html)
|
||||
* [2013](https://www.cs.uoregon.edu/research/summerschool/summer13/curriculum.html)
|
||||
* [2014](https://www.cs.uoregon.edu/research/summerschool/summer14/curriculum.html)
|
||||
* [2015](https://www.cs.uoregon.edu/research/summerschool/summer15/curriculum.html)
|
||||
* [2016](https://www.cs.uoregon.edu/research/summerschool/summer16/curriculum.php)
|
||||
* [2017](https://www.cs.uoregon.edu/research/summerschool/summer17/topics.php)
|
||||
* [2018](https://www.cs.uoregon.edu/research/summerschool/summer18/topics.php)
|
|
@ -1,18 +0,0 @@
|
|||
[data-md-color-scheme=slate] #what-i-cannot-create-i-do-not-understand {
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
|
||||
[data-md-color-scheme=default] #what-i-cannot-create-i-do-not-understand {
|
||||
color: #2f2f2f;
|
||||
font-weight: 700;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
|
||||
.md-typeset .md-annotation__index > ::before {
|
||||
content: attr(data-md-annotation-id);
|
||||
}
|
||||
.md-typeset :focus-within > .md-annotation__index > ::before {
|
||||
transform: none;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
mkdocs-material
|
||||
mike
|
||||
mkdocs-git-revision-date-localized-plugin
|
||||
mkdocs-glightbox
|
|
@ -1,48 +0,0 @@
|
|||
version: "3.9"
|
||||
|
||||
services:
|
||||
serene-docs:
|
||||
image: serenelang/serene-docs
|
||||
environment:
|
||||
USER_UID: 1100
|
||||
USER_GID: 1100
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
networks:
|
||||
- public_lb
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.serene-lang.rule=Host(`serene-lang.org`)"
|
||||
- "traefik.http.routers.serene-lang.entrypoints=websecure"
|
||||
- "traefik.http.routers.serene-lang.tls=true"
|
||||
- "traefik.http.routers.serene-lang.tls.certresolver=default"
|
||||
- "traefik.http.services.serene-lang-web.loadbalancer.server.port=3000"
|
||||
- "traefik.http.services.serene-lang-web.loadbalancer.server.scheme=http"
|
||||
- "traefik.http.routers.serene-lang.service=serene-lang-web"
|
||||
- "traefik.docker.network=public_lb"
|
||||
- "traefik.http.middlewares.serene-lang-ratelimit.ratelimit.average=50"
|
||||
- "traefik.http.middlewares.serene-lang-ratelimit.ratelimit.burst=10"
|
||||
- "traefik.http.routers.serene-lang.middlewares=serene-lang-ratelimit"
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
max_attempts: 3
|
||||
update_config:
|
||||
parallelism: 1
|
||||
delay: 5s
|
||||
order: stop-first
|
||||
|
||||
logging:
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
networks:
|
||||
public_lb:
|
||||
external: true
|
||||
name: public_lb
|
|
@ -1,80 +0,0 @@
|
|||
#+TITLE: Serene's Language Specification
|
||||
#+AUTHOR: Sameer Rahmani
|
||||
#+SEQ_TODO: TODO(t/!) | DONE(d%)
|
||||
#+TAGS:
|
||||
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty nolatexpreview
|
||||
#+OPTIONS: tex:t
|
||||
#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Eule
|
||||
# book style has to be remapped to koma scripts scrbook
|
||||
#+LATEX_CLASS: book
|
||||
#+LATEX_HEADER: \usepackage[english]{babel}
|
||||
#+LATEX_CLASS_OPTIONS: [fontsize=11pt,paper=a5, pagesize=auto]
|
||||
#+LATEX_HEADER: \KOMAoptions{fontsize=11pt}
|
||||
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
|
||||
#+LATEX_HEADER: \usepackage{microtype}
|
||||
#+LATEX_HEADER: \usepackage{pxfonts}
|
||||
|
||||
#+LATEX_HEADER: \usepackage{amsmath}
|
||||
#+LATEX_HEADER: \usepackage{amssymb}
|
||||
#+LATEX_HEADER: \usepackage{mathabx}
|
||||
|
||||
#+LATEX_HEADER: \usepackage{tcolorbox}
|
||||
#+LATEX_HEADER: \setlength{\parskip}{1em}
|
||||
|
||||
#+LATEX_HEADER: \newtcolorbox{infobox}[2][]{colback=cyan!5!white,before skip=14pt,after skip=8pt,colframe=cyan!75!black,sharp corners,title={#2},#1}
|
||||
#+LATEX_HEADER: \newcommand\tab[1][1cm]{\hspace*{#1}}
|
||||
#+LATEX_HEADER: \let\oldsection\section
|
||||
#+LATEX_HEADER: \newcommand\caution[1]{\textcolor{blue}{\textbf{#1}}}
|
||||
#+LATEX_HEADER: \renewcommand\section{\pagebreak\oldsection}
|
||||
#+LATEX_HEADER: \hypersetup{hidelinks}
|
||||
|
||||
#+LATEX_HEADER: \renewcommand{\contentsname}{Serene's Spec}
|
||||
|
||||
\clearpage\null\newpage
|
||||
|
||||
\chapter{Overview of Serene}
|
||||
|
||||
* Basic Types
|
||||
|
||||
* Special Forms
|
||||
|
||||
** ~def~:
|
||||
~def~ has the following form:
|
||||
|
||||
#+BEGIN_SRC lisp
|
||||
(def <NAME> <VALUE>)
|
||||
#+END_SRC
|
||||
|
||||
- Defines a global binding
|
||||
- Returns the name of the binding as a symbol
|
||||
- ~<NAME>~ has to be a symbol
|
||||
- If ~def~ is not a top level expression, it will create an ~undef~ global binding which
|
||||
will be set to the ~<VALUE>~ when the execution flow reaches the ~def~ itself.
|
||||
|
||||
* Libraries
|
||||
In terms of static and dynamic libraries, If the library is a Serene library
|
||||
meaning that it is designed to only work with serene (we will see how in a bit), then
|
||||
whatever namespaces that it contains will be added to the compiler and all those
|
||||
namespaces will be map to the library (all the namespaces will point to the same JITDylib).
|
||||
|
||||
But if the library is a generic static or dynamic library a namespace with the same
|
||||
name as the library minus the suffix will be added to the compiler, for example ~libssh.so~
|
||||
will be mapped to ~libssh~ namespace.
|
||||
** Static
|
||||
|
||||
** Dynamic
|
||||
|
||||
** Object
|
||||
* Unsorted
|
||||
** Eval
|
||||
Evaluating any form using =eval= will add the form to the namespace containing the
|
||||
=eval= expression.
|
||||
* Glossary
|
||||
- Symbol :: A Lisp Symbol. Just a symbol. A name that might be bound to a value
|
||||
and evaluates to the value.
|
||||
- IR Symbol :: The ~Symbol~ infrastructure essentially provides a non-SSA mechanism in which to refer to an
|
||||
operation in IR symbolically with a name. On MLIR level they are different from *native symbols*
|
||||
even though we use them to refer to *native symbols*. But they don't necessarily map to
|
||||
*native symbols*.
|
||||
- Native Sybol :: As the name suggests native symbols refer to native code symbols. Like those you find in an
|
||||
object file.
|
642
docs/videos.org
642
docs/videos.org
|
@ -5,21 +5,21 @@
|
|||
|
||||
* DONE Episode 1 - Introduction
|
||||
** What is it all about?
|
||||
- Create a programming lang
|
||||
- Guide for contributors
|
||||
- A LLVM/MLIR guide
|
||||
- Create a programming lang
|
||||
- Guide for contributors
|
||||
- A LLVM/MLIR guide
|
||||
** The Plan
|
||||
- Git branches
|
||||
- No live coding
|
||||
- Feel free to contribute
|
||||
- Git branches
|
||||
- No live coding
|
||||
- Feel free to contribute
|
||||
** Serene and a bit of history
|
||||
- Other Implementations
|
||||
- Requirements
|
||||
- C++ 14
|
||||
- CMake
|
||||
- Repository: https://devheroes.codes/Serene
|
||||
- Website: lxsameer.com
|
||||
Email: lxsameer@gnu.org
|
||||
- Other Implementations
|
||||
- Requirements
|
||||
- C++ 14
|
||||
- CMake
|
||||
- Repository: https://devheroes.codes/Serene
|
||||
- Website: lxsameer.com
|
||||
Email: lxsameer@gnu.org
|
||||
* DONE Episode 2 - Basic Setup
|
||||
CLOSED: [2021-07-10 Sat 09:04]
|
||||
** Installing Requirements
|
||||
|
@ -230,41 +230,41 @@ the following code blocks. Both of those are distributed with the LLVM.
|
|||
|
||||
*** General syntax
|
||||
#+BEGIN_SRC mlir
|
||||
%result:2 = "somedialect.blah"(%x#2) { some.attribute = true, other_attribute = 3 }
|
||||
: (!somedialect<"example_type">) -> (!somedialect<"foo_s">, i8)
|
||||
loc(callsite("main" at "main.srn":10:8))
|
||||
%result:2 = "somedialect.blah"(%x#2) { some.attribute = true, other_attribute = 3 }
|
||||
: (!somedialect<"example_type">) -> (!somedialect<"foo_s">, i8)
|
||||
loc(callsite("main" at "main.srn":10:8))
|
||||
#+END_SRC
|
||||
|
||||
*** Blocks and Regions
|
||||
#+BEGIN_SRC mlir
|
||||
func @simple(i64, i1) -> i64 {
|
||||
^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
|
||||
cond_br %cond, ^bb1, ^bb2
|
||||
cond_br %cond, ^bb1, ^bb2
|
||||
|
||||
^bb1:
|
||||
br ^bb3(%a: i64) // Branch passes %a as the argument
|
||||
br ^bb3(%a: i64) // Branch passes %a as the argument
|
||||
|
||||
^bb2:
|
||||
%b = addi %a, %a : i64
|
||||
br ^bb3(%b: i64) // Branch passes %b as the argument
|
||||
%b = addi %a, %a : i64
|
||||
br ^bb3(%b: i64) // Branch passes %b as the argument
|
||||
|
||||
// ^bb3 receives an argument, named %c, from predecessors
|
||||
// and passes it on to bb4 along with %a. %a is referenced
|
||||
// directly from its defining operation and is not passed through
|
||||
// an argument of ^bb3.
|
||||
^bb3(%c: i64):
|
||||
//br ^bb4(%c, %a : i64, i64)
|
||||
"serene.ifop"(%c) ({ // if %a is in-scope in the containing region...
|
||||
// then %a is in-scope here too.
|
||||
%new_value = "another_op"(%c) : (i64) -> (i64)
|
||||
//br ^bb4(%c, %a : i64, i64)
|
||||
"serene.ifop"(%c) ({ // if %a is in-scope in the containing region...
|
||||
// then %a is in-scope here too.
|
||||
%new_value = "another_op"(%c) : (i64) -> (i64)
|
||||
|
||||
^someblock(%new_value):
|
||||
%x = "some_other_op"() {value = 4 : i64} : () -> i64
|
||||
^someblock(%new_value):
|
||||
%x = "some_other_op"() {value = 4 : i64} : () -> i64
|
||||
|
||||
}) : (i64) -> (i64)
|
||||
}) : (i64) -> (i64)
|
||||
^bb4(%d : i64, %e : i64):
|
||||
%0 = addi %d, %e : i64
|
||||
return %0 : i64 // Return is also a terminator.
|
||||
%0 = addi %d, %e : i64
|
||||
return %0 : i64 // Return is also a terminator.
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
|
@ -277,15 +277,15 @@ Command line arguments to emir =slir=
|
|||
Output:
|
||||
#+BEGIN_SRC mlir
|
||||
module @user {
|
||||
%0 = "serene.fn"() ( {
|
||||
%2 = "serene.value"() {value = 0 : i64} : () -> i64
|
||||
return %2 : i64
|
||||
}) {args = {}, name = "main", sym_visibility = "public"} : () -> i64
|
||||
%0 = "serene.fn"() ( {
|
||||
%2 = "serene.value"() {value = 0 : i64} : () -> i64
|
||||
return %2 : i64
|
||||
}) {args = {}, name = "main", sym_visibility = "public"} : () -> i64
|
||||
|
||||
%1 = "serene.fn"() ( {
|
||||
%2 = "serene.value"() {value = 0 : i64} : () -> i64
|
||||
return %2 : i64
|
||||
}) {args = {n = i64, v = i64, y = i64}, name = "main1", sym_visibility = "public"} : () -> i64
|
||||
%1 = "serene.fn"() ( {
|
||||
%2 = "serene.value"() {value = 0 : i64} : () -> i64
|
||||
return %2 : i64
|
||||
}) {args = {n = i64, v = i64, y = i64}, name = "main1", sym_visibility = "public"} : () -> i64
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
|
@ -298,16 +298,16 @@ Command line arguments to emir =mlir=
|
|||
|
||||
Output:
|
||||
#+BEGIN_SRC mlir
|
||||
module @user {
|
||||
module @user {
|
||||
func @main() -> i64 {
|
||||
%c3_i64 = constant 3 : i64
|
||||
return %c3_i64 : i64
|
||||
%c3_i64 = constant 3 : i64
|
||||
return %c3_i64 : i64
|
||||
}
|
||||
func @main1(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
|
||||
%c3_i64 = constant 3 : i64
|
||||
return %c3_i64 : i64
|
||||
}
|
||||
%c3_i64 = constant 3 : i64
|
||||
return %c3_i64 : i64
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
*** LIR
|
||||
|
@ -318,16 +318,16 @@ Command line arguments to emir =lir=
|
|||
|
||||
Output:
|
||||
#+BEGIN_SRC mlir
|
||||
module @user {
|
||||
module @user {
|
||||
llvm.func @main() -> i64 {
|
||||
%0 = llvm.mlir.constant(3 : i64) : i64
|
||||
llvm.return %0 : i64
|
||||
%0 = llvm.mlir.constant(3 : i64) : i64
|
||||
llvm.return %0 : i64
|
||||
}
|
||||
llvm.func @main1(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
|
||||
%0 = llvm.mlir.constant(3 : i64) : i64
|
||||
llvm.return %0 : i64
|
||||
}
|
||||
%0 = llvm.mlir.constant(3 : i64) : i64
|
||||
llvm.return %0 : i64
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
*** LLVMIR
|
||||
|
@ -338,36 +338,36 @@ Command line arguments to emir =llvmir=
|
|||
|
||||
Output:
|
||||
#+BEGIN_SRC llvm
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
declare i8* @malloc(i64 %0)
|
||||
declare i8* @malloc(i64 %0)
|
||||
|
||||
declare void @free(i8* %0)
|
||||
declare void @free(i8* %0)
|
||||
|
||||
define i64 @main() !dbg !3 {
|
||||
define i64 @main() !dbg !3 {
|
||||
ret i64 3, !dbg !7
|
||||
}
|
||||
}
|
||||
|
||||
define i64 @main1(i64 %0, i64 %1, i64 %2) !dbg !9 {
|
||||
define i64 @main1(i64 %0, i64 %1, i64 %2) !dbg !9 {
|
||||
ret i64 3, !dbg !10
|
||||
}
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2}
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "mlir", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
!1 = !DIFile(filename: "LLVMDialectModule", directory: "/")
|
||||
!2 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!3 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !4, type: !5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
|
||||
!4 = !DIFile(filename: "REPL", directory: "/home/lxsameer/src/serene/serene/build")
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{}
|
||||
!7 = !DILocation(line: 0, column: 10, scope: !8)
|
||||
!8 = !DILexicalBlockFile(scope: !3, file: !4, discriminator: 0)
|
||||
!9 = distinct !DISubprogram(name: "main1", linkageName: "main1", scope: null, file: !4, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
|
||||
!10 = !DILocation(line: 1, column: 11, scope: !11)
|
||||
!11 = !DILexicalBlockFile(scope: !9, file: !4, discriminator: 0)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "mlir", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
!1 = !DIFile(filename: "LLVMDialectModule", directory: "/")
|
||||
!2 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!3 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !4, type: !5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
|
||||
!4 = !DIFile(filename: "REPL", directory: "/home/lxsameer/src/serene/serene/build")
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{}
|
||||
!7 = !DILocation(line: 0, column: 10, scope: !8)
|
||||
!8 = !DILexicalBlockFile(scope: !3, file: !4, discriminator: 0)
|
||||
!9 = distinct !DISubprogram(name: "main1", linkageName: "main1", scope: null, file: !4, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
|
||||
!10 = !DILocation(line: 1, column: 11, scope: !11)
|
||||
!11 = !DILexicalBlockFile(scope: !9, file: !4, discriminator: 0)
|
||||
#+END_SRC
|
||||
|
||||
** Resources
|
||||
|
@ -562,8 +562,7 @@ and tries to =resolve= *undefined* symbols
|
|||
** Let's look at some code
|
||||
** Resources:
|
||||
- [[https://lwn.net/Articles/276782/][20 part linker essay]]
|
||||
* DONE Episode 13 - Source Managers
|
||||
CLOSED: [2021-12-18 Sat 11:17]
|
||||
* Episode 13 - Source Managers
|
||||
** FAQ:
|
||||
- What tools are you using?
|
||||
|
||||
|
@ -583,500 +582,3 @@ I didn't show it in action
|
|||
- ...
|
||||
|
||||
- LLVM provides a =SourceMgr= class that we're not using it
|
||||
* DONE Episode 14 - JIT Basics
|
||||
CLOSED: [2022-01-05 Wed 17:37]
|
||||
** Updates:
|
||||
- Lost my data :_(
|
||||
- Fixed some compatibility issues
|
||||
- New video series on *How to build an editor with Emacs Lisp*
|
||||
|
||||
** What is Just In Time Compilation?
|
||||
- Compiling at "runtime" (air quote)
|
||||
Or it might be better to say, "on demand compilation"
|
||||
- Usually in interpreters and Runtimes
|
||||
|
||||
#+NAME: ep-14-jit-1
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/jit.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="Some kind of input code"]
|
||||
b[label="JIT"]
|
||||
c[label="Some sort of target code"]
|
||||
d[label="Execute the result"]
|
||||
a -> b -> c -> d
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-14-jit-1
|
||||
[[file:/tmp/jit.svg]]
|
||||
|
||||
|
||||
|
||||
#+NAME: ep-14-jit-2
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/jit-2.svg :cmdline -Kdot -Tsvg
|
||||
|
||||
digraph G {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="Source code"]
|
||||
b[label="Parser"]
|
||||
c[label="Semantic Analyzer"]
|
||||
d[label="IR Generator"]
|
||||
e[label="Pass Manager"]
|
||||
f[label="Object Layer"]
|
||||
g[label="Native Code"]
|
||||
z[label="Preload Core libs"]
|
||||
a -> b
|
||||
b -> c {label="AST"}
|
||||
c -> d
|
||||
z -> f
|
||||
subgraph cluster0 {
|
||||
color=lightgrey;
|
||||
d -> e -> f
|
||||
label = "JIT Engine";
|
||||
}
|
||||
f -> g
|
||||
g -> Store
|
||||
g -> Execute
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-14-jit-2
|
||||
[[file:/tmp/jit-2.svg]]
|
||||
|
||||
|
||||
- Trade off
|
||||
Compilation speed vs Execution speed
|
||||
*** JIT vs Typical interpreters
|
||||
|
||||
** Why to use JIT?
|
||||
- Make the interpreter to run "faster" (air quote again)
|
||||
- Speed up the compilation
|
||||
Avoid generating the target code and generate some byte-code instead
|
||||
and then use a JIT in runtime to execute the byte-code.
|
||||
- Use runtime data to find optimization opportunities.
|
||||
- Support more archs
|
||||
- And many other reasons
|
||||
** How we're going to use a JIT?
|
||||
- We need a JIT engine to implement Lisp Macros
|
||||
- Compile time vs Runtime
|
||||
+ Abstraction
|
||||
- A JIT engine to just compile Serene code
|
||||
- Our compiler will be a fancy JIT engine
|
||||
|
||||
#+NAME: ep-14-jit-3
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/jit-3.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="Serene AST"]
|
||||
b[label="For every node"]
|
||||
c[label="is it a macro call?" shapp="diamond"]
|
||||
d[label="Add it to JIT"]
|
||||
e[label="Expand it (call it)"]
|
||||
f[label="Generate target code"]
|
||||
a -> b
|
||||
|
||||
|
||||
subgraph cluster0 {
|
||||
color=lightgrey;
|
||||
b -> c
|
||||
c -> d [label="NO"]
|
||||
c -> e [label="YES"]
|
||||
e -> b
|
||||
d -> f
|
||||
label = "JIT Engine";
|
||||
}
|
||||
|
||||
f -> Store
|
||||
f -> Execute
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-14-jit-3
|
||||
[[file:/tmp/jit-3.svg]]
|
||||
|
||||
|
||||
** LLVM/MLIR and JIT
|
||||
- 3 different approaches
|
||||
- MLIR's JIT
|
||||
- LLVM JITs
|
||||
+ MCJIT (Deprecated)
|
||||
+ LLJIT (Based on ORCv2)
|
||||
+ LazyLLJIT (Based on LLJIT)
|
||||
- Use LLVM's ORCv2 directly to create an engine
|
||||
* DONE Episode 15 - LLVM ORC JIT
|
||||
CLOSED: [2022-01-28 Fri 12:15]
|
||||
** Uptades:
|
||||
- Created a bare min JIT that:
|
||||
- Eagrly compiles namespaces
|
||||
- Reload namespacs
|
||||
- I guess this the time to start the Serene's Spec
|
||||
|
||||
** What is ORCv2?
|
||||
- On request compiler
|
||||
- Replaces MCJIT
|
||||
- ORCv2 docs and examples
|
||||
- Kaleidoscope tutorial (not complete)
|
||||
|
||||
Before We can move to Serene's code we need to understand ORC first
|
||||
|
||||
** Terminology
|
||||
*** Execution Session
|
||||
A running JIT program. It contains the JITDylibs, error reporting mechanisms, and dispatches
|
||||
the materializers.
|
||||
|
||||
*** JITAddress
|
||||
It's just an address of a JITed code
|
||||
|
||||
*** JITDylib
|
||||
Represents a JIT'd dynamic library.
|
||||
|
||||
This class aims to mimic the behavior of a shared object, but without requiring
|
||||
the contained program representations to be compiled up-front. The JITDylib's
|
||||
content is defined by adding MaterializationUnits, and contained MaterializationUnits
|
||||
will typically rely on the JITDylib's links-against order to resolve external references.
|
||||
|
||||
JITDylibs cannot be moved or copied. Their address is stable, and useful as
|
||||
a key in some JIT data structures.
|
||||
|
||||
*** MaterializationUnit
|
||||
A =MaterializationUnit= represents a set of symbol definitions that can
|
||||
be materialized as a group, or individually discarded (when
|
||||
overriding definitions are encountered).
|
||||
|
||||
=MaterializationUnits= are used when providing lazy definitions of symbols to
|
||||
JITDylibs. The JITDylib will call materialize when the address of a symbol
|
||||
is requested via the lookup method. The =JITDylib= will call discard if a
|
||||
stronger definition is added or already present.
|
||||
|
||||
MaterializationUnit stores in JITDylibs.
|
||||
|
||||
*** MaterializationResponsibility
|
||||
Represents and tracks responsibility for materialization and mediates interactions between
|
||||
=MaterializationUnits= and =JITDylibs=. It provides a way for Dylib to find out about the outcome
|
||||
of the materialization.
|
||||
|
||||
*** Memory Manager
|
||||
A class that manages how JIT engine should use memory, like allocations and deallocations.
|
||||
=SectionMemoryManager= is a simple memory manager that is provided by ORC.
|
||||
|
||||
*** Layers
|
||||
ORC based JIT engines are constructed from several layers. Each layer has a specific responsiblity
|
||||
and passes the result of its operation to the next layer. E.g Compile Layer, Link layer and ....
|
||||
|
||||
*** Resource Tracker
|
||||
The API to remove or transfer the ownership of JIT resources. Usually, a resource is a module.
|
||||
|
||||
*** ThreadSafeModule
|
||||
A thread safe container for the LLVM module.
|
||||
|
||||
** ORC highlevel API
|
||||
- ORC provides a Layer based design to that let us create our own JIT engine.
|
||||
- It comes with two ready to use engines:
|
||||
We will look at their implementaion later
|
||||
+ LLJIT
|
||||
+ LLLazyJIT
|
||||
|
||||
** Two major solutions to build a JIT
|
||||
- Wrap LLJIT or LLLazyJIT
|
||||
- Create your own JIT engine and the wrapper
|
||||
|
||||
** Resources
|
||||
*** Docs
|
||||
- https://www.llvm.org/docs/ORCv2.html
|
||||
|
||||
*** Examples
|
||||
- https://github.com/llvm/llvm-project/tree/main/llvm/examples/HowToUseLLJIT
|
||||
- https://github.com/llvm/llvm-project/tree/main/llvm/examples/OrcV2Examples/LLJITDumpObjects
|
||||
- https://github.com/llvm/llvm-project/tree/main/llvm/examples/OrcV2Examples/LLJITWithInitializers
|
||||
- https://github.com/llvm/llvm-project/tree/main/llvm/examples/OrcV2Examples/LLJITWithLazyReexports
|
||||
|
||||
*** Talks
|
||||
- [[https://www.youtube.com/watch?v=i-inxFudrgI][ORCv2 -- LLVM JIT APIs Deep Dive]]
|
||||
- [[https://www.youtube.com/watch?v=MOQG5vkh9J8][Updating ORC JIT for Concurrency]]
|
||||
- [[https://www.youtube.com/watch?v=hILdR8XRvdQ][ORC -- LLVM's Next Generation of JIT API]]
|
||||
* DONE Eposide 16 - ORC Layers
|
||||
CLOSED: [2022-02-26 Sat 12:50]
|
||||
** Updates:
|
||||
*** Support for adding AST directly to the JIT
|
||||
*** Minor change to SLIR (big changes are coming)
|
||||
*** Started to unify the llvm::Errors with Serene errors
|
||||
*** Tablegen backend for error classes
|
||||
** The plan for today
|
||||
- We had a brief look at LLJIT/LLLazyJIT
|
||||
- Better understanding
|
||||
To understand them better we need to understand other components first. Starting from *layers*.
|
||||
- We'll have a look at how to define our own layers in the future episodes.
|
||||
|
||||
** What are Layers?
|
||||
- Layers are the basic blocks of an engine
|
||||
- They are composable (kinda)
|
||||
- Each layer has it's own requirements and details
|
||||
- Each layer holds a reference to it's downstream layer
|
||||
|
||||
#+NAME: ep-16-jit-1
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/ep16-1.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="Input Type A"]
|
||||
b[label="Input Type B"]
|
||||
c[label="Layer A"]
|
||||
d[label="Layer B"]
|
||||
e[label="Layer C"]
|
||||
f[label="Layer D"]
|
||||
g[label="Layer E"]
|
||||
h[label="Target Code"]
|
||||
a -> c
|
||||
b -> d
|
||||
|
||||
subgraph cluster0 {
|
||||
color=lightgrey;
|
||||
c -> e
|
||||
d -> e
|
||||
e -> f
|
||||
f -> g
|
||||
|
||||
label = "JIT Engine";
|
||||
}
|
||||
|
||||
g -> h
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-16-jit-1
|
||||
[[file:/tmp/ep16-1.svg]]
|
||||
|
||||
** Kaleidoscope JIT
|
||||
|
||||
- Chapter 1
|
||||
|
||||
#+NAME: ep-16-jit-2
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/ep16-2.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="LLVM IR Module"]
|
||||
b[label="Compiler Layer"]
|
||||
c[label="Object Layer"]
|
||||
d[label="Target Code"]
|
||||
|
||||
a -> b
|
||||
|
||||
subgraph cluster0 {
|
||||
color=lightgrey;
|
||||
b -> c
|
||||
|
||||
label = "Kaleidoscope JIT";
|
||||
}
|
||||
|
||||
c -> d
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-16-jit-2
|
||||
[[file:/tmp/ep16-2.svg]]
|
||||
|
||||
- Chapter 2
|
||||
#+NAME: ep-16-jit-3
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/ep16-3.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box"]
|
||||
edge [color=gray80]
|
||||
rankdir = "LR"
|
||||
|
||||
a[label="LLVM IR Module"]
|
||||
b[label="Compiler Layer"]
|
||||
c[label="Object Layer"]
|
||||
e[label="Target Code"]
|
||||
d[label="Optimize layer"]
|
||||
a -> d
|
||||
|
||||
subgraph cluster0 {
|
||||
color=lightgrey;
|
||||
d -> b
|
||||
b -> c
|
||||
|
||||
label = "Kaleidoscope JIT";
|
||||
}
|
||||
|
||||
c -> e
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-16-jit-3
|
||||
[[file:/tmp/ep16-3.svg]]
|
||||
|
||||
* DONE Episode 17 - Custom ORC Layers
|
||||
CLOSED: [2022-03-28 Mon 14:00]
|
||||
** Updates:
|
||||
- Finished the basic compiler wiring
|
||||
- Restructured the source tree
|
||||
- Tweaked the build system mostly for install targets
|
||||
- Refactoring, cleaning up the code and writing tests
|
||||
** Quick overview an ORC based JIT engine
|
||||
- JIT engines are made out of layers
|
||||
- Engines have a hierarchy of layers
|
||||
- Layers don't know about each other
|
||||
- Layers wrap the program representation in a =MaterializationUnit=, which is
|
||||
then stored in the =JITDylib=.
|
||||
- =MaterializationUnits= are responsible for describing the definitions they provide,
|
||||
and for unwrapping the program representation and passing it back to the layer when
|
||||
compilation is required.
|
||||
- When a =MaterializationUnit= hands a program representation back to the layer it comes
|
||||
with an associated =MaterializationResponsibility= object. This object tracks the
|
||||
definitions that must be materialized and provides a way to notify the =JITDylib= once
|
||||
they are either successfully materialized or a failure occurs.
|
||||
|
||||
** In order to build a custom layer we need:
|
||||
*** A custom materialization unit
|
||||
Let's have a look at the =MaterializationUnit= class.
|
||||
|
||||
*** And the layer class itself
|
||||
The layer classes are not special but conventionally the come with few functions
|
||||
like: =add=, =emit= and =getInterface=.
|
||||
|
||||
* DONE Episode 18 - JIT Engine Part 1
|
||||
CLOSED: [2022-03-29 Tue 19:56]
|
||||
** =Halley= JIT Engine
|
||||
- It's not the final implementation
|
||||
- Wraps LLJIT and LLLazyJIT
|
||||
- Uses object cache layer
|
||||
- Supports ASTs and Namespaces
|
||||
|
||||
* DONE Episode 19 - JIT Engine Part 2
|
||||
CLOSED: [2022-05-04 Wed 21:30]
|
||||
** How Serene is different from other programming langs?
|
||||
- Serene is just a JIT engine
|
||||
- Compiletime vs Runtime
|
||||
+ The borderline is not clear in case of Serene
|
||||
|
||||
The Big picture
|
||||
#+NAME: ep-19-jit-1
|
||||
#+BEGIN_SRC graphviz-dot :file /tmp/ep19-1.svg :cmdline -Kdot -Tsvg
|
||||
digraph {
|
||||
fontcolor="gray80"
|
||||
|
||||
graph [bgcolor=transparent]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
edge [color=gray80, fontcolor="gray80"]
|
||||
|
||||
|
||||
input_ns[label="Input Namespace"]
|
||||
|
||||
ast[label="AST"]
|
||||
vast[label="Valid AST"]
|
||||
ir[label="LLVM IR"]
|
||||
|
||||
subgraph cluster_2 {
|
||||
label="REPL"
|
||||
color="gray80"
|
||||
|
||||
graph [bgcolor=transparent, fontcolor="gray80"]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
|
||||
input_form[label="Input Form"]
|
||||
result[label="Evaluation result"]
|
||||
result -> input_form[label="Loop"]
|
||||
}
|
||||
|
||||
subgraph cluster_0 {
|
||||
label="JIT"
|
||||
color="gray80"
|
||||
|
||||
graph [bgcolor=transparent, fontcolor="gray80"]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
|
||||
|
||||
execute[label="Execute native code"]
|
||||
binary[label="Binary File"]
|
||||
|
||||
subgraph cluster_1 {
|
||||
label="AddAst/Ns"
|
||||
color="gray80"
|
||||
|
||||
graph [bgcolor=transparent, fontcolor="gray80"]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
|
||||
vast -> ir [label="Compile (No optimization)"]
|
||||
|
||||
subgraph cluster_4 {
|
||||
label="Macro Expansion"
|
||||
color="gray80"
|
||||
|
||||
graph [bgcolor=transparent, fontcolor="gray80"]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
|
||||
vast -> macros [label=" Find the macros"]
|
||||
macros -> JITDylib [label=" look up the required\n Symbols in compiled code"]
|
||||
JITDylib -> symbols [label=" lookup"]
|
||||
}
|
||||
|
||||
wrapped_code[lable="Wrapped IR"]
|
||||
ir -> wrapped_code[label= " Wrap top level Forms in \nfunctions/calls"]
|
||||
wrapped_code -> native [label=" Compile (No optimization)"]
|
||||
}
|
||||
|
||||
symbols -> execute [label="Execute the functions mapped to the symbols"]
|
||||
execute -> vast
|
||||
execute -> result [label=" Print"]
|
||||
execute -> binary [label=" Dump"]
|
||||
|
||||
native -> execute [label="invoke"]
|
||||
native -> JITDylib [label="Add"]
|
||||
JITDylib -> Context [label="Store as part the namespace"]
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
label="CLI interface"
|
||||
color="gray80"
|
||||
|
||||
graph [bgcolor=transparent, fontcolor="gray80"]
|
||||
node [color=gray80 shape="box", fontcolor="gray80"]
|
||||
|
||||
input_ns -> file [label=" resolve to file"]
|
||||
}
|
||||
|
||||
input_form -> ast [label=" read"]
|
||||
file -> ast [label=" read"]
|
||||
ast -> vast [label=" Semantic Analysis"]
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: ep-19-jit-1
|
||||
[[file:/tmp/ep19-1.png]]
|
||||
** Let's look at some code
|
||||
* Episode 20 - Future Roadmap
|
||||
** So Far
|
||||
- We created a bare bone and minimal compiler
|
||||
+ That is capable of just in time and ahead of time compilation
|
||||
- We had an over of MLIR and pass management
|
||||
- We didn't spend time on fundamentals
|
||||
** Design change
|
||||
- The current implementation is suitable for a static compiler
|
||||
- We want to move toward a more dynamic compiler
|
||||
** What's next?
|
||||
- Part 2
|
||||
- We're going to focus on some of the compiler fundamentals
|
||||
- We will create simple utilities to help us in our journey
|
||||
- Hopefully we will talk about type systems
|
||||
- We're going to sharpen our skills on LLVM/MLIR
|
||||
- I'm going to work on the new design
|
||||
|
|
149
flake.lock
149
flake.lock
|
@ -1,149 +0,0 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715865404,
|
||||
"narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715870890,
|
||||
"narHash": "sha256-nacSOeXtUEM77Gn0G4bTdEOeFIrkCBXiyyFZtdGwuH0=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "fa606cccd7b0ccebe2880051208e4a0f61bfc8c1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"git-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1710765496,
|
||||
"narHash": "sha256-p7ryWEeQfMwTB6E0wIUd5V2cFTgq+DRRBz2hYGnJZyA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e367f7a1fb93137af22a3908f00b9a35e2d286a7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1714640452,
|
||||
"narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1710695816,
|
||||
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1712525377,
|
||||
"narHash": "sha256-TbfZDd8NN6gx7eU5XQWgF/ojnnkTvn7cPXWdY4PVTMU=",
|
||||
"owner": "lxsameer",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c738ee8ad1c35383037c20fa13eaac17c8ae98c5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "lxsameer",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c738ee8ad1c35383037c20fa13eaac17c8ae98c5",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"git-hooks": "git-hooks",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
132
flake.nix
132
flake.nix
|
@ -1,132 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
{
|
||||
description = "Serene programming language";
|
||||
|
||||
inputs.nixpkgs.url =
|
||||
"github:lxsameer/nixpkgs/c738ee8ad1c35383037c20fa13eaac17c8ae98c5";
|
||||
#inputs.nixpkgs.url = "/home/lxsameer/src/nixpkgs/";
|
||||
inputs.git-hooks.url = "github:cachix/git-hooks.nix";
|
||||
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
|
||||
outputs = { self, nixpkgs, git-hooks, flake-parts, ... }@inputs:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [ "aarch64-darwin" "riscv64-linux" "x86_64-linux" ];
|
||||
|
||||
flake = { };
|
||||
perSystem = { config, self', inputs', system, pkgs, lib, ... }:
|
||||
let
|
||||
version = "1.0.0";
|
||||
|
||||
overlays = (lib.attrsets.attrValues (import ./nix/overlays.nix { }));
|
||||
utils = import ./nix/utils.nix { inherit nixpkgs; };
|
||||
|
||||
hostPkgs = pkgs;
|
||||
targetPkgs = utils.getPkgs system overlays;
|
||||
|
||||
# Create a stdenv based on LLVM
|
||||
stdenv = targetPkgs.stdenvAdapters.overrideCC targetPkgs.stdenv
|
||||
targetPkgs.llvmPackages_18.clangUseLLVM;
|
||||
|
||||
gc = targetPkgs.callPackage ./nix/boehmgc.nix { inherit stdenv; };
|
||||
|
||||
zlib' = targetPkgs.zlib-ng.overrideAttrs (old: {
|
||||
cmakeFlags = [
|
||||
"-DCMAKE_INSTALL_PREFIX=/"
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-DINSTALL_UTILS=ON"
|
||||
"-DZLIB_COMPAT=ON"
|
||||
];
|
||||
});
|
||||
|
||||
# By default llvm adds zlib to `propagatedBuildInputs` which means any
|
||||
# package that uses llvm will indirectly depends on zlib. And since
|
||||
# by default that zlib is built as a shared lib (since our packageset
|
||||
# is not static), We can't statically link to it. So, we just replace
|
||||
# that zlib with our override of zlib-ng
|
||||
clang' = stdenv.cc.overrideAttrs (old: {
|
||||
propagatedBuildInputs = [ stdenv.cc.bintools ]
|
||||
++ [ targetPkgs.zlib.static ];
|
||||
});
|
||||
|
||||
llvm = targetPkgs.llvmPackages_18.llvm.overrideAttrs
|
||||
(old: { propagatedBuildInputs = [ targetPkgs.zlib.static ]; });
|
||||
|
||||
# This is the actual stdenv that we need to use anywhere else
|
||||
stdenv' =
|
||||
targetPkgs.stdenvAdapters.overrideCC targetPkgs.stdenv clang';
|
||||
|
||||
nativeBuildToolsDeps = (with hostPkgs; [ cmake ninja ccache ]);
|
||||
|
||||
buildToolsDeps = (with targetPkgs; [
|
||||
llvm
|
||||
llvmPackages_18.mlir
|
||||
llvmPackages_18.clang
|
||||
iwyu
|
||||
]);
|
||||
|
||||
buildDeps = (with targetPkgs; [
|
||||
gc
|
||||
zlib'
|
||||
llvm
|
||||
llvmPackages_18.mlir
|
||||
llvmPackages_18.clang
|
||||
]);
|
||||
|
||||
testDeps = (with hostPkgs; [ gtest gmock gbenchmark ]);
|
||||
|
||||
in {
|
||||
devShells.default =
|
||||
(targetPkgs.mkShell.override { stdenv = stdenv'; }) {
|
||||
inherit (self.checks.${system}.git-hook-check) shellHook;
|
||||
|
||||
nativeBuildInputs = nativeBuildToolsDeps ++ buildToolsDeps;
|
||||
buildInputs = buildDeps ++ testDeps
|
||||
++ self.checks.${system}.git-hook-check.enabledPackages;
|
||||
};
|
||||
|
||||
packages.blah = buildDeps ++ testDeps ++ nativeBuildToolsDeps
|
||||
++ buildToolsDeps;
|
||||
packages.devshell = stdenv'.mkDerivation {
|
||||
inherit version;
|
||||
name = "devshell";
|
||||
|
||||
src = ./.;
|
||||
doBuild = false;
|
||||
doUnpack = false;
|
||||
doCheck = false;
|
||||
nativeBuildInputs = nativeBuildToolsDeps ++ buildToolsDeps;
|
||||
buildInputs = buildDeps ++ testDeps;
|
||||
};
|
||||
|
||||
checks = {
|
||||
git-hook-check = git-hooks.lib.${system}.run {
|
||||
src = ./.;
|
||||
hooks = {
|
||||
nixfmt.enable = true;
|
||||
clang-format = {
|
||||
enable = true;
|
||||
types_or = hostPkgs.lib.mkForce [ "c" "c++" ];
|
||||
};
|
||||
shellcheck.enable = true;
|
||||
cmake-format.enable = true;
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory("serene/slir/")
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
// the configured options and settings
|
||||
|
||||
#define SERENE_VERSION "@PROJECT_VERSION@"
|
||||
|
||||
// Should we build the support for MLIR CL OPTIONS?
|
||||
#cmakedefine SERENE_WITH_MLIR_CL_OPTION
|
||||
|
||||
#endif
|
|
@ -0,0 +1,162 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_CONTEXT_H
|
||||
#define SERENE_CONTEXT_H
|
||||
|
||||
#include "serene/diagnostics.h"
|
||||
#include "serene/environment.h"
|
||||
#include "serene/export.h"
|
||||
#include "serene/namespace.h"
|
||||
#include "serene/passes.h"
|
||||
#include "serene/slir/dialect.h"
|
||||
#include "serene/source_mgr.h"
|
||||
|
||||
#include <llvm/ADT/None.h>
|
||||
#include <llvm/ADT/Optional.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/Support/Host.h>
|
||||
#include <mlir/Dialect/StandardOps/IR/Ops.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
#include <mlir/Pass/PassManager.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace reader {
|
||||
class LocationRange;
|
||||
} // namespace reader
|
||||
|
||||
namespace exprs {
|
||||
class Expression;
|
||||
using Node = std::shared_ptr<Expression>;
|
||||
} // namespace exprs
|
||||
|
||||
enum class CompilationPhase {
|
||||
Parse,
|
||||
Analysis,
|
||||
SLIR,
|
||||
MLIR, // Lowered slir to other dialects
|
||||
LIR, // Lowered to the llvm ir dialect
|
||||
IR, // Lowered to the LLVMIR itself
|
||||
NoOptimization,
|
||||
O1,
|
||||
O2,
|
||||
O3,
|
||||
};
|
||||
|
||||
class SERENE_EXPORT SereneContext {
|
||||
struct Options {
|
||||
/// Whether to use colors for the output or not
|
||||
bool withColors = true;
|
||||
|
||||
Options() = default;
|
||||
};
|
||||
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
// IMPORTANT:
|
||||
// These two contextes have to be the very first members of the class in
|
||||
// order to destroy last. DO NOT change the order or add anything before
|
||||
// them
|
||||
// --------------------------------------------------------------------------
|
||||
llvm::LLVMContext llvmContext;
|
||||
mlir::MLIRContext mlirContext;
|
||||
|
||||
mlir::PassManager pm;
|
||||
|
||||
std::unique_ptr<DiagnosticEngine> diagEngine;
|
||||
|
||||
/// The source manager is responsible for loading namespaces and practically
|
||||
/// managing the source code in form of memory buffers.
|
||||
SourceMgr sourceManager;
|
||||
|
||||
/// The set of options to change the compilers behaivoirs
|
||||
Options opts;
|
||||
|
||||
std::string targetTriple;
|
||||
|
||||
/// Insert the given `ns` into the context. The Context object is
|
||||
/// the owner of all the namespaces. The `ns` will overwrite any
|
||||
/// namespace with the same name.
|
||||
void insertNS(NSPtr &ns);
|
||||
|
||||
/// Sets the n ame of the current namespace in the context and return
|
||||
/// a boolean indicating the status of this operation. The operation
|
||||
/// will fail if the namespace does not exist in the namespace table.
|
||||
bool setCurrentNS(llvm::StringRef ns_name);
|
||||
|
||||
/// Return the current namespace that is being processed at the moment
|
||||
Namespace &getCurrentNS();
|
||||
|
||||
/// Lookup the namespace with the give name in the current context and
|
||||
/// return a pointer to it or a `nullptr` in it doesn't exist.
|
||||
Namespace *getNS(llvm::StringRef ns_name);
|
||||
|
||||
SereneContext()
|
||||
: pm(&mlirContext), diagEngine(makeDiagnosticEngine(*this)),
|
||||
targetPhase(CompilationPhase::NoOptimization) {
|
||||
mlirContext.getOrLoadDialect<serene::slir::SereneDialect>();
|
||||
mlirContext.getOrLoadDialect<mlir::StandardOpsDialect>();
|
||||
|
||||
// We need to create one empty namespace, so that the JIT can
|
||||
// start it's operation.
|
||||
auto ns = makeNamespace(*this, "serene.user", llvm::None);
|
||||
|
||||
// TODO: Get the crash report path dynamically from the cli
|
||||
// pm.enableCrashReproducerGeneration("/home/lxsameer/mlir.mlir");
|
||||
|
||||
// TODO: Set the target triple with respect to the CLI args
|
||||
targetTriple = llvm::sys::getDefaultTargetTriple();
|
||||
};
|
||||
|
||||
/// Set the target compilation phase of the compiler. The compilation
|
||||
/// phase dictates the behavior and the output type of the compiler.
|
||||
void setOperationPhase(CompilationPhase phase);
|
||||
|
||||
CompilationPhase getTargetPhase() { return targetPhase; };
|
||||
int getOptimizatioLevel();
|
||||
|
||||
MaybeNS readNamespace(const std::string &name);
|
||||
MaybeNS readNamespace(const std::string &name, reader::LocationRange loc);
|
||||
|
||||
private:
|
||||
CompilationPhase targetPhase;
|
||||
|
||||
// The namespace table. Every namespace that needs to be compiled has
|
||||
// to register itself with the context and appear on this table.
|
||||
// This table acts as a cache as well.
|
||||
std::map<std::string, NSPtr> namespaces;
|
||||
|
||||
// Why string vs pointer? We might rewrite the namespace and
|
||||
// holding a pointer means that it might point to the old version
|
||||
std::string current_ns;
|
||||
};
|
||||
|
||||
/// Creates a new context object. Contexts are used through out the compilation
|
||||
/// process to store the state
|
||||
SERENE_EXPORT std::unique_ptr<SereneContext> makeSereneContext();
|
||||
|
||||
/// Terminates the serene compiler process in a thread safe manner
|
||||
SERENE_EXPORT void terminate(SereneContext &ctx, int exitCode);
|
||||
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_DIAGNOSTICS_H
|
||||
#define SERENE_DIAGNOSTICS_H
|
||||
|
||||
#include "serene/errors/constants.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/reader/location.h"
|
||||
#include "serene/source_mgr.h"
|
||||
|
||||
#include <serene/export.h>
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <mlir/IR/Diagnostics.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace serene {
|
||||
class SereneContext;
|
||||
class DiagnosticEngine;
|
||||
|
||||
class Diagnostic {
|
||||
// TODO: Add support for llvm::SMFixIt
|
||||
friend DiagnosticEngine;
|
||||
|
||||
enum Type {
|
||||
Error,
|
||||
|
||||
// TODO: Add support for remarks and notes
|
||||
Remark,
|
||||
Note,
|
||||
};
|
||||
|
||||
SereneContext &ctx;
|
||||
reader::LocationRange loc;
|
||||
std::string fn;
|
||||
errors::ErrorVariant *err = nullptr;
|
||||
Type type = Type::Error;
|
||||
std::string message, lineContents;
|
||||
|
||||
std::string getPrefix(llvm::StringRef prefix = "");
|
||||
|
||||
public:
|
||||
Diagnostic(SereneContext &ctx, reader::LocationRange loc,
|
||||
errors::ErrorVariant *e, llvm::StringRef msg,
|
||||
llvm::StringRef fn = "")
|
||||
: ctx(ctx), loc(loc), fn(fn), err(e), message(msg){};
|
||||
|
||||
protected:
|
||||
void print(llvm::raw_ostream &os, llvm::StringRef prefix = "");
|
||||
void writeColorByType(llvm::raw_ostream &os, llvm::StringRef str);
|
||||
};
|
||||
|
||||
class DiagnosticEngine {
|
||||
SereneContext &ctx;
|
||||
|
||||
mlir::DiagnosticEngine &diagEngine;
|
||||
|
||||
Diagnostic toDiagnostic(reader::LocationRange loc, errors::ErrorVariant &e,
|
||||
llvm::StringRef msg, llvm::StringRef fn = "");
|
||||
|
||||
void print(llvm::raw_ostream &os, Diagnostic &d);
|
||||
|
||||
public:
|
||||
DiagnosticEngine(SereneContext &ctx);
|
||||
|
||||
void enqueueError(llvm::StringRef msg);
|
||||
void emitSyntaxError(reader::LocationRange loc, errors::ErrorVariant &e,
|
||||
llvm::StringRef msg = "");
|
||||
|
||||
void emit(const errors::ErrorPtr &err);
|
||||
void emit(const errors::ErrorTree &errs);
|
||||
|
||||
/// Throw out an error with the given `msg` and terminate the execution
|
||||
void panic(llvm::StringRef msg);
|
||||
};
|
||||
|
||||
/// Create a new instance of the `DiagnosticEngine` from the give
|
||||
/// `SereneContext`
|
||||
std::unique_ptr<DiagnosticEngine> makeDiagnosticEngine(SereneContext &ctx);
|
||||
|
||||
/// Throw out an error with the given `msg` and terminate the execution.
|
||||
SERENE_EXPORT void panic(SereneContext &ctx, llvm::StringRef msg);
|
||||
|
||||
/// Throw the give `ErrorTree` \p errs and terminate the execution.
|
||||
SERENE_EXPORT void throwErrors(SereneContext &ctx, errors::ErrorTree &errs);
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,12 +16,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ENVIRONMENT_H
|
||||
#define ENVIRONMENT_H
|
||||
#ifndef SERENE_ENVIRONMENT_H
|
||||
#define SERENE_ENVIRONMENT_H
|
||||
|
||||
#include "utils.h"
|
||||
#include "serene/llvm/patches.h"
|
||||
|
||||
#include <llvm/ADT/StringMap.h>
|
||||
#include <llvm/ADT/DenseMap.h>
|
||||
#include <mlir/Support/LogicalResult.h>
|
||||
|
||||
namespace serene {
|
||||
|
@ -29,21 +29,20 @@ namespace serene {
|
|||
/// This class represents a classic lisp environment (or scope) that holds the
|
||||
/// bindings from type `K` to type `V`. For example an environment of symbols
|
||||
/// to expressions would be `Environment<Symbol, Node>`
|
||||
template <typename V>
|
||||
template <typename K, typename V>
|
||||
class Environment {
|
||||
|
||||
Environment<V> *parent;
|
||||
Environment<K, V> *parent;
|
||||
|
||||
using StorageType = llvm::StringMap<V>;
|
||||
// The actual bindings storage
|
||||
StorageType pairs;
|
||||
llvm::DenseMap<K, V> pairs;
|
||||
|
||||
public:
|
||||
Environment() : parent(nullptr) {}
|
||||
explicit Environment(Environment *parent) : parent(parent){};
|
||||
Environment(Environment *parent) : parent(parent){};
|
||||
|
||||
/// Look up the given `key` in the environment and return it.
|
||||
std::optional<V> lookup(llvm::StringRef key) {
|
||||
llvm::Optional<V> lookup(K key) {
|
||||
if (auto value = pairs.lookup(key)) {
|
||||
return value;
|
||||
}
|
||||
|
@ -52,27 +51,15 @@ public:
|
|||
return parent->lookup(key);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
return llvm::None;
|
||||
};
|
||||
|
||||
/// Insert the given `key` with the given `value` into the storage. This
|
||||
/// operation will shadow an aleady exist `key` in the parent environment
|
||||
mlir::LogicalResult insert_symbol(llvm::StringRef key, V value) {
|
||||
auto result = pairs.insert_or_assign(key, value);
|
||||
UNUSED(result);
|
||||
mlir::LogicalResult insert_symbol(K key, V value) {
|
||||
pairs.insert(std::pair<K, V>(key, value));
|
||||
return mlir::success();
|
||||
};
|
||||
|
||||
inline typename StorageType::iterator begin() { return pairs.begin(); }
|
||||
|
||||
inline typename StorageType::iterator end() { return pairs.end(); }
|
||||
|
||||
inline typename StorageType::const_iterator begin() const {
|
||||
return pairs.begin();
|
||||
}
|
||||
inline typename StorageType::const_iterator end() const {
|
||||
return pairs.end();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace serene
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,11 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "serene/core/core.h"
|
||||
#include "serene/types/types.h"
|
||||
#ifndef SERENE_ERRORS_H
|
||||
#define SERENE_ERRORS_H
|
||||
|
||||
namespace serene {
|
||||
#include "serene/errors/errc.h"
|
||||
#include "serene/errors/error.h"
|
||||
|
||||
int read() { return 0; };
|
||||
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_ERRORS_CONSTANTS_H
|
||||
#define SERENE_ERRORS_CONSTANTS_H
|
||||
|
||||
#include <llvm/Support/FormatVariadic.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace serene {
|
||||
namespace errors {
|
||||
|
||||
/// This enum represent the expression type and **not** the value type.
|
||||
enum class ErrType {
|
||||
Syntax,
|
||||
Semantic,
|
||||
Compile,
|
||||
};
|
||||
|
||||
enum ErrID {
|
||||
E0000 = 0,
|
||||
E0001,
|
||||
E0002,
|
||||
E0003,
|
||||
E0004,
|
||||
E0005,
|
||||
E0006,
|
||||
E0007,
|
||||
E0008,
|
||||
E0009,
|
||||
E0010,
|
||||
E0011,
|
||||
E0012,
|
||||
E0013,
|
||||
};
|
||||
|
||||
struct ErrorVariant {
|
||||
ErrID id;
|
||||
|
||||
std::string description;
|
||||
std::string longDescription;
|
||||
|
||||
ErrorVariant(ErrID id, std::string desc, std::string longDesc)
|
||||
: id(id), description(std::move(desc)),
|
||||
longDescription(std::move(longDesc)){};
|
||||
|
||||
std::string getErrId() { return llvm::formatv("E{0:d}", id); };
|
||||
};
|
||||
|
||||
static ErrorVariant
|
||||
UnknownError(E0000, "Can't find any description for this error.", "");
|
||||
static ErrorVariant
|
||||
DefExpectSymbol(E0001, "The first argument to 'def' has to be a Symbol.",
|
||||
"");
|
||||
|
||||
static ErrorVariant DefWrongNumberOfArgs(
|
||||
E0002, "Wrong number of arguments is passed to the 'def' form.", "");
|
||||
|
||||
static ErrorVariant FnNoArgsList(E0003, "'fn' form requires an argument list.",
|
||||
"");
|
||||
|
||||
static ErrorVariant FnArgsMustBeList(E0004, "'fn' arguments should be a list.",
|
||||
"");
|
||||
|
||||
static ErrorVariant CantResolveSymbol(E0005, "Can't resolve the given name.",
|
||||
"");
|
||||
static ErrorVariant
|
||||
DontKnowHowToCallNode(E0006, "Don't know how to call the given expression.",
|
||||
"");
|
||||
|
||||
static ErrorVariant PassFailureError(E0007, "Pass Failure.", "");
|
||||
|
||||
static ErrorVariant NSLoadError(E0008, "Faild to find a namespace.", "");
|
||||
|
||||
static ErrorVariant
|
||||
NSAddToSMError(E0009, "Faild to add the namespace to the source manager.",
|
||||
"");
|
||||
|
||||
static ErrorVariant
|
||||
EOFWhileScaningAList(E0010, "EOF reached before closing of list", "");
|
||||
|
||||
static ErrorVariant InvalidDigitForNumber(E0011, "Invalid digit for a number.",
|
||||
"");
|
||||
|
||||
static ErrorVariant
|
||||
TwoFloatPoints(E0012, "Two or more float point characters in a number", "");
|
||||
|
||||
static ErrorVariant
|
||||
InvalidCharacterForSymbol(E0013, "Invalid character for a symbol", "");
|
||||
|
||||
static std::map<ErrID, ErrorVariant *> ErrDesc = {
|
||||
{E0000, &UnknownError}, {E0001, &DefExpectSymbol},
|
||||
{E0002, &DefWrongNumberOfArgs}, {E0003, &FnNoArgsList},
|
||||
{E0004, &FnArgsMustBeList}, {E0005, &CantResolveSymbol},
|
||||
{E0006, &DontKnowHowToCallNode}, {E0007, &PassFailureError},
|
||||
{E0008, &NSLoadError}, {E0009, &NSAddToSMError},
|
||||
{E0010, &EOFWhileScaningAList}, {E0011, &InvalidDigitForNumber},
|
||||
{E0012, &TwoFloatPoints}, {E0013, &InvalidCharacterForSymbol}};
|
||||
|
||||
} // namespace errors
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_ERRORS_ERRC_H
|
||||
#define SERENE_ERRORS_ERRC_H
|
||||
|
||||
#include <llvm/Support/Errc.h>
|
||||
|
||||
namespace serene {
|
||||
|
||||
/// A collection of common error codes in Serene
|
||||
enum class errc {
|
||||
argument_list_too_long = int(std::errc::argument_list_too_long),
|
||||
argument_out_of_domain = int(std::errc::argument_out_of_domain),
|
||||
bad_address = int(std::errc::bad_address),
|
||||
bad_file_descriptor = int(std::errc::bad_file_descriptor),
|
||||
broken_pipe = int(std::errc::broken_pipe),
|
||||
device_or_resource_busy = int(std::errc::device_or_resource_busy),
|
||||
directory_not_empty = int(std::errc::directory_not_empty),
|
||||
executable_format_error = int(std::errc::executable_format_error),
|
||||
file_exists = int(std::errc::file_exists),
|
||||
file_too_large = int(std::errc::file_too_large),
|
||||
filename_too_long = int(std::errc::filename_too_long),
|
||||
function_not_supported = int(std::errc::function_not_supported),
|
||||
illegal_byte_sequence = int(std::errc::illegal_byte_sequence),
|
||||
inappropriate_io_control_operation =
|
||||
int(std::errc::inappropriate_io_control_operation),
|
||||
interrupted = int(std::errc::interrupted),
|
||||
invalid_argument = int(std::errc::invalid_argument),
|
||||
invalid_seek = int(std::errc::invalid_seek),
|
||||
io_error = int(std::errc::io_error),
|
||||
is_a_directory = int(std::errc::is_a_directory),
|
||||
no_child_process = int(std::errc::no_child_process),
|
||||
no_lock_available = int(std::errc::no_lock_available),
|
||||
no_space_on_device = int(std::errc::no_space_on_device),
|
||||
no_such_device_or_address = int(std::errc::no_such_device_or_address),
|
||||
no_such_device = int(std::errc::no_such_device),
|
||||
no_such_file_or_directory = int(std::errc::no_such_file_or_directory),
|
||||
no_such_process = int(std::errc::no_such_process),
|
||||
not_a_directory = int(std::errc::not_a_directory),
|
||||
not_enough_memory = int(std::errc::not_enough_memory),
|
||||
not_supported = int(std::errc::not_supported),
|
||||
operation_not_permitted = int(std::errc::operation_not_permitted),
|
||||
permission_denied = int(std::errc::permission_denied),
|
||||
read_only_file_system = int(std::errc::read_only_file_system),
|
||||
resource_deadlock_would_occur = int(std::errc::resource_deadlock_would_occur),
|
||||
resource_unavailable_try_again =
|
||||
int(std::errc::resource_unavailable_try_again),
|
||||
result_out_of_range = int(std::errc::result_out_of_range),
|
||||
too_many_files_open_in_system = int(std::errc::too_many_files_open_in_system),
|
||||
too_many_files_open = int(std::errc::too_many_files_open),
|
||||
too_many_links = int(std::errc::too_many_links)
|
||||
};
|
||||
|
||||
/// The **official way** to create `std::error_code` in context of Serene.
|
||||
inline std::error_code make_error_code(errc E) {
|
||||
return std::error_code(static_cast<int>(E), std::generic_category());
|
||||
};
|
||||
|
||||
}; // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_ERRORS_ERROR_H
|
||||
#define SERENE_ERRORS_ERROR_H
|
||||
|
||||
#include "serene/errors/constants.h"
|
||||
#include "serene/errors/traits.h"
|
||||
#include "serene/reader/traits.h"
|
||||
#include "serene/traits.h"
|
||||
|
||||
#include <llvm/ADT/Optional.h>
|
||||
|
||||
namespace serene::reader {
|
||||
class LoccationRange;
|
||||
} // namespace serene::reader
|
||||
|
||||
namespace serene::errors {
|
||||
class Error;
|
||||
|
||||
using ErrorPtr = std::shared_ptr<errors::Error>;
|
||||
|
||||
// tree? Yupe, Errors can be stackable which makes a vector of them a tree
|
||||
using ErrorTree = std::vector<ErrorPtr>;
|
||||
using OptionalErrors = llvm::Optional<ErrorTree>;
|
||||
|
||||
/// This data structure represent the Lisp error. This type of expression
|
||||
/// doesn't show up in the AST but the compiler might rewrite the AST
|
||||
/// to contains error expressions
|
||||
class Error
|
||||
: public WithTrait<Error, IError, reader::ILocatable, serene::IDebuggable> {
|
||||
reader::LocationRange location;
|
||||
ErrorVariant *variant;
|
||||
std::string message;
|
||||
|
||||
public:
|
||||
Error(reader::LocationRange &loc, ErrorVariant &err, llvm::StringRef msg)
|
||||
: location(loc), variant(&err), message(msg){};
|
||||
|
||||
Error(reader::LocationRange &loc, ErrorVariant &err)
|
||||
: location(loc), variant(&err){};
|
||||
|
||||
std::string toString() const;
|
||||
reader::LocationRange &where();
|
||||
ErrorVariant *getVariant();
|
||||
std::string &getMessage();
|
||||
~Error() = default;
|
||||
};
|
||||
|
||||
/// Creates a new Error in the give location \p loc, with the given
|
||||
/// variant \p and an optional message \p msg and retuns a shared ptr
|
||||
/// to the error. This is the official API to make errors.
|
||||
ErrorPtr makeError(reader::LocationRange &loc, ErrorVariant &err,
|
||||
llvm::StringRef msg = "msg");
|
||||
|
||||
/// Creates a new ErrorTree out of a new Error that creats from the input
|
||||
/// argument and pass them to `makeError` function.
|
||||
ErrorTree makeErrorTree(reader::LocationRange &loc, ErrorVariant &err,
|
||||
llvm::StringRef msg = "msg");
|
||||
|
||||
}; // namespace serene::errors
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_ERRORS_TRAITS_H
|
||||
#define SERENE_ERRORS_TRAITS_H
|
||||
|
||||
#include "serene/errors/constants.h"
|
||||
#include "serene/traits.h"
|
||||
|
||||
namespace serene::errors {
|
||||
template <typename ConcreteType>
|
||||
class IError : public TraitBase<ConcreteType, IError> {
|
||||
public:
|
||||
IError(){};
|
||||
IError(const IError &) = delete;
|
||||
|
||||
ErrorVariant *getVariant();
|
||||
std::string getMessage();
|
||||
};
|
||||
|
||||
} // namespace serene::errors
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_CALL_H
|
||||
#define SERENE_EXPRS_CALL_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/exprs/list.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/Support/Error.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace exprs {
|
||||
class List;
|
||||
|
||||
/// This data structure represents a function. with a collection of
|
||||
/// arguments and the ast of a body
|
||||
class Call : public Expression {
|
||||
|
||||
public:
|
||||
Node target;
|
||||
Ast params;
|
||||
|
||||
Call(reader::LocationRange &loc, Node &target, Ast ¶ms)
|
||||
: Expression(loc), target(target), params(params){};
|
||||
|
||||
Call(Call &) = delete;
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
MaybeNode analyze(SereneContext & /*ctx*/) override;
|
||||
void generateIR(serene::Namespace & /*ns*/,
|
||||
mlir::ModuleOp & /*m*/) override{};
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
|
||||
/// Creates a call node out of a list.
|
||||
/// For exmaple: `(somefn (param1 param2) param3)`. This function
|
||||
/// is supposed to be used in the semantic analysis phase.
|
||||
///
|
||||
/// \param ctx The semantic analysis context object.
|
||||
/// \param list the list in question.
|
||||
|
||||
static MaybeNode make(SereneContext &ctx, List *list);
|
||||
|
||||
~Call() = default;
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_DEF_H
|
||||
#define SERENE_EXPRS_DEF_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/Support/Error.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace exprs {
|
||||
class List;
|
||||
|
||||
/// This data structure represents the operation to define a new binding via
|
||||
/// the `def` special form.
|
||||
class Def : public Expression {
|
||||
|
||||
public:
|
||||
std::string binding;
|
||||
Node value;
|
||||
|
||||
Def(reader::LocationRange &loc, llvm::StringRef binding, Node &v)
|
||||
: Expression(loc), binding(binding), value(v){};
|
||||
|
||||
Def(Def &d) = delete;
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
MaybeNode analyze(SereneContext & /*ctx*/) override;
|
||||
void generateIR(serene::Namespace & /*ns*/, mlir::ModuleOp & /*m*/) override;
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
|
||||
/// Create a Def node out a list. The list should contain the
|
||||
/// correct `def` form like `(def blah value)`. This function
|
||||
/// is supposed to be used in the semantic analysis phase.
|
||||
///
|
||||
/// \param ctx The semantic analysis context object.
|
||||
/// \param list the list containing the `def` form
|
||||
static MaybeNode make(SereneContext &ctx, List *list);
|
||||
|
||||
~Def() = default;
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,154 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_EXPRESSION_H
|
||||
#define SERENE_EXPRS_EXPRESSION_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/exprs/traits.h"
|
||||
#include "serene/reader/location.h"
|
||||
#include "serene/utils.h"
|
||||
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace serene {
|
||||
|
||||
/// Contains all the builtin AST expressions including those which do not appear
|
||||
/// in the syntax directly. Like function definitions.
|
||||
namespace exprs {
|
||||
|
||||
class Expression;
|
||||
|
||||
using Node = std::shared_ptr<Expression>;
|
||||
using MaybeNode = Result<Node, errors::ErrorTree>;
|
||||
|
||||
using Ast = std::vector<Node>;
|
||||
using MaybeAst = Result<Ast, errors::ErrorTree>;
|
||||
|
||||
static auto EmptyNode = MaybeNode::success(nullptr);
|
||||
|
||||
/// The base class of the expressions which provides the common interface for
|
||||
/// the expressions to implement.
|
||||
class Expression {
|
||||
public:
|
||||
/// The location range provide information regarding to where in the input
|
||||
/// string the current expression is used.
|
||||
reader::LocationRange location;
|
||||
|
||||
Expression(const reader::LocationRange &loc) : location(loc){};
|
||||
virtual ~Expression() = default;
|
||||
|
||||
/// Returns the type of the expression. We need this funciton to perform
|
||||
/// dynamic casting of expression object to implementations such as lisp or
|
||||
/// symbol.
|
||||
virtual ExprType getType() const = 0;
|
||||
|
||||
/// The AST representation of an expression
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
/// Analyzes the semantics of current node and return a new node in case
|
||||
/// that we need to semantically rewrite the current node and replace it with
|
||||
/// another node. For example to change from a List containing `(def a b)`
|
||||
/// to a `Def` node that represents defining a new binding.
|
||||
///
|
||||
/// \param ctx is the context object of the semantic analyzer.
|
||||
virtual MaybeNode analyze(SereneContext &ctx) = 0;
|
||||
|
||||
/// Genenates the correspondig SLIR of the expressoin and attach it to the
|
||||
/// given module.
|
||||
///
|
||||
/// \param ns The namespace that current expression is in it.
|
||||
/// \param m The target MLIR moduleOp to attach the operations to
|
||||
virtual void generateIR(serene::Namespace &ns, mlir::ModuleOp &m) = 0;
|
||||
};
|
||||
|
||||
/// Create a new `node` of type `T` and forwards any given parameter
|
||||
/// to the constructor of type `T`. This is the **official way** to create
|
||||
/// a new `Expression`. Here is an example:
|
||||
/// \code
|
||||
/// auto list = make<List>();
|
||||
/// \endcode
|
||||
///
|
||||
/// \param[args] Any argument with any type passed to this function will be
|
||||
/// passed to the constructor of type T.
|
||||
/// \return A unique pointer to an Expression
|
||||
template <typename T, typename... Args>
|
||||
Node make(Args &&...args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
};
|
||||
/// Create a new `node` of type `T` and forwards any given parameter
|
||||
/// to the constructor of type `T`. This is the **official way** to create
|
||||
/// a new `Expression`. Here is an example:
|
||||
/// \code
|
||||
/// auto list = makeAndCast<List>();
|
||||
/// \endcode
|
||||
///
|
||||
/// \param[args] Any argument with any type passed to this function will be
|
||||
/// passed to the constructor of type T.
|
||||
/// \return A unique pointer to a value of type T.
|
||||
template <typename T, typename... Args>
|
||||
std::shared_ptr<T> makeAndCast(Args &&...args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
};
|
||||
|
||||
/// The helper function to create a new `Node` and use that as the success case
|
||||
// of a `Result`. It should be useds where every we want to return a `MaybeNode`
|
||||
/// successfully
|
||||
template <typename T, typename... Args>
|
||||
Result<Node, errors::ErrorTree> makeSuccessfulNode(Args &&...args) {
|
||||
return Result<Node, errors::ErrorTree>::success(
|
||||
make<T>(std::forward<Args>(args)...));
|
||||
};
|
||||
|
||||
/// The hlper function to create an Errorful `Result<T,...>` (`T` would be
|
||||
/// either `Node` or `Ast` most of the time) with just one error created from
|
||||
/// passing any argument to this function to the `serene::errors::Error`
|
||||
/// constructor.
|
||||
template <typename T, typename... Args>
|
||||
Result<T, errors::ErrorTree> makeErrorful(Args &&...args) {
|
||||
std::vector<errors::ErrorPtr> v{
|
||||
std::move(makeAndCast<errors::Error>(std::forward<Args>(args)...))};
|
||||
return Result<T, errors::ErrorTree>::error(v);
|
||||
};
|
||||
|
||||
/// The hlper function to create an Error node (The failure case of a MaybeNod)
|
||||
/// with just one error created from passing any argument to this function to
|
||||
/// the `serene::errors::Error` constructor.
|
||||
template <typename... Args>
|
||||
MaybeNode makeErrorNode(Args &&...args) {
|
||||
std::vector<errors::ErrorPtr> v{
|
||||
std::move(makeAndCast<errors::Error>(std::forward<Args>(args)...))};
|
||||
return MaybeNode::error(v);
|
||||
};
|
||||
|
||||
/// Convert the given AST to string by calling the `toString` method
|
||||
/// of each node.
|
||||
SERENE_EXPORT std::string astToString(const Ast *);
|
||||
/// Converts the given ExprType to string.
|
||||
std::string stringifyExprType(ExprType);
|
||||
|
||||
/// Converts the given AST to string and prints it out
|
||||
void dump(Ast &);
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_FN_H
|
||||
#define SERENE_EXPRS_FN_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/exprs/list.h"
|
||||
#include "serene/namespace.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/Support/Error.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace exprs {
|
||||
class List;
|
||||
|
||||
/// This data structure represents a function. with a collection of
|
||||
/// arguments and the ast of a body
|
||||
class Fn : public Expression {
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
|
||||
// TODO: Use a coll type instead of a list here
|
||||
List args;
|
||||
Ast body;
|
||||
|
||||
Fn(SereneContext &ctx, reader::LocationRange &loc, List &args, Ast body);
|
||||
|
||||
Fn(Fn &f) = delete;
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
MaybeNode analyze(SereneContext & /*ctx*/) override;
|
||||
void generateIR(serene::Namespace & /*ns*/, mlir::ModuleOp & /*m*/) override;
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
|
||||
/// Creates a function node out of a function definition
|
||||
/// in a list. the list has to contain the correct definition
|
||||
/// of a function, for exmaple: `(fn (args1 arg2) body)`.This function
|
||||
/// is supposed to be used in the semantic analysis phase.
|
||||
///
|
||||
/// \param ctx The semantic analysis context object.
|
||||
/// \param list the list containing the `fn` form
|
||||
static MaybeNode make(SereneContext &ctx, List *list);
|
||||
|
||||
void setName(std::string);
|
||||
~Fn() = default;
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_LIST_H
|
||||
#define SERENE_EXPRS_LIST_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
|
||||
#include <llvm/ADT/Optional.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace exprs {
|
||||
|
||||
/// This class represents a List in the AST level and not the List as the data
|
||||
/// type.
|
||||
class List : public Expression {
|
||||
public:
|
||||
// Internal elements of the lest (small vector of shared pointers to
|
||||
// expressions)
|
||||
Ast elements;
|
||||
|
||||
List(const List &l); // Copy ctor
|
||||
List(List &&e) noexcept = default; // Move ctor
|
||||
|
||||
List(const reader::LocationRange &loc) : Expression(loc){};
|
||||
List(const reader::LocationRange &loc, Node &e);
|
||||
List(const reader::LocationRange &loc, Ast elems);
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
|
||||
void append(Node);
|
||||
|
||||
size_t count() const;
|
||||
|
||||
Ast from(uint index);
|
||||
|
||||
llvm::Optional<Expression *> at(uint index);
|
||||
|
||||
/// Return an iterator to be used with the `for` loop. It's implicitly called
|
||||
/// by the for loop.
|
||||
std::vector<Node>::const_iterator cbegin();
|
||||
|
||||
/// Return an iterator to be used with the `for` loop. It's implicitly called
|
||||
/// by the for loop.
|
||||
std::vector<Node>::const_iterator cend();
|
||||
|
||||
/// Return an iterator to be used with the `for` loop. It's implicitly called
|
||||
/// by the for loop.
|
||||
std::vector<Node>::iterator begin();
|
||||
|
||||
/// Return an iterator to be used with the `for` loop. It's implicitly called
|
||||
/// by the for loop.
|
||||
std::vector<Node>::iterator end();
|
||||
|
||||
MaybeNode analyze(SereneContext &ctx) override;
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
void generateIR(serene::Namespace &, mlir::ModuleOp &) override{};
|
||||
|
||||
~List() = default;
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_NUMBER_H
|
||||
#define SERENE_EXPRS_NUMBER_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/namespace.h"
|
||||
|
||||
#include <llvm/Support/FormatVariadic.h>
|
||||
|
||||
namespace serene {
|
||||
namespace exprs {
|
||||
|
||||
/// This data structure represent a number. I handles float points, integers,
|
||||
/// positive and negative numbers. This is not a data type representative.
|
||||
/// So it won't cast to actual numeric types and it has a string container
|
||||
/// to hold the parsed value.
|
||||
struct Number : public Expression {
|
||||
|
||||
// TODO: Use a variant here instead to store different number types
|
||||
std::string value;
|
||||
|
||||
bool isNeg;
|
||||
bool isFloat;
|
||||
|
||||
Number(reader::LocationRange &loc, const std::string &num, bool isNeg,
|
||||
bool isFloat)
|
||||
: Expression(loc), value(num), isNeg(isNeg), isFloat(isFloat){};
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
|
||||
MaybeNode analyze(SereneContext &ctx) override;
|
||||
void generateIR(serene::Namespace & /*ns*/, mlir::ModuleOp & /*m*/) override;
|
||||
|
||||
// TODO: This is horrible, we need to fix it after the mvp
|
||||
int toI64() const;
|
||||
|
||||
~Number() = default;
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_SYMBOL_H
|
||||
#define SERENE_EXPRS_SYMBOL_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
|
||||
namespace exprs {
|
||||
|
||||
/// This data structure represent the Lisp symbol. Just a symbol
|
||||
/// in the context of the AST and nothing else.
|
||||
class Symbol : public Expression {
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
|
||||
Symbol(reader::LocationRange &loc, llvm::StringRef name)
|
||||
: Expression(loc), name(name){};
|
||||
|
||||
Symbol(Symbol &s) : Expression(s.location) { this->name = s.name; }
|
||||
|
||||
ExprType getType() const override;
|
||||
std::string toString() const override;
|
||||
|
||||
MaybeNode analyze(SereneContext & /*ctx*/) override;
|
||||
void generateIR(serene::Namespace & /*ns*/,
|
||||
mlir::ModuleOp & /*m*/) override{};
|
||||
|
||||
~Symbol() = default;
|
||||
|
||||
static bool classof(const Expression *e);
|
||||
};
|
||||
|
||||
} // namespace exprs
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_EXPRS_TRAITS_H
|
||||
#define SERENE_EXPRS_TRAITS_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/reader/location.h"
|
||||
#include "serene/reader/traits.h"
|
||||
#include "serene/traits.h"
|
||||
#include "serene/utils.h"
|
||||
|
||||
namespace serene::exprs {
|
||||
/// This enum represent the expression type and **not** the value type.
|
||||
enum class ExprType {
|
||||
Symbol,
|
||||
List,
|
||||
Number,
|
||||
Def,
|
||||
Error,
|
||||
Fn,
|
||||
Call,
|
||||
};
|
||||
|
||||
/// The string represantion of built in expr types (NOT DATATYPES).
|
||||
static const char *exprTypes[] = {
|
||||
"Symbol", "List", "Number", "Def", "Error", "Fn", "Call",
|
||||
};
|
||||
|
||||
}; // namespace serene::exprs
|
||||
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Commentary:
|
||||
*/
|
||||
|
||||
#ifndef SERENE_JIT_H
|
||||
#define SERENE_JIT_H
|
||||
|
||||
#include "serene/errors.h"
|
||||
#include "serene/export.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/namespace.h"
|
||||
#include "serene/slir/generatable.h"
|
||||
#include "serene/utils.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/ExecutionEngine/JITEventListener.h>
|
||||
#include <llvm/ExecutionEngine/ObjectCache.h>
|
||||
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
|
||||
#include <llvm/Support/CodeGen.h>
|
||||
#include <llvm/Support/Debug.h>
|
||||
#include <mlir/Support/LLVM.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define JIT_LOG(...) \
|
||||
DEBUG_WITH_TYPE("JIT", llvm::dbgs() << "[JIT]: " << __VA_ARGS__ << "\n");
|
||||
|
||||
namespace serene {
|
||||
class SERENE_EXPORT JIT;
|
||||
|
||||
using MaybeJIT = llvm::Optional<std::unique_ptr<JIT>>;
|
||||
|
||||
/// A simple object cache following Lang's LLJITWithObjectCache example and
|
||||
/// MLIR's SimpelObjectCache.
|
||||
class ObjectCache : public llvm::ObjectCache {
|
||||
public:
|
||||
/// Cache the given `objBuffer` for the given module `m`. The buffer contains
|
||||
/// the combiled objects of the module
|
||||
void notifyObjectCompiled(const llvm::Module *m,
|
||||
llvm::MemoryBufferRef objBuffer) override;
|
||||
|
||||
// Lookup the cache for the given module `m` or returen a nullptr.
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module *m) override;
|
||||
|
||||
/// Dump cached object to output file `filename`.
|
||||
void dumpToObjectFile(llvm::StringRef filename);
|
||||
|
||||
private:
|
||||
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> cachedObjects;
|
||||
};
|
||||
|
||||
class JIT {
|
||||
// TODO: Should the JIT own the context ???
|
||||
Namespace &ns;
|
||||
|
||||
std::unique_ptr<llvm::orc::LLJIT> engine;
|
||||
|
||||
std::unique_ptr<ObjectCache> cache;
|
||||
|
||||
/// GDB notification listener.
|
||||
llvm::JITEventListener *gdbListener;
|
||||
|
||||
/// Perf notification listener.
|
||||
llvm::JITEventListener *perfListener;
|
||||
|
||||
public:
|
||||
JIT(Namespace &ns, bool enableObjectCache = true,
|
||||
bool enableGDBNotificationListener = true,
|
||||
bool enablePerfNotificationListener = true);
|
||||
|
||||
static MaybeJIT
|
||||
make(Namespace &ns, mlir::ArrayRef<llvm::StringRef> sharedLibPaths = {},
|
||||
mlir::Optional<llvm::CodeGenOpt::Level> jitCodeGenOptLevel = llvm::None,
|
||||
bool enableObjectCache = true, bool enableGDBNotificationListener = true,
|
||||
bool enablePerfNotificationListener = true);
|
||||
|
||||
/// Looks up a packed-argument function with the given name and returns a
|
||||
/// pointer to it. Propagates errors in case of failure.
|
||||
llvm::Expected<void (*)(void **)> lookup(llvm::StringRef name) const;
|
||||
|
||||
/// Invokes the function with the given name passing it the list of opaque
|
||||
/// pointers to the actual arguments.
|
||||
llvm::Error
|
||||
invokePacked(llvm::StringRef name,
|
||||
llvm::MutableArrayRef<void *> args = llvm::None) const;
|
||||
|
||||
/// Trait that defines how a given type is passed to the JIT code. This
|
||||
/// defaults to passing the address but can be specialized.
|
||||
template <typename T>
|
||||
struct Argument {
|
||||
static void pack(llvm::SmallVectorImpl<void *> &args, T &val) {
|
||||
args.push_back(&val);
|
||||
}
|
||||
};
|
||||
|
||||
/// Tag to wrap an output parameter when invoking a jitted function.
|
||||
template <typename T>
|
||||
struct FnResult {
|
||||
FnResult(T &result) : value(result) {}
|
||||
T &value;
|
||||
};
|
||||
|
||||
/// Helper function to wrap an output operand when using
|
||||
/// ExecutionEngine::invoke.
|
||||
template <typename T>
|
||||
static FnResult<T> result(T &t) {
|
||||
return FnResult<T>(t);
|
||||
}
|
||||
|
||||
// Specialization for output parameter: their address is forwarded directly to
|
||||
// the native code.
|
||||
template <typename T>
|
||||
struct Argument<Result<T>> {
|
||||
static void pack(llvm::SmallVectorImpl<void *> &args, FnResult<T> &result) {
|
||||
args.push_back(&result.value);
|
||||
}
|
||||
};
|
||||
|
||||
/// Invokes the function with the given name passing it the list of arguments
|
||||
/// by value. Function result can be obtain through output parameter using the
|
||||
/// `FnResult` wrapper defined above. For example:
|
||||
///
|
||||
/// func @foo(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface }
|
||||
///
|
||||
/// can be invoked:
|
||||
///
|
||||
/// int32_t result = 0;
|
||||
/// llvm::Error error = jit->invoke("foo", 42,
|
||||
/// result(result));
|
||||
template <typename... Args>
|
||||
llvm::Error invoke(llvm::StringRef funcName, Args... args) {
|
||||
const std::string adapterName = std::string("") + funcName.str();
|
||||
llvm::SmallVector<void *> argsArray;
|
||||
// Pack every arguments in an array of pointers. Delegate the packing to a
|
||||
// trait so that it can be overridden per argument type.
|
||||
// TODO: replace with a fold expression when migrating to C++17.
|
||||
int dummy[] = {0, ((void)Argument<Args>::pack(argsArray, args), 0)...};
|
||||
(void)dummy;
|
||||
return invokePacked(adapterName, argsArray);
|
||||
};
|
||||
|
||||
/// Dump object code to output file `filename`.
|
||||
void dumpToObjectFile(llvm::StringRef filename);
|
||||
|
||||
/// Register symbols with this ExecutionEngine.
|
||||
void registerSymbols(
|
||||
llvm::function_ref<llvm::orc::SymbolMap(llvm::orc::MangleAndInterner)>
|
||||
symbolMap);
|
||||
|
||||
std::unique_ptr<exprs::Expression> eval(SereneContext &ctx,
|
||||
std::string input);
|
||||
};
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef LLVM_IR_VALUE_H
|
||||
#define LLVM_IR_VALUE_H
|
||||
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#include <llvm/IR/Value.h>
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LLVM_PATCHES_H
|
||||
#define LLVM_PATCHES_H
|
||||
|
||||
#include <llvm/ADT/DenseMap.h>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Our specialization of DensMapInfo for string type. This will allow use to use
|
||||
// string
|
||||
template <>
|
||||
struct DenseMapInfo<std::string> {
|
||||
static inline std::string getEmptyKey() { return ""; }
|
||||
|
||||
static inline std::string getTombstoneKey() {
|
||||
// Maybe we need to use something else beside strings ????
|
||||
return "0TOMBED";
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const std::string &Val) {
|
||||
assert(Val != getEmptyKey() && "Cannot hash the empty key!");
|
||||
assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");
|
||||
return (unsigned)(llvm::hash_value(Val));
|
||||
}
|
||||
|
||||
static bool isEqual(const std::string &LHS, const std::string &RHS) {
|
||||
if (RHS == getEmptyKey()) {
|
||||
return LHS == getEmptyKey();
|
||||
}
|
||||
if (RHS == getTombstoneKey()) {
|
||||
return LHS == getTombstoneKey();
|
||||
}
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Commentary:
|
||||
* Rules of a namespace:
|
||||
* - A namespace has have a name and it has to own it.
|
||||
* - A namespace may or may not be assiciated with a file
|
||||
* - The internal AST of a namespace is an evergrowing tree which may expand at
|
||||
* any given time. For example via iteration of a REPL
|
||||
*/
|
||||
|
||||
#ifndef SERENE_NAMESPACE_H
|
||||
#define SERENE_NAMESPACE_H
|
||||
|
||||
#include "serene/environment.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/export.h"
|
||||
#include "serene/slir/generatable.h"
|
||||
#include "serene/traits.h"
|
||||
#include "serene/utils.h"
|
||||
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/ADT/Twine.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <mlir/IR/Builders.h>
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/OwningOpRef.h>
|
||||
#include <mlir/IR/Value.h>
|
||||
#include <mlir/Support/LogicalResult.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#define NAMESPACE_LOG(...) \
|
||||
DEBUG_WITH_TYPE("NAMESPACE", llvm::dbgs() << __VA_ARGS__ << "\n");
|
||||
|
||||
namespace serene {
|
||||
class SereneContext;
|
||||
|
||||
namespace exprs {
|
||||
class Expression;
|
||||
using Node = std::shared_ptr<Expression>;
|
||||
using Ast = std::vector<Node>;
|
||||
} // namespace exprs
|
||||
|
||||
using MaybeModule = llvm::Optional<std::unique_ptr<llvm::Module>>;
|
||||
using MaybeModuleOp = llvm::Optional<mlir::OwningOpRef<mlir::ModuleOp>>;
|
||||
|
||||
/// Serene's namespaces are the unit of compilation. Any code that needs to be
|
||||
/// compiled has to be in a namespace. The official way to create a new
|
||||
/// namespace is to use the `makeNamespace` function.
|
||||
class SERENE_EXPORT Namespace {
|
||||
private:
|
||||
SereneContext &ctx;
|
||||
|
||||
// Anonymous function counter. We need to assing a unique name to each
|
||||
// anonymous function and we use this counter to generate those names
|
||||
std::atomic<uint> fn_counter = 0;
|
||||
|
||||
/// The content of the namespace. It should alway hold a semantically
|
||||
/// correct AST. It means thet the AST that we want to stor here has
|
||||
/// to pass the semantic analyzer.
|
||||
exprs::Ast tree;
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
llvm::Optional<std::string> filename;
|
||||
|
||||
/// The root environment of the namespace on the semantic analysis phase.
|
||||
/// Which is a mapping from names to AST nodes ( no evaluation ).
|
||||
Environment<std::string, exprs::Node> semanticEnv;
|
||||
|
||||
/// Th root environmanet to store the MLIR value during the IR generation
|
||||
/// phase.
|
||||
Environment<llvm::StringRef, mlir::Value> symbolTable;
|
||||
|
||||
Namespace(SereneContext &ctx, llvm::StringRef ns_name,
|
||||
llvm::Optional<llvm::StringRef> filename);
|
||||
|
||||
exprs::Ast &getTree();
|
||||
|
||||
/// Expand the current tree of the namespace with the given \p ast by
|
||||
/// semantically analazing it first. If the give \p ast in not valid
|
||||
/// it will return analysis errors.
|
||||
errors::OptionalErrors expandTree(exprs::Ast &ast);
|
||||
|
||||
/// Increase the function counter by one
|
||||
uint nextFnCounter();
|
||||
|
||||
SereneContext &getContext();
|
||||
|
||||
// TODO: Fix the return type and use a `llvm::Optional` instead
|
||||
/// Generate and return a MLIR ModuleOp tha contains the IR of the namespace
|
||||
/// with respect to the compilation phase
|
||||
MaybeModuleOp generate();
|
||||
|
||||
/// Compile the namespace to a llvm module. It will call the
|
||||
/// `generate` method of the namespace to generate the IR.
|
||||
MaybeModule compileToLLVM();
|
||||
|
||||
/// Run all the passes specified in the context on the given MLIR ModuleOp.
|
||||
mlir::LogicalResult runPasses(mlir::ModuleOp &m);
|
||||
|
||||
/// Dumps the namespace with respect to the compilation phase
|
||||
void dump();
|
||||
|
||||
void enqueueError(llvm::StringRef e) const;
|
||||
|
||||
~Namespace();
|
||||
};
|
||||
|
||||
using NSPtr = std::shared_ptr<Namespace>;
|
||||
|
||||
using MaybeNS = Result<NSPtr, errors::ErrorTree>;
|
||||
/// Create a naw namespace with the given `name` and optional `filename` and
|
||||
/// return a shared pointer to it in the given Serene context. If the
|
||||
/// `setCurrent` argument is set to true, the created NS will become the
|
||||
/// curret namespace in the context
|
||||
SERENE_EXPORT NSPtr makeNamespace(SereneContext &ctx, llvm::StringRef name,
|
||||
llvm::Optional<llvm::StringRef> filename,
|
||||
bool setCurrent = true);
|
||||
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_PASSES_H
|
||||
#define SERENE_PASSES_H
|
||||
|
||||
#include <mlir/Pass/Pass.h>
|
||||
|
||||
namespace serene::passes {
|
||||
|
||||
/// Return a pass to convert SLIR dialect to built-in dialects
|
||||
/// of MLIR.
|
||||
std::unique_ptr<mlir::Pass> createSLIRLowerToMLIRPass();
|
||||
|
||||
/// Return a pass to convert different dialects of MLIR to LLVM dialect.
|
||||
std::unique_ptr<mlir::Pass> createSLIRLowerToLLVMDialectPass();
|
||||
|
||||
} // namespace serene::passes
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,8 +16,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOCATION_H
|
||||
#define LOCATION_H
|
||||
#ifndef SERENE_READER_LOCATION_H
|
||||
#define SERENE_READER_LOCATION_H
|
||||
|
||||
#include <mlir/IR/Diagnostics.h>
|
||||
#include <mlir/IR/Location.h>
|
||||
|
@ -25,6 +25,9 @@
|
|||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
class SereneContext;
|
||||
|
||||
namespace reader {
|
||||
|
||||
/// It represents a location in the input string to the parser via `line`,
|
||||
struct Location {
|
||||
|
@ -32,7 +35,7 @@ struct Location {
|
|||
/// a namespace in hand
|
||||
llvm::StringRef ns;
|
||||
|
||||
std::optional<llvm::StringRef> filename = std::nullopt;
|
||||
llvm::Optional<llvm::StringRef> filename = llvm::None;
|
||||
/// A pointer to the character that this location is pointing to
|
||||
/// it the input buffer
|
||||
const char *c = nullptr;
|
||||
|
@ -47,23 +50,21 @@ struct Location {
|
|||
::std::string toString() const;
|
||||
|
||||
Location() = default;
|
||||
explicit Location(llvm::StringRef ns,
|
||||
std::optional<llvm::StringRef> fname = std::nullopt,
|
||||
const char *c = nullptr, unsigned short int line = 0,
|
||||
unsigned short int col = 0, bool knownLocation = true)
|
||||
Location(llvm::StringRef ns,
|
||||
llvm::Optional<llvm::StringRef> fname = llvm::None,
|
||||
const char *c = nullptr, unsigned short int line = 0,
|
||||
unsigned short int col = 0, bool knownLocation = true)
|
||||
: ns(ns), filename(fname), c(c), line(line), col(col),
|
||||
knownLocation(knownLocation){};
|
||||
|
||||
Location clone() const;
|
||||
|
||||
// mlir::Location toMLIRLocation(mlir::MLIRContext &ctx);
|
||||
mlir::Location toMLIRLocation(SereneContext &ctx);
|
||||
|
||||
/// Returns an unknown location for the given \p ns.
|
||||
static Location UnknownLocation(llvm::StringRef ns) {
|
||||
return Location(ns, std::nullopt, nullptr, 0, 0, false);
|
||||
return Location(ns, llvm::None, nullptr, 0, 0, false);
|
||||
}
|
||||
|
||||
~Location() = default;
|
||||
};
|
||||
|
||||
class LocationRange {
|
||||
|
@ -72,25 +73,20 @@ public:
|
|||
Location end;
|
||||
|
||||
LocationRange() = default;
|
||||
explicit LocationRange(Location _start) : start(_start), end(_start){};
|
||||
LocationRange(Location _start) : start(_start), end(_start){};
|
||||
LocationRange(Location _start, Location _end) : start(_start), end(_end){};
|
||||
// LocationRange(const LocationRange &);
|
||||
|
||||
LocationRange(LocationRange &lr) : start(lr.start), end(lr.end){};
|
||||
|
||||
LocationRange(const LocationRange &lr) : start(lr.start), end(lr.end){};
|
||||
|
||||
bool isKnownLocation() const { return start.knownLocation; };
|
||||
|
||||
static LocationRange UnknownLocation(llvm::StringRef ns) {
|
||||
return LocationRange(Location::UnknownLocation(ns));
|
||||
}
|
||||
|
||||
~LocationRange() = default;
|
||||
};
|
||||
|
||||
void incLocation(Location &, const char *);
|
||||
void decLocation(Location &, const char *);
|
||||
|
||||
} // namespace reader
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,8 +18,8 @@
|
|||
|
||||
/**
|
||||
* Commentary:
|
||||
* `Reader` is the base parser class and accepts a buffer like object (usually
|
||||
* `llvm::StringRef`) as the input and parses it to create an AST (look at the
|
||||
* `Reader` is the base parser class and accepts a buffer like objenct (usually
|
||||
* `llvm::StringRef`) as the input and parsess it to create an AST (look at the
|
||||
* `serene::exprs::Expression` class).
|
||||
*
|
||||
* The parsing algorithm is quite simple and it is a LL(2). It means that, we
|
||||
|
@ -34,37 +34,50 @@
|
|||
* case contains the node and an `Error` on the failure case.
|
||||
*/
|
||||
|
||||
#ifndef READER_H
|
||||
#define READER_H
|
||||
#ifndef SERENE_READER_READER_H
|
||||
#define SERENE_READER_READER_H
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "location.h"
|
||||
#include "serene/errors.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/exprs/list.h"
|
||||
#include "serene/exprs/symbol.h"
|
||||
#include "serene/reader/location.h"
|
||||
#include "serene/serene.h"
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <system_error>
|
||||
|
||||
#include <llvm/Support/Debug.h>
|
||||
#include <llvm/Support/MemoryBuffer.h>
|
||||
#include <llvm/Support/MemoryBufferRef.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define READER_LOG(...) \
|
||||
DEBUG_WITH_TYPE("READER", llvm::dbgs() \
|
||||
<< "[READER]: " << __VA_ARGS__ << "\n");
|
||||
|
||||
namespace serene {
|
||||
namespace jit {
|
||||
class JIT;
|
||||
} // namespace jit
|
||||
namespace serene::reader {
|
||||
|
||||
/// Base reader class which reads from a string directly.
|
||||
class Reader {
|
||||
private:
|
||||
llvm::StringRef ns;
|
||||
std::optional<llvm::StringRef> filename;
|
||||
SereneContext &ctx;
|
||||
|
||||
const char *currentChar = nullptr;
|
||||
llvm::StringRef ns;
|
||||
llvm::Optional<llvm::StringRef> filename;
|
||||
|
||||
const char *currentChar = NULL;
|
||||
|
||||
llvm::StringRef buf;
|
||||
|
||||
/// The position tracker that we will use to determine the end of the
|
||||
/// buffer since the buffer might not be null terminated
|
||||
size_t currentPos = static_cast<size_t>(-1);
|
||||
size_t currentPos = -1;
|
||||
|
||||
Location currentLocation;
|
||||
|
||||
|
@ -85,36 +98,38 @@ private:
|
|||
static bool isValidForIdentifier(char c);
|
||||
|
||||
// The property to store the ast tree
|
||||
ast::Ast ast;
|
||||
exprs::Ast ast;
|
||||
|
||||
ast::MaybeNode readSymbol();
|
||||
ast::MaybeNode readNumber(bool);
|
||||
ast::MaybeNode readList();
|
||||
ast::MaybeNode readExpr();
|
||||
exprs::MaybeNode readSymbol();
|
||||
exprs::MaybeNode readNumber(bool);
|
||||
exprs::MaybeNode readList();
|
||||
exprs::MaybeNode readExpr();
|
||||
|
||||
bool isEndOfBuffer(const char *);
|
||||
|
||||
public:
|
||||
Reader(llvm::StringRef buf, llvm::StringRef ns,
|
||||
std::optional<llvm::StringRef> filename);
|
||||
Reader(llvm::MemoryBufferRef buf, llvm::StringRef ns,
|
||||
std::optional<llvm::StringRef> filename);
|
||||
Reader(SereneContext &ctx, llvm::StringRef buf, llvm::StringRef ns,
|
||||
llvm::Optional<llvm::StringRef> filename);
|
||||
Reader(SereneContext &ctx, llvm::MemoryBufferRef buf, llvm::StringRef ns,
|
||||
llvm::Optional<llvm::StringRef> filename);
|
||||
|
||||
// void setInput(const llvm::StringRef string);
|
||||
|
||||
/// Parses the the input and creates a possible AST out of it or errors
|
||||
/// otherwise.
|
||||
ast::MaybeAst read();
|
||||
exprs::MaybeAst read();
|
||||
|
||||
~Reader();
|
||||
};
|
||||
|
||||
/// Parses the given `input` string and returns a `Result<ast>`
|
||||
/// which may contains an AST or an `llvm::Error`
|
||||
ast::MaybeAst read(llvm::StringRef input, llvm::StringRef ns,
|
||||
std::optional<llvm::StringRef> filename);
|
||||
ast::MaybeAst read(llvm::MemoryBufferRef input, llvm::StringRef ns,
|
||||
std::optional<llvm::StringRef> filename);
|
||||
exprs::MaybeAst read(SereneContext &ctx, llvm::StringRef input,
|
||||
llvm::StringRef ns,
|
||||
llvm::Optional<llvm::StringRef> filename);
|
||||
exprs::MaybeAst read(SereneContext &ctx, llvm::MemoryBufferRef input,
|
||||
llvm::StringRef ns,
|
||||
llvm::Optional<llvm::StringRef> filename);
|
||||
} // namespace serene::reader
|
||||
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_READER_SEMANTICS_H
|
||||
#define SERENE_READER_SEMANTICS_H
|
||||
|
||||
#include "serene/context.h"
|
||||
#include "serene/errors/error.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
|
||||
namespace serene::reader {
|
||||
using AnalyzeResult = Result<exprs::Ast, std::vector<errors::ErrorPtr>>;
|
||||
/// The entry point to the Semantic analysis phase. It calls the `analyze`
|
||||
/// method of each node in the given AST and creates a new AST that contains a
|
||||
/// more comprehensive set of nodes in a semantically correct AST. If the
|
||||
/// `analyze` method of a node return a `nullptr` value as the `success` result
|
||||
/// (Checkout the `Result` type in `utils.h`) then the original node will be
|
||||
/// used instead. Also please note that in **Serene** Semantic errors
|
||||
/// represented as AST nodes as well. So you should expect an `analyze` method
|
||||
/// of a node to return a `Result<node>::Success(Error...)` in case of a
|
||||
/// semantic error.
|
||||
///
|
||||
/// \param ctx The semantic analysis context
|
||||
/// \param inputAst The raw AST to analyze and possibly rewrite.
|
||||
AnalyzeResult analyze(serene::SereneContext &ctx, exprs::Ast &inputAst);
|
||||
}; // namespace serene::reader
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_READER_TRAITS_H
|
||||
#define SERENE_READER_TRAITS_H
|
||||
|
||||
#include "serene/reader/location.h"
|
||||
#include "serene/traits.h"
|
||||
|
||||
namespace serene::reader {
|
||||
|
||||
template <typename ConcreteType>
|
||||
class ILocatable : public TraitBase<ConcreteType, ILocatable> {
|
||||
public:
|
||||
ILocatable(){};
|
||||
ILocatable(const ILocatable &) = delete;
|
||||
serene::reader::LocationRange &where() const {
|
||||
return this->Object().where();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
serene::reader::LocationRange &where(ILocatable<T> &);
|
||||
} // namespace serene::reader
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_SERENE_H
|
||||
#define SERENE_SERENE_H
|
||||
|
||||
#include "serene/config.h"
|
||||
#include "serene/context.h"
|
||||
#include "serene/export.h"
|
||||
#include "serene/exprs/expression.h"
|
||||
#include "serene/source_mgr.h"
|
||||
|
||||
namespace serene {
|
||||
|
||||
/// Clinet applications have to call this function before any interaction with
|
||||
/// the Serene's compiler API.
|
||||
SERENE_EXPORT void initCompiler();
|
||||
|
||||
/// Register the global CLI options of the serene compiler. If the client
|
||||
/// application needs to setup the compilers options automatically use this
|
||||
/// function in conjunction with `applySereneCLOptions`.
|
||||
SERENE_EXPORT void registerSereneCLOptions();
|
||||
|
||||
/// Applies the global compiler options on the give \p SereneContext. This
|
||||
/// function has to be called after `llvm::cl::ParseCommandLineOptions`.
|
||||
SERENE_EXPORT void applySereneCLOptions(SereneContext &ctx);
|
||||
|
||||
/// Reads the the given \p input as a Serene source code in the given
|
||||
/// \c SereneContext \p ctx and returns the possible AST tree of the input or an
|
||||
/// error otherwise.
|
||||
///
|
||||
/// In case of an error Serene will throw the error messages vis the diagnostic
|
||||
/// engine as well and the error that this function returns will be the generic
|
||||
/// error message.
|
||||
///
|
||||
/// Be aware than this function reads the input in the context of the current
|
||||
/// namespace. So for example if the input is somthing like:
|
||||
///
|
||||
/// (ns example.code) ....
|
||||
///
|
||||
/// and the current ns is `user` then if there is a syntax error in the input
|
||||
/// the error will be reported under the `user` ns. This is logical because
|
||||
/// this function reads the code and not evaluate it. the `ns` form has to be
|
||||
/// evaluated in order to change the ns.
|
||||
SERENE_EXPORT exprs::MaybeAst read(SereneContext &ctx, std::string &input);
|
||||
|
||||
/// Evaluates the given AST form \p input in the given \c SereneContext \p ctx
|
||||
/// and retuns a new expression as the result or a possible error.
|
||||
///
|
||||
/// In case of an error Serene will throw the error messages vis the diagnostic
|
||||
/// engine as well and the error that this function returns will be the
|
||||
/// generic error message.
|
||||
// SERENE_EXPORT exprs::MaybeNode eval(SereneContext &ctx, exprs::Ast input);
|
||||
|
||||
// TODO: Return a Serene String type instead of the std::string
|
||||
// TODO: Create an overload to get a stream instead of the result string
|
||||
/// Prints the given AST form \p input in the given \c SereneContext \p ctx
|
||||
/// into the given \p result.
|
||||
/// Note: print is a lisp action. Don't confuse it with a print function such
|
||||
/// as `println`.
|
||||
SERENE_EXPORT void print(SereneContext &ctx, const exprs::Ast &input,
|
||||
std::string &result);
|
||||
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
set(LLVM_TARGET_DEFINITIONS dialect.td)
|
||||
mlir_tablegen(ops.h.inc -gen-op-decls)
|
||||
mlir_tablegen(ops.cpp.inc -gen-op-defs)
|
||||
mlir_tablegen(dialect.h.inc -gen-dialect-decls)
|
||||
mlir_tablegen(dialect.cpp.inc -gen-dialect-defs)
|
||||
add_public_tablegen_target(SereneDialectGen)
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SERENE_SLIR_DIALECT_H
|
||||
#define SERENE_SLIR_DIALECT_H
|
||||
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/Dialect.h>
|
||||
#include <mlir/Interfaces/ControlFlowInterfaces.h>
|
||||
#include <mlir/Interfaces/SideEffectInterfaces.h>
|
||||
|
||||
// Include the auto-generated header file containing the declaration of the
|
||||
// serene's dialect.
|
||||
#include "serene/slir/dialect.h.inc"
|
||||
|
||||
// Include the auto-generated header file containing the declarations of the
|
||||
// serene's operations.
|
||||
// for more on GET_OP_CLASSES: https://mlir.llvm.org/docs/OpDefinitions/
|
||||
#define GET_OP_CLASSES
|
||||
|
||||
#include "serene/slir/ops.h.inc"
|
||||
|
||||
#endif // SERENE_SLIR_DIALECT_H
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef SERENE_DIALECT
|
||||
#define SERENE_DIALECT
|
||||
|
||||
include "mlir/IR/OpBase.td"
|
||||
include "mlir/IR/OpAsmInterface.td"
|
||||
include "mlir/IR/SymbolInterfaces.td"
|
||||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||
include "mlir/Interfaces/CallInterfaces.td"
|
||||
include "mlir/Interfaces/CastInterfaces.td"
|
||||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||
include "mlir/Interfaces/ControlFlowInterfaces.td"
|
||||
include "mlir/Interfaces/DataLayoutInterfaces.td"
|
||||
include "mlir/Interfaces/VectorInterfaces.td"
|
||||
|
||||
|
||||
// Dialect definition. It will directly generate the SereneDialect class
|
||||
def Serene_Dialect : Dialect {
|
||||
let name = "serene";
|
||||
let cppNamespace = "::serene::slir";
|
||||
let summary = "Primary IR of serene language.";
|
||||
let description = [{
|
||||
This dialect tries to map the special forms of a lisp into
|
||||
IR level operations.
|
||||
}];
|
||||
}
|
||||
|
||||
// Base class for Serene dialect operations. This operation inherits from the base
|
||||
// `Op` class in OpBase.td, and provides:
|
||||
// * The parent dialect of the operation.
|
||||
// * The mnemonic for the operation, or the name without the dialect prefix.
|
||||
// * A list of traits for the operation.
|
||||
class Serene_Op<string mnemonic, list<OpTrait> traits = []> :
|
||||
Op<Serene_Dialect, mnemonic, traits>;
|
||||
|
||||
|
||||
// All of the types will extend this class.
|
||||
class Serene_Type<string name> : TypeDef<Serene_Dialect, name> { }
|
||||
|
||||
|
||||
def ValueOp: Serene_Op<"value"> {
|
||||
|
||||
let summary = "This operation represent a value";
|
||||
let description = [{
|
||||
ValueOp
|
||||
}];
|
||||
|
||||
let arguments = (ins I64Attr:$value);
|
||||
let results = (outs I64);
|
||||
|
||||
//let verifier = [{ return serene::sir::verify(*this); }];
|
||||
|
||||
let builders = [
|
||||
OpBuilder<(ins "int":$value), [{
|
||||
// Build from fix 64 bit int
|
||||
build(odsBuilder, odsState, odsBuilder.getI64Type(), (uint64_t) value);
|
||||
}]>,
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Add the FunctionLike trait here and include its header file in dialect.h
|
||||
def FnOp: Serene_Op<"fn", [
|
||||
AffineScope, AutomaticAllocationScope,
|
||||
IsolatedFromAbove,
|
||||
]> {
|
||||
|
||||
let summary = "This operation is just a place holder for a function";
|
||||
let description = [{
|
||||
A place holder for an anonymous function. For example consider an expression
|
||||
like `(def a (fn (x) x))`, in this case we don't immediately create an anonymous
|
||||
function since we need to set the name and create the function later.
|
||||
}];
|
||||
|
||||
let arguments = (ins StrAttr:$name,
|
||||
DictionaryAttr:$args,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
|
||||
let regions = (region AnyRegion:$body);
|
||||
let results = (outs I64);
|
||||
|
||||
}
|
||||
|
||||
def ReturnOp: Serene_Op<"return", [NoSideEffect, HasParent<"FnOp">,
|
||||
ReturnLike, Terminator]> {
|
||||
|
||||
let summary = "This operation marks the return value of a function";
|
||||
let description = [{
|
||||
ReturnOp
|
||||
}];
|
||||
|
||||
let arguments = (ins AnyType:$operand);
|
||||
let assemblyFormat =
|
||||
[{ attr-dict $operand `:` type($operand) }];
|
||||
}
|
||||
|
||||
#endif // SERENE_DIALECT
|
|
@ -0,0 +1,120 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_SLIR_GENERATABLE_H
|
||||
#define SERENE_SLIR_GENERATABLE_H
|
||||
|
||||
#include "serene/slir/dialect.h"
|
||||
#include "serene/traits.h"
|
||||
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <mlir/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <mlir/ExecutionEngine/OptUtils.h>
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
#include <mlir/Support/LogicalResult.h>
|
||||
#include <mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h>
|
||||
#include <mlir/Target/LLVMIR/ModuleTranslation.h>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace serene {
|
||||
class Namespace;
|
||||
class SereneContext;
|
||||
} // namespace serene
|
||||
|
||||
namespace serene::slir {
|
||||
|
||||
template <typename T>
|
||||
class GeneratableUnit : public TraitBase<T, GeneratableUnit> {
|
||||
public:
|
||||
GeneratableUnit(){};
|
||||
GeneratableUnit(const GeneratableUnit &) = delete;
|
||||
|
||||
void generate(serene::Namespace &ns) {
|
||||
// TODO: should we return any status or possible error here or
|
||||
// should we just populate them in a ns wide state?
|
||||
this->Object().generateIR(ns);
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Generatable : public TraitBase<T, Generatable> {
|
||||
public:
|
||||
Generatable(){};
|
||||
Generatable(const Generatable &) = delete;
|
||||
|
||||
mlir::LogicalResult generate() { return this->Object().generate(); };
|
||||
mlir::LogicalResult runPasses() { return this->Object().runPasses(); };
|
||||
|
||||
mlir::ModuleOp &getModule() { return this->Object().getModule(); };
|
||||
serene::SereneContext &getContext() { return this->Object().getContext(); };
|
||||
|
||||
void dump() { this->Object().dump(); };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
mlir::LogicalResult generate(Generatable<T> &t) {
|
||||
return t.generate();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<llvm::Module> toLLVMIR(Generatable<T> &t) {
|
||||
auto &module = t.getModule();
|
||||
auto &ctx = t.getContext();
|
||||
// Register the translation to LLVM IR with the MLIR context.
|
||||
mlir::registerLLVMDialectTranslation(ctx.mlirContext);
|
||||
|
||||
// Convert the module to LLVM IR in a new LLVM IR context.
|
||||
auto llvmModule = mlir::translateModuleToLLVMIR(module, ctx.llvmContext);
|
||||
if (!llvmModule) {
|
||||
// TODO: Return a Result type instead
|
||||
llvm::errs() << "Failed to emit LLVM IR\n";
|
||||
throw std::runtime_error("Failed to emit LLVM IR\n");
|
||||
}
|
||||
|
||||
// Initialize LLVM targets.
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
|
||||
// TODO: replace this call with our own version of setupTargetTriple
|
||||
mlir::ExecutionEngine::setupTargetTriple(llvmModule.get());
|
||||
|
||||
/// Optionally run an optimization pipeline over the llvm module.
|
||||
auto optPipeline = mlir::makeOptimizingTransformer(
|
||||
/*optLevel=*/ctx.getOptimizatioLevel(), /*sizeLevel=*/0,
|
||||
/*targetMachine=*/nullptr);
|
||||
if (auto err = optPipeline(llvmModule.get())) {
|
||||
llvm::errs() << "Failed to optimize LLVM IR " << err << "\n";
|
||||
throw std::runtime_error("Failed to optimize LLVM IR");
|
||||
}
|
||||
|
||||
return std::move(llvmModule);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void dump(Generatable<T> &t) {
|
||||
t.dump();
|
||||
};
|
||||
|
||||
} // namespace serene::slir
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -15,16 +15,21 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SERENE_SLIR_SLIR_H
|
||||
#define SERENE_SLIR_SLIR_H
|
||||
|
||||
namespace llvm {
|
||||
class RecordKeeper;
|
||||
class raw_ostream;
|
||||
} // namespace llvm
|
||||
#include "serene/exprs/expression.h"
|
||||
|
||||
#define DEBUG_TYPE "errors-backend"
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace serene {
|
||||
|
||||
void emitErrors(llvm::RecordKeeper &rk, llvm::raw_ostream &os);
|
||||
|
||||
namespace slir {
|
||||
std::unique_ptr<llvm::Module> compileToLLVMIR(serene::SereneContext &ctx,
|
||||
mlir::ModuleOp &module);
|
||||
} // namespace slir
|
||||
} // namespace serene
|
||||
|
||||
#endif
|
|
@ -0,0 +1,116 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_SLIR_TRAITS_H
|
||||
#define SERENE_SLIR_TRAITS_H
|
||||
|
||||
#include "serene/slir/dialect.h"
|
||||
#include "serene/traits.h"
|
||||
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <mlir/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <mlir/ExecutionEngine/OptUtils.h>
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
#include <mlir/Support/LogicalResult.h>
|
||||
#include <mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h>
|
||||
#include <mlir/Target/LLVMIR/ModuleTranslation.h>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace serene {
|
||||
class Namespace;
|
||||
class SereneContext;
|
||||
} // namespace serene
|
||||
|
||||
namespace serene::slir {
|
||||
|
||||
template <typename T>
|
||||
class GeneratableUnit : public TraitBase<T, GeneratableUnit> {
|
||||
public:
|
||||
GeneratableUnit(){};
|
||||
GeneratableUnit(const GeneratableUnit &) = delete;
|
||||
|
||||
void generate(serene::Namespace &ns) { this->Object().generateIR(ns); };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Generatable : public TraitBase<T, Generatable> {
|
||||
public:
|
||||
Generatable(){};
|
||||
Generatable(const Generatable &) = delete;
|
||||
|
||||
mlir::LogicalResult generate() { return this->Object().generate(); };
|
||||
mlir::LogicalResult runPasses() { return this->Object().runPasses(); };
|
||||
|
||||
mlir::ModuleOp &getModule() { return this->Object().getModule(); };
|
||||
serene::SereneContext &getContext() { return this->Object().getContext(); };
|
||||
|
||||
void dump() { this->Object().dump(); };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
mlir::LogicalResult generate(Generatable<T> &t) {
|
||||
return t.generate();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<llvm::Module> toLLVMIR(Generatable<T> &t) {
|
||||
auto &module = t.getModule();
|
||||
auto &ctx = t.getContext();
|
||||
// Register the translation to LLVM IR with the MLIR context.
|
||||
mlir::registerLLVMDialectTranslation(ctx.mlirContext);
|
||||
|
||||
// Convert the module to LLVM IR in a new LLVM IR context.
|
||||
auto llvmModule = mlir::translateModuleToLLVMIR(module, ctx.llvmContext);
|
||||
if (!llvmModule) {
|
||||
// TODO: Return a Result type instead
|
||||
llvm::errs() << "Failed to emit LLVM IR\n";
|
||||
throw std::runtime_error("Failed to emit LLVM IR\n");
|
||||
}
|
||||
|
||||
// Initialize LLVM targets.
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
|
||||
// TODO: replace this call with our own version of setupTargetTriple
|
||||
mlir::ExecutionEngine::setupTargetTriple(llvmModule.get());
|
||||
|
||||
/// Optionally run an optimization pipeline over the llvm module.
|
||||
auto optPipeline = mlir::makeOptimizingTransformer(
|
||||
/*optLevel=*/ctx.getOptimizatioLevel(), /*sizeLevel=*/0,
|
||||
/*targetMachine=*/nullptr);
|
||||
if (auto err = optPipeline(llvmModule.get())) {
|
||||
llvm::errs() << "Failed to optimize LLVM IR " << err << "\n";
|
||||
throw std::runtime_error("Failed to optimize LLVM IR");
|
||||
}
|
||||
|
||||
return std::move(llvmModule);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void dump(Generatable<T> &t) {
|
||||
t.dump();
|
||||
};
|
||||
|
||||
} // namespace serene::slir
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,16 +16,25 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "serene/core/core.h"
|
||||
#include "serene/types/types.h"
|
||||
#ifndef SERENE_SLIR_UTILS_H
|
||||
#define SERENE_SLIR_UTILS_H
|
||||
|
||||
#include <cstdio>
|
||||
#include "serene/reader/location.h"
|
||||
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
|
||||
namespace serene {
|
||||
|
||||
extern "C" int SERENE_EXPORT compile() {
|
||||
printf("compile11\n");
|
||||
return 2;
|
||||
};
|
||||
|
||||
class Namespace;
|
||||
} // namespace serene
|
||||
|
||||
namespace serene::slir {
|
||||
|
||||
/**
|
||||
* Convert a Serene location to MLIR FileLineLoc Location
|
||||
*/
|
||||
::mlir::Location toMLIRLocation(serene::Namespace &,
|
||||
serene::reader::Location &);
|
||||
|
||||
} // namespace serene::slir
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,8 +19,8 @@
|
|||
#ifndef SERENE_SOURCE_MGR_H
|
||||
#define SERENE_SOURCE_MGR_H
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "location.h"
|
||||
#include "serene/namespace.h"
|
||||
#include "serene/reader/location.h"
|
||||
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
#include <llvm/ADT/StringMap.h>
|
||||
|
@ -32,16 +32,13 @@
|
|||
#include <mlir/Support/Timing.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#define SMGR_LOG(...) \
|
||||
DEBUG_WITH_TYPE("sourcemgr", llvm::dbgs() \
|
||||
<< "[SMGR]: " << __VA_ARGS__ << "\n");
|
||||
|
||||
namespace serene {
|
||||
namespace jit {
|
||||
class JIT;
|
||||
} // namespace jit
|
||||
class SereneContext;
|
||||
|
||||
/// This class is quite similar to the `llvm::SourceMgr` in functionality. We
|
||||
/// even borrowed some of the code from the original implementation but removed
|
||||
|
@ -55,16 +52,16 @@ class JIT;
|
|||
///
|
||||
/// Later on, whenever we need to refer to the source file of a namespace for
|
||||
/// diagnosis purposes or any other purpose we can use the functions in this
|
||||
/// class to get hold of a pointer to a specific `Location` of the
|
||||
/// class to get hold of a pointer to a specific `reader::Location` of the
|
||||
/// buffer.
|
||||
///
|
||||
/// Note: Unlike the original version, SourceMgr does not handle the diagnostics
|
||||
/// and it uses the Serene's `DiagnosticEngine` for that matter.
|
||||
class SourceMgr {
|
||||
class SERENE_EXPORT SourceMgr {
|
||||
|
||||
public:
|
||||
// TODO: Make it a vector of supported suffixes
|
||||
constexpr static const char *DEFAULT_SUFFIX = "srn";
|
||||
std::string DEFAULT_SUFFIX = "srn";
|
||||
|
||||
private:
|
||||
struct SrcBuffer {
|
||||
|
@ -98,11 +95,11 @@ private:
|
|||
|
||||
/// This is the location of the parent import or unknown location if it is
|
||||
/// the main namespace
|
||||
LocationRange importLoc;
|
||||
reader::LocationRange importLoc;
|
||||
|
||||
SrcBuffer() = default;
|
||||
SrcBuffer(SrcBuffer &&) noexcept;
|
||||
SrcBuffer(const SrcBuffer &) = delete;
|
||||
SrcBuffer(const SrcBuffer &) = delete;
|
||||
SrcBuffer &operator=(const SrcBuffer &) = delete;
|
||||
~SrcBuffer();
|
||||
};
|
||||
|
@ -131,12 +128,12 @@ private:
|
|||
static std::string convertNamespaceToPath(std::string ns_name);
|
||||
|
||||
public:
|
||||
SourceMgr() = default;
|
||||
SourceMgr(const SourceMgr &) = delete;
|
||||
SourceMgr() = default;
|
||||
SourceMgr(const SourceMgr &) = delete;
|
||||
SourceMgr &operator=(const SourceMgr &) = delete;
|
||||
SourceMgr(SourceMgr &&) = default;
|
||||
SourceMgr &operator=(SourceMgr &&) = default;
|
||||
~SourceMgr() = default;
|
||||
SourceMgr &operator=(SourceMgr &&) = default;
|
||||
~SourceMgr() = default;
|
||||
|
||||
/// Set the `loadPaths` to the given \p dirs. `loadPaths` is a vector of
|
||||
/// directories that Serene will look in order to find a file that constains a
|
||||
|
@ -174,7 +171,7 @@ public:
|
|||
/// Add a new source buffer to this source manager. This takes ownership of
|
||||
/// the memory buffer.
|
||||
unsigned AddNewSourceBuffer(std::unique_ptr<llvm::MemoryBuffer> f,
|
||||
const LocationRange &includeLoc);
|
||||
reader::LocationRange includeLoc);
|
||||
|
||||
/// Lookup for a file containing the namespace definition of with given
|
||||
/// namespace name \p name. In case that the file exists, it returns an
|
||||
|
@ -184,7 +181,8 @@ public:
|
|||
///
|
||||
/// \p importLoc is a location in the source code where the give namespace is
|
||||
/// imported.
|
||||
ast::MaybeNS readNamespace(std::string name, const LocationRange &importLoc);
|
||||
MaybeNS readNamespace(SereneContext &ctx, std::string name,
|
||||
reader::LocationRange importLoc);
|
||||
};
|
||||
|
||||
}; // namespace serene
|
|
@ -0,0 +1,122 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a CRTP based Trait implementation that allows to use Trait like
|
||||
* classes to create polymorphic functions and API statically at compile type
|
||||
* without any runtime shenanigans. For more on CRTP checkout:
|
||||
*
|
||||
* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
|
||||
*
|
||||
* In order to define a trait, use the `TraitBase` class like:
|
||||
|
||||
* \code
|
||||
* template <typename ConcreteType>
|
||||
* class Blahable : public TraitBase<ConcreteType, Blahable> {}
|
||||
* \endcode
|
||||
*
|
||||
* Every Trait has to take the `ConcreteType` as template argument and pass it
|
||||
* to the `TraitBase`. Checkout the documentation of `TraitBase` for more info
|
||||
* on creating a new Trait.
|
||||
*
|
||||
* Alongside with each Trait type, you should provide the "Official" interface
|
||||
* of the Trait via some standalone functions that operates on the Trait type.
|
||||
* For example Imagine we have a Trait type called `ABC` with two main
|
||||
* functionality `foo` and `bar`. We need to create two functions as follows:
|
||||
*
|
||||
* \code
|
||||
* template <typename T>
|
||||
* SomeType Foo(ABC<T> &t) { return t.foo(); };
|
||||
*
|
||||
* template <typename T>
|
||||
* SomeType bar(ABC<T> &t, int x) { return t.bar(x); };
|
||||
* \endcode
|
||||
*
|
||||
* These two functions will be the official interface to the trait `ABC`.
|
||||
* IMPORTANT NOTE: Make sure to pass a reference of type `ABC<T>` to the
|
||||
* functions and DO NOT PASS BY COPY. Since copying will copy the value by the
|
||||
* trait type only, we would not be able to statically case it to the
|
||||
* implementor type and it will lead to some allocation problem.
|
||||
*
|
||||
* Traits can be used via `WithTrait` helper class which provides a clean
|
||||
* interface to mix and match Trait types.
|
||||
*
|
||||
*/
|
||||
#ifndef SERENE_TRAITS_H
|
||||
#define SERENE_TRAITS_H
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace serene {
|
||||
|
||||
/// A placeholder structure that replaces the concrete type of the
|
||||
/// Imlementations Which might have child classes.
|
||||
struct FinalImpl;
|
||||
|
||||
/// In order to use Traits, we can use `WithTrait` class as the base
|
||||
/// of any implementation class and pass the Trait classes as template argument
|
||||
/// for example:
|
||||
///
|
||||
/// \code
|
||||
/// class Expression : public WithTrait<Expression, Printable, Locatable> {}
|
||||
/// \endcode
|
||||
template <typename ConcreteType, template <typename T> class... Traits>
|
||||
class WithTrait : public Traits<ConcreteType>... {
|
||||
protected:
|
||||
WithTrait(){};
|
||||
friend ConcreteType;
|
||||
};
|
||||
|
||||
/// This class provides the common functionality among the Trait Types and
|
||||
/// every Trait has to inherit from this class. Here is an example:
|
||||
///
|
||||
/// \code
|
||||
/// template <typename ConcreteType>
|
||||
/// class Blahable : public TraitBase<ConcreteType, Blahable> {}
|
||||
/// \endcode
|
||||
///
|
||||
/// In the Trait class the underlaying object which implements the Trait
|
||||
/// is accessable via the `Object` method.
|
||||
template <typename ConcreteType, template <typename> class TraitType>
|
||||
class TraitBase {
|
||||
protected:
|
||||
/// Statically casts the object to the concrete type object to be
|
||||
/// used in the Trait Types.
|
||||
// const ConcreteType &Object() const {
|
||||
// return static_cast<const ConcreteType &>(*this);
|
||||
// };
|
||||
|
||||
ConcreteType &Object() { return static_cast<ConcreteType &>(*this); };
|
||||
};
|
||||
|
||||
template <typename ConcreteType>
|
||||
class IDebuggable : public TraitBase<ConcreteType, IDebuggable> {
|
||||
public:
|
||||
IDebuggable(){};
|
||||
IDebuggable(const IDebuggable &) = delete;
|
||||
std::string toString() const { return this->Object().toString(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::string toString(IDebuggable<T> &t) {
|
||||
return t.toString();
|
||||
}
|
||||
|
||||
}; // namespace serene
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,8 +16,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "reader.h"
|
||||
#ifndef SERENE_TRAITS_LOCATABLE_H
|
||||
#define SERENE_TRAITS_LOCATABLE_H
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(Reader, ReadNumber) { EXPECT_EQ(1, 1); }
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,12 +16,20 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERENE_COMMANDS_H
|
||||
#define SERENE_COMMANDS_H
|
||||
#ifndef SERENE_TYPES_TYPE_H
|
||||
#define SERENE_TYPES_TYPE_H
|
||||
|
||||
namespace serene::commands {
|
||||
int cc(int argc, char **argv);
|
||||
int run();
|
||||
} // namespace serene::commands
|
||||
#include <string>
|
||||
|
||||
namespace serene::types {
|
||||
|
||||
class Type {
|
||||
public:
|
||||
virtual ~Type() = default;
|
||||
|
||||
/// The AST representation of a type
|
||||
virtual std::string toString() const = 0;
|
||||
};
|
||||
}; // namespace serene::types
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,8 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
#ifndef SERENE_UTILS_H
|
||||
#define SERENE_UTILS_H
|
||||
|
||||
#include "serene/export.h"
|
||||
|
||||
#include <llvm/Support/Error.h>
|
||||
|
||||
|
@ -56,7 +58,7 @@ namespace serene {
|
|||
///
|
||||
/// works perfectly.
|
||||
template <typename T, typename E = llvm::Error>
|
||||
class Result {
|
||||
class SERENE_EXPORT Result {
|
||||
|
||||
// The actual data container
|
||||
std::variant<T, E> contents;
|
||||
|
@ -67,7 +69,7 @@ class Result {
|
|||
Result(InPlace i, Content &&c) : contents(i, std::forward<Content>(c)){};
|
||||
|
||||
public:
|
||||
explicit constexpr Result(const T &v)
|
||||
constexpr Result(const T &v)
|
||||
: Result(std::in_place_index_t<0>(), std::move(v)){};
|
||||
|
||||
/// Return a pointer to the success case value of the result. It is
|
||||
|
@ -129,10 +131,5 @@ public:
|
|||
operator bool() const { return ok(); }
|
||||
};
|
||||
|
||||
inline void makeFQSymbolName(const llvm::StringRef &ns,
|
||||
const llvm::StringRef &sym, std::string &result) {
|
||||
result = (ns + "/" + sym).str();
|
||||
};
|
||||
|
||||
} // namespace serene
|
||||
#endif
|
|
@ -0,0 +1,92 @@
|
|||
// DO NOT EDIT THIS FILE: It is aute generated by './builder
|
||||
// gen_precompile_index'
|
||||
#ifndef SERENE_PRECOMPIL_H
|
||||
#define SERENE_PRECOMPIL_H
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/IR/Attributes.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/Dialect.h"
|
||||
#include "mlir/IR/Identifier.h"
|
||||
#include "mlir/IR/Location.h"
|
||||
#include "mlir/IR/MLIRContext.h"
|
||||
#include "mlir/IR/OpDefinition.h"
|
||||
#include "mlir/IR/OpImplementation.h"
|
||||
#include "mlir/IR/Value.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
#include <llvm/ADT/ArrayRef.h>
|
||||
#include <llvm/ADT/Optional.h>
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/ExecutionEngine/JITEventListener.h>
|
||||
#include <llvm/ExecutionEngine/ObjectCache.h>
|
||||
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
|
||||
#include <llvm/ExecutionEngine/Orc/ExecutionUtils.h>
|
||||
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
|
||||
#include <llvm/ExecutionEngine/Orc/IRTransformLayer.h>
|
||||
#include <llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h>
|
||||
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
|
||||
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
|
||||
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/Value.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <llvm/Support/CodeGen.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#include <llvm/Support/Debug.h>
|
||||
#include <llvm/Support/ErrorHandling.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/FormatVariadic.h>
|
||||
#include <llvm/Support/Host.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
#include <llvm/Support/TargetRegistry.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <llvm/Support/ToolOutputFile.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm/Target/TargetOptions.h>
|
||||
#include <mlir/Conversion/AffineToStandard/AffineToStandard.h>
|
||||
#include <mlir/Conversion/SCFToStandard/SCFToStandard.h>
|
||||
#include <mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h>
|
||||
#include <mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h>
|
||||
#include <mlir/Dialect/Affine/IR/AffineOps.h>
|
||||
#include <mlir/Dialect/LLVMIR/LLVMDialect.h>
|
||||
#include <mlir/Dialect/MemRef/IR/MemRef.h>
|
||||
#include <mlir/Dialect/SCF/SCF.h>
|
||||
#include <mlir/Dialect/StandardOps/IR/Ops.h>
|
||||
#include <mlir/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <mlir/ExecutionEngine/OptUtils.h>
|
||||
#include <mlir/IR/Block.h>
|
||||
#include <mlir/IR/Builders.h>
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
#include <mlir/IR/OperationSupport.h>
|
||||
#include <mlir/IR/OwningOpRef.h>
|
||||
#include <mlir/IR/Value.h>
|
||||
#include <mlir/Pass/Pass.h>
|
||||
#include <mlir/Pass/PassManager.h>
|
||||
#include <mlir/Support/FileUtilities.h>
|
||||
#include <mlir/Support/LLVM.h>
|
||||
#include <mlir/Support/LogicalResult.h>
|
||||
#include <mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h>
|
||||
#include <mlir/Target/LLVMIR/ModuleTranslation.h>
|
||||
#include <mlir/Transforms/DialectConversion.h>
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
\documentclass{article}
|
||||
|
||||
\title{Serene's mathematical cheatsheet}
|
||||
\author{Sameer Rahmani}
|
||||
\date{January 2024}
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\usepackage[default,light,semibold]{sourcesanspro}
|
||||
\setsansfont{Source Sans Pro}
|
||||
\usepackage{etoolbox}
|
||||
\usepackage{titlesec}
|
||||
\usepackage{fontspec}
|
||||
\usepackage[left=0.6in,top=0.3in,right=0.6in,bottom=0.6in]{geometry} % Document margins
|
||||
\usepackage{hyperref}
|
||||
\usepackage{mfirstuc}
|
||||
|
||||
\edef\restoreparindent{\parindent=\the\parindent\relax}
|
||||
\usepackage{parskip}
|
||||
\restoreparindent{}
|
||||
\pagestyle{empty}
|
||||
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\newpage
|
||||
|
||||
\end{document}
|
135
mkdocs.yml
135
mkdocs.yml
|
@ -1,135 +0,0 @@
|
|||
site_name: Serene Programming Language
|
||||
site_description: A modern, typed lisp
|
||||
site_author: lxsameer
|
||||
repo_url: https://devheroes.codes/serene/serene
|
||||
repo_name: Serene
|
||||
copyright: Copyright © 2019 - 2023 Sameer Rahmani
|
||||
edit_uri: _edit/master/docs/pages/
|
||||
|
||||
docs_dir: ./docs/pages
|
||||
site_dir: ./build/docs
|
||||
|
||||
nav:
|
||||
- Home: 'index.md'
|
||||
- Getting Started: 'getting_started.md'
|
||||
- Resources: 'resources.md'
|
||||
|
||||
theme:
|
||||
name: material
|
||||
logo: /images/serene.png
|
||||
favicon: /images/serene.png
|
||||
icon:
|
||||
repo: fontawesome/brands/git-alt
|
||||
edit: material/pencil
|
||||
view: material/eye
|
||||
|
||||
features:
|
||||
- content.action.edit
|
||||
- navigation.tracking
|
||||
- navigation.instant
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
- navigation.sections
|
||||
- navigation.expand
|
||||
- navigation.indexes
|
||||
- toc.follow
|
||||
- toc.integrate
|
||||
- navigation.top
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- search.share
|
||||
- header.autohide
|
||||
- navigation.footer
|
||||
- content.code.copy
|
||||
- content.code.annotate
|
||||
|
||||
palette:
|
||||
- scheme: slate
|
||||
# toggle:
|
||||
# icon: material/brightness-4
|
||||
# name: Switch to light mode
|
||||
primary: deep purple
|
||||
accent: amber
|
||||
|
||||
# # Palette toggle for light mode
|
||||
# - scheme: default
|
||||
# toggle:
|
||||
# icon: material/brightness-7
|
||||
# name: Switch to dark mode
|
||||
# primary: deep purple
|
||||
# accent: amber
|
||||
# # Palette toggle for dark mode
|
||||
|
||||
|
||||
|
||||
|
||||
plugins:
|
||||
- git-revision-date-localized:
|
||||
enable_creation_date: true
|
||||
- search
|
||||
|
||||
# - social:
|
||||
# concurrency: 16
|
||||
- tags
|
||||
#tags_file: tags.md
|
||||
|
||||
- mike:
|
||||
# These fields are all optional; the defaults are as below...
|
||||
alias_type: symlink
|
||||
redirect_template: null
|
||||
deploy_prefix: ''
|
||||
canonical_version: null
|
||||
version_selector: true
|
||||
css_dir: css
|
||||
javascript_dir: js
|
||||
|
||||
extra:
|
||||
version:
|
||||
provider: mike
|
||||
social:
|
||||
- icon: fontawesome/brands/mastodon
|
||||
link: https://social.lxsameer.com/@lxsameer
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/@lxsameer
|
||||
- icon: fontawesome/brands/youtube
|
||||
link: https://www.youtube.com/c/lxsameer
|
||||
|
||||
generator: false
|
||||
|
||||
extra_css:
|
||||
- stylesheets/extra.css
|
||||
|
||||
markdown_extensions:
|
||||
- attr_list
|
||||
- md_in_html
|
||||
- def_list
|
||||
- footnotes
|
||||
- tables
|
||||
- md_in_html
|
||||
- pymdownx.superfences
|
||||
- admonition
|
||||
- pymdownx.details
|
||||
- pymdownx.highlight:
|
||||
anchor_linenums: true
|
||||
line_spans: __span
|
||||
pygments_lang_class: true
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.snippets
|
||||
- pymdownx.superfences
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.arithmatex:
|
||||
generic: true
|
||||
|
||||
extra_javascript:
|
||||
- javascripts/mathjax.js
|
||||
- https://polyfill.io/v3/polyfill.min.js?features=es6
|
||||
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
|
@ -1,76 +0,0 @@
|
|||
{ lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
nixVersions,
|
||||
libatomic_ops,
|
||||
cmake,
|
||||
ninja,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: rec {
|
||||
pname = "boehmgc";
|
||||
version = "8.2.4";
|
||||
|
||||
src = fetchurl {
|
||||
urls = [
|
||||
"https://github.com/ivmai/bdwgc/releases/download/v${finalAttrs.version}/gc-${finalAttrs.version}.tar.gz"
|
||||
];
|
||||
sha256 = "sha256-PQ082+B3QD0xBrtA8Mu1Y0E9bv27Kn4c1ohlld7Ej8I=";
|
||||
};
|
||||
|
||||
|
||||
nativeBuildInputs = [ cmake ninja ];
|
||||
buildInputs = [ libatomic_ops ];
|
||||
#outputs = [ "out" "dev" "doc" ];
|
||||
ninjaFlags = [ "-v" ];
|
||||
cmakeFlags = [
|
||||
#"-Denable_cplusplus=ON"
|
||||
"-Ddefault_enable_threads=ON"
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-Denable_threads=ON"
|
||||
"-Denable_parallel_mark=ON"
|
||||
"-Denable_thread_local_alloc=ON"
|
||||
"-Denable_mmap=ON"
|
||||
# TODO: Do we want to return the pages to the OS if empty for N collections?
|
||||
"-Denable_munmap=ON"
|
||||
"-Denable_werror=ON"
|
||||
# TODO: Do we want the entire GC in a single object file?
|
||||
"-Denable_single_obj_compilation=ON"
|
||||
"-Dwith_libatomic_ops=OFF"
|
||||
"-Dwithout_libatomic_ops=ON"
|
||||
"-DCMAKE_INSTALL_LIBDIR=${placeholder "out"}/lib"
|
||||
];
|
||||
|
||||
# `gctest` fails under emulation on aarch64-darwin
|
||||
doCheck = !(stdenv.isDarwin && stdenv.isx86_64);
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
passthru.tests = nixVersions;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://hboehm.info/gc/";
|
||||
description = "The Boehm-Demers-Weiser conservative garbage collector for C and C++";
|
||||
longDescription = ''
|
||||
The Boehm-Demers-Weiser conservative garbage collector can be used as a
|
||||
garbage collecting replacement for C malloc or C++ new. It allows you
|
||||
to allocate memory basically as you normally would, without explicitly
|
||||
deallocating memory that is no longer useful. The collector
|
||||
automatically recycles memory when it determines that it can no longer
|
||||
be otherwise accessed.
|
||||
|
||||
The collector is also used by a number of programming language
|
||||
implementations that either use C as intermediate code, want to
|
||||
facilitate easier interoperation with C libraries, or just prefer the
|
||||
simple collector interface.
|
||||
|
||||
Alternatively, the garbage collector may be used as a leak detector for
|
||||
C or C++ programs, though that is not its primary goal.
|
||||
'';
|
||||
# non-copyleft, X11-style license
|
||||
changelog = "https://github.com/ivmai/bdwgc/blob/v${finalAttrs.version}/ChangeLog";
|
||||
license = "https://hboehm.info/gc/license.txt";
|
||||
maintainers = with maintainers; [ AndersonTorres ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
})
|
111
nix/overlays.nix
111
nix/overlays.nix
|
@ -1,111 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
{ ... }:
|
||||
with builtins;
|
||||
let getEnv = p: (p.env or { }).NIX_LDFLAGS or p.NIX_LDFLAGS or "";
|
||||
in {
|
||||
# Most of these overlays are do to bugs and problems
|
||||
# in upstream nixpkgs. But thanks to their design
|
||||
# We can fix them using these overlays and contribute
|
||||
# them upstream little by little.
|
||||
sereneDev = (final: prev:
|
||||
if !prev.stdenv.hostPlatform.isLinux then
|
||||
prev
|
||||
else {
|
||||
|
||||
p11-kit = prev.p11-kit.overrideAttrs
|
||||
(old: { patches = [ ./nix/patches/p11-kit_skip_test.patch ]; });
|
||||
|
||||
cpio = prev.cpio.overrideAttrs (old: {
|
||||
nativeBuildInputs = [ final.autoreconfHook ];
|
||||
NIX_CFLAGS_COMPILE = "-Wno-implicit-function-declaration";
|
||||
});
|
||||
|
||||
libedit = prev.libedit.overrideAttrs (old: {
|
||||
# Musl is ISO 10646 compliant but doesn't define __STDC_ISO_10646__ we need to do it ourselves
|
||||
NIX_CFLAGS_COMPILE = "-D__STDC_ISO_10646__=201103L";
|
||||
});
|
||||
|
||||
elfutils = prev.elfutils.overrideAttrs (old: {
|
||||
# libcxx does not have __cxa_demangle
|
||||
configureFlags = old.configureFlags ++ [ "--disable-demangler" ];
|
||||
});
|
||||
|
||||
ccache = prev.ccache.overrideAttrs (old: {
|
||||
nativeBuildInputs = old.nativeBuildInputs ++ [ final.elfutils ];
|
||||
});
|
||||
|
||||
# We don't need systemd at all
|
||||
util-linux = prev.util-linux.override { systemdSupport = false; };
|
||||
|
||||
# libpam exmaples use glibc. We need to disable them
|
||||
linux-pam = prev.linux-pam.overrideAttrs (old: {
|
||||
postConfigure = ''
|
||||
sed 's/examples//' -i Makefile
|
||||
'';
|
||||
});
|
||||
|
||||
#=============================================================
|
||||
# Since we're using lld-18, and --no-undefined-version is the
|
||||
# default in lld-18. We need to explicitly turn it off for
|
||||
# these problematic packages untill they fix it upstream.
|
||||
libxcrypt = prev.libxcrypt.overrideAttrs (old: {
|
||||
env.NIX_LDFLAGS = "${getEnv old} --undefined-version";
|
||||
|
||||
#old.NIX_FLAGS ++ final.lib.optional (prev.stdenv.cc.isClang)
|
||||
});
|
||||
|
||||
ncurses = prev.ncurses.overrideAttrs
|
||||
(old: { env.NIX_LDFLAGS = "${getEnv old} --undefined-version"; });
|
||||
|
||||
libbsd = prev.libbsd.overrideAttrs (old: {
|
||||
env.NIX_LDFLAGS = "${getEnv old} --undefined-version";
|
||||
# NIX_LDFLAGS = [ ] ++ final.lib.optional (prev.stdenv.cc.isClang)
|
||||
# [ "--undefined-version" ];
|
||||
});
|
||||
|
||||
libxml2 = prev.libxml2.overrideAttrs (old: {
|
||||
env.NIX_LDFLAGS = "${getEnv old} --undefined-version";
|
||||
propagatedBuildInputs = old.propagatedBuildInputs
|
||||
++ [ final.zlib.static ];
|
||||
# NIX_LDFLAGS = [ ] ++ final.lib.optional (prev.stdenv.cc.isClang)
|
||||
# [ "--undefined-version" ];
|
||||
});
|
||||
|
||||
# binutils = prev.binutils.overrideAttrs (old: {
|
||||
# env.NIX_LDFLAGS = (getEnv old NIX_LDFLAGS " ") ++ "--undefined-version";
|
||||
# buildInputs = [ final.zlib final.gettext final.zlib.static ];
|
||||
# });
|
||||
|
||||
});
|
||||
|
||||
iwyu = (final: prev: {
|
||||
iwyu = (prev.include-what-you-use.overrideAttrs (old:
|
||||
let version = "0.22";
|
||||
in {
|
||||
inherit version;
|
||||
|
||||
src = prev.fetchurl {
|
||||
url =
|
||||
"${old.meta.homepage}/downloads/${old.pname}-${version}.src.tar.gz";
|
||||
hash = "sha256-hZB0tGHqS4MlpzQYwgfKM7XmVmsI5rWH65FkQWVppt0=";
|
||||
};
|
||||
cmakeFlags = [ "-DCMAKE_PREFIX_PATH=${prev.llvmPackages_18.llvm.dev}" ];
|
||||
|
||||
})).override { llvmPackages = prev.__splicedPackages.llvmPackages_18; };
|
||||
|
||||
});
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
From 132b779414c2236c1350b578b59c8edcfc4c5a14 Mon Sep 17 00:00:00 2001
|
||||
From: Sameer Rahmani <lxsameer@gnu.org>
|
||||
Date: Sat, 25 Nov 2023 13:14:42 +0000
|
||||
Subject: [PATCH] test
|
||||
|
||||
---
|
||||
common/test.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/common/test.c b/common/test.c
|
||||
index 6cdbd1fa2118..6cd6f84bcdc7 100644
|
||||
--- a/common/test.c
|
||||
+++ b/common/test.c
|
||||
@@ -614,8 +614,9 @@ p11_test_copy_setgid (const char *input,
|
||||
assert (fd >= 0);
|
||||
|
||||
copy_file (input, fd);
|
||||
- if (fchown (fd, getuid (), group) < 0)
|
||||
- assert_not_reached ();
|
||||
+ if (fchown (fd, getuid (), group) < 0) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
if (fchmod (fd, 02750) < 0)
|
||||
assert_not_reached ();
|
||||
if (close (fd) < 0)
|
||||
--
|
||||
2.41.0
|
|
@ -1,29 +0,0 @@
|
|||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
{ nixpkgs }: {
|
||||
getPkgs = system: overlays:
|
||||
if system == "x86_64-linux" then
|
||||
import nixpkgs {
|
||||
inherit system overlays;
|
||||
linker = "lld";
|
||||
crossSystem = nixpkgs.lib.systems.examples.musl64 // {
|
||||
useLLVM = true;
|
||||
};
|
||||
}
|
||||
else
|
||||
import nixpkgs { inherit system overlays; };
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
FROM docker.io/debian:sid-slim
|
||||
|
||||
ARG VERSION
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
gnupg \
|
||||
cmake \
|
||||
ccache \
|
||||
git \
|
||||
ninja-build \
|
||||
binutils \
|
||||
lsb-release \
|
||||
wget \
|
||||
software-properties-common \
|
||||
zlib1g \
|
||||
cppcheck \
|
||||
shellcheck \
|
||||
zlib1g-dev
|
||||
|
||||
RUN wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh
|
||||
RUN ./llvm.sh ${VERSION} all
|
||||
RUN apt-get update --fix-missing && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
mlir-${VERSION}-tools \
|
||||
libmlir-${VERSION}-dev \
|
||||
libmlir-${VERSION} \
|
||||
libmlir-${VERSION}-dbgsym \
|
||||
liblld-${VERSION} \
|
||||
liblld-${VERSION}-dev \
|
||||
clang-format-${VERSION} \
|
||||
clang-tidy-${VERSION}
|
||||
|
||||
RUN ln -s `which lld-${VERSION}` /usr/bin/lld && \
|
||||
ln -s `which clang-${VERSION}` /usr/bin/clang && \
|
||||
ln -s `which clang++-${VERSION}` /usr/bin/clang++ && \
|
||||
ln -s `which clang-format-${VERSION}` /usr/bin/clang-format && \
|
||||
ln -s `which clang-tidy-${VERSION}` /usr/bin/clang-tidy && \
|
||||
ln -s `which mlir-tblgen-${VERSION}` /usr/bin/mlir-tblgen
|
||||
|
||||
ENV MLIR_DIR /usr/lib/llvm-${VERSION}
|
||||
ENV CMAKE_PREFIX_PATH=/usr/lib/llvm-${VERSION}
|
||||
ENV LD_LIBRARY_PATH=/usr/lib/llvm-${VERSION}/lib/clang/${VERSION}.0.0/lib/linux/
|
||||
ENV CC=/usr/bin/clang
|
||||
ENV CXX=/usr/bin/clang++
|
||||
|
||||
# --branch clang_${VERSION}
|
||||
WORKDIR /iwuy
|
||||
RUN git clone https://github.com/include-what-you-use/include-what-you-use.git --depth 1 && \
|
||||
mkdir build && cd build && \
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH=/usr/lib/llvm-${VERSION} ../include-what-you-use && \
|
||||
cmake --build . && \
|
||||
cmake -P cmake_install.cmake
|
||||
|
||||
WORKDIR /boehm
|
||||
RUN git clone https://github.com/ivmai/bdwgc.git --depth 1 --branch v8.2.0 && \
|
||||
mkdir build && cd build && \
|
||||
cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -Denable_cplusplus=ON -Denable_threads=ON \
|
||||
-Denable_gcj_support=OFF -Dinstall_headers=ON \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON ../bdwgc && \
|
||||
cmake --build . --config Release && \
|
||||
cmake -P cmake_install.cmake
|
||||
|
||||
WORKDIR /app
|
||||
RUN rm /iwuy -rf && rm /boehm -rf && rm /llvm.sh
|
||||
|
||||
RUN apt-get purge -y git software-properties-common wget && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean
|
|
@ -1,11 +0,0 @@
|
|||
FROM rg.fr-par.scw.cloud/serene/llvm:latest
|
||||
|
||||
WORKDIR /app
|
||||
# For CI
|
||||
COPY .pre-commit-config.yaml .
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends git python3 python3-pip && \
|
||||
pip3 install pre-commit && \
|
||||
git init . && \
|
||||
pre-commit autoupdate && \
|
||||
rm -fv /app/.pre-commit-config.yaml
|
|
@ -1,24 +0,0 @@
|
|||
FROM debian:sid-slim as builder
|
||||
|
||||
RUN apt-get update --fix-missing && apt-get install -y wget gnupg ccache cmake ccache git ninja-build build-essential binutils
|
||||
|
||||
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
|
||||
RUN echo "deb http://apt.llvm.org/unstable/ llvm-toolchain main" >> /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update --fix-missing && apt-get install -y clang-format-15 clang-tidy-15 clang-tools-15 clang-15 clangd-15 libc++-15-dev libc++1-15 libc++abi-15-dev libc++abi1-15 libclang-15-dev libclang1-15 liblldb-15-dev lld-15 lldb-15 llvm-15-dev llvm-15-runtime llvm python3-clang-15 python3-lldb-15 mlir-15-tools libmlir-15-dev
|
||||
|
||||
RUN mkdir -p /opt/build
|
||||
|
||||
WORKDIR /opt/build
|
||||
COPY ./ /usr/src/llvm-project
|
||||
|
||||
RUN ln -s `which lld-15` /usr/bin/lld && ln -s `which lldb-15` /usr/bin/lldb
|
||||
|
||||
RUN cmake -G Ninja /usr/src/llvm-project/llvm -DCMAKE_INSTALL_PREFIX=/opt/llvm -DLLVM_PARALLEL_COMPILE_JOBS=7 -DLLVM_PARALLEL_LINK_JOBS=1 -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_CCACHE_BUILD=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_ENABLE_PROJECTS='clang;lldb;lld;mlir;clang-tools-extra;compiler-rt' -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -DLLVM_ENABLE_LLD=ON
|
||||
|
||||
RUN cmake --build .
|
||||
RUN cmake -DCMAKE_INSTALL_PREFIX=/opt/llvm -P cmake_install.cmake
|
||||
|
||||
FROM debian:sid-slim
|
||||
|
||||
COPY --from=builder /opt/llvm /opt/llvm
|
|
@ -1,9 +0,0 @@
|
|||
FROM rg.fr-par.scw.cloud/serene/llvm:15-8
|
||||
|
||||
ARG TASK=build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN ./builder ${TASK}
|
|
@ -1,47 +0,0 @@
|
|||
FROM alpine:edge
|
||||
|
||||
RUN apk update \
|
||||
&& apk add --no-cache \
|
||||
ninja \
|
||||
make \
|
||||
clang \
|
||||
clang-dev \
|
||||
bison \
|
||||
flex \
|
||||
# compiler-rt \ #
|
||||
# llvm-libunwind \
|
||||
# lld \
|
||||
gcc \
|
||||
libgcc
|
||||
curl \
|
||||
g++ \
|
||||
alpine-sdk \
|
||||
libatomic \
|
||||
libgcc \
|
||||
cmake \
|
||||
bash \
|
||||
git \
|
||||
linux-headers \
|
||||
zlib \
|
||||
zlib-dev \
|
||||
zstd \
|
||||
zstd-dev \
|
||||
tar \
|
||||
xz \
|
||||
python3
|
||||
|
||||
# RUN ln -sf /usr/bin/clang /usr/bin/cc \
|
||||
# && ln -sf /usr/bin/clang++ /usr/bin/c++ \
|
||||
# && ls -l /usr/bin/cc /usr/bin/c++ \
|
||||
# && cc --version \
|
||||
# && c++ --version
|
||||
# && update-alternatives --install /usr/bin/cc cc /usr/bin/clang 10\
|
||||
# && update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 10\
|
||||
|
||||
|
||||
RUN addgroup -S serene && \
|
||||
adduser -h /home/serene -S serene -G serene
|
||||
|
||||
USER serene:serene
|
||||
ENV HOME=/home/serene
|
||||
WORKDIR /home/serene/serene
|
|
@ -1,22 +0,0 @@
|
|||
FROM alpine:edge
|
||||
|
||||
RUN apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add --no-cache \
|
||||
alpine-sdk \
|
||||
linux-headers \
|
||||
gcc \
|
||||
g++ \
|
||||
libgcc \
|
||||
build-base \
|
||||
zlib \
|
||||
zlib-dev \
|
||||
zstd \
|
||||
zstd-dev
|
||||
# clang-dev \
|
||||
# compiler-rt \
|
||||
# libc++-dev \
|
||||
# llvm-runtimes \
|
||||
# libc++-static \
|
||||
# llvm-libunwind \
|
||||
# lld \
|
|
@ -0,0 +1,36 @@
|
|||
FROM debian:11-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y wget gnupg
|
||||
|
||||
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
|
||||
RUN echo "deb http://apt.llvm.org/bullseye/ llvm-toolchain-bullseye-13 main" >> /etc/apt/sources.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y ccache cmake ccache git ninja-build build-essential clang-13 lldb-13 lld-13
|
||||
|
||||
ENV CXX=clang++-13
|
||||
ENV CC=clang-13
|
||||
|
||||
RUN mkdir -p /opt/build
|
||||
COPY ./llvm-project /usr/src/llvm-project
|
||||
|
||||
WORKDIR /opt/build
|
||||
|
||||
ENV LDFLAGS="-fuse-ld=lld-13"
|
||||
|
||||
RUN cmake -G Ninja /usr/src/llvm-project/llvm \
|
||||
-DCMAKE_INSTALL_PREFIX=/opt/llvm \
|
||||
-DLLVM_PARALLEL_COMPILE_JOBS=7 \
|
||||
-DLLVM_PARALLEL_LINK_JOBS=1 \
|
||||
-DLLVM_BUILD_EXAMPLES=ON \
|
||||
-DLLVM_TARGETS_TO_BUILD="X86" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DLLVM_ENABLE_ASSERTIONS=ON \
|
||||
-DLLVM_CCACHE_BUILD=ON \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DLLVM_ENABLE_PROJECTS='clang;lldb;lld;mlir;clang-tools-extra;compiler-rt' \
|
||||
-DCMAKE_C_COMPILER=clang-13 \
|
||||
-DCMAKE_CXX_COMPILER=clang++-13 \
|
||||
-DLLVM_ENABLE_LLD=ON
|
||||
|
||||
RUN cmake --build .
|
||||
RUN cmake -DCMAKE_INSTALL_PREFIX=/opt/llvm -P cmake_install.cmake
|
|
@ -1,6 +1,6 @@
|
|||
;;; serene-dev --- Serene's development lib for Emacs users -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (c) 2019-2024 Sameer Rahmani
|
||||
;; Copyright (c) 2019-2021 Sameer Rahmani
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://serene-lang.org
|
||||
|
@ -35,25 +35,18 @@
|
|||
(defvar serene/compile-buffer "*compile*")
|
||||
|
||||
|
||||
(defmacro serene/builder (command &optional buf-name sync)
|
||||
(defmacro serene/builder (command &optional buf-name)
|
||||
"Run the given COMMAND via the builder script.
|
||||
Use the optional BUF-NAME as the buffer.
|
||||
|
||||
If SYNC is non-nil it will block."
|
||||
Use the optional BUF-NAME as the buffer."
|
||||
(let ((buf (or buf-name (format "*%s*" command))))
|
||||
(if (not sync)
|
||||
`(projectile-run-async-shell-command-in-root
|
||||
(format "./builder %s" ,command) ,buf)
|
||||
`(projectile-run-shell-command-in-root
|
||||
(format "./builder %s" ,command) ,buf))))
|
||||
`(projectile-run-async-shell-command-in-root (format "./builder %s" ,command) ,buf)))
|
||||
|
||||
|
||||
(defun serene/compile (&optional sync)
|
||||
(defun serene/compile ()
|
||||
"Compile the project.
|
||||
It will run the `./builder compile' asynchronously or synchronously if
|
||||
SYNC is non-nil."
|
||||
It will run the `./builder compile' asynchronously."
|
||||
(interactive)
|
||||
(serene/builder "compile" serene/compile-buffer sync))
|
||||
(serene/builder "compile" serene/compile-buffer))
|
||||
|
||||
|
||||
(defun serene/build ()
|
||||
|
|
|
@ -1,46 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512mm"
|
||||
height="512mm"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg931"
|
||||
inkscape:export-filename="serene.png"
|
||||
inkscape:export-filename="/home/lxsameer/src/serene/serene/resources/images/serene.png"
|
||||
inkscape:export-xdpi="25.4"
|
||||
inkscape:export-ydpi="25.4"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="serene.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||
sodipodi:docname="serene.svg">
|
||||
<defs
|
||||
id="defs925" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.29845254"
|
||||
inkscape:cx="170.88144"
|
||||
inkscape:cy="1060.4701"
|
||||
inkscape:zoom="0.074613135"
|
||||
inkscape:cx="-3552.8237"
|
||||
inkscape:cy="741.94593"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="g1039"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1063"
|
||||
inkscape:window-height="1064"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata928">
|
||||
<rdf:RDF>
|
||||
|
@ -49,6 +46,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
|
@ -56,25 +54,28 @@
|
|||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:32.4311;stroke-linejoin:round"
|
||||
id="rect1506"
|
||||
width="512"
|
||||
height="512"
|
||||
x="0"
|
||||
y="1.8041124e-14" />
|
||||
<g
|
||||
id="g1039"
|
||||
transform="matrix(5.4643699,0,0,5.4643699,-646.86584,-18.784791)">
|
||||
<path
|
||||
id="path293"
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0676825;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.1472,4.0209328 c -1.69431,0 -3.25301,0.4054703 -4.67634,1.2165468 L 127.87228,24.027579 c -1.55881,0.743535 -2.84653,1.893108 -3.79538,3.380092 -1.01663,1.486995 -1.49162,3.24371 -1.49162,5.068664 v 35.6206 c 0,1.824974 0.47447,3.581711 1.49162,5.068684 0.94894,1.486995 2.23657,2.63658 3.79538,3.380083 l 32.59858,18.790093 c 1.42333,0.811046 2.98203,1.216548 4.67634,1.216548 0.0302,0 0.0503,-0.0032 0.0806,-0.0032 0.0302,2.32e-4 0.0604,0.0032 0.0806,0.0032 1.6943,0 3.25302,-0.40547 4.67633,-1.216548 l 32.5986,-18.790093 c 1.55881,-0.743535 2.84655,-1.893088 3.79538,-3.380083 1.01665,-1.486973 1.49162,-3.24371 1.49162,-5.068684 v -35.6206 c 0,-1.824954 -0.47547,-3.581669 -1.49162,-5.068664 -0.94894,-1.486984 -2.23657,-2.6366 -3.79538,-3.380092 L 169.98472,5.2374796 c -1.42332,-0.8111397 -2.98203,-1.2165468 -4.67634,-1.2165468 -0.0302,0 -0.0604,0.00316 -0.0806,0.00316 -0.0302,-1.475e-4 -0.0503,-0.00316 -0.0806,-0.00316 z m 0,7.4347692 c 0.0302,0 0.0604,0.01106 0.0806,0.01106 0.0302,-0.0011 0.0604,-0.01106 0.0806,-0.01106 0.33847,0 0.67695,0.06826 0.94794,0.271142 l 32.73594,18.857089 0.26998,0.06826 v 0.06731 c 0.33848,0.135118 0.67797,0.40567 0.88045,0.676023 0.20348,0.337959 0.27199,0.675517 0.27199,1.08104 v 35.620589 c 0,0.405576 -0.0705,0.743134 -0.27199,1.081061 -0.20349,0.270247 -0.54197,0.540905 -0.88045,0.676023 v 0.06826 l -0.26998,0.134011 -32.73594,18.858585 c -0.27099,0.135129 -0.60947,0.202535 -0.94794,0.202535 -0.0302,0 -0.0604,-0.0084 -0.0806,-0.0084 -0.0302,0 -0.0604,0.0084 -0.0806,0.0084 -0.33848,0 -0.67696,-0.06731 -0.94794,-0.202535 L 131.46337,70.05651 131.1934,69.922499 v -0.06826 c -0.33848,-0.135118 -0.67796,-0.405776 -0.88045,-0.676023 -0.20348,-0.337958 -0.27199,-0.675517 -0.27199,-1.081061 V 32.47643 c 0,-0.405565 0.0705,-0.743123 0.27199,-1.081029 0.2035,-0.270353 0.54197,-0.540895 0.88045,-0.676023 v -0.06732 l 0.26997,-0.06826 32.73589,-18.857121 c 0.27098,-0.202841 0.60946,-0.271152 0.94794,-0.271152 z" />
|
||||
<path
|
||||
id="path1019"
|
||||
style="clip-rule:evenodd;fill:#5e246d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0608809;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.1553,8.6703245 c -1.52405,0 -2.92581,0.364799 -4.2061,1.094368 L 131.62653,26.666424 c -1.40216,0.668814 -2.56034,1.702681 -3.41384,3.040234 -0.91447,1.337561 -1.34213,2.918061 -1.34213,4.559619 v 32.040724 c 0,1.641575 0.4272,3.221583 1.34213,4.559126 0.85358,1.337564 2.01168,2.37194 3.41384,3.040727 l 29.32267,16.901731 c 1.28029,0.729541 2.68205,1.094366 4.2061,1.094366 0.0272,0 0.0453,-0.0029 0.0725,-0.0029 0.0272,2.1e-4 0.0544,0.0029 0.0725,0.0029 1.52404,0 2.9263,-0.364797 4.20658,-1.094366 l 29.32268,-16.901731 c 1.40215,-0.668814 2.56034,-1.703163 3.41383,-3.040727 0.91448,-1.337543 1.34165,-2.917551 1.34165,-4.559126 V 34.266277 c 0,-1.641558 -0.42761,-3.222058 -1.34165,-4.559619 -0.85357,-1.337553 -2.01168,-2.37146 -3.41383,-3.040234 L 169.50681,9.7646925 c -1.28028,-0.729626 -2.68254,-1.094368 -4.20658,-1.094368 -0.0272,0 -0.0544,0.0029 -0.0725,0.0029 -0.0272,-1.33e-4 -0.0453,-0.0029 -0.0725,-0.0029 z" />
|
||||
style="clip-rule:evenodd;fill:#5e246d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0642522;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.15124,6.3658643 c -1.60844,0 -3.08783,0.3850005 -4.43901,1.1549697 L 129.7658,25.358505 c -1.4798,0.70585 -2.70212,1.796968 -3.60288,3.208589 -0.96511,1.411629 -1.41645,3.079649 -1.41645,4.812109 v 33.814991 c 0,1.732478 0.45086,3.39998 1.41645,4.81159 0.90085,1.411632 2.12308,2.503287 3.60288,3.209108 l 30.94643,17.837671 c 1.35118,0.76994 2.83057,1.154967 4.43901,1.154967 0.0287,0 0.0478,-0.0031 0.0765,-0.0031 0.0287,2.22e-4 0.0574,0.0031 0.0765,0.0031 1.60843,0 3.08834,-0.384998 4.43952,-1.154967 L 200.6902,75.214892 c 1.47979,-0.70585 2.70212,-1.797476 3.60287,-3.209108 0.96512,-1.41161 1.41594,-3.079112 1.41594,-4.81159 V 33.379203 c 0,-1.73246 -0.45129,-3.40048 -1.41594,-4.812109 -0.90084,-1.411621 -2.12308,-2.502781 -3.60287,-3.208589 L 169.74372,7.520834 c -1.35118,-0.7700301 -2.83109,-1.1549697 -4.43952,-1.1549697 -0.0287,0 -0.0574,0.0031 -0.0765,0.0031 -0.0287,-1.402e-4 -0.0478,-0.0031 -0.0765,-0.0031 z" />
|
||||
<path
|
||||
id="path1052"
|
||||
style="clip-rule:evenodd;fill:#8800aa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0608809;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.15533,8.670325 c -1.52405,0 -2.92612,0.364723 -4.2064,1.094292 l -29.32265,16.901821 c -1.40215,0.668814 -2.56047,1.702863 -3.41397,3.040416 -0.91447,1.337562 -1.34172,2.917739 -1.34172,4.559297 V 66.30712 c 0,1.641577 0.4268,3.221773 1.34172,4.559316 0.85358,1.337562 2.01182,2.371621 3.41397,3.040407 l 29.32265,16.901815 c 1.28028,0.729542 2.68235,1.094293 4.2064,1.094293 0.0272,0 0.0453,-0.0028 0.0725,-0.0028 0.0272,2.08e-4 0.0544,0.0028 0.0725,0.0028 1.52404,0 2.92611,-0.364723 4.20639,-1.094293 l 29.32261,-16.901815 c 1.40215,-0.668815 2.56048,-1.702845 3.41397,-3.040407 0.91448,-1.337543 1.34172,-2.917739 1.34172,-4.559316 V 34.266151 c 0,-1.641558 -0.42769,-3.221735 -1.34172,-4.559297 -0.85358,-1.337553 -2.01182,-2.37164 -3.41397,-3.040416 L 169.50673,9.764617 c -1.28028,-0.729626 -2.68235,-1.094292 -4.20639,-1.094292 -0.0272,0 -0.0544,0.0028 -0.0725,0.0028 -0.0272,-1.32e-4 -0.0453,-0.0028 -0.0725,-0.0028 z m 0,6.687625 c 0.0272,0 0.0544,0.0099 0.0725,0.0099 0.0272,-9.48e-4 0.0544,-0.0099 0.0725,-0.0099 0.30446,0 0.60892,0.0614 0.85267,0.243894 l 29.44621,16.962079 0.24284,0.0614 v 0.06055 c 0.30447,0.121539 0.60984,0.364903 0.79198,0.608087 0.18303,0.303996 0.24465,0.607632 0.24465,0.972402 v 32.04096 c 0,0.364818 -0.0634,0.668454 -0.24465,0.972422 -0.18305,0.243089 -0.48751,0.486547 -0.79198,0.608087 v 0.0614 L 195.59921,68.069776 166.153,85.0332 c -0.24375,0.121549 -0.54821,0.182181 -0.85267,0.182181 -0.0272,0 -0.0544,-0.0076 -0.0725,-0.0076 -0.0272,0 -0.0544,0.0076 -0.0725,0.0076 -0.30447,0 -0.60893,-0.06055 -0.85268,-0.182181 L 134.8565,68.069776 134.61366,67.949231 v -0.0614 c -0.30447,-0.12154 -0.60984,-0.364998 -0.79198,-0.608087 -0.18303,-0.303996 -0.24465,-0.607632 -0.24465,-0.972422 V 34.266236 c 0,-0.364808 0.0634,-0.668444 0.24465,-0.972393 0.18305,-0.243184 0.48751,-0.486538 0.79198,-0.608087 v -0.06055 l 0.24284,-0.0614 29.44615,-16.962107 c 0.24375,-0.182456 0.54821,-0.243904 0.85268,-0.243904 z" />
|
||||
style="clip-rule:evenodd;fill:#8800aa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0642522;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.15142,6.365746 c -1.60844,0 -3.08815,0.38492 -4.43933,1.154889 l -30.9464,17.837766 c -1.4798,0.70585 -2.70226,1.79716 -3.60302,3.20878 -0.96511,1.41163 -1.41602,3.07931 -1.41602,4.81177 v 33.81525 c 0,1.73248 0.45043,3.40018 1.41602,4.81179 0.90085,1.41163 2.12322,2.50295 3.60302,3.20877 l 30.9464,17.83776 c 1.35118,0.76994 2.83089,1.15489 4.43933,1.15489 0.0287,0 0.0478,-0.003 0.0765,-0.003 0.0287,2.2e-4 0.0574,0.003 0.0765,0.003 1.60843,0 3.08814,-0.38492 4.43932,-1.15489 l 30.94636,-17.83776 c 1.4798,-0.70585 2.70227,-1.79714 3.60302,-3.20877 0.96512,-1.41161 1.41602,-3.07931 1.41602,-4.81179 v -33.81525 c 0,-1.73246 -0.45138,-3.40014 -1.41602,-4.81177 -0.90085,-1.41162 -2.12322,-2.50297 -3.60302,-3.20878 L 169.74375,7.520635 c -1.35118,-0.770029 -2.83089,-1.154889 -4.43932,-1.154889 -0.0287,0 -0.0574,0.003 -0.0765,0.003 -0.0287,-1.4e-4 -0.0478,-0.003 -0.0765,-0.003 z m 0,7.057955 c 0.0287,0 0.0574,0.0105 0.0765,0.0105 0.0287,-10e-4 0.0574,-0.0105 0.0765,-0.0105 0.32132,0 0.64264,0.0648 0.89989,0.2574 l 31.0768,17.90136 0.25629,0.0648 v 0.0639 c 0.32133,0.12827 0.64361,0.38511 0.83583,0.64176 0.19317,0.32083 0.2582,0.64128 0.2582,1.02625 v 33.81524 c 0,0.38502 -0.0669,0.70547 -0.2582,1.02627 -0.19318,0.25655 -0.5145,0.51349 -0.83583,0.64176 v 0.0648 l -0.25629,0.12722 -31.0768,17.90278 c -0.25725,0.12828 -0.57857,0.19227 -0.89989,0.19227 -0.0287,0 -0.0574,-0.008 -0.0765,-0.008 -0.0287,0 -0.0574,0.008 -0.0765,0.008 -0.32133,0 -0.64265,-0.0639 -0.8999,-0.19227 l -31.07674,-17.90278 -0.25629,-0.12722 v -0.0648 c -0.32133,-0.12827 -0.64361,-0.38521 -0.83583,-0.64176 -0.19317,-0.32083 -0.2582,-0.64128 -0.2582,-1.02627 v -33.81537 c 0,-0.38501 0.0669,-0.70546 0.2582,-1.02624 0.19318,-0.25665 0.5145,-0.51348 0.83583,-0.64176 v -0.0639 l 0.25629,-0.0648 31.07674,-17.90139 c 0.25725,-0.19256 0.57857,-0.25741 0.8999,-0.25741 z" />
|
||||
<path
|
||||
id="path1050"
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.41896;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.17999,20.897696 c -1.07631,0 -2.06645,0.257548 -2.9705,0.772834 l -20.70721,11.93581 c -0.99023,0.472268 -1.8082,1.202568 -2.41097,2.147113 -0.64608,0.944583 -0.9475,2.060499 -0.9475,3.219727 v 3.633996 h 4.73462 v 0.0163 c 6.8149,-0.117304 21.45623,-0.03705 21.98758,0.42094 0.63431,0.547085 0.88168,1.721805 1.21596,3.772099 0.009,0.08405 -0.009,0.175141 -0.0634,0.254469 -0.20117,0.296596 -0.41955,0.585687 -0.63068,0.875849 -1.43759,1.978472 -2.91387,3.896301 -4.65022,5.726257 -1.56119,1.64223 -3.31765,3.199013 -5.3842,4.613912 -2.3275,1.594324 -5.04746,3.006097 -8.26853,4.121131 -0.0544,0.0216 -0.10692,0.04245 -0.15766,0.0687 0.0453,0.01895 0.0634,0.02985 0.0816,0.038 3.31692,1.018387 5.58871,1.336814 7.53438,0.906142 1.92437,-0.42599 4.15057,-1.738557 6.8544,-4.417186 3.6135,-3.105379 4.80762,-5.200093 5.60901,-5.773539 0.82096,-0.587478 0.98071,0.319811 1.48526,2.772322 0.1486,0.691138 0.34886,1.609342 0.61979,2.571786 0.0816,0.289992 0.17036,0.592823 0.27003,0.905195 0.6198,1.762624 1.25292,3.04215 1.93199,3.867638 0.68322,0.830387 1.43677,1.234812 2.39574,1.246656 1.39717,0.018 8.63198,-2.82147 13.87373,-5.602348 v 2.608683 c 0,0.257643 -0.0453,0.471993 -0.17217,0.686713 -0.12957,0.171702 -0.34433,0.343584 -0.55999,0.42943 v 0.0434 l -0.17216,0.08499 -20.79447,11.979349 c -0.17217,0.08585 -0.38693,0.128589 -0.60258,0.128589 -0.0181,0 -0.0363,-0.0057 -0.0544,-0.0057 -0.0181,0 -0.0362,0.0057 -0.0544,0.0057 -0.21567,0 -0.43043,-0.04245 -0.60259,-0.128589 l -20.79447,-11.979349 -0.17217,-0.08499 v -0.0434 c -0.21475,-0.08585 -0.43041,-0.257728 -0.55999,-0.42943 -0.12957,-0.214625 -0.17216,-0.42907 -0.17216,-0.686713 V 48.480119 h -4.73562 v 13.120052 c 0,1.159265 0.30174,2.275172 0.94759,3.219727 0.60258,0.944564 1.42074,1.674816 2.41088,2.147103 l 20.70729,11.935838 c 0.90433,0.515191 1.8942,0.77274 2.97051,0.77274 0.0181,0 0.0363,-0.0019 0.0544,-0.0019 0.0181,1.42e-4 0.0363,0.0019 0.0544,0.0019 1.07622,0 2.06645,-0.257549 2.9705,-0.77274 l 20.7072,-11.935838 c 0.99023,-0.472268 1.8082,-1.202539 2.41097,-2.147113 0.64608,-0.944555 0.94746,-2.060461 0.94746,-3.219717 v -9.607122 l -4.70903,2.131015 c -0.003,0.0019 -0.007,0.0028 -0.009,0.0038 l -0.0181,0.0085 v 9.38e-4 c -3.48484,1.756371 -11.14498,4.995067 -11.61364,4.952542 -0.48841,-0.04434 -0.97229,-0.86085 -1.83811,-2.850834 -1.36047,-3.088617 -1.92382,-6.659801 -2.61575,-9.97412 -0.10602,-0.505431 -0.20116,-0.997673 -0.28996,-1.462304 -0.18938,-0.967172 -0.35611,-1.848631 -0.54188,-2.632334 -0.4576,-1.990419 -1.04505,-3.389012 -2.60913,-4.059636 -0.78019,-0.334535 -7.12363,-0.491692 -13.78929,-0.447414 -3.89132,0.02615 -7.80693,0.126609 -10.86815,0.294151 0.0634,-0.03885 0.12596,-0.07504 0.19029,-0.10022 v -0.04245 l 0.17126,-0.0434 20.79447,-11.978402 c 0.17217,-0.128864 0.38692,-0.172062 0.60258,-0.172062 0.0181,0 0.0363,0.0076 0.0544,0.0076 0.0181,-9.38e-4 0.0363,-0.0076 0.0544,-0.0076 0.21566,0 0.43041,0.0434 0.60258,0.172062 l 20.79455,11.978402 0.17127,0.0434 v 0.04245 c 0.21566,0.08585 0.43041,0.257643 0.55999,0.42943 0.12958,0.21472 0.17308,0.42907 0.17308,0.686713 v 8.600731 l 4.73549,-2.046854 v -6.553877 c 0,-1.159256 -0.30175,-2.275152 -0.94747,-3.219726 -0.60258,-0.944555 -1.42073,-1.674807 -2.41096,-2.147094 l -20.7073,-11.935801 c -0.90433,-0.515191 -1.89419,-0.772739 -2.9705,-0.772739 -0.0181,0 -0.0363,0.0028 -0.0544,0.0028 -0.0181,-9.5e-5 -0.0363,-0.0028 -0.0544,-0.0028 z" />
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49754;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
d="m 165.17475,19.270251 c -1.13592,0 -2.18088,0.27181 -3.135,0.81563 l -21.85388,12.59676 c -1.04506,0.49842 -1.90833,1.26916 -2.54448,2.26601 -0.68185,0.99689 -0.99996,2.1746 -0.99996,3.39802 v 3.83523 h 4.9968 v 0.0172 c 7.19228,-0.1238 22.64437,-0.0391 23.20515,0.44425 0.66943,0.57738 0.9305,1.81715 1.28329,3.98098 0.01,0.0887 -0.01,0.18484 -0.0669,0.26856 -0.21231,0.31302 -0.44278,0.61812 -0.6656,0.92435 -1.5172,2.08803 -3.07523,4.11206 -4.90773,6.04335 -1.64764,1.73317 -3.50137,3.37616 -5.68235,4.86941 -2.45639,1.68261 -5.32697,3.17256 -8.7264,4.34934 -0.0574,0.0228 -0.11284,0.0448 -0.1664,0.0725 0.0478,0.02 0.0669,0.0315 0.0861,0.0401 3.5006,1.07478 5.89819,1.41084 7.9516,0.95632 2.03093,-0.44958 4.38041,-1.83483 7.23397,-4.66179 3.8136,-3.27734 5.07384,-5.48805 5.91961,-6.09325 0.86642,-0.62001 1.03502,0.33752 1.5675,2.92584 0.15683,0.72941 0.36818,1.69846 0.65412,2.7142 0.0861,0.30605 0.17979,0.62565 0.28498,0.95532 0.65412,1.86023 1.3223,3.21061 2.03897,4.08181 0.72106,0.87637 1.51634,1.30319 2.52841,1.31569 1.47454,0.019 9.10998,-2.97771 14.64199,-5.91258 v 2.75314 c 0,0.27191 -0.0478,0.49813 -0.1817,0.72474 -0.13675,0.18121 -0.3634,0.36261 -0.591,0.45321 v 0.0458 l -0.1817,0.0897 -21.94597,12.64271 c -0.1817,0.0906 -0.40835,0.13571 -0.63595,0.13571 -0.0191,0 -0.0383,-0.006 -0.0574,-0.006 -0.0191,0 -0.0382,0.006 -0.0574,0.006 -0.22761,0 -0.45426,-0.0448 -0.63596,-0.13571 l -21.94597,-12.64271 -0.1817,-0.0897 v -0.0458 c -0.22664,-0.0906 -0.45425,-0.272 -0.591,-0.45321 -0.13675,-0.22651 -0.1817,-0.45283 -0.1817,-0.72474 v -13.84658 h -4.99785 v 13.84658 c 0,1.22346 0.31845,2.40116 1.00006,3.39802 0.63595,0.99687 1.49941,1.76756 2.54438,2.266 l 21.85397,12.59679 c 0.95441,0.54372 1.99909,0.81553 3.135,0.81553 0.0191,0 0.0383,-0.002 0.0574,-0.002 0.0191,1.5e-4 0.0383,0.002 0.0574,0.002 1.13582,0 2.18088,-0.27181 3.135,-0.81553 l 21.85388,-12.59679 c 1.04506,-0.49842 1.90833,-1.26913 2.54447,-2.26601 0.68186,-0.99686 0.99993,-2.17456 0.99993,-3.39801 v -10.13912 l -4.96979,2.24902 c -0.003,0.002 -0.007,0.003 -0.009,0.004 l -0.0191,0.009 v 9.9e-4 c -3.67781,1.85363 -11.76214,5.27167 -12.25675,5.22679 -0.51545,-0.0468 -1.02613,-0.90852 -1.93989,-3.0087 -1.43581,-3.25965 -2.03036,-7.02859 -2.7606,-10.52644 -0.11189,-0.53342 -0.2123,-1.05292 -0.30602,-1.54328 -0.19987,-1.02073 -0.37583,-1.951 -0.57188,-2.7781 -0.48294,-2.10064 -1.10292,-3.57668 -2.75362,-4.28444 -0.82339,-0.35306 -7.5181,-0.51892 -14.55287,-0.47219 -4.10681,0.0276 -8.23925,0.13362 -11.46998,0.31044 0.0669,-0.041 0.13293,-0.0792 0.20083,-0.10577 v -0.0448 l 0.18074,-0.0458 21.94597,-12.64171 c 0.1817,-0.136 0.40835,-0.18159 0.63595,-0.18159 0.0191,0 0.0383,0.008 0.0574,0.008 0.0191,-9.9e-4 0.0383,-0.008 0.0574,-0.008 0.2276,0 0.45425,0.0458 0.63595,0.18159 l 21.94606,12.64171 0.18075,0.0458 v 0.0448 c 0.2276,0.0906 0.45425,0.27191 0.591,0.45321 0.13676,0.22661 0.18266,0.45283 0.18266,0.72474 v 9.077 l 4.99772,-2.1602 v -6.9168 c 0,-1.22345 -0.31846,-2.40114 -0.99993,-3.39802 -0.63595,-0.99686 -1.49941,-1.76755 -2.54447,-2.26599 l -21.85397,-12.59675 c -0.95441,-0.54372 -1.99909,-0.81553 -3.135,-0.81553 -0.0191,0 -0.0383,0.003 -0.0574,0.003 -0.0191,-10e-5 -0.0383,-0.003 -0.0574,-0.003 z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.8 KiB |
|
@ -1 +0,0 @@
|
|||
Here is a list of all the generous people who has supported Serene so far:
|
101
scripts/.zshrc
101
scripts/.zshrc
|
@ -1,101 +0,0 @@
|
|||
#! /bin/zsh
|
||||
# shellcheck disable=all
|
||||
# Serene Programming Language
|
||||
#
|
||||
# Copyright (c) 2019-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
mkdir -p "$HOME/.config/serene/"
|
||||
|
||||
export HISTFILE="$HOME/.config/serene/.zsh_history"
|
||||
export HISTFILESIZE=500
|
||||
export SAVEHIST=500
|
||||
export HISTSIZE=500
|
||||
|
||||
setopt HIST_IGNORE_DUPS
|
||||
setopt NO_HIST_BEEP
|
||||
setopt PROMPT_SUBST
|
||||
setopt NO_BEEP
|
||||
setopt AUTO_CD
|
||||
setopt CORRECT
|
||||
setopt SHARE_HISTORY
|
||||
setopt HIST_IGNORE_ALL_DUPS
|
||||
setopt NO_ERR_EXIT
|
||||
|
||||
function user_prompt () {
|
||||
if [ $UID != 0 ]; then
|
||||
echo "%F{028}%F{002}> "
|
||||
else
|
||||
echo "%F{001}# "
|
||||
fi
|
||||
}
|
||||
|
||||
autoload -U colors && colors
|
||||
autoload -Uz compinit
|
||||
compinit
|
||||
|
||||
zstyle ':completion:*' auto-description 'specify: %d'
|
||||
zstyle ':completion:*' completer _expand _complete _correct _approximate
|
||||
zstyle ':completion:*' format 'Completing %d'
|
||||
zstyle ':completion:*' group-name ''
|
||||
if [ "$(uname 2> /dev/null)" = "Linux" ]; then
|
||||
zstyle ':completion:*' menu select=2 eval "$(dircolors -b)"
|
||||
fi
|
||||
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
|
||||
zstyle ':completion:*' list-colors ''
|
||||
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
|
||||
zstyle ':completion:*' matcher-list '' 'm:{a-z}={A-Z}' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=* l:|=*'
|
||||
zstyle ':completion:*' menu select=long
|
||||
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
|
||||
zstyle ':completion:*' use-compctl false
|
||||
zstyle ':completion:*' verbose true
|
||||
|
||||
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
|
||||
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'
|
||||
|
||||
echo "Welcome to serene's development environment"
|
||||
|
||||
PROMPT='
|
||||
%F{015}[%F{099}${BUILDER:-SERENE}%F{015}][%F{198}$(git branch --show-current)%F{015}]
|
||||
%F{005}%~%F{003} $(user_prompt)%f'
|
||||
|
||||
|
||||
echo -e "\nSerene Development Shell $VERSION"
|
||||
echo -e "\nCopyright (C) 2019-2024"
|
||||
echo -e "Sameer Rahmani <lxsameer@gnu.org>"
|
||||
echo -e "Serene comes with ABSOLUTELY NO WARRANTY;"
|
||||
echo -e "This is free software, and you are welcome"
|
||||
echo -e "to redistribute it under certain conditions;"
|
||||
echo -e "for details take a look at the LICENSE file.\n"
|
||||
echo -e "\nUse the 'help' command to view a list of helpers.\n"
|
||||
|
||||
ME=$(cd "$(dirname "$0")/." >/dev/null 2>&1 ; pwd -P)
|
||||
export ME
|
||||
|
||||
BUILD_DIR_NAME="build"
|
||||
export BUILD_DIR_NAME
|
||||
|
||||
BUILD_DIR="$ME/$BUILD_DIR_NAME"
|
||||
export BUILD_DIR
|
||||
|
||||
SERENE_HOME_DIR="$HOME/.serene"
|
||||
export SERENE_HOME_DIR
|
||||
|
||||
VERSION="0.9.0"
|
||||
builder="${BUILDER:l}"
|
||||
|
||||
. "$ME/scripts/${builder}functions.sh"
|
||||
|
||||
|
||||
export PROMPT
|
|
@ -0,0 +1,342 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Copyright 2018 Undo Ltd.
|
||||
#
|
||||
# https://github.com/barisione/clang-format-hooks
|
||||
|
||||
# Force variable declaration before access.
|
||||
set -u
|
||||
# Make any failure in piped commands be reflected in the exit code.
|
||||
set -o pipefail
|
||||
|
||||
readonly bash_source="${BASH_SOURCE[0]:-$0}"
|
||||
|
||||
##################
|
||||
# Misc functions #
|
||||
##################
|
||||
|
||||
function error_exit() {
|
||||
for str in "$@"; do
|
||||
echo -n "$str" >&2
|
||||
done
|
||||
echo >&2
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
########################
|
||||
# Command line parsing #
|
||||
########################
|
||||
|
||||
function show_help() {
|
||||
if [ -t 1 ] && hash tput 2> /dev/null; then
|
||||
local -r b=$(tput bold)
|
||||
local -r i=$(tput sitm)
|
||||
local -r n=$(tput sgr0)
|
||||
else
|
||||
local -r b=
|
||||
local -r i=
|
||||
local -r n=
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
${b}SYNOPSIS${n}
|
||||
|
||||
To reformat git diffs:
|
||||
|
||||
${i}$bash_source [OPTIONS] [FILES-OR-GIT-DIFF-OPTIONS]${n}
|
||||
|
||||
To reformat whole files, including unchanged parts:
|
||||
|
||||
${i}$bash_source [-f | --whole-file] FILES${n}
|
||||
|
||||
${b}DESCRIPTION${n}
|
||||
|
||||
Reformat C or C++ code to match a specified formatting style.
|
||||
|
||||
This command can either work on diffs, to reformat only changed parts of
|
||||
the code, or on whole files (if -f or --whole-file is used).
|
||||
|
||||
${b}FILES-OR-GIT-DIFF-OPTIONS${n}
|
||||
List of files to consider when applying clang-format to a diff. This is
|
||||
passed to "git diff" as is, so it can also include extra git options or
|
||||
revisions.
|
||||
For example, to apply clang-format on the changes made in the last few
|
||||
revisions you could use:
|
||||
${i}\$ $bash_source HEAD~3${n}
|
||||
|
||||
${b}FILES${n}
|
||||
List of files to completely reformat.
|
||||
|
||||
${b}-f, --whole-file${n}
|
||||
Reformat the specified files completely (including parts you didn't
|
||||
change).
|
||||
The fix is printed on stdout by default. Use -i if you want to modify
|
||||
the files on disk.
|
||||
|
||||
${b}--staged, --cached${n}
|
||||
Reformat only code which is staged for commit.
|
||||
The fix is printed on stdout by default. Use -i if you want to modify
|
||||
the files on disk.
|
||||
|
||||
${b}-i${n}
|
||||
Reformat the code and apply the changes to the files on disk (instead
|
||||
of just printing the fix on stdout).
|
||||
|
||||
${b}--apply-to-staged${n}
|
||||
This is like specifying both --staged and -i, but the formatting
|
||||
changes are also staged for commit (so you can just use "git commit"
|
||||
to commit what you planned to, but formatted correctly).
|
||||
|
||||
${b}--style STYLE${n}
|
||||
The style to use for reformatting code.
|
||||
If no style is specified, then it's assumed there's a .clang-format
|
||||
file in the current directory or one of its parents.
|
||||
|
||||
${b}--help, -h, -?${n}
|
||||
Show this help.
|
||||
EOF
|
||||
}
|
||||
|
||||
# getopts doesn't support long options.
|
||||
# getopt mangles stuff.
|
||||
# So we parse manually...
|
||||
declare positionals=()
|
||||
declare has_positionals=false
|
||||
declare whole_file=false
|
||||
declare apply_to_staged=false
|
||||
declare staged=false
|
||||
declare in_place=false
|
||||
declare style=file
|
||||
declare ignored=()
|
||||
while [ $# -gt 0 ]; do
|
||||
declare arg="$1"
|
||||
shift # Past option.
|
||||
case "$arg" in
|
||||
-h | -\? | --help )
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
-f | --whole-file )
|
||||
whole_file=true
|
||||
;;
|
||||
--apply-to-staged )
|
||||
apply_to_staged=true
|
||||
;;
|
||||
--cached | --staged )
|
||||
staged=true
|
||||
;;
|
||||
-i )
|
||||
in_place=true
|
||||
;;
|
||||
--style=* )
|
||||
style="${arg//--style=/}"
|
||||
;;
|
||||
--style )
|
||||
[ $# -gt 0 ] || \
|
||||
error_exit "No argument for --style option."
|
||||
style="$1"
|
||||
shift
|
||||
;;
|
||||
--internal-opt-ignore-regex=* )
|
||||
ignored+=("${arg//--internal-opt-ignore-regex=/}")
|
||||
;;
|
||||
--internal-opt-ignore-regex )
|
||||
ignored+=("${arg//--internal-opt-ignore-regex=/}")
|
||||
[ $# -gt 0 ] || \
|
||||
error_exit "No argument for --internal-opt-ignore-regex option."
|
||||
ignored+=("$1")
|
||||
shift
|
||||
;;
|
||||
-- )
|
||||
# Stop processing further arguments.
|
||||
if [ $# -gt 0 ]; then
|
||||
positionals+=("$@")
|
||||
has_positionals=true
|
||||
fi
|
||||
break
|
||||
;;
|
||||
-* )
|
||||
error_exit "Unknown argument: $arg"
|
||||
;;
|
||||
*)
|
||||
positionals+=("$arg")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Restore positional arguments, access them from "$@".
|
||||
if [ ${#positionals[@]} -gt 0 ]; then
|
||||
set -- "${positionals[@]}"
|
||||
has_positionals=true
|
||||
fi
|
||||
|
||||
[ -n "$style" ] || \
|
||||
error_exit "If you use --style you need to specify a valid style."
|
||||
|
||||
#######################################
|
||||
# Detection of clang-format & friends #
|
||||
#######################################
|
||||
|
||||
# clang-format.
|
||||
declare format="${CLANG_FORMAT:-}"
|
||||
if [ -z "$format" ]; then
|
||||
format=$(type -p clang-format)
|
||||
fi
|
||||
|
||||
if [ -z "$format" ]; then
|
||||
error_exit \
|
||||
$'You need to install clang-format.\n' \
|
||||
$'\n' \
|
||||
$'On Ubuntu/Debian this is available in the clang-format package or, in\n' \
|
||||
$'older distro versions, clang-format-VERSION.\n' \
|
||||
$'On Fedora it\'s available in the clang package.\n' \
|
||||
$'You can also specify your own path for clang-format by setting the\n' \
|
||||
$'$CLANG_FORMAT environment variable.'
|
||||
fi
|
||||
|
||||
# clang-format-diff.
|
||||
if [ "$whole_file" = false ]; then
|
||||
invalid="/dev/null/invalid/path"
|
||||
if [ "${OSTYPE:-}" = "linux-gnu" ]; then
|
||||
readonly sort_version=-V
|
||||
else
|
||||
# On macOS, sort doesn't have -V.
|
||||
readonly sort_version=-n
|
||||
fi
|
||||
declare paths_to_try=()
|
||||
# .deb packages directly from upstream.
|
||||
# We try these first as they are probably newer than the system ones.
|
||||
while read -r f; do
|
||||
paths_to_try+=("$f")
|
||||
done < <(compgen -G "/usr/share/clang/clang-format-*/clang-format-diff.py" | sort "$sort_version" -r)
|
||||
# LLVM official releases (just untarred in /usr/local).
|
||||
while read -r f; do
|
||||
paths_to_try+=("$f")
|
||||
done < <(compgen -G "/usr/local/clang+llvm*/share/clang/clang-format-diff.py" | sort "$sort_version" -r)
|
||||
# Maybe it's in the $PATH already? This is true for Ubuntu and Debian.
|
||||
paths_to_try+=( \
|
||||
"$(type -p clang-format-diff 2> /dev/null || echo "$invalid")" \
|
||||
"$(type -p clang-format-diff.py 2> /dev/null || echo "$invalid")" \
|
||||
)
|
||||
# Fedora.
|
||||
paths_to_try+=( \
|
||||
/usr/share/clang/clang-format-diff.py \
|
||||
)
|
||||
# Gentoo.
|
||||
while read -r f; do
|
||||
paths_to_try+=("$f")
|
||||
done < <(compgen -G "/usr/lib/llvm/*/share/clang/clang-format-diff.py" | sort -n -r)
|
||||
# Homebrew.
|
||||
while read -r f; do
|
||||
paths_to_try+=("$f")
|
||||
done < <(compgen -G "/usr/local/Cellar/clang-format/*/share/clang/clang-format-diff.py" | sort -n -r)
|
||||
|
||||
declare format_diff=
|
||||
|
||||
# Did the user specify a path?
|
||||
if [ -n "${CLANG_FORMAT_DIFF:-}" ]; then
|
||||
format_diff="$CLANG_FORMAT_DIFF"
|
||||
else
|
||||
for path in "${paths_to_try[@]}"; do
|
||||
if [ -e "$path" ]; then
|
||||
# Found!
|
||||
format_diff="$path"
|
||||
if [ ! -x "$format_diff" ]; then
|
||||
format_diff="python $format_diff"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$format_diff" ]; then
|
||||
error_exit \
|
||||
$'Cannot find clang-format-diff which should be shipped as part of the same\n' \
|
||||
$'package where clang-format is.\n' \
|
||||
$'\n' \
|
||||
$'Please find out where clang-format-diff is in your distro and report an issue\n' \
|
||||
$'at https://github.com/barisione/clang-format-hooks/issues with details about\n' \
|
||||
$'your operating system and setup.\n' \
|
||||
$'\n' \
|
||||
$'You can also specify your own path for clang-format-diff by setting the\n' \
|
||||
$'$CLANG_FORMAT_DIFF environment variable, for instance:\n' \
|
||||
$'\n' \
|
||||
$' CLANG_FORMAT_DIFF="python /.../clang-format-diff.py" \\\n' \
|
||||
$' ' "$bash_source"
|
||||
fi
|
||||
|
||||
readonly format_diff
|
||||
fi
|
||||
|
||||
|
||||
############################
|
||||
# Actually run the command #
|
||||
############################
|
||||
|
||||
if [ "$whole_file" = true ]; then
|
||||
|
||||
[ "$has_positionals" = true ] || \
|
||||
error_exit "No files to reformat specified."
|
||||
[ "$staged" = false ] || \
|
||||
error_exit "--staged/--cached only make sense when applying to a diff."
|
||||
|
||||
read -r -a format_args <<< "$format"
|
||||
format_args+=("-style=file")
|
||||
[ "$in_place" = true ] && format_args+=("-i")
|
||||
|
||||
"${format_args[@]}" "$@"
|
||||
|
||||
else # Diff-only.
|
||||
|
||||
if [ "$apply_to_staged" = true ]; then
|
||||
[ "$staged" = false ] || \
|
||||
error_exit "You don't need --staged/--cached with --apply-to-staged."
|
||||
[ "$in_place" = false ] || \
|
||||
error_exit "You don't need -i with --apply-to-staged."
|
||||
staged=true
|
||||
readonly patch_dest=$(mktemp)
|
||||
trap '{ rm -f "$patch_dest"; }' EXIT
|
||||
else
|
||||
readonly patch_dest=/dev/stdout
|
||||
fi
|
||||
|
||||
declare git_args=(git diff -U0 --no-color)
|
||||
[ "$staged" = true ] && git_args+=("--staged")
|
||||
|
||||
# $format_diff may contain a command ("python") and the script to excute, so we
|
||||
# need to split it.
|
||||
read -r -a format_diff_args <<< "$format_diff"
|
||||
[ "$in_place" = true ] && format_diff_args+=("-i")
|
||||
|
||||
# Build the regex for paths to consider or ignore.
|
||||
# We use negative lookahead assertions which preceed the list of allowed patterns
|
||||
# (that is, the extensions we want).
|
||||
exclusions_regex=
|
||||
if [ "${#ignored[@]}" -gt 0 ]; then
|
||||
for pattern in "${ignored[@]}"; do
|
||||
exclusions_regex="$exclusions_regex(?!$pattern)"
|
||||
done
|
||||
fi
|
||||
|
||||
"${git_args[@]}" "$@" \
|
||||
| "${format_diff_args[@]}" \
|
||||
-p1 \
|
||||
-style="$style" \
|
||||
-iregex="$exclusions_regex"'.*\.(c|cpp|cxx|cc|h|hpp|m|mm|js|java)' \
|
||||
> "$patch_dest" \
|
||||
|| exit 1
|
||||
|
||||
if [ "$apply_to_staged" = true ]; then
|
||||
if [ ! -s "$patch_dest" ]; then
|
||||
echo "No formatting changes to apply."
|
||||
exit 0
|
||||
fi
|
||||
patch -p0 < "$patch_dest" || \
|
||||
error_exit "Cannot apply fix to local files."
|
||||
git apply -p0 --cached < "$patch_dest" || \
|
||||
error_exit "Cannot apply fix to git staged changes."
|
||||
fi
|
||||
|
||||
fi
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue