1
0
Fork 0

Compare commits

..

11 Commits

11 changed files with 694 additions and 263 deletions

2
.gitignore vendored
View File

@ -1,7 +1,7 @@
*.swp *.swp
*.swo *.swo
*.link *.link
compile-r7rs compile-scheme
test-r7rs test-r7rs
test test
*.c *.c

104
Makefile
View File

@ -3,7 +3,7 @@ SCHEME=chibi
VERSION=1.0.0 VERSION=1.0.0
R6RSTMP=tmp/${SCHEME}-r6rs R6RSTMP=tmp/${SCHEME}-r6rs
R7RSTMP=tmp/${SCHEME}-r7rs R7RSTMP=tmp/${SCHEME}-r7rs
DOCKERTAG=compile-r7rs-test-${SCHEME} DOCKERTAG=compile-scheme-test-${SCHEME}
DOCKERIMG=${SCHEME}:head DOCKERIMG=${SCHEME}:head
ifeq "${SCHEME}" "chicken" ifeq "${SCHEME}" "chicken"
DOCKERIMG="chicken:5" DOCKERIMG="chicken:5"
@ -15,10 +15,13 @@ STATIC_LIBS=libs.util.a libs.library-util.a libs.data.a libs.srfi-64-util.a
all: build-chibi all: build-chibi
README.md: doc/compile-scheme.1
printf "<pre>\n$$(MANWIDTH=80 man -l doc/compile-scheme.1)\n</pre>" > README.md
build-chibi: build-chibi:
echo "#!/bin/sh" > compile-r7rs echo "#!/bin/sh" > compile-scheme
echo "chibi-scheme -A ${PREFIX}/lib/compile-r7rs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs echo "chibi-scheme -A ${PREFIX}/lib/compile-scheme ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
chmod +x compile-r7rs chmod +x compile-scheme
build-chicken: build-chicken:
csc -R r7rs -X r7rs -static -c -J -unit libs.util -o libs.util.o libs/util.sld csc -R r7rs -X r7rs -static -c -J -unit libs.util -o libs.util.o libs/util.sld
@ -28,70 +31,76 @@ build-chicken:
csc -R r7rs -X r7rs -static -c -J -unit libs.data -o libs.data.o libs/data.sld csc -R r7rs -X r7rs -static -c -J -unit libs.data -o libs.data.o libs/data.sld
ar rcs libs.data.a libs.data.o ar rcs libs.data.a libs.data.o
csc -R r7rs -X r7rs -static \ csc -R r7rs -X r7rs -static \
-o compile-r7rs \ -o compile-scheme \
-uses libs.util \ -uses libs.util \
-uses libs.library-util \ -uses libs.library-util \
-uses libs.data \ -uses libs.data \
-uses foreign.c \ -uses foreign.c \
-uses srfi-170 \ -uses srfi-170 \
compile-r7rs.scm compile-scheme.scm
deb: build-chicken deb: build-gauche
mkdir -p deb/bin mkdir -p deb/usr/local/bin
cp compile-r7rs deb/bin/ cp compile-scheme deb/usr/local/bin/
mkdir -p deb/usr/local/lib/compile-scheme
cp compile-scheme.scm deb/usr/local/lib/compile-scheme/
cp -r libs/ deb/usr/local/lib/compile-scheme/
mkdir -p deb/DEBIAN mkdir -p deb/DEBIAN
printf "Package: compile-r7rs\nArchitecture: amd64\nVersion: ${VERSION}\nSection: misc\nMaintainer: Retropikzel <retropikzel@iki.fi>\nDescription: SRFI 138: Compiling Scheme programs to executables - Implementation" \ printf "Package: compile-scheme\nArchitecture: amd64\nDepends: gauche\nVersion: ${VERSION}\nSection: misc\nMaintainer: Retropikzel <retropikzel@iki.fi>\nDescription: SRFI 138: Compiling Scheme programs to executables - Implementation\n" \
> deb/DEBIAN/control > deb/DEBIAN/control
dpkg-deb -b deb dpkg-deb -b deb
mv deb.deb compile-scheme-${VERSION}.deb
# FIXME build-gauche:
#build-gauche: echo "#!/bin/sh" > compile-scheme
#echo "#!/bin/sh" > compile-r7rs echo "gosh -r7 -I ${PREFIX}/lib/compile-scheme -I ${PREFIX}/lib/compile-scheme/libs ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
#echo "gosh -r -I ${PREFIX}/lib/compile-r7rs -I ${PREFIX}/lib/compile-r7rs/libs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs chmod +x compile-scheme
#chmod +x compile-r7rs
build-guile: build-guile:
echo "#!/bin/sh" > compile-r7rs echo "#!/bin/sh" > compile-scheme
echo "guile --r7rs --auto-compile -I -q -L ${PREFIX}/lib/compile-r7rs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs echo "guile --r7rs --auto-compile -I -q -L ${PREFIX}/lib/compile-scheme ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
chmod +x compile-r7rs chmod +x compile-scheme
# FIXME # FIXME
#build-kawa: #build-kawa:
#echo "#!/bin/sh" > compile-r7rs #echo "#!/bin/sh" > compile-scheme
#echo "kawa -J--add-exports=java.base/jdk.internal.foreign.abi=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign.layout=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED -Dkawa.import.path=/usr/local/share/kawa/lib/*.sld:${PREFIX}/lib/compile-r7rs/*.sld --r7rs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\" 2> /dev/null" >> compile-r7rs #echo "kawa -J--add-exports=java.base/jdk.internal.foreign.abi=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign.layout=ALL-UNNAMED -J--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED -Dkawa.import.path=/usr/local/share/kawa/lib/*.sld:${PREFIX}/lib/compile-scheme/*.sld --r7rs ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\" 2> /dev/null" >> compile-scheme
#chmod +x compile-r7rs #chmod +x compile-scheme
# FIXME # FIXME
#build-racket: #build-racket:
#echo "#!/bin/sh" > compile-r7rs #echo "#!/bin/sh" > compile-scheme
#echo "racket -I r7rs -S ${PREFIX}/lib/compile-r7rs --script ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs #echo "racket -I r7rs -S ${PREFIX}/lib/compile-scheme --script ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
build-sagittarius: build-sagittarius:
echo "#!/bin/sh" > compile-r7rs echo "#!/bin/sh" > compile-scheme
echo "sash -A ${PREFIX}/lib/compile-r7rs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs echo "sash -A ${PREFIX}/lib/compile-scheme ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
chmod +x compile-r7rs chmod +x compile-scheme
build-stklos: build-stklos:
echo "#!/bin/sh" > compile-r7rs echo "#!/bin/sh" > compile-scheme
echo "stklos -I ${PREFIX}/lib/compile-r7rs ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm \"\$$@\"" >> compile-r7rs echo "stklos -I ${PREFIX}/lib/compile-scheme ${PREFIX}/lib/compile-scheme/compile-scheme.scm \"\$$@\"" >> compile-scheme
chmod +x compile-r7rs chmod +x compile-scheme
install: install:
mkdir -p ${PREFIX}/bin mkdir -p ${PREFIX}/bin
mkdir -p ${PREFIX}/lib/compile-r7rs mkdir -p ${PREFIX}/lib/compile-scheme
cp -r libs ${PREFIX}/lib/compile-r7rs/ cp -r libs ${PREFIX}/lib/compile-scheme/
cp compile-r7rs.scm ${PREFIX}/lib/compile-r7rs/compile-r7rs.scm cp compile-scheme.scm ${PREFIX}/lib/compile-scheme/compile-scheme.scm
install compile-r7rs ${PREFIX}/bin/compile-r7rs install compile-scheme ${PREFIX}/bin/compile-scheme
mkdir -p ${PREFIX}/share/man/man1
cp doc/compile-scheme.1 ${PREFIX}/share/man/man1/
if [ -d /etc/bash_completion.d ]; then cp bash_completion.sh /etc/bash_completion.d/compile-scheme; fi
uninstall: uninstall:
rm -rf ${PREFIX}/lib/compile-r7rs rm -rf ${PREFIX}/lib/compile-scheme
rm -rf ${PREFIX}/bin/compile-r7rs rm -rf ${PREFIX}/bin/compile-scheme
test-r6rs: test-r6rs:
rm -rf ${R6RSTMP} rm -rf ${R6RSTMP}
mkdir -p ${R6RSTMP} mkdir -p ${R6RSTMP}
cp -r r6rs-testfiles/* ${R6RSTMP}/ cp -r r6rs-testfiles/* ${R6RSTMP}/
cd ${R6RSTMP} && COMPILE_R7RS=${SCHEME} compile-r7rs -I ./libs -o main main.sps cd ${R6RSTMP} && COMPILE_R7RS=${SCHEME} compile-scheme -I ./libs -o main main.sps
cd ${R6RSTMP} && ./main 1 2 3 > test-result.txt cd ${R6RSTMP} && ./main 1 2 3 > test-result.txt
@grep "Test successfull (\"1\" \"2\" \"3\")" ${R6RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R6RSTMP}/test-result.txt && exit 1) @grep "Test successfull (\"1\" \"2\" \"3\")" ${R6RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R6RSTMP}/test-result.txt && exit 1)
@ -103,7 +112,7 @@ test-r6rs-php:
rm -rf ${R6RSTMP} rm -rf ${R6RSTMP}
mkdir -p ${R6RSTMP} mkdir -p ${R6RSTMP}
cp -r r6rs-php-testfiles/* ${R6RSTMP}/ cp -r r6rs-php-testfiles/* ${R6RSTMP}/
cd ${R6RSTMP} && COMPILE_R7RS=${SCHEME} COMPILE_R7RS_TARGET=php compile-r7rs -o main.php main.sps cd ${R6RSTMP} && COMPILE_R7RS=${SCHEME} compile-scheme -t php -o main.php main.sps
-cd ${R6RSTMP} && php main.php > test-result.txt 2>&1 -cd ${R6RSTMP} && php main.php > test-result.txt 2>&1
@grep "Test successfull" ${R6RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R6RSTMP}/test-result.txt && exit 1) @grep "Test successfull" ${R6RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R6RSTMP}/test-result.txt && exit 1)
@ -115,7 +124,7 @@ test-r7rs:
rm -rf ${R7RSTMP} rm -rf ${R7RSTMP}
mkdir -p ${R7RSTMP} mkdir -p ${R7RSTMP}
cp -r r7rs-testfiles/* ${R7RSTMP}/ cp -r r7rs-testfiles/* ${R7RSTMP}/
cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} compile-r7rs -I ./libs -o main main.scm cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} compile-scheme -I ./libs main.scm
-cd ${R7RSTMP} && ./main 1 2 3 > test-result.txt 2>&1 -cd ${R7RSTMP} && ./main 1 2 3 > test-result.txt 2>&1
@grep "Test successfull (\"1\" \"2\" \"3\")" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1) @grep "Test successfull (\"1\" \"2\" \"3\")" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1)
@ -127,7 +136,7 @@ test-r7rs-wine:
rm -rf ${R7RSTMP} rm -rf ${R7RSTMP}
mkdir -p ${R7RSTMP} mkdir -p ${R7RSTMP}
cp -r r7rs-testfiles/* ${R7RSTMP}/ cp -r r7rs-testfiles/* ${R7RSTMP}/
cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} COMPILE_R7RS_TARGET=windows compile-r7rs -I ./libs -o main.bat main.scm cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} COMPILE_R7RS_TARGET=windows compile-scheme -I ./libs -o main.bat main.scm
-cd ${R7RSTMP} && wine main.bat 1 2 3 > test-result.txt 2>&1 -cd ${R7RSTMP} && wine main.bat 1 2 3 > test-result.txt 2>&1
@grep "Test successfull (\"1\" \"2\" \"3\")" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1) @grep "Test successfull (\"1\" \"2\" \"3\")" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1)
@ -139,7 +148,7 @@ test-r7rs-php:
rm -rf ${R7RSTMP} rm -rf ${R7RSTMP}
mkdir -p ${R7RSTMP} mkdir -p ${R7RSTMP}
cp -r r7rs-php-testfiles/* ${R7RSTMP}/ cp -r r7rs-php-testfiles/* ${R7RSTMP}/
cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} COMPILE_R7RS_TARGET=php compile-r7rs -o main.php main.scm cd ${R7RSTMP} && COMPILE_R7RS=${SCHEME} COMPILE_R7RS_TARGET=php compile-scheme -o main.php main.scm
-cd ${R7RSTMP} && php main.php > test-result.txt 2>&1 -cd ${R7RSTMP} && php main.php > test-result.txt 2>&1
@grep "Test successfull" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1) @grep "Test successfull" ${R7RSTMP}/test-result.txt || (echo "Test failed, output: " && cat ${R7RSTMP}/test-result.txt && exit 1)
@ -148,17 +157,4 @@ test-r7rs-php-docker:
docker run -v "${PWD}":/workdir -w /workdir -t ${DOCKERTAG} sh -c "make SCHEME=${SCHEME} test-r7rs-php" docker run -v "${PWD}":/workdir -w /workdir -t ${DOCKERTAG} sh -c "make SCHEME=${SCHEME} test-r7rs-php"
clean: clean:
rm -rf test-r7rs git clean -X -f
rm -rf compile-r7rs
find . -name "*.so" -delete
find . -name "*.o*" -delete
find . -name "*.a*" -delete
find . -name "*.rkt" -delete
find . -name "*.link" -delete
find . -name "*.meta" -delete
find . -name "*.import.*" -delete
rm -rf libs.library-util.c
rm -rf dist
rm -rf deps

286
README.md
View File

@ -1,197 +1,115 @@
compile-r7rs is a tool to compile Scheme programs, it aims for compability <pre>
with [SRFI-138](https://srfi.schemers.org/srfi-138/srfi-138.html). compile-scheme(1) General Commands Manual compile-scheme(1)
Despite it's name it also supports R6RS. Schemers, unite! <3 NAME
compile-scheme - Compiling Scheme programs to executables
[Jenkins](https://jenkins.scheme.org/job/retropikzel/job/compile-r7rs/) SYNOPSIS
compile-scheme [-A path] [-I path] [-o path] input-file.sps
## Notes compile-scheme [-A path] [-I path] [-o path] input-file.scm
- No support for -D flag yet. compile-scheme long-option
- Not all implementations support adding to beginning or end o load path so
-I and -A might work the same
## Build and install DESCRIPTION
compile-scheme is a tool to compile R6RS and R7RS Scheme programs. It
supports most of SRFI-138 but also adds more features.
You can run compile-r7rs on Chibi, Chicken, Gauche, Guile, Kawa, Sagittarius or The program input-file is compiled into an executable file. The result
STklos. ing executable file is written to file specified by the -o path (if
present) or to the file named same as input-file but without the .scm or
snow-chibi --impls=SCHEME "(foreign c)" .sps suffix. On Windows either .bat or .exe is appended to the output
snow-chibi --impls=SCHEME "(srfi 170)" name.
make build-SCHEME
make install
## Usage
### R6RS
Replace the .scm file with .sps file in the next section.
### R7RS
You need to install each Scheme implementation yourself.
The environment variable COMPILE\_R7RS must be set to the **name** of the
implementation as specified in the support list.
**This differs from the SRFI** as the SRFI excepts a path.
To get the list of supported R6RS implementations run:
compile-r7rs --list-r6rs-schemes
To get the list of supported R7RS implementations run:
compile-r7rs --list-r7rs-schemes
To get the list of all supported implementations run:
compile-r7rs --list-schemes
Then run it with the .scm file for R7RS, or .sps file for R6RS.
COMPILE_R7RS=<implementation name> compile-r7rs -I . -o main main.scm
Which produces file called main, which you can run. Note that when given Scheme
is interpreter the file contains commands that run the script, and even when
the file is combiled binary it might need the compiled libraries.
No other file suffixes are supported at the moment.
Setting value of COMPILE\_R7RS to implementation name that supports only r7rs
and input file to .sps file and other way around is undefined behaviour.
### Environment variables
- COMPILE\_R7RS
- **Name** of the implementation you want to compile with
- **This differs from the SRFI** as it excepts a path
- COMPILE\_R7RS\_SCHEME_NAME
- Additional string to insert right after the command and it's arguments
can be used for example to pass C compiler flags on implementations that
compile to C or anything or otherwise as backdoor
- For example for Chicken to link with libcurl you would set
COMPILE\_R7RS\_CHICKEN="-L -lcurl"
- If implementation has - it is changed to \_, for example mit-scheme ->
MIT\_SCHEME
- **This differs from the SRFI** as it's not in there
## Supported implementations
SUPPORTED IMPLEMENTATIONS
Some implementations support both compiling and interpreting, in that Some implementations support both compiling and interpreting, in that
case only the compiler functionality is used and the implementation is marked case only the compiler functionality is used and the implementation is
as compiler. marked as compiler.
- chezscheme R6RS Compilers
- interpreter loko
- R6RS
- chibi
- interpreter
- R7RS
- chicken
- compiler
- R7RS
- cyclone
- compiler
- R7RS
- foment
- interpreter
- R7RS
- gauche
- interpreter
- R7RS
- guile
- interpreter
- R6RS
- R7RS
- Has include bug https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66046
but for some reason it seems to work for me atleast sometimes
- ikarus
- interpreter
- R6RS
- ironscheme
- interpreter
- R6RS
- kawa
- interpreter
- R7RS
- Native access is enabled by default so pffi can work
- larceny
- interpreter
- R6RS
- R7RS
- loko
- compiler
- R6RS
- R7RS
- meevax
- r7rs
- mit-scheme
- interpreter
- R7RS
- mosh
- interpreter
- R6RS
- R7RS
- racket
- interpreter
- Has compiling capabilities but I havent got them to work yet
- r6rs
- r7rs
- sagittarius
- interpreter
- R6RS
- R7RS
- skint
- interpreter
- R7RS
- stklos
- interpreter
- R7RS
- tr7
- interpreter
- R7RS
- ypsilon
- interpreter
- R6RS
- R7RS
## Roadmap R6RS Interpreters
chezscheme guile ikarus ironscheme mosh racket sagittarius ypsilon
- Support for more implementations R7RS Compilers
- gambit chicken cyclone loko
- husk
- Dont know how to add directories to load path yet, might not be
implemented
- r7rs
- picrin
- Might not be possible, seems to not have (include...) that works like
others
- r7rs
- scheme-rs
- Waiting for implementation support
- r6rs
- r7rs
- stak
- Waiting for implementation support https://github.com/raviqqe/stak/issues/2355
- r7rs
- vicare
- So old that I have problems compiling it in Docker, so testing is
hard but I expect it to work once I get it to compile as it is R6RS
implementation
- r6rs
- Better and tested support for Windows
- Right now there is support for running this but I can not quarantee it
works on all if any cases
- Support for -D
- Most implementations dont have this or equivalent flag, but it would be
really nice feature to have so filing issues and implementing it myself is
something I would like to do
- Ask implementations to support adding to the front and back of load path, or
implement this onto implementations myself
- This might not be as important, but it would be nice to go towards SRFI-138
conformaty
- Environment variable to force the target operating system
- Since for example for interpreters the program produces .bat file with
command to run the interpreter "cross compiling" is easy.
R7RS Interpreters
chibi foment gauche guile kawa larceny meevax mit-scheme mosh racket
sagittarius skint stklos tr7 ypsilon
OPTIONS
-A path Append path to the list of directories that are searched in or
der to locate imported libraries.
-I path Prepend directory to the list of directories that are searched
in order to locate imported libraries.
-o output-file Use the output-file file, instead of the default deducted
from input-file, for the executable file produced.
Multiple instances of the -A, and -I options can be specified.
--list-r6rs List supported R6RS implementations.
--list-r7rs List supported R7RS implementations.
--list-all List all supported implementations.
--version Show the software version.
--help Shows you command to read this manual page. :)
ENVIRONMENT
COMPILE_R7RS
COMPILE_SCHEME
Either of these environment variables must be set. Set either to
the name of the implementation as specified in the support list.
This differs from SRFI-138 as the SRFI excepts a path.
STANDARDS
SRFI 138: Compiling Scheme programs to executables.
https://srfi.schemers.org/srfi-138/srfi-138.html
CAVEATS
Differences from SRFI-138
No support for -D flag.
Not all implementations support adding to beginning or end of
load path so -I and -A might work the same
Only supports one input-file.
EXAMPLES
Compile R6RS file with all dependencies in the same directory.
COMPILE_SCHEME=<SCHEME> compile-scheme main.sps
Compile R7RS file with all dependencies in the same directory.
COMPILE_SCHEME=<SCHEME> compile-scheme main.scm
Compile R6RS file with dependencies in libs directory.
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs main.sps
Compile R7RS file with dependencies in libs directory.
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs main.scm
Compile R6RS file with dependencies in libs directory, to output named
foo.
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs -o foo main.sps
Compile R7RS file with dependencies in libs directory, to output named
foo.
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs -o foo main.scm
compile-scheme(1)
</pre>

101
bash_completion.sh Normal file
View File

@ -0,0 +1,101 @@
_compile_scheme()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
shortopts="-A -I"
longopts="--list-r6rs --list-r7rs --list-all --help --version"
targets="unix" # windows php"
outputfound=false
for i in "${COMP_WORDS[@]}"; do
if [[ "$i" == "-o" ]] ; then
outputfound=true
fi
done
#targetfound=false
#for i in "${COMP_WORDS[@]}"; do
#if [[ "$i" == "-t" ]] ; then
#targetfound=true
#fi
done
if [[ "$outputfound" == "false" ]]; then
shortopts="${shortopts} -o"
fi
#if [[ "$targetfound" == "false" ]]; then
#shortopts="${shortopts} -t"
#fi
opts="${shortopts} ${longopts}"
if [[ ${prev} == -o ]] ; then
COMPREPLY=( $(compgen -W "" -- ${cur}) )
return 0
elif [[ ${prev} == -I ]] ; then
COMPREPLY=()
return 0
elif [[ ${prev} == -A ]] ; then
COMPREPLY=()
return 0
#elif [[ ${prev} == -t ]] ; then
#COMPREPLY=( $(compgen -W "${targets}" -- ${cur}) )
#return 0
elif [[ ${cur} == -o ]] ; then
COMPREPLY=("")
return 0
#elif [[ ${cur} == -t ]] ; then
#COMPREPLY=("")
#return 0
elif [[ ${prev} == *.sps ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
elif [[ ${prev} == *.scm ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
elif [[ ${cur} == -* ]] ; then
for i in "${COMP_WORDS[@]}"; do
if [[ "$i" == *.sps ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
if [[ "$i" == *.scm ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
done
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
elif [[ ${cur} == --* ]] ; then
for i in "${COMP_WORDS[@]}"; do
if [[ "$i" == *.sps ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
if [[ "$i" == *.scm ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
done
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
elif [[ ${cur} == * ]] ; then
for i in "${COMP_WORDS[@]}"; do
if [[ "$i" == *.sps ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
if [[ "$i" == *.scm ]] ; then
COMPREPLY=( $(compgen -W "${shortopts}" -- ${cur}) )
return 0
fi
done
COMPREPLY=( $(compgen -W "$(find . -maxdepth 1 -type f -name "*.sps" -o -name "*.scm" -printf '%f\n')" -- ${cur}) )
return 0
fi
}
# `foo` <tab> <tab> would show autocomplete above wordlist
complete -o bashdefault -o default -F _compile_scheme compile-scheme
# # If you want simplest wordlist, use below instead:
#complete -W "--help --verbose --version" compile-scheme
#

View File

@ -1,3 +0,0 @@
@echo off
set "PFFI_LOAD_PATH=%PROGRAMFILES%/compile-r7rs/snow/srfi"
sash.exe -r7 -L "%PROGRAMFILES%/compile-r7rs/snow" -L "%PROGRAMFILES%/compile-r7rs" "%PROGRAMFILES%/compile-r7rs/main.scm" %*

View File

@ -3,12 +3,21 @@
(scheme read) (scheme read)
(scheme write) (scheme write)
(scheme process-context) (scheme process-context)
(foreign c)
(libs util) (libs util)
(libs data) (libs data)
(libs library-util) (libs library-util)
(srfi 170)) (srfi 170))
(when (member "--help" (command-line))
(display "For help see: man compile-scheme")
(newline)
(exit 0))
(when (member "--version" (command-line))
(display "1.0.0")
(newline)
(exit 0))
(when (or (member "--list-r6rs" (command-line)) (when (or (member "--list-r6rs" (command-line))
(member "--list-r6rs-schemes" (command-line))) (member "--list-r6rs-schemes" (command-line)))
(for-each (lambda (scheme) (display scheme) (display " ")) r6rs-schemes) (for-each (lambda (scheme) (display scheme) (display " ")) r6rs-schemes)
@ -21,34 +30,35 @@
(newline) (newline)
(exit 0)) (exit 0))
(when (or (member "--list" (command-line)) (when (or (member "--list-all" (command-line))
(member "--list-schemes" (command-line))) (member "--list-schemes" (command-line)))
(for-each (lambda (scheme) (display scheme) (display " ")) all-schemes) (for-each (lambda (scheme) (display scheme) (display " ")) all-schemes)
(newline) (newline)
(exit 0)) (exit 0))
(define scheme (if (get-environment-variable "COMPILE_R7RS") (define scheme
(string->symbol (get-environment-variable "COMPILE_R7RS")) (cond
#f)) ((get-environment-variable "COMPILE_R7RS")
(string->symbol (get-environment-variable "COMPILE_R7RS")))
((get-environment-variable "COMPILE_SCHEME")
(string->symbol (get-environment-variable "COMPILE_SCHEME")))
(else #f)))
(when (not scheme) (when (not scheme)
(display "Environment variable COMPILE_R7RS not set." (current-error-port)) (display "Either environment variable COMPILE_R7RS or COMPILE_SCHEME is not set." (current-error-port))
(newline (current-error-port)) (newline (current-error-port))
(exit 1)) (exit 1))
(when (not (assoc scheme data)) (error "Unsupported implementation" scheme)) (when (not (assoc scheme data)) (error "Unsupported implementation" scheme))
(define compilation-target
(if (get-environment-variable "COMPILE_R7RS_TARGET")
(string->symbol (get-environment-variable "COMPILE_R7RS_TARGET"))
(cond-expand (windows 'windows)
(else 'unix))))
(define input-file (define input-file
(let ((input-file #f)) (let ((input-file #f))
(for-each (for-each
(lambda (item) (lambda (item)
(when (or (string-ends-with? item ".scm") (if (or (string-ends-with? item ".scm")
(string-ends-with? item ".sps")) (string-ends-with? item ".sps"))
(set! input-file item))) (set! input-file item)))
(list-tail (command-line) 1)) (list-tail (command-line) 1))
(when (not input-file)
(error "The intput-file must be either .scm (R7RS) or .sps (R6RS)"))
input-file)) input-file))
(define single-library-input-file (define single-library-input-file
@ -70,7 +80,7 @@
(define scheme-type (cdr (assoc 'type (cdr (assoc scheme data))))) (define scheme-type (cdr (assoc 'type (cdr (assoc scheme data)))))
(define output-file (define compilation-target
(let ((outfile (if (member "-o" (command-line)) (let ((outfile (if (member "-o" (command-line))
(cadr (member "-o" (command-line))) (cadr (member "-o" (command-line)))
(if input-file (if input-file
@ -81,6 +91,25 @@
(string-append outfile ".bin") (string-append outfile ".bin")
outfile))) outfile)))
(define compilation-target
(cond
((member "-t" (command-line))
(cadr (member "-t" (command-line))))
(else
(cond-expand (windows 'windows)
(else 'unix)))))
(define output-file
(let ((outfile
(cond
((member "-o" (command-line))
(cadr (member "-o" (command-line))))
(input-file (string-cut-from-end input-file 4)))))
(if (and (symbol=? scheme-type 'compiler)
(symbol=? compilation-target 'php))
(string-append outfile ".bin")
outfile)))
(define prepend-directories (define prepend-directories
(letrec ((looper (lambda (rest result) (letrec ((looper (lambda (rest result)
(if (null? rest) (if (null? rest)
@ -114,13 +143,6 @@
(newline) (newline)
(exit 0)) (exit 0))
(define-c-library c-stdlib
'("stdlib.h")
libc-name
'((additional-versions ("6"))))
(define-c-procedure c-system c-stdlib 'system 'int '(pointer))
#;(define search-library-files #;(define search-library-files
(lambda (directory) (lambda (directory)
(let ((result (list))) (let ((result (list)))
@ -165,12 +187,10 @@
((symbol=? compilation-target 'windows) "") ((symbol=? compilation-target 'windows) "")
((symbol=? compilation-target 'php) "") ((symbol=? compilation-target 'php) "")
(else "exec")) (else "exec"))
;; How to get the script file
(cond (cond
((symbol=? compilation-target 'windows) "%0%") ((symbol=? compilation-target 'windows) "%0%")
((symbol=? compilation-target 'php) "$binname") ((symbol=? compilation-target 'php) "$binname")
(else "\"$0\"")) (else "\"$0\""))
;(else "$(cd -- \"$(dirname \"$0\")\" >/dev/null 2>&1 && pwd -P)/\"$0\""))
(cond (cond
((symbol=? compilation-target 'windows) "") ((symbol=? compilation-target 'windows) "")
((symbol=? compilation-target 'php) "") ((symbol=? compilation-target 'php) "")
@ -207,7 +227,7 @@
(let* ((library-command (scheme-library-command file))) (let* ((library-command (scheme-library-command file)))
(for-each (for-each
(lambda (command) (lambda (command)
(let ((exit-code (c-system (string->c-utf8 command)))) (let ((exit-code (system command)))
(when (not (= exit-code 0)) (when (not (= exit-code 0))
(exit exit-code)))) (exit exit-code))))
library-command))) library-command)))
@ -258,14 +278,14 @@
#\newline #\newline
,scheme-program)))))) ,scheme-program))))))
(cond ((symbol=? compilation-target 'unix) (cond ((symbol=? compilation-target 'unix)
(c-system (string->c-utf8 (string-append "chmod +x " output-file))))))) (system (string-append "chmod +x " output-file))))))
(when (and (symbol=? scheme-type 'compiler) input-file) (when (and (symbol=? scheme-type 'compiler) input-file)
(when (and output-file (file-exists? output-file)) (when (and output-file (file-exists? output-file))
(delete-file output-file)) (delete-file output-file))
(for-each (for-each
(lambda (command) (lambda (command)
(let ((exit-code (c-system (string->c-utf8 command)))) (let ((exit-code (system command)))
(when (not (= exit-code 0)) (when (not (= exit-code 0))
(exit exit-code)))) (exit exit-code))))
scheme-command) scheme-command)

39
doc/HACKING.md Normal file
View File

@ -0,0 +1,39 @@
## Roadmap
- Support for more implementations
- gambit
- Adding paths to compiled executable is such a pain that no support yet
- husk
- Dont know how to add directories to load path yet, might not be
implemented
- r7rs
- picrin
- Might not be possible, seems to not have (include...) that works like
others
- r7rs
- scheme-rs
- Waiting for implementation support
- r6rs
- r7rs
- stak
- Waiting for implementation support https://github.com/raviqqe/stak/issues/2355
- r7rs
- vicare
- So old that I have problems compiling it in Docker, so testing is
hard but I expect it to work once I get it to compile as it is R6RS
implementation
- r6rs
- Better and tested support for Windows
- Right now there is support for running this but I can not quarantee it
works on all if any cases
- Support for -D
- Most implementations dont have this or equivalent flag, but it would be
really nice feature to have so filing issues and implementing it myself is
something I would like to do
- Ask implementations to support adding to the front and back of load path, or
implement this onto implementations myself
- This might not be as important, but it would be nice to go towards SRFI-138
conformaty
- Environment variable to force the target operating system
- Since for example for interpreters the program produces .bat file with
command to run the interpreter "cross compiling" is easy.

12
doc/INSTALL.md Normal file
View File

@ -0,0 +1,12 @@
## Build and install
You will need to have snow-chibi installed, it comes with Chibi Scheme.
You can run compile-r7rs on Chibi, Chicken, Gauche, Guile, Kawa, Sagittarius or
STklos.
snow-chibi --impls=SCHEME "(foreign c)"
snow-chibi --impls=SCHEME "(srfi 170)"
make build-SCHEME
make install

125
doc/compile-scheme.1 Normal file
View File

@ -0,0 +1,125 @@
.TH compile-scheme 1
.SH NAME
compile-scheme \- Compiling Scheme programs to executables
.SH SYNOPSIS
.P
\fBcompile-scheme\fR [\fB-A\fR \fIpath\fR] [\fB-I\fR \fIpath\fR] [\fB-o\fR \fIpath\fR] \fIinput-file.sps\fR
\#\fBcompile-scheme\fR [\fB-A\fR \fIpath\fR] [\fB-I\fR \fIpath\fR] [\fB-o\fR \fIpath\fR] [\fB-t\fR \fItarget\fR] \fIinput-file.sps\fR
.P
\fBcompile-scheme\fR [\fB-A\fR \fIpath\fR] [\fB-I\fR \fIpath\fR] [\fB-o\fR \fIpath\fR] \fIinput-file.scm\fR
\#\fBcompile-scheme\fR [\fB-A\fR \fIpath\fR] [\fB-I\fR \fIpath\fR] [\fB-o\fR \fIpath\fR] [\fB-t\fR \fItarget\fR] \fIinput-file.scm\fR
.P
\fBcompile-scheme\fR \fIlong-option\fR
.SH DESCRIPTION
.P
\fBcompile-scheme\fR is a tool to compile R6RS and R7RS Scheme programs.
It supports most of SRFI-138 but also adds more features.
.P
The program \fIinput-file\fR is compiled into an executable file.
The resulting executable file is written to file specified by the \fB-o\fR \fIpath\fR (if present) or to the file named same as \fIinput-file\fR but without the .scm or .sps suffix.
On Windows either .bat or .exe is appended to the output name.
.SH SUPPORTED IMPLEMENTATIONS
.P
Some implementations support both compiling and interpreting, in that
case only the compiler functionality is used and the implementation is marked
as compiler.
.SS "R6RS Compilers"
loko
.SS "R6RS Interpreters"
chezscheme guile ikarus ironscheme mosh racket sagittarius ypsilon
.SS "R7RS Compilers"
chicken cyclone loko
.SS "R7RS Interpreters"
chibi foment gauche guile kawa larceny meevax mit-scheme mosh racket sagittarius skint stklos tr7 ypsilon
.SH OPTIONS
.P
\fB\-A\fR \fIpath\fR
Append path to the list of directories that are searched in order to locate imported libraries.
.P
\fB\-I\fR \fIpath\fR
Prepend directory to the list of directories that are searched in order to locate imported libraries.
.P
\fB-o\fR \fIoutput-file\fR
Use the \fIoutput-file\fR file, instead of the default deducted from input-file, for the executable file produced.
.P
Multiple instances of the -A, and -I options can be specified.
\#.P
\#\fB\-t\fR { \fIunix\fR | \fIwindows\fR | \fIphp\fR }
\#\fB\-t\fR \fIunix\fR
\#Set the compilation target.
\#This is not needed if you are compiling for the target OS you are running.
\#Cross compilation is only supported in following cases:
\#.IP
\#From \fIunix\fR host to \fIwindows\fR target when chosen implementation is interpreter.
\#.IP
\#From \fIwindows\fR host to \fIunix\fR target when chosen implementation is interpreter.
\#.IP
\#From \fIunix\fR host to \fIphp\fR target when chosen implementation is interpreter.
\#.IP
\#From \fIwindows\fR host to \fIphp\fR target when chosen implementation is interpreter.
.P
.B \-\-list-r6rs
List supported R6RS implementations.
.P
.B \-\-list-r7rs
List supported R7RS implementations.
.P
.B \-\-list-all
List all supported implementations.
\#.P
\#\fB\-\-list-targets\fR
\#List all supported compilation targets.
.P
\fB\-\-version\fR
Show the software version.
.P
\fB\-\-help\fR
Shows you command to read this manual page. :)
.SH ENVIRONMENT
.P
\fBCOMPILE_R7RS\fR
.P
\fBCOMPILE_SCHEME\fR
.IP
Either of these environment variables \fBmust\fR be set.
Set either to the \fBname\fR of the implementation as specified in the support list.
\fBThis differs from SRFI-138\fR as the SRFI excepts a path.
.SH STANDARDS
.P
SRFI 138: Compiling Scheme programs to executables.
https://srfi.schemers.org/srfi-138/srfi-138.html
.SH CAVEATS
.P
Differences from SRFI-138
.IP
No support for -D flag.
.IP
Not all implementations support adding to beginning or end of load path so -I and -A might work the same
.IP
Only supports one input-file.
.SH EXAMPLES
.P
Compile R6RS file with all dependencies in the same directory.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme main.sps
.P
Compile R7RS file with all dependencies in the same directory.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme main.scm
.P
Compile R6RS file with dependencies in libs directory.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs main.sps
.P
Compile R7RS file with dependencies in libs directory.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs main.scm
.P
Compile R6RS file with dependencies in libs directory, to output named foo.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs -o foo main.sps
.P
Compile R7RS file with dependencies in libs directory, to output named foo.
.IP
COMPILE_SCHEME=<SCHEME> compile-scheme -I ./libs -o foo main.scm

View File

@ -1,12 +1,22 @@
(define-library (define-library
(libs util) (libs util)
(cond-expand
(gauche
(import (scheme base) (import (scheme base)
(scheme write) (scheme write)
(scheme file) (scheme file)
(scheme char) (scheme char)
(scheme process-context) (scheme process-context)
(foreign c)) (only (gauche base) sys-system)))
(export echo (else
(import (scheme base)
(scheme write)
(scheme file)
(scheme char)
(scheme process-context)
(foreign c))))
(export system
echo
cat cat
r6rs-schemes r6rs-schemes
r7rs-schemes r7rs-schemes
@ -31,6 +41,19 @@
trim-end trim-end
trim-both) trim-both)
(begin (begin
(cond-expand
(gauche
(define system sys-system))
(else
(define-c-library c-stdlib
'("stdlib.h")
libc-name
'((additional-versions ("6"))))
(define-c-procedure c-system c-stdlib 'system 'int '(pointer))
(define (system cmd)
(c-system (string->c-utf8 cmd)))))
(define (echo text) (display text) (newline)) (define (echo text) (display text) (newline))
(define (cat path) (for-each (lambda (line) (echo line)) (file->list path))) (define (cat path) (for-each (lambda (line) (echo line)) (file->list path)))
(define r6rs-schemes '(chezscheme (define r6rs-schemes '(chezscheme

200
old-README.md Normal file
View File

@ -0,0 +1,200 @@
compile-r7rs is a tool to compile R6RS and R7RS Scheme programs
It aims for compability
with [SRFI-138](https://srfi.schemers.org/srfi-138/srfi-138.html).
Despite it's name it also supports R6RS. Schemers, unite! <3
[Jenkins](https://jenkins.scheme.org/job/retropikzel/job/compile-r7rs/)
## Notes
- No support for -D flag yet.
- Not all implementations support adding to beginning or end o load path so
-I and -A might work the same
## Build and install
You can run compile-r7rs on Chibi, Chicken, Gauche, Guile, Kawa, Sagittarius or
STklos.
snow-chibi --impls=SCHEME "(foreign c)"
snow-chibi --impls=SCHEME "(srfi 170)"
make build-SCHEME
make install
## Usage
### R6RS
Replace the .scm file with .sps file in the next section.
### R7RS
You need to install each Scheme implementation yourself.
The environment variable COMPILE\_R7RS must be set to the **name** of the
implementation as specified in the support list.
**This differs from the SRFI** as the SRFI excepts a path.
To get the list of supported R6RS implementations run:
compile-r7rs --list-r6rs-schemes
To get the list of supported R7RS implementations run:
compile-r7rs --list-r7rs-schemes
To get the list of all supported implementations run:
compile-r7rs --list-schemes
Then run it with the .scm file for R7RS, or .sps file for R6RS.
COMPILE_R7RS=<implementation name> compile-r7rs -I . -o main main.scm
Which produces file called main, which you can run. Note that when given Scheme
is interpreter the file contains commands that run the script, and even when
the file is combiled binary it might need the compiled libraries.
No other file suffixes are supported at the moment.
Setting value of COMPILE\_R7RS to implementation name that supports only r7rs
and input file to .sps file and other way around is undefined behaviour.
### Environment variables
- COMPILE\_R7RS
- **Name** of the implementation you want to compile with
- **This differs from the SRFI** as it excepts a path
- COMPILE\_R7RS\_SCHEME_NAME
- Additional string to insert right after the command and it's arguments
can be used for example to pass C compiler flags on implementations that
compile to C or anything or otherwise as backdoor
- For example for Chicken to link with libcurl you would set
COMPILE\_R7RS\_CHICKEN="-L -lcurl"
- If implementation has - it is changed to \_, for example mit-scheme ->
MIT\_SCHEME
- **This differs from the SRFI** as it's not in there
## Supported implementations
Some implementations support both compiling and interpreting, in that
case only the compiler functionality is used and the implementation is marked
as compiler.
- chezscheme
- interpreter
- R6RS
- chibi
- interpreter
- R7RS
- chicken
- compiler
- R7RS
- cyclone
- compiler
- R7RS
- foment
- interpreter
- R7RS
- gauche
- interpreter
- R7RS
- guile
- interpreter
- R6RS
- R7RS
- Has include bug https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66046
but for some reason it seems to work for me atleast sometimes
- ikarus
- interpreter
- R6RS
- ironscheme
- interpreter
- R6RS
- kawa
- interpreter
- R7RS
- Native access is enabled by default so pffi can work
- larceny
- interpreter
- R6RS
- R7RS
- loko
- compiler
- R6RS
- R7RS
- meevax
- r7rs
- mit-scheme
- interpreter
- R7RS
- mosh
- interpreter
- R6RS
- R7RS
- racket
- interpreter
- Has compiling capabilities but I havent got them to work yet
- r6rs
- r7rs
- sagittarius
- interpreter
- R6RS
- R7RS
- skint
- interpreter
- R7RS
- stklos
- interpreter
- R7RS
- tr7
- interpreter
- R7RS
- ypsilon
- interpreter
- R6RS
- R7RS
## Roadmap
- Support for more implementations
- gambit
- Adding paths to compiled executable is such a pain that no support yet
- husk
- Dont know how to add directories to load path yet, might not be
implemented
- r7rs
- picrin
- Might not be possible, seems to not have (include...) that works like
others
- r7rs
- scheme-rs
- Waiting for implementation support
- r6rs
- r7rs
- stak
- Waiting for implementation support https://github.com/raviqqe/stak/issues/2355
- r7rs
- vicare
- So old that I have problems compiling it in Docker, so testing is
hard but I expect it to work once I get it to compile as it is R6RS
implementation
- r6rs
- Better and tested support for Windows
- Right now there is support for running this but I can not quarantee it
works on all if any cases
- Support for -D
- Most implementations dont have this or equivalent flag, but it would be
really nice feature to have so filing issues and implementing it myself is
something I would like to do
- Ask implementations to support adding to the front and back of load path, or
implement this onto implementations myself
- This might not be as important, but it would be nice to go towards SRFI-138
conformaty
- Environment variable to force the target operating system
- Since for example for interpreters the program produces .bat file with
command to run the interpreter "cross compiling" is easy.