diff --git a/.gitignore b/.gitignore
index 7e3e70a0..c799dc45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
-build/*
+*.o
+bin/
+lib/
src/load_piclib.c
src/init_contrib.c
docs/contrib.rst
diff --git a/.travis.yml b/.travis.yml
index 8400d479..3d9ab350 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,8 +8,9 @@ env:
before_script:
- sudo apt-get update -qq
- sudo apt-get install -y libc6:i386 libgcc1:i386 gcc-4.6-base:i386 gcc-multilib
- - cd build
script:
- perl --version
- - cmake .. && make test
- - cmake -DCMAKE_BUILD_TYPE=Debug .. && make test > /dev/null
+ - make test
+ - make clean
+ - make debug
+ - make test 2> /dev/null >/dev/null
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 45a3a2b6..00000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-cmake_minimum_required(VERSION 2.6)
-cmake_policy(VERSION 2.6)
-if(POLICY CMP0037)
- cmake_policy(SET CMP0037 OLD)
-endif()
-
-PROJECT(picrin)
-
-# load extra cmake modules
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
-
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY lib)
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wall -Wextra")
-set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g -DDEBUG=1")
-
-option(STRICT_C89_MODE "Strict c89 mode" OFF)
-if(STRICT_C89_MODE)
- add_definitions(-std=c89 -ansi -pedantic)
-endif()
-
-include_directories(extlib/benz/include)
-
-# build picrin
-include(piclib/CMakeLists.txt)
-include(contrib/CMakeLists.txt)
-include(src/CMakeLists.txt)
-include(docs/CMakeLists.txt)
-
-# ----
-
-# $ make run
-add_custom_target(run bin/picrin DEPENDS repl)
-
-# $ make test
-add_custom_target(test DEPENDS test-r7rs test-contribs)
-
-# $ make test-r7rs
-add_custom_target(test-r7rs bin/picrin ${PROJECT_SOURCE_DIR}/t/r7rs-tests.scm DEPENDS repl)
-
-# $ make test-contribs
-add_custom_target(test-contribs DEPENDS ${CONTRIB_TESTS})
-
-# $ make tak
-add_custom_target(tak bin/picrin ${PROJECT_SOURCE_DIR}/etc/tak.scm DEPENDS repl)
-
-# $ make lines
-add_custom_target(lines find . -name "*.[chyl]" | xargs wc -l WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..8305c3f8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,86 @@
+BENZ_SRCS = $(wildcard extlib/benz/*.c)
+BENZ_OBJS = $(BENZ_SRCS:.c=.o)
+
+PICRIN_SRCS = \
+ src/main.c\
+ src/load_piclib.c\
+ src/init_contrib.c
+PICRIN_OBJS = \
+ $(PICRIN_SRCS:.c=.o)
+PICRIN_LIBS = \
+ piclib/picrin/base.scm\
+ piclib/picrin/macro.scm\
+ piclib/picrin/record.scm\
+ piclib/picrin/array.scm\
+ piclib/picrin/dictionary.scm\
+ piclib/picrin/experimental/lambda.scm\
+ piclib/picrin/syntax-rules.scm\
+ piclib/picrin/test.scm
+
+CONTRIB_SRCS =
+CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o)
+CONTRIB_LIBS =
+CONTRIB_INITS =
+CONTRIB_TESTS =
+CONTRIB_DOCS = $(wildcard contrib/*/docs/*.rst)
+
+CFLAGS += -I./extlib/benz/include
+# CFLAGS += -std=c89 -ansi -pedantic
+LDFLAGS += -lm
+
+prefix = /usr/local
+
+all: CFLAGS += -O2 -Wall -Wextra
+all: bin/picrin
+
+include contrib/*/nitro.mk
+
+debug: CFLAGS += -O0 -g -DDEBUG=1
+debug: bin/picrin
+
+bin/picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a
+ $(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a $(LDFLAGS)
+
+src/load_piclib.c: $(PICRIN_LIBS) $(CONTRIB_LIBS)
+ perl etc/mkloader.pl $(PICRIN_LIBS) $(CONTRIB_LIBS) > $@
+
+src/init_contrib.c:
+ perl etc/mkinit.pl $(CONTRIB_INITS) > $@
+
+lib/libbenz.a: $(BENZ_OBJS)
+ $(AR) $(ARFLAGS) $@ $(BENZ_OBJS)
+
+%.o: extlib/benz/include/picrin.h extlib/benz/include/picrin/*.h
+
+doc: docs/*.rst docs/contrib.rst
+ $(MAKE) -C docs html
+ mkdir -p doc
+ cp -uR docs/_build/* -t doc/
+
+docs/contrib.rst: $(CONTRIB_DOCS)
+ echo "Contrib Libraries \\\(a.k.a nitros\\\)" > $@
+ echo "================================" >> $@
+ echo "" >> $@
+ cat $(CONTRIB_DOCS) >> $@
+
+run: bin/picrin
+ bin/picrin
+
+test: test-r7rs test-contribs
+
+test-r7rs: bin/picrin t/r7rs-tests.scm
+ bin/picrin t/r7rs-tests.scm
+
+test-contribs: bin/picrin $(CONTRIB_TESTS)
+
+install: all
+ install -c bin/picrin $(prefix)/bin/picrin
+
+clean:
+ rm -f src/load_piclib.c src/init_contrib.c
+ rm -f lib/libbenz.a
+ rm -f $(BENZ_OBJS)
+ rm -f $(PICRIN_OBJS)
+ rm -f $(CONTRIB_OBJS)
+
+.PHONY: all insall clean run test test-r7rs test-contribs doc $(CONTRIB_TESTS)
diff --git a/README.md b/README.md
index 1fccaac1..319b0424 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,18 @@
[![Build Status](https://travis-ci.org/picrin-scheme/picrin.png)](https://travis-ci.org/picrin-scheme/picrin)
[![Docs Status](https://readthedocs.org/projects/picrin/badge/?version=latest)](https://picrin.readthedocs.org/)
-Picrin is a lightweight scheme implementation intended to comply with full R7RS specification. Its code is written in pure C89 and does not require any special external libraries installed on the platform.
+Picrin is a lightweight R7RS scheme implementation written in pure C89. It contains a reasonably fast VM, an improved hygienic macro system, usuful contribution libraries, and simple but powerful C interface.
+
+- R7RS compatible
+- Reentrant design (all VM states are stored in single global state object)
+- Bytecode interpreter
+- Direct threaded VM
+- Internal representation by nan-boxing (available only on x64)
+- Conservative call/cc implementation (VM stack and native c stack can interleave)
+- Exact GC (simple mark and sweep, partially reference count)
+- String representation by rope
+- Hygienic macro transformers (syntactic closures, explicit and implicit renaming macros)
+- Extended library syntax
## Documentation
@@ -17,71 +28,36 @@ https://github.com/picrin-scheme/picrin
## IRC
-There is a chat room on chat.freenode.org, channel #picrin. IRC logs here: https://botbot.me/freenode/picrin/
+Our chat room is at #picrin channel, chat.freenode.org. IRC logs here: https://botbot.me/freenode/picrin/
-## How to use it
+## Build
-To build picrin, you need some build tools installed on your platform.
+Just type `make` in the project root directory. You will find an executable binary newly created at bin/ directory.
-- cmake (>= 2.6)
+ $ make
+When you are building picrin on x86_64 system, PIC_NAN_BOXING flag is automatically turned on (see include/picrin/config.h for detail).
-### Generate Makefile
+## Install
-Change directory to `build` then run `cmake` to create Makefile. Once `Makefile` is generated you can run `make` command to build picrin.
-
- $ cd build
- $ cmake ..
-
-Actually you don't necessarily need to move to `build` directory before running `cmake` (in that case `$ cmake .`), but I strongly recommend to follow above instruction.
-
-Before generating Makefile, you can change some compilation switches to enable or disable optional features. Take *NAN_BOXING* for example, when you turn on "Use C11 feature" flag and the platform supports addresses of 48bit length, it is enabled.
-
-### Build
-
-A built executable binary will be under bin/ directory and shared libraries under lib/.
-
- $ make
-
-If you are building picrin on other systems than x86_64, PIC_NAN_BOXING flag is automatically turned on (see include/picrin/config.h for detail).
-
-### Install
-
-Just running `make install`, picrin library, headers, and runtime binary are install on your system, by default into `/usr/local` directory. You can change this value via cmake.
+`make install` target is provided. By default it installs picrin binary into `/usr/local/bin/`.
$ make install
-### Run
+Since picrin does not use autoconf, if you want to specify the install directory, pass the custom path to `make` via command line argument.
-Before installing picrin, you can try picrin without breaking any of your system. Simply directly run the binary `bin/picrin` from terminal, or you can use `make` to execute it like this.
+ $ make install prefix=/path/to/dir
- $ make run
-
-### Run Test
-To run all the test including contribs, execute this.
-
- $ make test
-
-To test only R7RS features,
-
- $ make test-r7rs
-
-### Debug run
-
-If you execute `cmake` with debug flag `-DCMAKE_BUILD_TYPE=Debug`, it builds the binary with all debug flags enabled (PIC_GC_STRESS, VM_DEBUG, DEBUG).
-
- $ cmake -DCMAKE_BUILD_TYPE=Debug ..
-
## Requirement
-Picrin scheme depends on some external libraries to build the binary:
+To build Picrin Scheme from source code, some external libraries are required:
- perl
+- regex.h of POSIX.1
- libedit (optional)
-- regex.h of POSIX.1 (optional)
-Optional libraries are, if cmake detected them, automatically enabled.
-The compilation is tested only on Mac OSX and Ubuntu. I think (or hope) it'll be ok to compile and run on other operating systems such as Arch or Windows, but I don't guarantee :(
+Make command automatically turns on optional libraries if available.
+Picrin is mainly developed on Mac OS X and only tested on OS X or Ubuntu 14.04+. When you tried to run picrin on other platforms and found something was wrong with it, please send us an issue.
## Authors
diff --git a/build/.gitkeep b/bin/.gitkeep
similarity index 100%
rename from build/.gitkeep
rename to bin/.gitkeep
diff --git a/cmake/FindPYTHON.cmake b/cmake/FindPYTHON.cmake
deleted file mode 100644
index 3268da79..00000000
--- a/cmake/FindPYTHON.cmake
+++ /dev/null
@@ -1,193 +0,0 @@
-##############################################################################
-# @file FindPythonInterp.cmake
-# @brief Find Python interpreter.
-#
-# @par Input variables:
-#
-#
-# @tp @b Python_ADDITIONAL_VERSIONS @endtp
-# List of version numbers that should be taken into account when
-# searching for Python. |
-#
-#
-#
-# @par Output variables:
-#
-#
-# @tp @b PYTHONINTERP_FOUND @endtp
-# Was the Python executable found. |
-#
-#
-# @tp @b PYTHON_EXECUTABLE @endtp
-# Path to the Python interpreter. |
-#
-#
-# @tp @b PYTHON_VERSION_STRING @endtp
-# Python version found e.g. 2.5.2. |
-#
-#
-# @tp @b PYTHON_VERSION_MAJOR @endtp
-# Python major version found e.g. 2. |
-#
-#
-# @tp @b PYTHON_VERSION_MINOR @endtp
-# Python minor version found e.g. 5. |
-#
-#
-# @tp @b PYTHON_VERSION_PATCH @endtp
-# Python patch version found e.g. 2. |
-#
-#
-#
-# @note This module has been copied from the Git repository of CMake on
-# 4/12/2012, i.e., before the release of CMake 2.8.8. Once CMake 2.8.8
-# or any version is available for all major platforms, consider to
-# remove this module from the BASIS package.
-#
-# @ingroup CMakeFindModules
-##############################################################################
-
-#=============================================================================
-# Copyright 2005-2010 Kitware, Inc.
-# Copyright 2011 Bjoern Ricks
-# Copyright 2012 Rolf Eike Beer
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# * Neither the names of Kitware, Inc., the Insight Software Consortium,
-# nor the names of their contributors may be used to endorse or promote
-# products derived from this software without specific prior written
-# permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#=============================================================================
-
-unset(_Python_NAMES)
-
-set(_PYTHON1_VERSIONS 1.6 1.5)
-set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
-
-if(PythonInterp_FIND_VERSION)
- if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
- string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION}")
- string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}")
- list(APPEND _Python_NAMES python${_PYTHON_FIND_MAJ_MIN} python${_PYTHON_FIND_MAJ})
- unset(_PYTHON_FIND_OTHER_VERSIONS)
- if(NOT PythonInterp_FIND_VERSION_EXACT)
- foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
- if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
- list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
- endif()
- endforeach()
- endif(NOT PythonInterp_FIND_VERSION_EXACT)
- unset(_PYTHON_FIND_MAJ_MIN)
- unset(_PYTHON_FIND_MAJ)
- else(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
- list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION})
- set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS})
- endif(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
-else(PythonInterp_FIND_VERSION)
- set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
-endif(PythonInterp_FIND_VERSION)
-
-list(APPEND _Python_NAMES python)
-
-# Search for the current active python version first
-find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES})
-
-# Set up the versions we know about, in the order we will search. Always add
-# the user supplied additional versions to the front.
-set(_Python_VERSIONS
- ${Python_ADDITIONAL_VERSIONS}
- ${_PYTHON_FIND_OTHER_VERSIONS}
- )
-
-unset(_PYTHON_FIND_OTHER_VERSIONS)
-unset(_PYTHON1_VERSIONS)
-unset(_PYTHON2_VERSIONS)
-unset(_PYTHON3_VERSIONS)
-
-# Search for newest python version if python executable isn't found
-if(NOT PYTHON_EXECUTABLE)
- foreach(_CURRENT_VERSION ${_Python_VERSIONS})
- set(_Python_NAMES python${_CURRENT_VERSION})
- if(WIN32)
- list(APPEND _Python_NAMES python)
- endif()
- find_program(PYTHON_EXECUTABLE
- NAMES ${_Python_NAMES}
- PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]
- )
- endforeach()
-endif()
-
-# determine python version string
-if(PYTHON_EXECUTABLE)
- execute_process(COMMAND "${PYTHON_EXECUTABLE}" -E -c
- "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))"
- OUTPUT_VARIABLE _VERSION
- RESULT_VARIABLE _PYTHON_VERSION_RESULT
- ERROR_QUIET)
- if(NOT _PYTHON_VERSION_RESULT)
- string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}")
- list(GET _VERSION 0 PYTHON_VERSION_MAJOR)
- list(GET _VERSION 1 PYTHON_VERSION_MINOR)
- list(GET _VERSION 2 PYTHON_VERSION_PATCH)
- if(PYTHON_VERSION_PATCH EQUAL 0)
- # it's called "Python 2.7", not "2.7.0"
- string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}")
- endif()
- else()
- # sys.version predates sys.version_info, so use that
- execute_process(COMMAND "${PYTHON_EXECUTABLE}" -E -c "import sys; sys.stdout.write(sys.version)"
- OUTPUT_VARIABLE _VERSION
- RESULT_VARIABLE _PYTHON_VERSION_RESULT
- ERROR_QUIET)
- if(NOT _PYTHON_VERSION_RESULT)
- string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}")
- string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}")
- string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}")
- if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
- string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}")
- else()
- set(PYTHON_VERSION_PATCH "0")
- endif()
- else()
- # sys.version was first documented for Python 1.5, so assume
- # this is older.
- set(PYTHON_VERSION_STRING "1.4")
- set(PYTHON_VERSION_MAJOR "1")
- set(PYTHON_VERSION_MINOR "4")
- set(PYTHON_VERSION_PATCH "0")
- endif()
- endif()
- unset(_PYTHON_VERSION_RESULT)
- unset(_VERSION)
-endif(PYTHON_EXECUTABLE)
-
-# handle the QUIETLY and REQUIRED arguments and set PYTHONINTERP_FOUND to TRUE if
-# all listed variables are TRUE
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING)
-
-mark_as_advanced(PYTHON_EXECUTABLE)
diff --git a/contrib/03.callcc/CMakeLists.txt b/contrib/03.callcc/CMakeLists.txt
deleted file mode 100644
index 55a73452..00000000
--- a/contrib/03.callcc/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB PICRIN_CALLCC_SOURCES ${PROJECT_SOURCE_DIR}/contrib/03.callcc/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS callcc)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_CALLCC_SOURCES})
diff --git a/contrib/03.callcc/nitro.mk b/contrib/03.callcc/nitro.mk
new file mode 100644
index 00000000..60dbe96b
--- /dev/null
+++ b/contrib/03.callcc/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += callcc
+CONTRIB_SRCS += $(wildcard contrib/03.callcc/*.c)
diff --git a/contrib/03.file/CMakeLists.txt b/contrib/03.file/CMakeLists.txt
deleted file mode 100644
index 22987e3e..00000000
--- a/contrib/03.file/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB PICRIN_FILE_SOURCES ${PROJECT_SOURCE_DIR}/contrib/03.file/src/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS file)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_FILE_SOURCES})
diff --git a/contrib/03.file/nitro.mk b/contrib/03.file/nitro.mk
new file mode 100644
index 00000000..d6bcbd93
--- /dev/null
+++ b/contrib/03.file/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += file
+CONTRIB_SRCS += $(wildcard contrib/03.file/src/*.c)
diff --git a/contrib/03.load/CMakeLists.txt b/contrib/03.load/CMakeLists.txt
deleted file mode 100644
index bb0d6a3d..00000000
--- a/contrib/03.load/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB PICRIN_LOAD_SOURCES ${PROJECT_SOURCE_DIR}/contrib/03.load/src/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS load)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_LOAD_SOURCES})
diff --git a/contrib/03.load/nitro.mk b/contrib/03.load/nitro.mk
new file mode 100644
index 00000000..87566d36
--- /dev/null
+++ b/contrib/03.load/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += load
+CONTRIB_SRCS += $(wildcard contrib/03.load/src/*.c)
diff --git a/contrib/03.mutable-string/CMakeLists.txt b/contrib/03.mutable-string/CMakeLists.txt
deleted file mode 100644
index faa8402b..00000000
--- a/contrib/03.mutable-string/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-file(GLOB PICRIN_MUTABLE_STRING_SOURCES
- ${PROJECT_SOURCE_DIR}/contrib/03.mutable-string/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS mutable_string)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_MUTABLE_STRING_SOURCES})
diff --git a/contrib/03.mutable-string/nitro.mk b/contrib/03.mutable-string/nitro.mk
new file mode 100644
index 00000000..37d31b55
--- /dev/null
+++ b/contrib/03.mutable-string/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += mutable_string
+CONTRIB_SRCS += $(wildcard contrib/03.mutable-string/*.c)
diff --git a/contrib/03.system/CMakeLists.txt b/contrib/03.system/CMakeLists.txt
deleted file mode 100644
index c18f3266..00000000
--- a/contrib/03.system/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB PICRIN_SYSTEM_SOURCES ${PROJECT_SOURCE_DIR}/contrib/03.system/src/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS system)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_SYSTEM_SOURCES})
diff --git a/contrib/03.system/nitro.mk b/contrib/03.system/nitro.mk
new file mode 100644
index 00000000..e9553587
--- /dev/null
+++ b/contrib/03.system/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += system
+CONTRIB_SRCS += $(wildcard contrib/03.system/src/*.c)
diff --git a/contrib/03.time/CMakeLists.txt b/contrib/03.time/CMakeLists.txt
deleted file mode 100644
index dc69714a..00000000
--- a/contrib/03.time/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB PICRIN_TIME_SOURCES ${PROJECT_SOURCE_DIR}/contrib/03.time/src/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS time)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_TIME_SOURCES})
diff --git a/contrib/03.time/nitro.mk b/contrib/03.time/nitro.mk
new file mode 100644
index 00000000..61b7c4d3
--- /dev/null
+++ b/contrib/03.time/nitro.mk
@@ -0,0 +1,2 @@
+CONTRIB_INITS += time
+CONTRIB_SRCS += $(wildcard contrib/03.time/src/*.c)
diff --git a/contrib/05.r7rs/CMakeLists.txt b/contrib/05.r7rs/CMakeLists.txt
deleted file mode 100644
index 814d80c2..00000000
--- a/contrib/05.r7rs/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-list(APPEND PICLIB_SCHEME_LIBS
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/base.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/cxr.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/read.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/write.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/file.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/case-lambda.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/lazy.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/eval.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/inexact.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/load.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/process-context.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/time.scm
- ${PROJECT_SOURCE_DIR}/contrib/05.r7rs/scheme/r5rs.scm
- )
diff --git a/contrib/05.r7rs/nitro.mk b/contrib/05.r7rs/nitro.mk
new file mode 100644
index 00000000..b811b92e
--- /dev/null
+++ b/contrib/05.r7rs/nitro.mk
@@ -0,0 +1,14 @@
+CONTRIB_LIBS += \
+ contrib/05.r7rs/scheme/base.scm\
+ contrib/05.r7rs/scheme/cxr.scm\
+ contrib/05.r7rs/scheme/read.scm\
+ contrib/05.r7rs/scheme/write.scm\
+ contrib/05.r7rs/scheme/file.scm\
+ contrib/05.r7rs/scheme/case-lambda.scm\
+ contrib/05.r7rs/scheme/lazy.scm\
+ contrib/05.r7rs/scheme/eval.scm\
+ contrib/05.r7rs/scheme/inexact.scm\
+ contrib/05.r7rs/scheme/load.scm\
+ contrib/05.r7rs/scheme/process-context.scm\
+ contrib/05.r7rs/scheme/time.scm\
+ contrib/05.r7rs/scheme/r5rs.scm
diff --git a/contrib/10.optional/CMakeLists.txt b/contrib/10.optional/CMakeLists.txt
deleted file mode 100644
index c6a60a8a..00000000
--- a/contrib/10.optional/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-file(GLOB OPTIONAL_FILES ${PROJECT_SOURCE_DIR}/contrib/10.optional/piclib/*.scm)
-list(APPEND PICLIB_CONTRIB_LIBS ${OPTIONAL_FILES})
-add_custom_target(test-optional
- for test in ${PROJECT_SOURCE_DIR}/contrib/10.optional/t/*.scm \;
- do
- bin/picrin "$$test" \;
- done
- DEPENDS repl)
-set(CONTRIB_TESTS ${CONTRIB_TESTS} test-optional)
diff --git a/contrib/10.optional/nitro.mk b/contrib/10.optional/nitro.mk
new file mode 100644
index 00000000..9048a19f
--- /dev/null
+++ b/contrib/10.optional/nitro.mk
@@ -0,0 +1,7 @@
+CONTRIB_LIBS += $(wildcard contrib/10.optional/piclib/*.scm)
+CONTRIB_TESTS += test-optional
+
+test-optional: bin/picrin
+ for test in `ls contrib/10.optional/t/*.scm`; do \
+ bin/picrin $$test; \
+ done
diff --git a/contrib/10.partcont/CMakeLists.txt b/contrib/10.partcont/CMakeLists.txt
deleted file mode 100644
index 65f16fb2..00000000
--- a/contrib/10.partcont/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-file(GLOB PARTCONT_FILES ${PROJECT_SOURCE_DIR}/contrib/10.partcont/piclib/*.scm)
-list(APPEND PICLIB_CONTRIB_LIBS ${PARTCONT_FILES})
diff --git a/contrib/10.partcont/nitro.mk b/contrib/10.partcont/nitro.mk
new file mode 100644
index 00000000..454bd39d
--- /dev/null
+++ b/contrib/10.partcont/nitro.mk
@@ -0,0 +1 @@
+CONTRIB_LIBS += $(wildcard contrib/10.partcont/piclib/*.scm)
diff --git a/contrib/10.pretty-print/CMakeLists.txt b/contrib/10.pretty-print/CMakeLists.txt
deleted file mode 100644
index cf0327da..00000000
--- a/contrib/10.pretty-print/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-list(APPEND PICLIB_CONTRIB_LIBS ${PROJECT_SOURCE_DIR}/contrib/10.pretty-print/pretty-print.scm)
diff --git a/contrib/10.pretty-print/nitro.mk b/contrib/10.pretty-print/nitro.mk
new file mode 100644
index 00000000..28070d61
--- /dev/null
+++ b/contrib/10.pretty-print/nitro.mk
@@ -0,0 +1 @@
+CONTRIB_LIBS += contrib/10.pretty-print/pretty-print.scm
diff --git a/contrib/10.random/CMakeLists.txt b/contrib/10.random/CMakeLists.txt
deleted file mode 100644
index 224686b9..00000000
--- a/contrib/10.random/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-file(GLOB PICRIN_RANDOM_SOURCES ${PROJECT_SOURCE_DIR}/contrib/10.random/src/*.c)
-
-list(APPEND PICRIN_CONTRIB_INITS random)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_RANDOM_SOURCES})
-add_custom_target(test-random
- for test in ${PROJECT_SOURCE_DIR}/contrib/10.random/t/*.scm \;
- do
- bin/picrin "$$test" \;
- done
- DEPENDS repl)
-set(CONTRIB_TESTS ${CONTRIB_TESTS} test-random)
diff --git a/contrib/10.random/nitro.mk b/contrib/10.random/nitro.mk
new file mode 100644
index 00000000..e7ba691d
--- /dev/null
+++ b/contrib/10.random/nitro.mk
@@ -0,0 +1,8 @@
+CONTRIB_INITS += random
+CONTRIB_SRCS += $(wildcard contrib/10.random/src/*.c)
+CONTRIB_TESTS += test-random
+
+test-random: bin/picrin
+ for test in `ls contrib/10.random/t/*.scm`; do \
+ bin/picrin $$test; \
+ done
diff --git a/contrib/10.readline/CMakeLists.txt b/contrib/10.readline/CMakeLists.txt
deleted file mode 100644
index 413e8c19..00000000
--- a/contrib/10.readline/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# readline
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/contrib/10.readline/cmake/")
-
-find_package(Libedit)
-if (Libedit_FOUND)
- add_definitions(${Libedit_DEFINITIONS} -DPIC_READLINE_FOUND=1 -DPIC_READLINE_INCLUDE_DIR_SUFFIX=${Libedit_INCLUDE_DIR_SUFFIX})
- include_directories(${Libedit_INCLUDE_DIR})
-
- file(GLOB PICRIN_READLINE_SOURCES ${PROJECT_SOURCE_DIR}/contrib/10.readline/src/*.c)
-
- list(APPEND PICRIN_CONTRIB_INITS readline)
- list(APPEND PICRIN_CONTRIB_LIBRARIES ${Libedit_LIBRARIES})
- list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_READLINE_SOURCES})
- add_custom_target(test-readline for test in ${PROJECT_SOURCE_DIR}/contrib/10.readline/t/*.scm \; do bin/picrin "$$test" \; done DEPENDS repl)
- set(CONTRIB_TESTS ${CONTRIB_TESTS} test-readline)
-endif(Libedit_FOUND)
diff --git a/contrib/10.readline/cmake/FindLibedit.cmake b/contrib/10.readline/cmake/FindLibedit.cmake
deleted file mode 100644
index 9a771988..00000000
--- a/contrib/10.readline/cmake/FindLibedit.cmake
+++ /dev/null
@@ -1,107 +0,0 @@
-# - Try to find libedit
-# Once done this will define
-#
-# Libedit_FOUND - system has libedit
-# Libedit_INCLUDE_DIRS - the libedit include directory
-# Libedit_LIBRARIES - Link these to use libedit
-# Libedit_DEFINITIONS - Compiler switches required for using libedit
-#
-# Copyright (c) 2014 Yuichi Nishiwaki
-# Copyright (c) 2008 Andreas Schneider
-# Modified for other libraries by Lasse Kärkkäinen
-#
-# Redistribution and use is allowed according to the terms of the New
-# BSD license.
-#
-
-
-if (Libedit_LIBRARIES AND Libedit_INCLUDE_DIRS)
- # in cache already
- set(Libedit_FOUND TRUE)
-else (Libedit_LIBRARIES AND Libedit_INCLUDE_DIRS)
- # use pkg-config to get the directories and then use these values
- # in the FIND_PATH() and FIND_LIBRARY() calls
- if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
- include(UsePkgConfig)
- pkgconfig(libedit _Libedit_INCLUDEDIR _Libedit_LIBDIR _Libedit_LDFLAGS _Libedit_CFLAGS)
- else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
- find_package(PkgConfig)
- if (PKG_CONFIG_FOUND)
- pkg_check_modules(_LIBEDIT libedit)
- endif (PKG_CONFIG_FOUND)
- endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
- find_path(Libedit_EDITLINE_INCLUDE_DIR
- NAMES
- editline/readline.h
- editline/history.h
- PATHS
- ${_Libedit_INCLUDEDIR}
- /usr/include
- /usr/local/include
- /opt/local/include
- /sw/include
- )
- if (Libedit_EDITLINE_INCLUDE_DIR)
- set(Libedit_INCLUDE_DIR_SUFFIX editline)
- set(Libedit_INCLUDE_DIR ${Libedit_EDITLINE_INCLUDE_DIR})
- else (Libedit_EDITLINE_INCLUDE_DIR)
- find_path(Libedit_READLINE_INCLUDE_DIR
- NAMES
- readline/readline.h
- readline/history.h
- PATHS
- /usr/include/edit
- /usr/local/include/edit
- /opt/local/include/edit
- /sw/include/edit
- )
- if (Libedit_READLINE_INCLUDE_DIR)
- set(Libedit_INCLUDE_DIR_SUFFIX readline)
- set(Libedit_INCLUDE_DIR ${Libedit_READLINE_INCLUDE_DIR})
- endif (Libedit_READLINE_INCLUDE_DIR)
- endif (Libedit_EDITLINE_INCLUDE_DIR)
-
- find_library(Libedit_LIBRARY
- NAMES
- edit
- PATHS
- ${_Libedit_LIBDIR}
- /usr/lib
- /usr/local/lib
- /opt/local/lib
- /sw/lib
- )
-
- if (Libedit_LIBRARY)
- set(Libedit_FOUND TRUE)
- endif (Libedit_LIBRARY)
-
- set(Libedit_INCLUDE_DIRS
- ${Libedit_INCLUDE_DIR}
- )
-
- if (Libedit_FOUND)
- set(Libedit_LIBRARIES
- ${Libedit_LIBRARIES}
- ${Libedit_LIBRARY}
- )
- endif (Libedit_FOUND)
-
- if (Libedit_INCLUDE_DIRS AND Libedit_LIBRARIES)
- set(Libedit_FOUND TRUE)
- endif (Libedit_INCLUDE_DIRS AND Libedit_LIBRARIES)
-
- if (Libedit_FOUND)
- if (NOT Libedit_FIND_QUIETLY)
- message(STATUS "Found libedit: ${Libedit_LIBRARY}, ${Libedit_INCLUDE_DIR}")
- endif (NOT Libedit_FIND_QUIETLY)
- else (Libedit_FOUND)
- if (Libedit_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find libedit")
- endif (Libedit_FIND_REQUIRED)
- endif (Libedit_FOUND)
-
- # show the Libedit_INCLUDE_DIRS and Libedit_LIBRARIES variables only in the advanced view
- mark_as_advanced(Libedit_INCLUDE_DIRS Libedit_LIBRARIES)
-
-endif (Libedit_LIBRARIES AND Libedit_INCLUDE_DIRS)
diff --git a/contrib/10.readline/nitro.mk b/contrib/10.readline/nitro.mk
new file mode 100644
index 00000000..51d296ea
--- /dev/null
+++ b/contrib/10.readline/nitro.mk
@@ -0,0 +1,16 @@
+libedit_exists := $(shell pkg-config libedit --exists; echo $$?)
+
+ifeq ($(libedit_exists),0)
+ CONTRIB_SRCS += contrib/10.readline/src/readline.c
+ CONTRIB_INITS += readline
+ CONTRIB_TESTS += test-readline
+ LDFLAGS += `pkg-config libedit --libs`
+endif
+
+contrib/src/readline.o: contrib/src/readline.c
+ $(CC) $(CFLAGS) -o $@ $< `pkg-config libedit --cflags`
+
+test-readline: bin/picrin
+ for test in `ls contrib/10.readline/t/*.scm`; do \
+ bin/picrin $$test; \
+ done
diff --git a/contrib/10.readline/src/readline.c b/contrib/10.readline/src/readline.c
index fe831ddd..84d3f37f 100644
--- a/contrib/10.readline/src/readline.c
+++ b/contrib/10.readline/src/readline.c
@@ -7,13 +7,7 @@ forget to use the C++ extern "C" to get it to compile.
*/
#include "picrin.h"
-#if PIC_READLINE_INCLUDE_DIR_SUFFIX == readline
-#include
-#include
-#else
#include
-#include
-#endif
static pic_value
pic_rl_readline(pic_state *pic)
diff --git a/contrib/10.regexp/CMakeLists.txt b/contrib/10.regexp/CMakeLists.txt
deleted file mode 100644
index c13c76d3..00000000
--- a/contrib/10.regexp/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# regex
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/contrib/10.regexp/cmake/")
-
-find_package(REGEX)
-
-if (REGEX_FOUND)
- add_definitions(${REGEX_DEFINITIONS})
- include_directories(${REGEX_INCLUDE_DIR})
-
- file(GLOB PICRIN_REGEX_SOURCES ${PROJECT_SOURCE_DIR}/contrib/10.regexp/src/*.c)
-
- list(APPEND PICRIN_CONTRIB_INITS regexp)
- list(APPEND PICRIN_CONTRIB_LIBRARIES ${REGEX_LIBRARIES})
- list(APPEND PICRIN_CONTRIB_SOURCES ${PICRIN_REGEX_SOURCES})
- add_custom_target(test-regexp for test in ${PROJECT_SOURCE_DIR}/contrib/10.regexp/t/*.scm \; do bin/picrin "$$test" \; done DEPENDS repl)
- set(CONTRIB_TESTS ${CONTRIB_TESTS} test-regexp)
-endif()
diff --git a/contrib/10.regexp/cmake/FindREGEX.cmake b/contrib/10.regexp/cmake/FindREGEX.cmake
deleted file mode 100644
index f7b88113..00000000
--- a/contrib/10.regexp/cmake/FindREGEX.cmake
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- cmake -*-
-#
-# FindRegex.cmake: Try to find Regex
-#
-# Copyright (C) 2014- Yuichi Nishiwaki
-# Copyright (C) 2005-2013 EDF-EADS-Phimeca
-#
-# This library is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This library 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# along with this library. If not, see .
-#
-# @author dutka
-# @date 2010-02-04 16:44:49 +0100 (Thu, 04 Feb 2010)
-#
-# - Try to find Regex
-# Once done this will define
-#
-# REGEX_FOUND - System has Regex
-# REGEX_INCLUDE_DIR - The Regex include directory
-# REGEX_LIBRARIES - The libraries needed to use Regex
-# REGEX_DEFINITIONS - Compiler switches required for using Regex
-#
-#
-# ChangeLogs:
-#
-# 2014/05/07 - Yuichi Nishiwaki
-# On Mac, it finds /System/Library/Frameworks/Ruby.framework/Headers/regex.h,
-# which was a part of superold version of glibc when POSIX standard didn't exist.
-# To avoid this behavior, we call find_path twice, searching /usr/include and
-# /usr/local/include first and if nothing was found then searching $PATH in the
-# second stage.
-#
-
-IF (REGEX_INCLUDE_DIR AND REGEX_LIBRARIES)
- # in cache already
- SET(Regex_FIND_QUIETLY TRUE)
-ENDIF (REGEX_INCLUDE_DIR AND REGEX_LIBRARIES)
-
-#IF (NOT WIN32)
-# # use pkg-config to get the directories and then use these values
-# # in the FIND_PATH() and FIND_LIBRARY() calls
-# FIND_PACKAGE(PkgConfig)
-# PKG_CHECK_MODULES(PC_REGEX regex)
-# SET(REGEX_DEFINITIONS ${PC_REGEX_CFLAGS_OTHER})
-#ENDIF (NOT WIN32)
-
-FIND_PATH(REGEX_INCLUDE_DIR regex.h
- PATHS /usr/include /usr/local/include
- NO_DEFAULT_PATH
- )
-
-IF (NOT REGEX_INCLUDE_DIR)
- FIND_PATH(REGEX_INCLUDE_DIR regex.h
- HINTS
- ${REGEX_INCLUDEDIR}
- ${PC_LIBXML_INCLUDE_DIRS}
- PATH_SUFFIXES regex
- )
-ENDIF()
-
-FIND_LIBRARY(REGEX_LIBRARIES NAMES c regex
- HINTS
- ${PC_REGEX_LIBDIR}
- ${PC_REGEX_LIBRARY_DIRS}
- )
-
-INCLUDE(FindPackageHandleStandardArgs)
-
-# handle the QUIETLY and REQUIRED arguments and set REGEX_FOUND to TRUE if
-# all listed variables are TRUE
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Regex DEFAULT_MSG REGEX_LIBRARIES REGEX_INCLUDE_DIR)
-
-MARK_AS_ADVANCED(REGEX_INCLUDE_DIR REGEX_LIBRARIES)
diff --git a/contrib/10.regexp/nitro.mk b/contrib/10.regexp/nitro.mk
new file mode 100644
index 00000000..9fe45e2f
--- /dev/null
+++ b/contrib/10.regexp/nitro.mk
@@ -0,0 +1,8 @@
+CONTRIB_SRCS += contrib/10.regexp/src/regexp.c
+CONTRIB_INITS += regexp
+CONTRIB_TESTS += test-regexp
+
+test-regexp: bin/picrin
+ for test in `ls contrib/10.regexp/t/*.scm`; do \
+ bin/picrin $$test; \
+ done
diff --git a/contrib/10.srfi/CMakeLists.txt b/contrib/10.srfi/CMakeLists.txt
deleted file mode 100644
index 1cabb620..00000000
--- a/contrib/10.srfi/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-list(APPEND PICLIB_CONTRIB_LIBS
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/1.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/8.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/17.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/26.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/43.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/60.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/95.scm
- ${PROJECT_SOURCE_DIR}/contrib/10.srfi/srfi/111.scm
- )
diff --git a/contrib/10.srfi/nitro.mk b/contrib/10.srfi/nitro.mk
new file mode 100644
index 00000000..d8ac54ab
--- /dev/null
+++ b/contrib/10.srfi/nitro.mk
@@ -0,0 +1,9 @@
+CONTRIB_LIBS += \
+ contrib/10.srfi/srfi/1.scm\
+ contrib/10.srfi/srfi/8.scm\
+ contrib/10.srfi/srfi/17.scm\
+ contrib/10.srfi/srfi/26.scm\
+ contrib/10.srfi/srfi/43.scm\
+ contrib/10.srfi/srfi/60.scm\
+ contrib/10.srfi/srfi/95.scm\
+ contrib/10.srfi/srfi/111.scm
diff --git a/contrib/20.for/CMakeLists.txt b/contrib/20.for/CMakeLists.txt
deleted file mode 100644
index 5e109d90..00000000
--- a/contrib/20.for/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB FOR_FILES ${PROJECT_SOURCE_DIR}/contrib/20.for/piclib/*.scm)
-list(APPEND PICLIB_CONTRIB_LIBS ${FOR_FILES})
-add_custom_target(test-for for test in ${PROJECT_SOURCE_DIR}/contrib/20.for/t/*.scm \; do bin/picrin "$$test" \; done DEPENDS repl)
-set(CONTRIB_TESTS ${CONTRIB_TESTS} test-for)
diff --git a/contrib/20.for/nitro.mk b/contrib/20.for/nitro.mk
new file mode 100644
index 00000000..b2c2cbad
--- /dev/null
+++ b/contrib/20.for/nitro.mk
@@ -0,0 +1,7 @@
+CONTRIB_LIBS += $(wildcard contrib/20.for/piclib/*.scm)
+CONTRIB_TESTS += test-for
+
+test-for: bin/picrin
+ for test in `ls contrib/20.for/t/*.scm`; do \
+ bin/picrin "$$test"; \
+ done
diff --git a/contrib/20.repl/CMakeLists.txt b/contrib/20.repl/CMakeLists.txt
deleted file mode 100644
index 7fc3bf06..00000000
--- a/contrib/20.repl/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-list(APPEND PICLIB_CONTRIB_LIBS ${PROJECT_SOURCE_DIR}/contrib/20.repl/repl.scm)
-list(APPEND PICRIN_CONTRIB_SOURCES ${PROJECT_SOURCE_DIR}/contrib/20.repl/repl.c)
-list(APPEND PICRIN_CONTRIB_INITS repl)
diff --git a/contrib/20.repl/nitro.mk b/contrib/20.repl/nitro.mk
new file mode 100644
index 00000000..f03e4ad7
--- /dev/null
+++ b/contrib/20.repl/nitro.mk
@@ -0,0 +1,3 @@
+CONTRIB_LIBS += contrib/20.repl/repl.scm
+CONTRIB_SRCS += contrib/20.repl/repl.c
+CONTRIB_INITS += repl
diff --git a/contrib/20.repl/repl.scm b/contrib/20.repl/repl.scm
index f745ce4e..60411749 100644
--- a/contrib/20.repl/repl.scm
+++ b/contrib/20.repl/repl.scm
@@ -11,7 +11,9 @@
(else
(begin
(define (readline str)
- (if (tty?) (display str))
+ (when (tty?)
+ (display str)
+ (flush-output-port))
(read-line))
(define (add-history str)
#f))))
diff --git a/contrib/30.main/CMakeLists.txt b/contrib/30.main/CMakeLists.txt
deleted file mode 100644
index ceef792f..00000000
--- a/contrib/30.main/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-list(APPEND PICLIB_CONTRIB_LIBS ${PROJECT_SOURCE_DIR}/contrib/30.main/main.scm)
diff --git a/contrib/30.main/nitro.mk b/contrib/30.main/nitro.mk
new file mode 100644
index 00000000..a425fdc0
--- /dev/null
+++ b/contrib/30.main/nitro.mk
@@ -0,0 +1 @@
+CONTRIB_LIBS += contrib/30.main/main.scm
diff --git a/contrib/40.class/CMakeLists.txt b/contrib/40.class/CMakeLists.txt
deleted file mode 100644
index 5281edcd..00000000
--- a/contrib/40.class/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-file(GLOB CLASS_FILES ${PROJECT_SOURCE_DIR}/contrib/40.class/piclib/picrin/*.scm)
-list(APPEND PICLIB_CONTRIB_LIBS ${CLASS_FILES})
diff --git a/contrib/40.class/nitro.mk b/contrib/40.class/nitro.mk
new file mode 100644
index 00000000..cec300c1
--- /dev/null
+++ b/contrib/40.class/nitro.mk
@@ -0,0 +1 @@
+CONTRIB_LIBS += $(wildcard contrib/40.class/piclib/picrin/*.scm)
diff --git a/contrib/50.protocol/CMakeLists.txt b/contrib/50.protocol/CMakeLists.txt
deleted file mode 100644
index 41b4df2f..00000000
--- a/contrib/50.protocol/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-file(GLOB PROTOCOL_FILES ${PROJECT_SOURCE_DIR}/contrib/50.protocol/piclib/picrin/*.scm)
-list(APPEND PICLIB_CONTRIB_LIBS ${PROTOCOL_FILES})
diff --git a/contrib/50.protocol/nitro.mk b/contrib/50.protocol/nitro.mk
new file mode 100644
index 00000000..2db1bf31
--- /dev/null
+++ b/contrib/50.protocol/nitro.mk
@@ -0,0 +1 @@
+CONTRIB_LIBS += $(wildcard contrib/50.protocol/piclib/picrin/*.scm)
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
deleted file mode 100644
index 11050d90..00000000
--- a/contrib/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-file(GLOB CONTRIBS ${PROJECT_SOURCE_DIR}/contrib/*/CMakeLists.txt)
-list(SORT CONTRIBS)
-foreach(contrib ${CONTRIBS})
- include(${contrib})
-endforeach()
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
deleted file mode 100644
index a468e943..00000000
--- a/docs/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# contribs
-file(GLOB PICRIN_CONTRIB_DOCS ${PROJECT_SOURCE_DIR}/contrib/*/docs/*.rst)
-file(GLOB PICRIN_DOCS ${PROJECT_SOURCE_DIR}/docs/*.rst)
-list(SORT PICRIN_CONTRIB_DOCS)
-
-set(PICRIN_CONTRIBS_DOC ${PROJECT_SOURCE_DIR}/docs/contrib.rst)
-set(PICRIN_DOC_OUTPUT_DIRECTORY doc)
-
-add_custom_command(
- OUTPUT ${PICRIN_CONTRIBS_DOC}
- COMMAND echo "Contrib Libraries \\\(a.k.a nitros\\\)" > ${PICRIN_CONTRIBS_DOC}
- COMMAND echo "================================" >> ${PICRIN_CONTRIBS_DOC}
- COMMAND echo "" >> ${PICRIN_CONTRIBS_DOC}
- COMMAND cat ${PICRIN_CONTRIB_DOCS} >> ${PICRIN_CONTRIBS_DOC}
- DEPENDS ${PICRIN_CONTRIB_DOCS}
- )
-
-add_custom_target(doc
- COMMAND make -C ${PROJECT_SOURCE_DIR}/docs html
- DEPENDS ${PICRIN_CONTRIBS_DOC}
- )
-
-add_custom_command(
- TARGET doc POST_BUILD
- COMMAND mkdir -p ${PICRIN_DOC_OUTPUT_DIRECTORY}
- COMMAND cp -uR ${PROJECT_SOURCE_DIR}/docs/_build/* -t ${PICRIN_DOC_OUTPUT_DIRECTORY}/
- )
\ No newline at end of file
diff --git a/docs/deploy.rst b/docs/deploy.rst
index 7a4a9330..7bb36135 100644
--- a/docs/deploy.rst
+++ b/docs/deploy.rst
@@ -4,68 +4,34 @@ Installation
Installation instructions below.
-Build and Install
------------------
-
-To build picrin, you need some build tools installed on your platform.
-
-- cmake (>= 2.6)
-- git
-
-Because of submodule dependencies, it is necessary to get picrin's source code via git clone command. Basically our git dependencies are only due to submodules, so in fact, If you have no git on your machine, it is possible to build it by downloading a tarball from github page as well. But in such case, you are assumed to modify CMakeLists.txt by yourself to get it work completely. We just strongly recommend you to use git-clone.
-
-Generate Makefile
-^^^^^^^^^^^^^^^^^
-
-Change directory to `build` then run `ccmake` to create Makefile. Once `Makefile` is generated you can run `make` command to build picrin::
-
- $ cd build
-
- $ ccmake ..
-
-Actually you don't necessarily need to move to `build` directory before running `ccmake` (in that case `$ ccmake .`), but I strongly recommend to follow above instruction.
-
-Before generating Makefile, you can change some compilation switches to enable or disable optional features. Take *NAN_BOXING* for example, when you turn on "Use C11 feature" flag and the platform supports addresses of 48bit length, it is enabled.
-
Build
-^^^^^
+-----
-A built executable binary will be under bin/ directory and shared libraries under lib/::
+Just type `make` in the project root directory. You will find an executable binary newly created at bin/ directory.
- $ make
+ $ make
-If you are building picrin on other systems than x86_64, PIC_NAN_BOXING flag is automatically turned on (see include/picrin/config.h for detail).
+When you are building picrin on x86_64 system, PIC_NAN_BOXING flag is automatically turned on (see include/picrin/config.h for detail).
Install
-^^^^^^^
+-------
-Just running `make install`, picrin library, headers, and runtime binary are install on your system, by default into `/usr/local` directory. You can change this value via ccmake::
+`make install` target is provided. By default it installs picrin binary into `/usr/local/bin/`.
- $ make install
+ $ make install
-Run
-^^^
-
-Before installing picrin, you can try picrin without breaking any of your system. Simply directly run the binary `bin/picrin` from terminal, or you can use `make` to execute it like this::
-
- $ make run
-
-Debug run
-^^^^^^^^^
-
-If you execute `cmake` with debug flag `-DCMAKE_BUILD_TYPE=Debug`, it builds the binary with all debug flags enabled (PIC_GC_STRESS, VM_DEBUG, DEBUG)::
-
- $ cmake -DCMAKE_BUILD_TYPE=Debug ..
+Since picrin does not use autoconf, if you want to specify the install directory, pass the custom path to `make` via command line argument.
+ $ make install prefix=/path/to/dir
Requirement
-----------
-Picrin scheme depends on some external libraries to build the binary:
+To build Picrin Scheme from source code, some external libraries are required:
- perl
-- readline (optional)
-- regex.h of POSIX.1 (optional)
+- regex.h of POSIX.1
+- libedit (optional)
-Optional libraries are, if cmake detected them, automatically enabled.
-The compilation is tested only on Mac OSX and Ubuntu. I think (or hope) it'll be ok to compile and run on other operating systems such as Arch or Windows, but I don't guarantee :(
+Make command automatically turns on optional libraries if available.
+Picrin is mainly developed on Mac OS X and only tested on OS X or Ubuntu 14.04+. When you tried to run picrin on other platforms and found something was wrong with it, please send us an issue.
diff --git a/docs/intro.rst b/docs/intro.rst
index 5cc22c15..fa72e69c 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -1,20 +1,18 @@
Introduction
============
-Picrin is a lightweight scheme implementation intended to comply with full R7RS specification. Its code is written in pure C89 and does not require any special external libraries installed on the platform.
+Picrin is a lightweight R7RS scheme implementation written in pure C89. It contains a reasonably fast VM, an improved hygienic macro system, usuful contribution libraries, and simple but powerful C interface.
-- R7RS compatibility
-- reentrant design (all VM states are stored in single global state object)
-- bytecode interpreter (based on stack VM)
-- direct threaded VM
-- internal representation by nan-boxing
-- conservative call/cc implementation (users can freely interleave native stack with VM stack)
-- exact GC (simple mark and sweep, partially reference count is used as well)
-- string representation by rope data structure
-- support full set hygienic macro transformers, including implicit renaming macros
-- extended library syntax
-- advanced REPL support (multi-line input, etc)
-- tiny & portable library (all functions will be in `libpicrin.so`)
+- R7RS compatible
+- Reentrant design (all VM states are stored in single global state object)
+- Bytecode interpreter
+- Direct threaded VM
+- Internal representation by nan-boxing (available only on x64)
+- Conservative call/cc implementation (VM stack and native c stack can interleave)
+- Exact GC (simple mark and sweep, partially reference count)
+- String representation by rope
+- Hygienic macro transformers (syntactic closures, explicit and implicit renaming macros)
+- Extended library syntax
Homepage
--------
diff --git a/.gitmodules b/lib/.gitkeep
similarity index 100%
rename from .gitmodules
rename to lib/.gitkeep
diff --git a/piclib/CMakeLists.txt b/piclib/CMakeLists.txt
deleted file mode 100644
index 5e734f4a..00000000
--- a/piclib/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-list(APPEND PICLIB_SCHEME_LIBS
- ${PROJECT_SOURCE_DIR}/piclib/picrin/base.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/macro.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/record.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/array.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/dictionary.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/experimental/lambda.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/syntax-rules.scm
- ${PROJECT_SOURCE_DIR}/piclib/picrin/test.scm
- )
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
deleted file mode 100644
index 0ca3b949..00000000
--- a/src/CMakeLists.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-### libpicrin ###
-
-find_package(Perl REQUIRED)
-
-# benz
-file(GLOB BENZ_SOURCES extlib/benz/*.c)
-
-# srcs
-file(GLOB PICRIN_SOURCES src/*.c)
-
-# piclib
-set(PICLIB_SOURCE ${PROJECT_SOURCE_DIR}/src/load_piclib.c)
-add_custom_command(
- OUTPUT ${PICLIB_SOURCE}
- COMMAND ${PERL_EXECUTABLE} etc/mkloader.pl ${PICLIB_SCHEME_LIBS} ${PICLIB_CONTRIB_LIBS} > ${PICLIB_SOURCE}
- DEPENDS ${PICLIB_SCHEME_LIBS} ${PICLIB_CONTRIB_LIBS}
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
- )
-
-# contrib
-set(CONTRIB_INIT ${PROJECT_SOURCE_DIR}/src/init_contrib.c)
-add_custom_command(
- OUTPUT ${CONTRIB_INIT}
- COMMAND ${PERL_EXECUTABLE} etc/mkinit.pl ${PICRIN_CONTRIB_INITS} > ${CONTRIB_INIT}
- DEPENDS ${PICRIN_CONTRIB_SOURCES}
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
- )
-
-add_library(picrin SHARED ${BENZ_SOURCES} ${PICRIN_SOURCES} ${PICLIB_SOURCE} ${PICRIN_CONTRIB_SOURCES} ${CONTRIB_INIT})
-target_link_libraries(picrin m ${PICRIN_CONTRIB_LIBRARIES})
-
-# install
-set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
-install(TARGETS picrin DESTINATION lib)
-install(DIRECTORY extlib/benz/include/ DESTINATION include FILES_MATCHING PATTERN "*.h")
-
-### picrin ###
-
-list(APPEND REPL_LIBRARIES picrin)
-
-# build
-add_executable(repl src/main.c)
-set_target_properties(repl PROPERTIES OUTPUT_NAME picrin)
-target_link_libraries(repl ${REPL_LIBRARIES})
-
-# install
-install(TARGETS repl RUNTIME DESTINATION bin)