Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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 HOLDERS 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.
CHICKEN is a compiler that translates Scheme source-files into C, which in turn can be fed to a C-compiler to generate a standalone executable. This principle, which is used by several existing compilers, achieves high portability because C is implemented on nearly all available platforms.
This package is distributed under a BSD license and as such is free to use and modify. An interpreter is also available and can be used as a scripting environment or for testing programs before compilation.
The method of compilation and the design of the runtime-system follow closely Henry Baker's "Cheney on the MTA"
[1] paper
and expose a number of interesting properties: consing (creation of data on the heap) is relatively inexpensive, because
a generational
garbage collection scheme is used, in which short-lived data structures are reclaimed extremely quickly. Furthermore,
call-with-current-continuation
is practically for free and CHICKEN does not suffer under any
performance penalties if
first-class continuations are used in complex ways. The generated C code is fully tail-recursive.
Some of the features supported by CHICKEN:
syntax-case
highlevel macros
match
package
format
,
UNIX system calls and extended data structures
The compiler translates Scheme source-code into fairly portable C source-code that can be compiled and linked with
most available C compilers. The interface to CHICKEN is intentionally simple. System dependent makefiles, shell-scripts
or batch-files should perform any necessary steps before and after invocation of CHICKEN. On UNIX-compatible systems,
a shell script named chicken-config
is supplied that emits the correct options for the host system's
C compiler (enter "chicken-config -help"
on the command line for a list of available options).
chicken FILENAME {OPTION}
FILENAME
is the complete pathname of the source-file that is to be translated into C. A filename
argument of "-"
specifies that the source text should be read from standard input.
Possible options are:
-benchmark-mode
-optimize-level 3 -fixnum-arithmetic -disable-interrupts -block
.
-block
eval
and unused toplevel bindings are
removed.
-case-sensitive
case-sensitive
feature identifier.
-check-syntax
-database-size NUMBER
-debug MODES
MODES
is a string of characters that select
debugging information about the compiler that will be printed to standard output.
t | show time and memory needed |
---|---|
b | show breakdown of time needed for each compiler pass |
o | show performed optimizations |
r | show invocation parameters |
s | show program-size information and other statistics |
a | show node-matching during simplification |
p | show execution of compiler sub-passes |
i | show potential inlining candidates |
m | show GC statistics during compilation |
x | display information about experimental features |
1 | show source expressions |
2 | show canonicalized expressions |
3 | show expressions converted into CPS |
4 | show database after each analysis pass |
5 | show expressions after each optimization pass |
6 | show expressions after each inlining pass |
7 | show expressions after complete optimization |
8 | show database after final analysis |
9 | show expressions after closure conversion |
-debug-calls
do
or named let
procedures. -debug-calls
implies -emit-debug-info
.
-debug-level LEVEL
- Selects amount of debug-information.
LEVEL
should be an integer.
-debug-level 0
is equivalent to -no-trace
.
-debug-level 1
does nothing.
-debug-level 2
is equivalent to -emit-debug-info
.
-debug-level 3
is equivalent to
-emit-debug-info -debug-calls
.
-debug-level N
with N
>= 4
is equivalent to
-emit-debug-info -debug-calls -debug-loops
.
-debug-loops
- Emits debug-information for all procedures, i.e.
do
loops and named let
.
Note that this will turn all tail-recursive loops into non-tail-recursive ones. Implies -debug-calls
and -emit-debug-info
.
-dependency-output FILENAME
- Specifies target filename for dependency rule generated by the
-write-dependencies
option.
-disable-interrupts
- Equivalent to the
(disable-interrupts)
declaration. No interrupt-checks are generated for compiled
programs.
-emit-debug-info
- Emits extended debugging information for use with the
debugger
unit.
Note that this option increases code size and
execution speed substantially. Moreover the compiler instruments the source code in such ways that any calls in
tail position (besides do
loops and named let
forms) are not tail-calls
anymore!
-epilogue FILENAME
- Includes the file named
FILENAME
at the end of the compiled source file.
The include-path is not searched. This option may be given multiple
times.
-expand-only
- Stops compilation after macro expansion phase and writes canonicalized expressions to output file.
-explicit-use
- Disables automatic use of the units library and eval. Use this option if compiling a library unit
instead of an application unit.
-extend FILENAME
- Loads a Scheme source file before compilation commences. This feature can be used to extend the compiler.
This option may be given multiple times.
-feature SYMBOL
- Registers
SYMBOL
to be a valid feature identifier for cond-expand
.
-fixnum-arithmetic
- Equivalent to
(fixnum-arithmetic)
declaration. Assume all mathematical operations use
small integer arguments.
-heap-size NUMBER
- Sets the static heap size of the generated executable to
NUMBER
bytes. The parameter may be
followed by a M (m) or K (k) suffix which stand for mega- and kilobytes, respectively.
The default heap size is 16 megabytes.
-help
- Print a summary of available options and the format of the command line parameters and exit the compiler.
-hygienic
- Load syntax-case macro package and enable high-level macros in compiled code.
This option registers the
hygienic-macros
feature identifier.
-include-path PATHNAME
- Specifies an additional search path for files included via the
include
special form. This option may be given multiple times. If the environment variable
CHICKEN_INCLUDE_PATH
is set, it should contain a list of alternative include
pathnames separated by ";". The environment variable CHICKEN_HOME
is also considered as a search path.
-inline
- Enable procedure inlining.
Note: this option, when applied to large source files can result in ridiculously long compile times.
-inline-limit NUMBER
- Specify maximum growth of original program due to inlining in
NUMBER
percent (i.e.
-inline-limit 100
limits the size of the program to twice its original size).
The default inline-limit is 100 percent.
-inline-passes NUMBER
- Specifies maximal number of inlining passes. The default number is 3.
-no-trace
- Disable generation of tracing information. If a compiled executable should halt due to a runtime error,
then a file containing a stack-trace will be written to the current directory under the name
STACKTRACE
.
Each line in the created file gives the name and the line-number (if available) of a procedure call.
With this option given, the generated code is slightly faster.
-no-fancy-ports
- Identical to the
(no-fancy-ports)
declaration. All ports are assumed to be file- or
stdio- ports.
-no-feature SYMBOL
- Unregisters feature identifier
SYMBOL
.
-no-warnings
- Disable generation of compiler warnings.
-no-winding-callcc
- Identical to the
(no-winding-callcc)
declaration. All uses of
call-with-current-continuation
do not respect dynamic-wind
before- and after-thunks.
-nursery NUMBER
-stack-size NUMBER
- Sets the size of the first heap-generation of the generated executable to
NUMBER
bytes. The parameter may
be followed by a M (m) or K (k) suffix. The default stack-size depends on the target platform.
-optimize
- Enables optimizations. This will improve performance of compiled programs, but compile times will
be longer.
-optimize-leaf-routines
- Enable leaf routine optimization.
-optimize-level LEVEL
- Enables certain sets of optimization options.
LEVEL
should be an integer.
-optimize-level 0
does nothing.
-optimize-level 1
is equivalent to -optimize -no-trace -optimize-leaf-routines
.
-optimize-level 2
is equivalent to -optimize -no-trace -optimize-leaf-routines
-usual-integrations
.
-optimize-level 3
is equivalent to -optimize -no-trace -optimize-leaf-routines
-usual-integrations -unsafe
.
-optimize-level N
with N
>= 4
is equivalent to
-optimize -no-trace -optimize-leaf-routines -usual-integrations -unsafe -inline
.
-output-file FILENAME
- Specifies the pathname of the generated C file. Default is
out.c
.
-postlude EXPRESSIONS
- Add
EXPRESSIONS
after all other toplevel expressions in the compiled file.
This option may be given multiple times. Processing of this option takes place after processing of
-epilogue
.
-prelude EXPRESSIONS
- Add
EXPRESSIONS
before all other toplevel expressions in the compiled file.
This option may be given multiple times. Processing of this option takes place before processing of
-prologue
.
-profile FILENAME
- Instruments the source code to count procedure calls and execution times. After the program terminates
(either via an explicit
exit
or implicitly), profiling statistics are written to
FILENAME
. Each line of the generated file contains a list with the procedure name,
the number of calls and the time spent executing it. Use the script formatprofile
to
display the profiling information in a more user-friendly form. Enter formatprofile
with
no arguments at the command line to get a list of available options.
Note that the file is only important in the compilation of the main compilation unit. For library units
the option is still needed (to record procedures defined in that unit), but the filename is ignored.
-prologue FILENAME
- Includes the file named
FILENAME
at the start of the compiled source file.
The include-path is not searched. This option may be given multiple times.
-quiet
- Disables output of compile information.
-srfi-7
- Process the source as a SRFI-7 configuration language file
(see: the SRFI-7 document).
-strict
- Disable non-standard macros. This option registers the
strict
feature identifier.
-strict-srfi-0
- Disable non-standard macros except
cond-expand
.
This option registers the strict
feature identifier.
-to-stdout
- Write compiled code to standard output instead of creating a .c file.
-unsafe
- Disable runtime safety checks.
-usual-integrations
- Specifies that standard procedures and certain internal procedures are never redefined, and can
be inlined. This is equivalent to declaring
(usual-integrations)
.
-version
- Prints the version and some copyright information and exit the compiler.
-verbose
- Prints progress information to standard output during compilation.
-write-dependencies
- Output a rule suitable for
make
which specify any dependencies of the currently
compiled file to included source files. If -dependency-output
is not given,
the rule is written to standard output. You can specify the -check-syntax
option
additionally to avoid compilation of the source file.
The environment variable CHICKEN_OPTIONS
can be set to
a string with default command-line options for the compiler.
After successful compilation a C source-file is generated and can be compiled with a C compiler. Executables generated with CHICKEN (and the compiler itself) accept a small set of runtime options:
-:b
-emit-debug-info
).
-:c
-:d
-:hNUMBER
-:sNUMBER
-:tNUMBER
-:w
The argument values may be given in bytes, in kilobytes (suffixed with K or k) or in megabytes
suffixed with M or m). Runtime options may be combined, like -:bc
, but everything
following a NUMBER
argument is ignored. So -:wh64m
is OK, but
-:h64mw
will not enable GC of unused symbols.
To compile a Scheme program (assuming a UNIX-like environment) we perform the following steps:
foo.scm
;;; foo.scm (define (fac n) (if (zero? n) 1 (* n (fac (- n 1))) ) ) (print (fac 10))
foo.scm
% chicken foo.scm -output-file foo.c
foo.c
% gcc foo.c -o foo `chicken-config -cflags -libs`
% foo
The option -output-file foo.c
specifies the name of the C file that is to
be generated by CHICKEN. Without this option a file named out.c
would be created.
If multiple Scheme modules are to be combined into a single executable, then we have to compile each module and link the resulting object files together with the runtime system:
foo.scm
and bar.scm
;;; foo.scm (declare (uses bar)) (write (fac 10)) (newline) ;;; bar.scm (declare (unit bar)) (define (fac n) (if (zero? n) 1 (* n (fac (- n 1))) ) )
foo.scm
and bar.scm
% chicken foo.scm -output-file foo.c % chicken bar.scm -output-file bar.c -explicit-use
foo.c
and bar.c
% gcc -c foo.c `chicken-config -cflags` % gcc -c bar.c `chicken-config -cflags`
foo.o
and bar.o
% gcc foo.o bar.o -o foo `chicken-config -libs`
% foo
The declarations specify which of the compiled files is the main module, and which
is the library module. An executable can only have one main module, since a program
has only a single entry-point. In this case foo.scm
is the main
module, because it doesn't have a unit
declaration.
Library modules should be compiled with the -explicit-use
option.
Extensions to the basic CHICKEN runtime libraries are available in a separate
utility library (libstuffed-chicken.a
on UNIX-like platforms,
chicken-utilities.lib
on Windows systems). Whenever you use
one or more of the units extras, format, srfi-1, srfi-4, srfi-13, srfi-14, srfi-18,
match, unistd, lolevel, tinyclos or regex, then you should add this library to
the command line of the C compiler or linker (this is equivalent to adding the -extra-libs
option to chicken-config
):
;;; foo.scm (declare (uses unistd format)) (format #t "Anno Domini ~@R~%" (+ 1900 (vector-ref (seconds->local-time (current-seconds)) 5)) % chicken foo.scm -output-file foo.c % gcc foo.c `chicken-config -cflags -extra-libs -libs` -o foo % foo
The compiler supplies a couple of hooks to add user-level passes to the compilation process. Before compilation
commences any Scheme source-files specified using the -extend
option are loaded and evaluated.
The parameters user-options-pass, user-read-pass, user-preprocessor-pass
and user-pass
can be
set to procedures that are called to perform certain compilation passes instead of the usual processing (for more
information about parameters see: Parameters).
[parameter] user-options-pass
-
(hyphen) removed and are converted to symbols.
-extend
option,
and so can only be changed in compiled user passes.
[parameter] user-read-pass
-prelude
options. The second argument is a list of source files including any
files specified by -prologue
and -epilogue
. The third argument is a list of
strings specified using -postlude
options. The procedure should return a list of toplevel
Scheme expressions.
[parameter] user-preprocessor-pass
[parameter] user-pass
Extensions loaded via -extend
are interpreted. To add compiled user-passes the compiler
has to be rebuild.
Loaded code has access to the library units extras, srfi-1, srfi-4
and match
.
The highlevel macro-system and multithreading is not available.
Note that the macroexpansion/canonicalization phase of the compiler adds certain forms to the source program.
These extra expressions are not seen by user-preprocessor-pass
but by user-pass
.
The script file extend-chicken
can be used to rebuild the compiler with added library
units, much in the same way as extend-csi
(see: extending the interpreter
).
It is relatively easy to create distributions of Scheme projects that have been compiled to C. The CHICKEN distribution
contains a template makefile (called Makefile.d
for GCC based systems, or
Makefile.d.vc
for Windows systems that use Visual C++) that can be adapted to build an executable from translated
C sources.
The runtime system of CHICKEN consists of only two handcoded C files (runtime.c
and
chicken.h
). All other modules of the runtime system and the extension
libraries are just compiled Scheme code.
An example:
;;; foo.scm (declare (uses bar)) (say-hello)and
;;; bar.scm (declare (unit bar) (uses unistd)) (define (say-hello) (print "Hello, " (nth-value 0 (user-information (current-user-id)))) )
% chicken foo.scm -output-file foo.c -quiet % chicken bar.scm -output-file bar.c -quiet -explicit-use
foo
would look like this:
CC = gcc CFLAGS = -I. -O3 -fomit-frame-pointer -fstrict-aliasing foo : foo.o bar.o libchicken.a libstuffed-chicken.a gcc -s -L. foo.o bar.o -o $@ -lchicken -lstuffed-chicken foo.o : foo.c chicken.h bar.o : bar.c chicken.h libchicken.a : runtime.o library.o eval.o syntax-case.o ar rus $@ $^ libstuffed-chicken.a : extras.o format.o srfi-1.o srfi-4.o srfi-13.o srfi-14.o match.o \ srfi-18.o lolevel.o regex.o unistd.o ar rus $@ $^ libembedded-chicken.a : embedded-runtime.o library.o eval.o syntax-case.o ar rus $@ $^ runtime.o : runtime.c chicken.h embedded-runtime.o : runtime.c chicken.h $(CC) $(CFLAGS) -DC_EMBEDDED -c $< -o $@ eval.o : eval.c chicken.h library.o : library.c chicken.h modules.o : modules.c chicken.h extras.o : extras.c chicken.h srfi-1.o : srfi-1.c chicken.h srfi-4.o : srfi-4.c chicken.h match.o : match.c chicken.h syntax-case.o : syntax-case.c chicken.h srfi-18.o : srfi-18.c chicken.h format.o : format.c chicken.h tinyclos.o : tinyclos.c chicken.h srfi-13.o : srfi-13.c chicken.h srfi-14.o : srfi-14.c chicken.h lolevel.o : lolevel.c chicken.h regex.o : regex.c chicken.h unistd.o : unistd.c chicken.h
$(CHICKEN_HOME)/src
(or just take them from the original tar archive).
chicken.h
.
libembedded-chicken.a
in the case the application is not embedded into
a C module). Most of the time not all library units are needed for a given application.
For the example above, a minimal makefile would look like this:
CC = gcc CFLAGS = -I. -O3 -fomit-frame-pointer -fstrict-aliasing foo : foo.o bar.o libchicken0.a libstuffed-chicken0.a gcc -s -L. foo.o bar.o -o $@ -lchicken0 -lstuffed-chicken0 foo.o : foo.c chicken.h bar.o : bar.c chicken.h libchicken0.a : runtime.o library.o eval.o ar rus $@ $^ libstuffed-chicken0.a : regex.o unistd.o ar rus $@ $^ runtime.o : runtime.c chicken.h eval.o : eval.c chicken.h library.o : library.c chicken.h regex.o : regex.c chicken.h unistd.o : unistd.c chicken.h
format | extras |
---|---|
srfi-13 | srfi-14 |
unistd | regex |
lolevel | srfi-4 extras |
tinyclos | extras |
bar
uses unistd
, which in turn
uses regex
. The units library
and eval
are used by foo
(these are used by default).
runtime
is needed in any case.
CHICKEN provides a simple interpreter for evaluating Scheme programs and expressions.
This interpreter can be used on its own and a simple read-eval-print loop is provided in the file
csi.scm
.
csi {FILENAME|OPTION}where
FILENAME
specifies a file with Scheme source-code.
If the extension of the source-file is .scm
, it may be omitted. The runtime options described
in Runtime options are also available for the interpreter.
If the environment variable CSI_OPTIONS
is set to a list of options, then these options
are additionally passed to every direct or indirect invocation of csi
. Please note that
runtime options (like -:...
) can not be passed using this method.
The options recognized by the interpreter are:
--
-:...
") are still recognized.
-case-sensitive
case-sensitive
feature identifier.
-batch
-eval EXPRESSIONS
EXPRESSIONS
.
-feature SYMBOL
SYMBOL
to be a valid feature identifier for cond-expand
.
-help
-hygienic
hygienic-macros
feature identifier.
-include-path PATHNAME
include
special form. This option may be given multiple times. If the environment variable
CHICKEN_INCLUDE_PATH
is set, it should contain a list of alternative include
pathnames separated by ";". The environment variable CHICKEN_HOME
is also considered as a search path.
-no-feature SYMBOL
SYMBOL
.
-no-init
~/.csirc
exists,
then it is loaded before the read-eval-print loop commences.
-no-warnings
-quiet
-script
-batch -quiet
, but also ignores all arguments after the argument
following -script
.
-srfi-7
-strict
-strict-srfi-0
cond-expand
.
-version
Since UNIX shells use the #! notation for starting scripts, the interpreter registers
the special read-syntax #!
as a comment and the reader ignores everything after the two characters up to
the end of the current line.
The easiest way is to use the -script
option like this:
% cat foo #! /usr/local/bin/csi -script (print (eval (with-input-from-string (car (command-line-arguments)) read))) % chmod +x foo % foo "(+ 3 4)" 7
The parameter command-line-arguments
is set to a list of the parameters that were
passed to the Scheme script.
Scripts can be compiled to standalone executables.
CHICKEN implements SRFI-22 and provides the Scheme script interpreters
scheme-r4rs, scheme-ieee-1178-1990, scheme-r5rs, scheme-srfi-0
and scheme-srfi-7
.
Scheme scripts can be compiled, the compiler determines language dialect from the
invocation line:
% cat bar #! /usr/bin/env scheme-r5rs (define (main args) (write (list->string (reverse (string->list (cadr args))))) (newline) ) % chmod +x bar % bar "one two three" "eerht owt eno" % chicken bar -output-file bar.c -quiet % gcc bar.c `chicken-config -cflags -libs` -o cbar % cbar "one two three" "eerht owt eno"
For more information, see the SRFI-22 document.
Note: The Scheme script interpreters scheme-r5rs
and scheme-srfi-0
invoke the CHICKEN interpreter (csi
) with the -hygienic
option,
which loads the highlevel macro definitions from a file. This will result in slightly longer startup times
for these scripts than for, say, scripts invoked via scheme-r4rs
.
Compiling the script to native code will of course eliminate the problem.
The toplevel loop understands a number of special commands:
,?
,NUM
NUM
th command in history-list
,h
,l FILENAME
FILENAME
(may be a symbol or string).
,ln FILENAME
,p EXP
EXP
.
,d EXP
EXP
.
,q
,s STRING-OR-SYMBOL
,t EXP
,ts
,x EXP
EXP
(the expression is not evaluated).
,x1 EXP
EXP
. If the expression is a macro form, then it is expanded
once (the expression is not evaluated).
The interpreter contains the definitions of the library units
extras, srfi-1
and syntax-case
, the describe
facility
and report
(see Additional files).
If available, the units unistd
and regex
are also included.
Additional macros and procedures available in the interpreter are:
[syntax] (autoload FILENAME (SYMBOL ...))
SYMBOL ...
will load
the Scheme source file FILENAME
and replace each of the procedures with its actual definition.
Say the file foo.scm
has the following contents:
;;; foo.scm (define (bar x) (* x 2))Then
(autoload "foo.scm" (bar)) (bar 2) ; loading foo.scm ... ==> 4
[syntax] (trace SYMBOL ...)
[syntax] (untrace SYMBOL ...)
[procedure] ($ [INDEX])
INDEX
in the history list.
[procedure] (& [INDEX])
INDEX
in the history list.
The interpreter csi
can be recompiled and relinked with arbitrary compiled Scheme modules.
A Scheme script named extend-csi
is provided on UNIX-compatible systems which makes this
process quite easy. Consider we have this file, named foo.scm
:
(declare (unit foo)) (define (foo) (print "Hello!"))
To compile the library unit foo
and add it to the interpreter we can perform
the following steps:
% chicken foo.scm -explicit-use -output-file foo.c -quiet % gcc -c foo.c `chicken-config -cflags` -o foo.o % extend-csi foo -output-file csifoo chicken /usr/local/share/chicken/src/csi.scm -optimize-level 1 -quiet -postlude "(##csi#run)" \ -prologue /usr/local/share/chicken/src/build.scm -prelude '(declare (uses regex unistd))' \ -prelude "(declare (uses foo))" gcc out.c foo.o `chicken-config -cflags -libs -extra-libs` -o csifoo rm -f out.c foo.o % csifoo -quiet >>> (foo) foo! >>>
For more information enter extend-csi
without arguments at the command line.
[4.1.3] A compiled procedure may not have more than 126 arguments. On x86 platforms this limit is raised to 1024.
[6.2.4] The runtime system uses the numerical string-conversion routines of the underlying C library and so does only understand standard (C-library) syntax for floating-point constants.
[6.2.5] The routines complex?
, real?
and rational?
are identical to the standard procedure number?
. The procedures numerator
,
denominator
and rationalize
are not implemented.
Also not implemented are all procedures related to complex numbers.
[6.2.6] The procedure string->number
can not parse complex numbers and does not obey
write/read invariance on inexact numbers.
[6.4] The maximum number of values that can be passed to continuations captured using
call-with-current-continuation
is 126.
[6.5] eval
ignores its second argument.
Code evaluated in scheme-report-environment
or null-environment
still
sees non-standard syntax.
[6.6.2] The procedure char-ready?
is handling terminal input ports only under DJGPP
correctly. On other platforms it returns always #t
.
The procedure read
can not parse complex numbers and does not obey
write/read invariance on inexact numbers.
[6.6.3] The procedures write
and display
do not obey
write/read invariance to inexact numbers.
[2.1] Identifiers may contain special characters if delimited with | ... |
.
[2.3] The brackets [ ... ]
are provided as an alternative syntax for ( ... )
.
A number of reader extensions is provided. See Non-standard read syntax.
[4] Numerous non-standard macros are provided. See Non-standard macros and special forms for more information.
[4.2.3] (begin)
is allowed in non-toplevel contexts and evaluates to an unspecified value.
[4.2.5] Delayed expressions may return multiple values.
[5.2.1] A define
occurring anywhere but at the beginning of a lambda
-
or let
-body is in every aspect equivalent to set!
.
[5.2.2] define-values
may be used in internal definitions if the R5RS macro system is not used.
[6] CHICKEN provides numerous non-standard procedures. See the manual sections on library units for more information.
[6.3.4] User defined character names are supported. See char-name
.
[6.3.5] CHICKEN supports special characters preceded with a backslash (\) in quoted string constants. \n
denotes the newline-character and \t
is equivalent to the TAB character.
[6.4] force
called with an argument that is not a promise returns that object unchanged.
Captured continuations can be safely invoked inside before- and after-thunks of a dynamic-wind
form and execute in a dynamic context in which the particular thunks are not established.
[6.6.1] The procedures open-input-file
, open-output-file
,
with-input-from-file
, with-output-to-file
, call-with-input-file
and call-with-output-file
accept an optional second (or third) argument which should be a keyword, if supplied. This argument specifies the mode in
which the file is opened. Possible values are the keywords #:text
, #:binary
or
#:append
.
[read syntax] #| ... |#
[read syntax] #;EXPRESSION
EXPRESSION
as a comment.
[read syntax] #,(CONSTRUCTORNAME DATUM ...)
[read syntax] #'EXPRESSION
(syntax EXPRESSION)
.
[read syntax] #:SYMBOL
[read syntax] #<<TAG
TAG
will be returned
as a single string:
(define msg #<<END "Hello, world!", he said. END )is equivalent to
(define msg "\"Hello, world!\", he said.")
[read syntax] #<#TAG
#<<
, but allows substitution of embedded Scheme expressions
prefixed with #
and optionally enclosed in { ... }
.
Two consecutive #
s are translated to a single #
:
(define three 3) (display #<#EOF This is a simple string with an embedded `##' character and substituted expressions: (+ three 99) ==> #(+ three 99) (three is "#{three}") EOF )prints
This is a simple string with an embedded `#' character and substituted expressions: (+ three 99) ==> 102 (three is "3")
[syntax] (:optional ARGS DEFAULT)
ARGS
is the empty list DEFAULT
is evaluated and returned, otherwise the first element of the
list ARGS
. It is an error if ARGS
contains more than one value.
(define (incr x . i) (+ x (:optional i 1))) (incr 10) ==> 11 (incr 12 5) ==> 17
[syntax] (case-lambda (LAMBDA-LIST1 EXP1 ...) ...)
(define plus (case-lambda (() 0) ((x) x) ((x y) (+ x y)) ((x y z) (+ (+ x y) z)) (args (apply + args)))) (plus) ==> 9 (plus 1) ==> 1 (plus 1 2 3) ==> 6For more information see documentation for SRFI-16.
[syntax] (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...) [syntax] (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)
ARGS
should be a rest-parameter taken from a lambda-list. let-optionals
binds VAR1 ...
to available arguments in parallel, or to
DEFAULT1 ...
if not enough arguments were provided.
let-optionals*
binds VAR1 ...
sequentially,
so every variable sees the previous ones. If a single variable RESTVAR
is given, then it is bound to any remaining arguments, othersise it is an error if any
excess arguments are provided.
(let-optionals '(one two) ((a 1) (b 2) (c 3)) (list a b c) ) ==> (one two 3) (let-optionals* '(one two) ((a 1) (b 2) (c a)) (list a b c) ) ==> (one two one)
[syntax] (let-string-start+end (START END [REST]) PROCEXP SEXP ARGEXP BODY ...)
[syntax] (and-let* (BINDING ...) EXP1 EXP2 ...)
BINDING
can be a list of a variable and
an expression, a list with a single expression, or a single variable. If the value of an expression bound to
a variable is #f
, the and-let*
form evaluates to #f
(and the subsequent bindings and the body are not executed).
Otherwise the next binding is performed. If all bindings/expressions evaluate to a true result, the body
is executed normally and the result of the last expression is the result of the and-let*
form. See also documentation for SRFI-2.
[syntax] (define-values (NAME ...) EXP)
EXP
.
This form may also be used in internal definitions.
[syntax] (fluid-let ((VAR1 X1) ...) BODY ...)
VAR1 ...
dynamically to the values
X1 ...
during execution of BODY ...
.
[syntax] (let-values (((NAME ...) EXP) ...) BODY ...)
EXP ...
.
All variables are bound simultaneously.
[syntax] (let*-values (((NAME ...) EXP) ...) BODY ...)
EXP ...
.
The variables are bound sequentially.
(let*-values (((a b) (values 2 3)) ((p) (+ a b)) ) p) ==> 5
[syntax] (letrec-values (((NAME ...) EXP) ...) BODY ...)
EXP ...
to multiple variables at once.
All variables are mutually recursive.
(letrec-values (((odd even) (values (lambda (n) (if (zero? n) #f (even (sub1 n)))) (lambda (n) (if (zero? n) #t (odd (sub1 n)))) ) ) ) (odd 17) ) ==> #t
[syntax] (parameterize ((PARAMETER1 X1) ...) BODY ...)
PARAMETER1 ...
dynamically to the values
X1 ...
during execution of BODY ...
.
(see also: make-parameter
)
[syntax] (receive (NAME1 ... [. NAMEn]) VALUEEXP BODY ...)
call-with-values
. Binds variables to the
result values of VALUEEXP
and evaluates BODY ...
.
[syntax] (set!-values (NAME ...) EXP)
EXP
to multiple variables.
[syntax] (define-constant (NAME VAR ... [. VAR]) BODY ...) [syntax] (define-constant NAME CONST)
define
when evaluated or interpreted.
Constant definitions should only appear at toplevel. Note that constants are local to the current compilation
unit and are not available outside of the source-file in which they are defined. Names of constants still exist
in the Scheme namespace and can be lexically shadowed.
[syntax] (define-id-macro NAME EXP)
NAME
will be substituted by the expression EXP
. Note that EXP
is not evaluated
at macro-definition time.
[syntax] (define-inline (NAME VAR ... [. VAR]) BODY ...) [syntax] (define-inline NAME EXP) [syntax] (define-integrable (NAME VAR ... [. VAR]) BODY ...) [syntax] (define-integrable NAME EXP)
NAME
will be replaced by EXP
or (lambda (VAR ... [. VAR]) BODY ...)
. This is similar to a macro, but variable-names and
-scope will be correctly handled. Inline substitutions take place after
macro-expansion. EXP
should be a lambda-expression. Any reference to NAME
should appear textually after it's definition. Note that inline procedures are local to the current compilation
unit and are not available outside of the source-file in which they are defined. Names of inline procedures still exist
in the Scheme namespace and can be lexically shadowed.
This construct is equivalent to define
when evaluated or interpreted. Inline definitions
should only appear at toplevel. define-integrable
is just a synonym for define-inline
.
[syntax] (define-macro (NAME VAR ... [. VAR]) EXP1 ...) [syntax] (define-macro NAME (lambda (VAR ... [. VAR]) EXP1 ...))
eval
, then the macro is visible in evaluated expressions during runtime. The second possible
syntax for define-macro
is allowed for portability purposes only. In this case the second argument must
be a lambda-expression.
[syntax] (let-id-macro ((NAME EXP) ...) EXP1 ...)
NAME
will be substituted
by the expression EXP
.
The defined identifier macros are only valid inside the body EXP1 ...
.
Note that the EXP
forms are not evaluated at macro-definition time.
[syntax] (let-macro (MACRODEF ...) EXP1 ...)
MACRODEF
may be of the form
(NAME (lambda LAMBDALIST BODY ...))
or of the form ((NAME . LAMBDALIST) BODY ...)
.
The defined macros are only valid inside the body EXP1 ...
.
[syntax] (unless TEST EXP1 EXP2 ...)
(if (not TEST) (begin EXP1 EXP2 ...))
[syntax] (when TEST EXP1 EXP2 ...)
(if TEST (begin EXP1 EXP2 ...))
[syntax] (define-record NAME SLOTNAME ...)
make-NAME
to create an instance of the structure
(with one initialization-argument for each slot).
(NAME? STRUCT)
tests any object for being an instance of this structure.
Slots are accessed via (NAME-SLOTNAME STRUCT)
and updated using
(NAME-SLOTNAME-set!
STRUCT
VALUE)
.
(define-record point x y) (define p1 (make-point 123 456)) (point? p1) ==> #t (point-x p1) ==> 123 (point-y-set! p1 99) (point-y p1) ==> 99
[syntax] (define-record-printer (NAME RECORDVAR PORTVAR) BODY ...) [syntax] (define-record-printer NAME PROCEDURE)
NAME
by associating
a procedure with the record type. When a record of this type is written using
display, write
or print
, then the procedure is called with
two arguments: the record to be printed and an output-port.
(define-record foo x y z) (define f (make-foo 1 2 3)) (define-record-printer (foo x out) (fprintf out "#,(foo ~S ~S ~S)" (foo-x x) (foo-y x) (foo-z x)) ) (define-reader-ctor 'foo make-foo) (define s (with-output-to-string (lambda () (write f)))) s ==> "#,(foo 1 2 3)" (equal? f (with-input-from-string s read))) ==> #t
[syntax] (record-case EXP ((HEAD1 VAR1 ...) BODY1 ...) ... [(else BODYN ...)])
BODY ...
that matches the
record EXP
, which should be a record of a type defined by define-record
.
A clause matches if the symbol HEAD
is equal to the record type of EXP
and
the record has at least the same number of slots as variables VAR ...
are specified.
If a clause matches, the variables VAR ...
are bound to the corresponding slot-values of
the matched record. If no clause matches the given structure, an unspecified value is returned.
(define-record foo x y) (define f1 (make-foo 123 456)) (record-case f1 ((bar p q r) (list "bar" p q r)) ((foo a b) (list "foo" a b)) (else "none") ) ==> ("foo" 123 456)Note that this form has nothing to do with the
record-case
macro used in Chez Scheme.
[syntax] (assert EXP [STRING ARG ...])
EXP
evaluates to false. An optional message STRING
and
arguments ARG ...
may be supplied to give a more informative error-message.
[syntax] (cond-expand FEATURE-CLAUSE ...)
srfi-0
,
srfi-2
, srfi-6
, srfi-8
, srfi-10
and chicken
.
If the source-file containing this form is currently compiled, the feature compiling
is defined.
For further information, see documentation for SRFI-0
This form is allowed to appear in non-toplevel expressions.
[syntax] (critical-section BODY ...)
BODY ...
with interrupts temporarily disabled.
[syntax] (eval-when (SITUATION ...) EXP ...)
SITUATION
should be one of the symbols
eval
, compile
or load
.
When encountered in the evaluator, and the situation specifier eval
is not given, then
this form is not evaluated and an unspecified value is returned.
When encountered in compiled code, and the situation specifier compile
is given, then
this form is evaluated during the compilation process.
When encountered in compiled code, and the situation specifier load
is not given, then
this form is ignored and an expression resulting into an unspecified value is compiled instead.
Note: it is currently not possible to use define-syntax
or define
inside eval-when
forms when hygienic macros are enabled.
[syntax] (include STRING)
.scm
, then it may be omitted.
The file is searched in the current directory and, if not found,
in all directories specified in the -include-path
option.
The expressions are treated as toplevel expressions, so it's generally a good idea
to use include
only in a toplevel context.
[syntax] (nth-value N EXP)
N
th value (counting from zero) of the values returned by expression
EXP
.
[syntax] (time EXP)
EXP
and print elapsed time and memory information.
[syntax] (declare DECLSPEC ...)
DECLSPEC
may be any of the following:
[declaration specifier] (always-bound SYMBOL ...)
[declaration specifier] (block)
-block
option.
[declaration specifier] (bound-to-procedure SYMBOL ...)
[declaration specifier] (foreign-declare STRING ...)
[declaration specifier] (inline)
-inline
option.
[declaration specifier] (inline-limit NUMBER)
-inline-limit
option (see: Using the compiler).
[declaration specifier] (interrupts-enabled)
[declaration specifier] (disable-interrupts) [declaration specifier] (interrupts-disabled) [declaration specifier] (not interrupts-enabled)
[declaration specifier] (no-fancy-ports)
[declaration specifier] (no-winding-callcc)
call-with-current-continuation
use non-winding semantics.
So any invocation of captured continuations will not execute any pending before- or after-thunks.
This means that the following forms should be used with care, since they expand into or call dynamic-wind
:
critical-section dynamic-wind fluid-let with-exception-handler handle-exceptions
[declaration specifier] (notinline) [declaration specifier] (not inline)
[declaration specifier] ([number-type] TYPE) [declaration specifier] (fixnum-arithmetic)
TYPE
may be fixnum
,
flonum
or generic
(which is the default).
[declaration specifier] ([not] standard-bindings SYMBOL ...)
not
is specified, then all but the given standard bindings are assumed to be never redefined.
[declaration specifier] ([not] extended-bindings SYMBOL ...)
not
is specified, then all but the given extended bindings are assumed to be never redefined.
[declaration specifier] ([not] usual-integrations SYMBOL ...)
not
is specified, then all but the given standard and extended bindings are assumed to be never redefined.
[declaration specifier] (unit SYMBOL)
[declaration specifier] (unsafe) [declaration specifier] (not safe)
-unsafe
option.
[declaration specifier] (uses SYMBOL ...)
cond-expand
knows about them.
[syntax] (define-foreign-parameter NAME TYPE [STRING])
define-foreign-variable
, but defines a globally (and externally) visible
procedure that accesses the foreign variable named STRING
(or NAME
if
STRING
is not supplied) like a parameter: calling the procedure with no arguments returns
the current value of the variable, calling it with an argument updates the variable's value. Note that you shouldn't
use this form to access C macros, since any assignment may be incorrect (STRING
has to specify an lvalue).
(define-foreign-parameter errno int) (errno 0) (errno) ==> 0 (errno 123) (errno) ==> 123
[syntax] (define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])
TYPE
. TYPE
may be a type-specifier
or a string, naming a C type. The namespace of foreign type specifiers is separate from the normal
Scheme namespace.
ARGCONVERT
and RETCONVERT
should evaluate to
procedures that map argument- and result-values to a value that can be transformed to TYPE
:
(declare (uses srfi-4) (foreign-declare "int foo(char *ptr, int i) { return(ptr[ i ]); }") ) (define-foreign-type bvector pointer u8vector->byte-vector) ((foreign-lambda int "foo" bvector int) '#u8(100 101 102) 1) ==> 101
[syntax] (define-foreign-variable NAME TYPE [STRING])
NAME
. STRING
should be
the real name of a foreign variable or parameterless macro. If STRING
is not given,
then the variable name NAME
will be converted to a string and used instead. All
references and assignments
(via set!
) are modified to correctly convert values between Scheme and C
representation. This foreign variable can only be accessed in the current compilation unit, but the name can
be lexically shadowed.
STRING
can name an arbitrary C expression. If no assignments are performed,
then STRING
doesn't even have to specifiy an lvalue.
[syntax] (foreign-callback-lambda RETURNTYPE NAME ARGTYPE)
foreign-lambda
, but also allows the called function to call
Scheme functions. See Callbacks.
[syntax] (foreign-callback-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
foreign-lambda*
, but also allows the called function to call
Scheme functions. See Callbacks.
[syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...)
lambda
expression. NAME
specifies the name of the external
procedure and should be a string or a symbol.
[syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
foreign-lambda
, but instead of generating code to call an external
function, the body of the C procedure is directly given in STRING ...
:
(define my-strlen (foreign-lambda* int ((c-string str)) "int n = 0; while(*(str++)) ++n; return(n);") ) (my-strlen "one two three") ==> 13For obscure technical reasons any use of the
return
statement should enclose the result
value in parantheses. For the same reasons return
without an argument is not allowed.
Here is a list of valid foreign type specifiers:
scheme-object
bool
#f
is false, anything else is true).
NULL
-pointer is #t
.
char unsigned-char
short unsigned-short
int unsigned-int
integer unsigned-integer
long unsigned-long
float double
pointer
#f
is also allowed and is passed as a NULL
pointer.
c-pointer
#f
is also allowed and is passed as a NULL
pointer.
c-string
#f
is also allowed and
is passed as a NULL
pointer. If uses as the type of a return value, a NULL
pointer will be returned as #f
.
void
(pointer TYPE)
TYPE
.
(struct NAME)
NAME
, which should be a string. Structs can not be directly passed
as arguments to foreign function, neither can they be result values. Pointers to structs are allowed, though.
(union NAME)
NAME
, which should be a string. Unions can not be directly passed
as arguments to foreign function, neither can they be result values. Pointers to unions are allowed, though.
(function RESULTTYPE (ARGUMENTTYPE1 ... [...]) [CALLCONV])
CALLCONV
specifies an optional calling convention and
should be a string. The meaning of this string is entirely platform dependent.
The value #f
is also allowed and is passed as a NULL
pointer.
To simplify embedding compiled Scheme code into arbitrary programs, one can define so called "entry points", which provide a uniform interface and parameter conversion facilities.
[syntax] (define-entry-point INDEX ((VAR1 TYPE1) ...) (RTYPE1 ...) EXP1 EXP2 ...)
INDEX
which should evaluate to an exact
integer. During execution of the body EXP1 EXP2 ...
the variables VAR1 ...
are bound to the parameters passed from the host program to the invoked entry point. The parameters passed
are converted according to the foreign type specifiers TYPE1 ...
. The expressions
should return as many values as foreign type specifiers are given in RTYPE1 ...
. The
results are then transformed into values that can be used in the host program.
Note: if one or more of the result types RTYPE ...
specify the type
c-string
, then the parameter type at the same positions in TYPE1 ...
have to be c-string
s as well, because the result strings are copied into the same area in memory.
You should also take care that the passed parameter buffer is long enough to hold the result string or
unpredictable things will happen.
If entry points were defined then the program will not terminate after execution of the last toplevel expression, but instead it will enter a loop that waits for the host to invoke one of the defined entry points.
The following C functions and data types are provided:
void CHICKEN_parse_command_line(int argc, char *argv[], int *heap, int *stack int *symbols)
argc
and argv
and
return the heap-, stack- and symbol-table limits given by runtime options of the form -:...
,
or choose default limits. The library procedure argv
can access the command-line only
if this function has been called by the containing application.
int CHICKEN_initialize(int heap, int stack, int symbols)
heap
holds the number
of bytes that are to be allocated for the secondary heap. stack
holds
the number of bytes for the primary heap. symbols
contains the size
of the symbol table. Passing 0
to one ore more of these parameters
will select a default size. Calling this function more than once has no effect. If enough
memory is available and initialization was successful, then 1
is returned,
otherwise this function returns 0
.
void CHICKEN_run(void **data, int *bytes, int *maxlen)
data, bytes
and maxlen
contain invocation parameters in raw form. Pass NULL
here.
Call this function once to execute all toplevel expressions in your compiled Scheme
program. If the runtime system was not initialized before, then CHICKEN_initialize
is called with default sizes.
void CHICKEN_invoke(int index, C_parameter *params, int count)
index
. count
should contain the number of parameters passed. params
is a pointer to
parameter data:
typedef union { long i; /* parameter type bool, [unsigned] int/short/long */ long c; /* parameter type [unsigned] char */ double f; /* parameter type float/double */ void *p; /* any pointer parameter type and C strings */ } C_parameter;
This function calls CHICKEN_run
if it was not called at least once before.
Here is a simple example (assuming a UNIX-like environment):
% cat foo.c #include <stdio.h> #include "chicken.h" int main(void) { C_parameter p[ 3 ]; char str[ 32 ] = "hello!"; /* We need some space for the result string! */ memset(p, 0, sizeof(p)); p[ 0 ].i = -99; p[ 1 ].p = str; p[ 2 ].f = 3.14; CHICKEN_invoke(1, p, 3); printf("->\n%d\n%s\n", p[ 0 ].i, p[ 1 ].p); return 0; } % cat bar.scm (define-entry-point 1 ((a integer) (b c-string) (c double)) (int c-string) (print (list a b c)) (values 123 "good bye!") ) % chicken bar.scm -output-file bar.c -quiet % gcc foo.c bar.c -o foo `chicken-config -cflags -emb-libs` % foo (-99 "hello!" 3.14) -> 123 good bye!
Note the use of -emb-libs
. We have to link with
a different runtime library, because the host program provides a main
function.
To enable an external C function to call back to Scheme, the form foreign-callback-lambda
(or foreign-callback-lambda*
)
has to be used. This generates special code to save and restore important state information during
execution of C code. There are two ways of calling Scheme procedures from C: the first is to invoke the
runtime function C_callback
with the closure to be called and the number of arguments.
The second is to define an externally visible wrapper function around a Scheme procedure with the
define-external
or foreign-callback-wrapper
forms.
[syntax] (define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...) [syntax] (define-external NAME TYPE [INIT])
NAME
should be a symbol, which, when
converted to a string, represents a legal C identifier. ARGUMENTTYPE1 ...
and
RETURNTYPE
are foreign type specifiers for the argument variables VAR1 ...
and the result, respectively.
QUALIFIERS
is an optional qualifer for the foreign procedure definition, like
__stdcall
.
(define-external (foo (c-string x)) int (string-length x))is equivalent to
(define foo (foreign-callback-wrapper int "foo" "" (c-string) (lambda (x) (string-length x))))
The second form of define-external
can be used to define variables that are accessible
from foreign code. It declares a global variable named by the symbol NAME
and that has
the type TYPE
. INIT
can be an arbitrary expression that is used to initialize
the variable. NAME
is accessible from Scheme just like any other foreign variable defined
by define-foreign-variable
.
Note: don't be tempted to assign strings or bytevectors to external variables. Garbage collection moves
those objects around, so it is very bad idea to assign pointers to heap-data. If you have to do so, then
copy the data object into statically allocated memory (for example by using evict
).
[syntax] (external-pointer NAME)
NAME
should be an external variable defined by (define-external NAME ...)
.
This form returns a pointer object that contains the address of the variable NAME
.
(define-external foo int) ((foreign-lambda* void (((pointer int) ip)) "*ip = 123;") (external-pointer foo)) foo ==> 123
[syntax] (foreign-callback-wrapper RETURNTYPE NAME QUALIFIERS (ARGUMENTTYPE1 ...) EXP)
EXP
. EXP
must be a lambda expression of the form (lambda ...)
. The wrapper will have
the name NAME
and will have a signature as specified in the return- and argument-types
given in RETURNTYPE
and ARGUMENTTYPE1 ...
.
QUALIFIERS
is a qualifier string for the function definition (see define-external
).
C_word C_callback(C_word closure, int argc)
closure
.
argc
should contain the number of arguments that are passed to the procedure on the
temporary stack. Values are put onto the temporary stack with the C_save
macro.
void C_save(C_word x)
x
on the temporary stack.
C_word C_fix(int integer) C_word C_make_character(int char_code) C_word C_SCHEME_END_OF_LIST C_word C_SCHEME_END_OF_FILE C_word C_SCHEME_FALSE C_word C_SCHEME_TRUE
C_word C_string(C_word **ptr, int length, char *string) C_word C_string2(C_word **ptr, char *zero_terminated_string) C_word C_intern2(C_word **ptr, char *zero_terminated_string) C_word C_pair(C_word **ptr, C_word car, C_word cdr) C_word C_flonum(C_word **ptr, double number) C_word C_int_to_num(C_word **ptr, int integer) C_word C_mpointer(C_word **ptr, void *pointer) C_word C_vector(C_word **ptr, int length, ...) C_word C_list(C_word **ptr, int length, ...)
ptr
and initialize a fresh
data object. The new data object is returned. ptr
should be the address
of an allocation pointer created with C_alloc
.
C_word *C_alloc(int words)
words
should be
the number of words needed for all data objects that are to be created in this function.
Note that the allocated data objects have to be passed to the Scheme function, or they will not
be seen by the garbage collector. Note also that the allocated memory will not be available after invocation
of the Scheme procedure, so only small or medium sized objects should be created that way.
int C_SIZEOF_LIST(int length) int C_SIZEOF_STRING(int length) int C_SIZEOF_VECTOR(int length) int C_SIZEOF_INTERNED_SYMBOL(int length) int C_SIZEOF_PAIR int C_SIZEOF_FLONUM int C_SIZEOF_POINTER
int C_character_code(C_word character) int C_unfix(C_word fixnum) double C_flonum_magnitude(C_word flonum) char *C_c_string(C_word string) int C_num_to_int(C_word fixnum_or_flonum) void *C_pointer_address(C_word pointer)
int C_header_size(C_word x) int C_header_bits(C_word x)
x
.
C_word C_block_item(C_word x, int index)
x
.
index
specifies the index of the slot to be fetched, starting at 0. Pairs have 2 slots, one for
the car and one for the cdr. Vectors have one slot for each element.
C_word C_make_header(C_word bits, C_word size)
C_word C_symbol_value(C_word symbol)
symbol
.
An example:
% cat foo.scm (declare (foreign-declare "extern int callout(int, int, int);")) (define callout (foreign-callback-lambda int "callout" int int int)) (define-external (callin (scheme-object xyz)) int (print "This is 'callin': " xyz) 123) (print (callout 1 2 3)) % cat bar.c #include <stdio.h> #include "chicken.h" extern int callout(int, int, int); extern int callin(C_word x); int callout(int x, int y, int z) { C_word *ptr = C_alloc(C_SIZEOF_LIST(3)); C_word lst; printf("This is 'callout': %d, %d, %d\n", x, y, z); lst = C_list(&ptr, 3, C_fix(x), C_fix(y), C_fix(z)); return callin(lst); } % chicken foo.scm -output-file foo.c -quiet % gcc foo.c bar.c -o foo `chicken-config -cflags -libs` % foo This is 'callout': 1, 2, 3 This is 'callin': (1 2 3) 123
Notes:
-nursery
option) or when running the executable (using the -:s
runtime option).
call-with-current-continuation
and passed to C code can
be invoked like any other Scheme procedure.
Certain behaviour of the interpreter and compiled programs can be customized via 'parameters', where a parameter is a procedure of zero or one arguments. To retrieve the value of a parameter call the parameter-procedure with zero arguments. To change the setting of the parameter, call the parameter-procedure with the new value as argument:
(define foo (make-parameter 123)) (foo) ==> 123 (foo 99) (foo) ==> 99
(See also: make-parameter
and parameterize
)
[parameter] case-sensitive
read
reads symbols and identifiers in case-sensitive mode and
uppercase characters in symbols are printed escaped.
[parameter] command-line-arguments
csi
) is invoked with the -script
option, or when a script is compiled, then this parameter contrains the list of arguments passed to the script, with the script
name removed.
[parameter] error-handler
(current-error-port)
. Returning normally from an
error-handler will kill all threads but the primordial one and invoke the value of (reset-handler)
.
[parameter] exit-handler
exit
is called, then this procedure will be invoked with the exit-code as argument. The default behaviour is to
terminate the program.
[parameter] eval-handler
eval
is invoked, it calls the value
of this parameter with the same arguments. The default behaviour is to evaluate the argument expression
and to ignore the second parameter.
[parameter] implicit-exit-handler
[parameter] reset-handler
reset
. The default behaviour in
compiled code is to invoke the value of (exit-handler)
. The default behaviour in the
interpreter is to abort the current computation and to restart the read-eval-print loop.
Terminology:
A unit names a single unit of compilation. Each unit of compilation is translated to a single C file by the compiler and
normally results in a single object module that will be linked resulting in a library or a standalone
executable.
A module designates a namespace, which maps names to symbols. The same name can have different
meanings in different modules. Similarly named objects can coexist in separate modules. A module may consist of several
source files, but a module can not include more than on compilation unit.
In normal mode the compiler and interpreter do not enforce any specific module discipline.
All global symbols exist in the same flat namespace. The define-module
form can be used to evaluate or compile files in a namespace separate from this flat
global namespace.
[syntax] (define-module NAME CLAUSE ...)
NAME
. Any previous definition of a module
with the same name will be overwritten. Each CLAUSE
specifies additional properties of the module:
[module clause] (export SYMBOL ...)
SYMBOL ...
exported symbols of this module, which can be externally referenced.
[module clause] (import (MODULE IMPORT ...) ...)
MODULE
. IMPORT
can be
a symbol or a list of the form (SYMBOL ALIAS)
. When an alias is specified, the symbol can
be accessed under this alias instead of the originally exported name SYMBOL
.
(import (MODULE))
, the syntax (import MODULE)
is
allowed.
[module clause] (import-excluding (MODULE EXCLUDE ...) ...)
MODULE
that are not given in EXCLUDE ...
.
(import-excluding (MODULE))
is in every aspect equivalent to (import (MODULE))
.
[module clause] (files FILENAME ...)
files
clause will be accessed
using the include
form, so the current include path will be respected.
During processing of the files, the feature identifier use-modules
is registered (for use in
cond-expand
).
[module clause] (begin EXPRESSION ...)
EXPRESSION ...
inside the namespace of the current module.
For larger pieces of code the files
clause might be more suitable. Forms given by this clause
type and forms included from files are processed in exactly the same order as they appear in the module
definition.
[module clause] (unit UNITNAME)
UNITNAME
must be a symbol.
This is useful for module definitions without files
clauses, that only specify the
bindings exported by an already existing library.
files
or
begin
clauses, then
it is assumed that the current compilation unit designates a libary unit, and a
(declare (unit UNITNAME))
declaration is generated.
Predefined modules in the CHICKEN system are:
scheme
scheme
module should be imported.
syntax-case
syntax-case
macro system.
chicken-library
chicken-extras
extras
).
chicken-lolevel
lolevel
).
chicken-unistd
unistd
UNIX interface.
chicken-regex
regex
regular expression library.
chicken-ffi
define-entry-point,
define-external
and all foreign type specifiers.
srfi-1 srfi-4 srfi-13 srfi-14 or char-set-lib srfi-18 format match debugger tinyclos
(declare (uses UNIT))
).
string-lib string-lib-internals
srfi-13
module
exports the bindings of both string-lib
and string-lib-internals
.
An example: Consider the following source file
;;; foo.scm (define-module bar (export hello) (import (scheme)) (begin (define (hello s) (string-append "Hello, " s "!") ) ) ) (define-module foo (import (bar) (scheme) (chicken-library) (chicken-extras (string-concatenate conc)) (srfi-13) ) (begin (print (conc (map hello '("one" "two" "three")) "\n")) ) )
Here we have a single compilation unit that contains the two modules foo
and bar
.
bar
exports the symbol hello
.
The module foo
imports bindings from bar
and some other modules.
The modules chicken-extras
and srfi-13
both export a binding for the symbol string-concatenate
. Here
we use conc
as an alias to the binding in extras
.
Compiling the file foo.scm
yields:
% chicken foo.scm -quiet -output-file foo.c % gcc foo.c `chicken-config -cflags -libs -extra-libs` -o foo % foo Hello, one! Hello, two! Hello, three!
Module definitions may not be nested and can be interpreted or compiled, but are not available in
code that is evaluated explicitly with eval
. To use modules, all code has to
be wrapped into module definition forms, either directly (using begin
clauses) or
indirectly (using files
clauses).
To use the module system with separately compiled library units, the following convenience macros can be used:
[syntax] (define-library-implementation NAME CLAUSE ...)
(define-module NAME (unit NAME) CLAUSE ...)
[syntax] (define-library-interface NAME EXPORT1 ...)
(define-module NAME (unit NAME) (export EXPORT1 ...))
As an example, consider these two source files
;;; bar.scm (define-library-implementation bar (import (scheme)) (begin (define (hello s) (string-append "Hello, " s "!") ) ) ) ;;; foo.scm (define-library-interface bar hello) (define-module foo (import (bar) (scheme) (chicken-library) (chicken-extras (string-concatenate conc)) (srfi-13) ) (begin (print (conc (map hello '("one" "two" "three")) "\n")) ) )
Both files are separately compiled:
% chicken foo.scm -quiet -output-file foo.c % chicken bar.scm -quiet -explicit-use -output-file bar.c % gcc -c bar.c `chicken-config -cflags` -o bar.o % gcc foo.c bar.o `chicken-config -cflags -libs -extra-libs` -o foo % foo Hello, one! Hello, two! Hello, three!
Note that the interface definitions of library modules have to be given in any module definition file that
imports those libraries. The interfaces of builtin library modules like chicken-library
are defined automatically, but for your own libraries it is helpful to have a central "repository"
for interface definitions. This is accomplished by the file .chicken-interfaces
.
Whenever module definitions are encountered, this file is loaded from either the current HOME
directory or the directory given in the environment variable CHICKEN_HOME
, if it exists.
This unit contains basic Scheme definitions. This unit is used by default, unless the executable
is compiled with the -explicit-use
option.
[procedure] (add1 N) [procedure] (sub1 N)
N
.
[procedure] (bitwise-and N1 N2) [procedure] (bitwise-ior N1 N2) [procedure] (bitwise-xor N1 N2) [procedure] (bitwise-not N) [procedure] (arithmetic-shift N1 N2)
arithmetic-shift
shifts the argument N1
by N2
bits to the left. If N2
is negative, than N1
is shifted to the right.
[procedure] (fixnum? X)
#t
if X
is a fixnum, or #f
otherwise.
[procedure] (fx+ N1 N2) [procedure] (fx- N1 N2) [procedure] (fx* N1 N2) [procedure] (fx/ N1 N2) [procedure] (fxmod N1 N2) [procedure] (fxneg N) [procedure] (fxmin N1 N2) [procedure] (fxmax N1 N2) [procedure] (fx= N1 N2) [procedure] (fx> N1 N2) [procedure] (fx< N1 N2) [procedure] (fx>= N1 N2) [procedure] (fx<= N1 N2)
fxneg
negates its argument.
[procedure] (signum N)
1
if N
is positive, -1
if N
is negative or 0
if N
is zero.
[procedure] (current-error-port)
[procedure] (end-of-file)
[procedure] (flush-output [PORT])
PORT
defaults to the value of
(current-output-port)
.
[procedure] (port-name PORT)
PORT
. This returns the filename that was used to open this file.
Returns a special tag string, enclosed into parantheses for non-file ports.
[procedure] (port-position PORT)
PORT
as two values: row and column number.
If the port does not support such an operation an error is signaled. This procedure is currently only available
for input ports.
[procedure] (delete-file STRING)
STRING
. If the file does not exist, an error is signaled.
[procedure] (file-exists? STRING)
#t
if a file with the given pathname exists, or #f
otherwise.
[variable] pathname-directory-separator
[variable] pathname-extension-separator
[procedure] (rename-file OLD NEW)
OLD
to NEW
. If the operation does not
succeed, an error is signaled.
[procedure] (get-output-string PORT)
(open-output-string)
.
[procedure] (open-input-string STRING)
STRING
.
[procedure] (open-output-string)
[procedure] (print-to-string EXP ...)
EXP
on string port and returns the result string.
[procedure] (features)
cond-expand
.
[procedure] (register-feature! FEATURE ...)
cond-expand
. FEATURE ...
may be a keyword, string or symbol.
[procedure] (unregister-feature! FEATURE ...)
FEATURE ...
may be a keyword, string or symbol.
Keywords are special symbols prefixed with #:
that evaluate to themselves.
Procedures can use keywords to accept optional named parameters in addition to normal required parameters.
Assignment to and bindings of keyword symbols is not allowed.
[procedure] (get-keyword KEYWORD ARGLIST [THUNK])
ARGLIST
specified under the keyword KEYWORD
.
If the keyword is not found, then the zero-argument procedure THUNK
is invoked and
the result value is returned. If THUNK
is not given, #f
is returned.
(define (increase x . args) (+ x (get-keyword args #:amount (lambda () 1))) ) (increase 123) ==> 124 (increase 123 #:amount 10) ==> 133
[procedure] (keyword? X)
#t
if X
is a keyword symbol, or #f
otherwise.
[procedure] (keyword->string KEYWORD)
KEYWORD
into a string.
[procedure] (string->keyword STRING)
STRING
.
Notes:
exn
are non-continuable.
exn
kind have an additional arguments
property that contains the arguments passed to the error-handler.
unistd
unit is available and used, then a user-interrupt (signal/int
)
signals an exception of the kind user-interrupt
.
[procedure] (argv)
(argv)
.
It depends on the host-shell wether arguments are expanded ('globbed') or not.
[procedure] (char-name SYMBOL-OR-CHAR [CHAR])
SYMBOL-OR-CHAR
is a symbol, then char-name
returns the character with
this name, or #f
if no character is defined under this name.
SYMBOL-OR-CHAR
is a character, then the name of the character is returned as a symbol,
or #f
if the character has no associated name.
If the optional argument CHAR
is provided, then SYMBOL-OR-CHAR
should be a symbol
that will be the new name of the given character.
If multiple names designate the same character, then the write
will use the character name that
was defined last.
(char-name 'space) ==> #\space (char-name #\space) ==> space (char-name 'bell) ==> #f (char-name (integer->char 7)) ==> #f (char-name 'bell (integer->char 7)) (char-name 'bell) ==> #\bell (char->integer (char-name 'bell)) ==> 7
[procedure] (current-milliseconds)
[procedure] (current-seconds)
[procedure] (enable-interrupts) [procedure] (disable-interrupts)
(disable-interrupts) (disable-interrupts) (enable-interrupts) ; <interupts still disabled - call enable-interrupts once more>
[procedure] (errno)
[procedure] (error STRING EXP ...)
(current-error-port)
and invokes the current value of (error-handler)
.
This conforms to SRFI-23.
[procedure] (exit [CODE])
exit-handler
).
[procedure] (gc [FLAG])
#f
) or major (#t
) GC is to be triggered. If no argument
is given, #t
is assumed.
[procedure] (gensym [STRING-OR-SYMBOL])
[procedure] (getenv STRING)
STRING
or #f
if that variable is not defined.
[procedure] (machine-type)
[procedure] (make-parameter VALUE [GUARD])
VALUE
. Invoking the procedure with one argument changes it's value to the value of that
argument (subsequent invocations with zero parameters return the new value). GUARD
should
be a procedure of a single argument. Any new values of the parameter (even the initial value)
are passed to this procedure. The guard procedure should check the value and/or convert it to an appropriate form.
[procedure] (port? X)
#t
if X
is a port object or #f
otherwise.
[procedure] (print EXP1 ...)
EXP1, ...
using display
and writes
a newline character to the port that is the value of (current-output-port)
.
[procedure] (print* EXP1 ...)
print
, but does not output a terminating newline character.
[procedure] (reset)
reset-handler
).
[procedure] (set-finalizer! X PROC)
PROC
, that will be called as soon as the non-immediate
data object X
is about to be garbage-collected (with that object as it's argument).
[procedure] (set-gc-report! FLAG)
FLAG
. A value of #t
shows
statistics after every major GC. A value true value different from #t
shows statistics after every
minor GC. #f
switches statistics off.
[procedure] (software-type)
[procedure] (string->uninterned-symbol STRING)
STRING
.
[procedure] (system STRING)
[procedure] (vector-copy! VECTOR1 VECTOR2 [COUNT])
VECTOR1>
into VECTOR2
. If the argument COUNT
is given, it specifies the maximal number of elements to be copied.
[procedure] (void)
This unit has support for evaluation and macro-handling. This unit is used by default, unless the executable
is compiled with the -explicit-use
option.
[procedure] (eval EXP [ENVIRONMENT])
EXP
and returns the result of the evaluation. The second arguments is always ignored.
[procedure] (load FILENAME [EVALPROC])
EVALPROC
(which defaults to eval
).
[procedure] (load-noisily FILENAME [EVALPROC])
load
but the result(s) of each evaluated toplevel-expression is written to standard output.
[procedure] (load-srfi-7-program FILENAME [EVALPROC])
[procedure] (read-eval-print-loop)
reset-handler
so that any invocation of
reset
restarts the read-eval-print loop. Also changes the current error-handler
to display a message, write any arguments to the value of (current-error-port)
and reset.
[procedure] (get-line-number EXPR)
EXPR
is a pair with the car being a symbol, and line-number information is available
for this expression, then this procedure returns the associated line number. If line-number information is not available,
then #f
is returned.
Note that line-number information for expressions is only available in the compiler.
[procedure] (macro? SYMBOL)
#t
if there exists a macro-definition for SYMBOL
.
[procedure] (macroexpand X)
X
is a macro-form, expand the macro (and repeat expansion until expression is a non-macro form).
Returns the resulting expression.
[procedure] (macroexpand-1 X)
X
is a macro-form, expand the macro.
Returns the resulting expression.
[procedure] (undefine-macro! SYMBOL)
SYMBOL
.
[procedure] (define-reader-ctor SYMBOL PROC)
#,
read syntax. For further information, see
documentation for SRFI-10.
This unit provides an interactive debugger. When compiling with the -emit-debug-info
option, then the debugger
unit is automatically declared as used. Any errors will enter
the debugger's read-eval-print loop. To enter a break-loop as soon as the executable starts, invoke the
compiled program with the -:b
runtime option.
[procedure] (break [MESSAGE])
MESSAGE
is provided, then it should be either a string or
#f
. For a list of available debugger commands enter ?
.
This unit contains a collection of useful utility definitions.
[procedure] (butlast LIST)
LIST
.
[procedure] (chop LIST N)
N
elements
of LIST
. If LIST
has a length that is not a multiple
of N
, then the last sublist contains the remaining elements.
(chop '(1 2 3 4 5 6) 2) ==> ((1 2) (3 4) (5 6)) (chop '(a b c d) 3) ==> ((a b c) (d))
[procedure] (compress BLIST LIST)
LIST
with corresponding true
values in the list BLIST
.
(define nums '(99 100 110 401 1234)) (compress (map odd? nums) nums) ==> (99 401)
[procedure] (flatten LIST1 ...)
LIST1 ...
concatenated together, with nested lists removed (flattened).
[procedure] (intersperse LIST X)
X
placed between each element.
[procedure] (tail? X LIST)
X
is one of the tails (cdr's) of LIST
.
[procedure] (call-with-input-string STRING PROC)
PROC
with a single argument that is a string-input-port with
the contents of STRING
.
[procedure] (call-with-output-string PROC)
PROC
with a single argument that is a string-output-port.
Returns the accumulated output-string.
[procedure] (with-input-from-string STRING THUNK)
THUNK
with the current input-port temporarily bound to an
input-string-port with the contents of STRING
.
[procedure] (with-output-to-string THUNK)
THUNK
with the current output-port temporarily bound to a string-output-port
and return the accumulated output string.
[procedure] (fprintf PORT FORMATSTRING ARG ...) [procedure] (printf FORMATSTRING ARG) [procedure] (sprintf FORMATSTRING ARG ...)
fprintf
), the value of (current-output-port)
(printf
) or a string (sprintf
).
The FORMATSTRING
can contain any sequence of characters. The character '~' prefixes special formatting directives:
~% | write newline character |
---|---|
~S | write the next argument |
~A | display the next argument |
~\n | skip all whitespace in the format-string until the next non-whitespace character |
~B | write the next argument as a binary number |
~O | write the next argument as an octal number |
~X | write the next argument as a hexadecimal number |
~C | write the next argument as a character |
~~ | display '~' |
~! | flush all pending output |
~? | invoke formatted output routine recursively with the next two arguments as format-string and list of parameters |
[procedure] (clear-hash-table! HASH-TABLE)
HASH-TABLE
.
[procedure] (get HASH-TABLE KEY PROP)
PROP
of the item KEY
in HASH-TABLE
. This facility can
be used as a kind of "disembodied" property-list. If no entry named KEY
is stored in
the hash-table or if no property PROP
for that key exists, #f
is returned.
[procedure] (hash-table? X)
#t
if the argument is a hash-table.
[procedure] (hash-table-count HASH-TABLE)
[procedure] (hash-table-for-each PROC HASH-TABLE)
PROC
which should expect two arguments. This procedure is called for each entry in the hash-table with the key and the value as parameters.
[procedure] (hash-table-ref HASH-TABLE KEY [DEFAULT])
KEY
. If no entry is stored in
the table, #f
is returned.
[procedure] (hash-table-set! HASH-TABLE KEY VALUE)
[procedure] (make-hash-table [SIZE])
eq?
. If SIZE
is provided it specifies the initial size of the hash-table. If the hash-table fills above a certain size it is automatically resized to accommodate more entries.
[procedure] (put! HASH-TABLE KEY PROP VALUE)
VALUE
as property PROP
under the item KEY
in the given hash-table. Any previously
existing value is overwritten.
[procedure] (list->queue LIST)
LIST
converted into a queue, where the first element of the list is
the same as the first element of the queue. The resulting queue may share memory with the list
and the list should not be modified after this operation.
[procedure] (make-queue)
[procedure] (queue? X)
#t
if X
is a queue, or #f
otherwise.
[procedure] (queue->list QUEUE)
QUEUE
converted into a list, where the first element of the list is
the same as the first element of the queue. The resulting list may share memory with the queue object
and should not be modified.
[procedure] (queue-add! QUEUE X)
X
to the rear of QUEUE
.
[procedure] (queue-empty? QUEUE)
#t
if QUEUE
is empty, or #f
otherwise.
[procedure] (queue-first QUEUE)
QUEUE
. If QUEUE
is empty an error is
signaled
[procedure] (queue-last QUEUE)
QUEUE
. If QUEUE
is empty an error is
signaled
[procedure] (queue-remove! QUEUE)
QUEUE
. If QUEUE
is empty an error is
signaled
[procedure] (merge LIST1 LIST2 LESS?) [procedure] (merge! LIST1 LIST2 LESS?)
merge!
is the destructive version of merge. LESS?
should be a procedure of two arguments, that returns true if the first argument is to be
ordered before the second argument.
[procedure] (sort SEQUENCE LESS?) [procedure] (sort! SEQUENCE LESS?)
SEQUENCE
, which should be a list or a vector. sort!
is the destructive version of sort.
[procedure] (sorted? SEQUENCE LESS?)
SEQUENCE
is already sorted.
[procedure] (random N)
N
-1.
[procedure] (randomize [X])
X
is not supplied, the current time is used.
[procedure] (make-input-port READ READY? CLOSE [PEEK])
READ
is called when the next character is to be read and should return a character
or the value of (end-of-file)
. READY?
is called when char-ready?
is called on this port and should return #t
or #f
.
CLOSE
is called when the port is closed. PEEK
is called when peek-char
is called on this port and should return a character or the value of (end-of-file)
.
if the argument PEEK
is not given, then READ
is used instead and the created port
object handles peeking automatically (by calling READ
and buffering the character).
[procedure] (make-output-port WRITE CLOSE)
WRITE
is called when output is sent to the port and receives a single argument, a string.
CLOSE
is called when thje port is closed and should be a procedure of no arguments.
[procedure] (pretty-print EXP [PORT])
PORT
defaults to the value of
(current-output-port)
.
[parameter] pretty-print-width
[procedure] (read-file [PORT])
PORT
,
which defaults to the value of (current-input-port)
.
[procedure] (read-line [PORT]) [procedure] (write-line STRING [PORT])
PORT
defaults to the value of (current-input-port)
and (current-output-port)
, respectively.
[procedure] (read-lines [PORT [MAX]])
MAX
or fewer lines from PORT
. PORT
defaults to the value of (current-input-port)
.
[procedure] (read-string NUM [PORT])
NUM
characters from PORT
, which defaults to the value of
(current-input-port)
. The characters are returned as a string of length NUM
or less, if the port contains fewer than NUM
characters.
[procedure] (with-error-output-to-port PORT THUNK)
THUNK
with the current error output-port temporarily bound to
PORT
.
[procedure] (with-input-from-port PORT THUNK)
THUNK
with the current input-port temporarily bound to PORT
.
[procedure] (with-output-to-port PORT THUNK)
THUNK
with the current output-port temporarily bound to PORT
.
[procedure] (string-any PROC STRING1 STRING2 ...)
PROC
on every Nth element of the argument strings and return the first result that
is true, or #f
if no application returned true.
[procedure] (string-capitalize STRING)
STRING
capitalized.
[procedure] (string-capitalize! STRING)
STRING
and returns the modified string.
[procedure] (string-concatenate LIST [STRING])
LIST
concatenated together.
If the second parameter STRING
is provided, then it is placed between each concatenated
string.
(string-concatenate '("one" "two") "three") <=> (apply string-append (intersperse '("one" "two") "three"))
[procedure] (string-filter PROC STRING)
STRING
.
PROC
should take one argument and return #f
if that argument is not to be
accumulated in the result string.
[procedure] (string-downcase STRING) [procedure] (string-upcase STRING)
[procedure] (string-downcase! STRING) [procedure] (string-upcase! STRING)
[procedure] (string-every PROC STRING1 STRING2 ...)
PROC
on every Nth element of the argument strings. If all results are true, return the last one. If no result was true, return #f
.
[procedure] (string-index PROC STRING1 STRING2 ...)
PROC
applied to the elements of STRING1
,
STRING2
... at position i is true.
[procedure] (string-trim STRING TRIMCHARS) [procedure] (string-left-trim STRING TRIMCHARS) [procedure] (string-right-trim STRING TRIMCHARS)
STRING
with all characters in the string TRIMCHARS
removed from the left/right side(s).
[procedure] (string-map PROC STRING1 STRING2 ...) [procedure] (string-map! PROC STRING1 STRING2 ...)
string-map
)
where each character is replaced with the result of the procedure.
[procedure] (string-reverse STRING) [procedure] (string-reverse! STRING)
STRING
. string-reverse!
is the destructive
version.
[procedure] (string-split STRING [DELIMITER-STRING [KEEPEMPTY]])
\t\n
" is assumed. If the parameter KEEPEMPTY
is given and not #f
,
then empty substrings are retained:
(string-split "one two three") ==> ("one" "two" "three") (string-split "foo:bar::baz:" ":" #t) ==> ("foo" "bar" "" "baz" "")
[procedure] (string-translate STRING FROM [TO])
STRING
with characters matching FROM
translated to TO
.
If TO
is omitted, then matching characters are removed. FROM
and
TO
may be a character, a string or a list. If both FROM
and
TO
are strings, then the character at the same position in TO
as
the matching character in FROM
is substituted.
[procedure] (substring-index WHICH WHERE [START]) [procedure] (substring-index-ci WHICH WHERE [START])
WHERE
where string WHICH
occurs.
If the optional argument START
is given, then the search starts at that index.
substring-index-ci
is a case-insensitive version of substring-index
.
[procedure] (constantly X)
X
regardless of the number and value of its arguments.
(constantly X) <=> (lambda args X)
[procedure] (complement PROC)
PROC
.
(complement PROC) <=> (lambda (x) (not (PROC x)))
[procedure] (compose PROC1 PROC2 ...)
PROC1 PROC2 ...
.
(compose F G) <=> (lambda args (call-with-values (lambda () (apply G args)) F))
[procedure] (flip PROC)
PROC
with its arguments swapped:
(flip PROC) <=> (lambda (x y) (PROC y x))
List library, see documentation for SRFI-1
Homogeneous numeric vectors, see documentation for SRFI-4. In addition to that, the following procedures are also provided:
[procedure] (u8vector->byte-vector U8VECTOR) [procedure] (s8vector->byte-vector S8VECTOR) [procedure] (u16vector->byte-vector U16VECTOR) [procedure] (s16vector->byte-vector S16VECTOR) [procedure] (u32vector->byte-vector U32VECTOR) [procedure] (s32vector->byte-vector S32VECTOR) [procedure] (f32vector->byte-vector F32VECTOR) [procedure] (f64vector->byte-vector F64VECTOR)
[procedure] (byte-vector->u8vector BYTE-VECTOR) [procedure] (byte-vector->s8vector BYTE-VECTOR) [procedure] (byte-vector->u16vector BYTE-VECTOR) [procedure] (byte-vector->s16vector BYTE-VECTOR) [procedure] (byte-vector->u32vector BYTE-VECTOR) [procedure] (byte-vector->s32vector BYTE-VECTOR) [procedure] (byte-vector->f32vector BYTE-VECTOR) [procedure] (byte-vector->f64vector BYTE-VECTOR)
BYTE-VECTOR
is taken
as a 'packed' representation of the contents of the vector. The argument-byte-vector shares memory with the
contents of the vector.
String library, see documentation for SRFI-13
(This library unit can be loaded in the interpreter csi using include
or
load
).
Character set library, see documentation for SRFI-14
(This library unit can be loaded in the interpreter csi using include
or
load
).
Andrew Wright's pattern matching package.
[syntax] (match EXP CLAUSE ...) [syntax] (match-lambda CLAUSE ...) [syntax] (match-lambda* CLAUSE ...) [syntax] (match-let ((PAT EXP) ...) BODY) [syntax] (match-let* ((PAT EXP) ...) BODY) [syntax] (match-letrec ((PAT EXP) ...) BODY) [syntax] (match-define PAT EXP)
[syntax] (define-structure (ID_0 ID_1 ... ID_N)) [syntax] (define-structure (ID_0 ID_1 ... ID_N) ((ID_{N+1} EXP_1) ... (ID_{N+M} EXP_M))) [syntax] (define-const-structure (ID_0 ARG_1 ... ARG_N)) [syntax] (define-const-structure (ID_0 ARG_1 ... ARG_N) ((ARG_{N+1} EXP_1) ... (ARG_{N+M} EXP_M)))
match
.
(match-error-control [MODE])
match...
macro forms are to be expanded.
With no argument this procedure returns the current mode. A single argument specifies the new mode that decides
what should happen if no match-clause applies.
#:error
#:match
#:fail
pair?
tests when the consequence is to fail in car
or cdr
rather than to signal an error.
#:unspecified
car
or cdr
or return an unspecified value.
unsafe
option or declaration.
When the GNU regex 0.12 package is available, then this unit provides some useful procedures for working
with regular expressions. See the
GNU documentation for detailed information about regular expression syntax. The selected syntax bits
are: RE_INTERVALS, RE_NO_BK_BRACES, RE_NO_BK_PARENS, RE_NO_BK_VBAR
.
[procedure] (grep REGEX LIST)
LIST
that match the regular expression REGEX
.
This procedure could be defined as follows:
(define (grep regex lst) (filter (lambda (x) (string-match regex x)) lst) )
[procedure] (pattern->regexp PATTERN)
PATTERN
into a regular expression.
(pattern->regexp "foo.*") ==> "^foo\\..*$"
[procedure] (string-match REGEXP STRING [START]) [procedure] (string-match-positions REGEXP STRING [START])
REGEXP
with STRING
and returns either #f
if the match failed, or a list of matching groups, where
the first element is the complete match. If the optional argument START
is supplied, it specifies the starting position in STRING
.
For each matching group the result-list contains either: #f
for a non-matching but
optional group; a list of start- and end-position of the match in STRING
(in the
case of string-match-positions
); or the matching substring (in the case of
string-match
).
[procedure] (string-search REGEXP STRING [START [RANGE]]) [procedure] (string-search-positions REGEXP STRING [START [RANGE]])
REGEXP
with
STRING
. The search can be limited to RANGE
characters.
Otherwise the procedures have the same behaviour as string-match
/
string-match-positions
.
[procedure] (string-split-fields REGEXP STRING [MODE [START]])
STRING
into a list of fields according to MODE
,
where MODE
can be the keyword #:infix
(REGEXP
matches field separator), the keyword #:suffix
(REGEXP
matches field terminator) or #t
(REGEXP
matches field),
which is the default.
[procedure] (string-substitute REGEXP SUBST STRING [INDEX])
STRING
that match REGEXP
and substitutes them
with the string SUBST
. The substitution can contain references to subexpressions in
REGEXP
with the \NUM
notation, where NUM
refers
to the NUMth parenthesized expression. The optional argument INDEX
defaults to 1 and
specifies the number of the match to be substituted. Any non-numeric index specifies that all
matches are to be substituted.
(string-substitute "([0-9]+) (eggs|chicks)" "\\2 (\\1)" "99 eggs or 99 chicks" 2) ==> "99 eggs or chicks (99)"
Hieb's and Dybvig's hygienic macro package. Provides syntax-case
and syntax-rules
. A postscript manual can be found here:
Indiana University Computer Science Department, Technical Report #356
Notes:
-hygienic
option to the compiler or interpreter. The unit has only to be declared as used, if compiled code
invokes macroexpand
or eval
with high-level macro syntax
forms.
define-macro, define-id-macro, let-macro, let-id-macro, let-optionals,
define-entry-point
and the
procedure undefine-macro!
can not be used.
define-values
is not allowed in internal definitions.
define-syntax
can not be used inside an eval-when
form.
A simple multithreading package. This threading package follows largely the specification of SRFI-18. For more information see documentation for SRFI-18.
Notes:
dynamic-wind
is involved.
make-parameter
)
dynamic-wind
thunks.
[procedure] (thread-quantum THREAD)
THREAD
, which is an exact integer specifying the approximate
time-slice of the thread.
[procedure] (thread-quantum-set! THREAD QUANTUM)
THREAD
to QUANTUM
.
(This library unit is autoload
ed into the interpreter csi on the first invocation of
format
).
[procedure] (format DESTINATION FORMAT-STRING . ARGUMENTS)
An almost complete implementation of Common LISP format description according to the CL reference book Common LISP from Guy L. Steele, Digital Press. This code was originally part of SLIB. The author is Dirk Lutzebaeck.
Returns #t
, #f
or a string; has side effect of printing
according to FORMAT-STRING
. If DESTINATION
is #t
, the output is to the current output port and #t
is returned. If DESTINATION
is #f
, a formatted string is returned as the result of the call.
If DESTINATION
is a string, DESTINATION
is regarded as the
format string; FORMAT-STRING
is then the first argument and the
output is returned as a string. If DESTINATION
is a number, the
output is to the value of (current-error-port)
.
Otherwise DESTINATION
must be an output port and
#t
is returned.
FORMAT-STRING
must be a string. In case of a formatting error
format returns #f
and prints a message on the value of
(current-error-port)
. Characters are output as if the string were output by
the display
function with the exception of those prefixed by a
tilde (~). For a detailed description of the FORMAT-STRING
syntax
please consult a Common LISP format reference manual. A list of all supported, non-supported and extended
directives can be found in format.txt.
This unit uses definitions from the extras
unit.
This unit provides services as used on many UNIX-like systems. This unit uses the regex
unit.
Note that the following definitions are not availabe on non-UNIX systems like Windows or DOS.
this unit uses the regex
unit.
[procedure] (create-temporary-file [EXTENSION])
EXTENSION
is not given,
then .tmp
is used. If the environment variable TMPDIR, TEMP
or TMP
is set, then
the pathname names a file in that directory.
[procedure] (absolute-pathname? PATHNAME)
#t
if the string PATHNAME
names an absolute pathname, and
returns #f
otherwise.
[procedure] (decompose-pathname PATHNAME)
PATHNAME
. For any component that is not contained in PATHNAME
,
#f
is returned.
[procedure] (make-pathname DIRECTORY FILENAME [EXTENSION]) [procedure] (make-absolute-pathname DIRECTORY FILENAME [EXTENSION]
DIRECTORY, FILENAME
and
(optionally) EXTENSION
. DIRECTORY
can be #f
(meaning
no directory component), a string or a list of strings. FILENAME
and EXTENSION
should be strings or #f
.
make-absolute-pathname
returns always an absolute pathname.
[procedure] (pathname-directory PATHNAME> [procedure] (pathname-file PATHNAME) [procedure] (pathname-extension PATHNAME)
PATHNAME
. If the pathname does not contain
the accessed component, then #f
is returned.
[procedure] (pathname-replace-directory PATHNAME DIRECTORY) [procedure] (pathname-replace-file PATHNAME FILENAME) [procedure] (pathname-replace-extension PATHNAME EXTENSION)
PATHANME
replaced by a new value.
[procedure] (pathname-strip-directory PATHNAME) [procedure] (pathname-strip-extension PATHNAME)
PATHNAME
stripped.
[procedure] (change-directory NAME)
NAME
.
[procedure] (current-directory)
[procedure] (create-directory NAME)
NAME
.
[procedure] (delete-directory NAME)
NAME
. The directory has
to be empty.
[procedure] (directory PATHNAME)
PATHNAME
.
[procedure] (directory? NAME)
#t
if there exists a file with the name NAME
and if that file is a directory, or #f
otherwise.
[procedure] (glob PATTERN1 ...)
PATTERN1 ...
, which
should be strings containing the usual file-patterns (with *
matching zero or more characters
and ?
matching zero or one character).
[procedure] (call-with-input-pipe CMDLINE PROC [MODE]) [procedure] (call-with-output-pipe CMDLINE PROC [MODE])
PROC
with a single argument: a input- or output port for a pipe connected to
the subprocess named in CMDLINE
. If PROC
returns normally, the pipe
is closed and any result values are returned.
[procedure] (close-input-pipe PORT) [procedure] (close-output-pipe PORT)
PORT
and waits until the connected subprocess finishes.
[procedure] (create-pipe)
pipe()
and returns 2 values:
the file-descriptors of the input- and output-ends of the pipe.
[procedure] (open-input-pipe CMDLINE [MODE])
CMDLINE
and returns a port, from which
the output of the process can be read. If MODE
is specified, it should be the keyword
#:text
(the default) or #:binary
.
[procedure] (open-output-pipe CMDLINE [MODE])
CMDLINE
and returns a port. Anything
written to that port is treated as the input for the process.
If MODE
is specified, it should be the keyword
#:text
(the default) or #:binary
.
[limit] pipe/buf
[procedure] (with-input-from-pipe CMDLINE THUNK [MODE]) [procedure] (with-output-to-pipe CMDLINE THUNK [MODE])
current-input-port/current-output-port
to a port
for a pipe connected to the subprocess named in CMDLINE
and call the procedure THUNK
with no arguments. After THUNK
returns normally the pipe is closed and the standard input-/output port
is restored to its previous value and any result values are returned.
(with-output-to-pipe "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -" (lambda () (print #<<EOF %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx> /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g{[}{]}J}J cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage EOF ) ) )
[procedure] (create-fifo FILENAME [MODE])
FILENAME
and the permission bits MODE
, which
defaults to
(+ perm/irwxu perm/irwxg perm/irwxo)
[procedure] (fifo? FILENAME)
#t
if the file with the name FILENAME
names a FIFO.
[procedure] (duplicate-fileno OLD [NEW])
NEW
is given, then the file-descriptor NEW
is opened to access
the file with the file-descriptor OLD
. Otherwise a fresh file-descriptor accessing the
same file as OLD
is returned.
[procedure] (file-close FILENO)
FILENO
.
[procedure] (file-open FILENAME FLAGS [MODE])
FILENAME
and open-flags FLAGS
using the C function open()
. On success a file-descriptor for the opened file is returned.
FLAGS
should be a bitmask containing one or more of the open/...
values
ored together using bitwise-ior
(or simply added together).
The optional MODE
should be a bitmask composed of one or more permission values like
perm/irusr
and is only relevant when a new file is created. The default mode is
perm/irwxu | perm/irgrp | perm/iroth
.
[procedure] (file-read FILENO SIZE [BUFFER])
SIZE
bytes from the file with the file-descriptor FILENO
.
If a string or bytevector is passed in the optional argument BUFFER
,
then this string will be destructively modified to contain the read data. This procedure returns two values:
the buffer containing the data and the number of bytes read.
[procedure] (file-select READFDLIST WRITEFDLIST [TIMEOUT])
READFDLIST
and
WRITEFDLIST
is ready for input or output, respectively. If the optional argument
TIMEOUT
is given and not false, then it should specify the number of seconds after
which the wait is to be aborted. This procedure returns two values: the lists of file-descriptors ready for
input and output, respectively.
[procedure] (file-write FILENO BUFFER [SIZE])
BUFFER
into the file with the file-descriptor
FILENO
. If the optional argument SIZE
is given, then only the specified
number of bytes are written.
[file descriptor] fileno/stdin [file descriptor] fileno/stdout [file descriptor] fileno/stderr
[flag] open/rdonly [flag] open/wronly [flag] open/rdwr [flag] open/read [flag] open/write [flag] open/creat [flag] open/append [flag] open/excl [flag] open/noctty [flag] open/nonblock [flag] open/trunc [flag] open/sync
file-open
.
[procedure] (open-input-file* FILENO [OPENMODE]) [procedure] (open-output-file* FILENO [OPENMODE])
FILENO
for input or output and returns a port.
FILENO
should be a positive exact integer.
OPENMODE
specifies an additional mode for opening the file (currently only
the keyword #:append
is supported, which opens an output-file for appending).
[procedure] (port->fileno PORT)
PORT
is a file-port, then a file-descriptor is returned for this port. Otherwise an
error is signaled.
[procedure] (file-modification-time FILENAME)
FILENAME
. If the file does not exist,
an error is signaled.
[procedure] (file-position FILE)
FILE
, which should be a port or a file-descriptor.
[procedure] (file-size FILENAME)
FILENAME
. If the file does not exist,
an error is signaled.
[procedure] (set-file-position! FILE POSITION [WHENCE])
FILE
to POSITION
,
which should be an exact integer. FILE
should be a port or a file-descriptor.
WHENCE
specifies how the position is to interpreted and should be one of the
values seek/set, seek/cur
and seek/end
. It defaults to
seek/set
.
[procedure] (current-process-id)
[procedure] (parent-process-id)
[procedure] (process-execute PATHNAME [LIST])
execv()
. If the optional argument LIST
is given, then it should contain
a list of strings which are passed as arguments to the subprocess.
[procedure] (process-fork [THUNK])
fork()
. Returns either
the PID of the child process or 0. If THUNK
is given, then the child process calls it
as a procedure with no arguments and terminates.
[procedure] (process-run PATHNAME [LIST])
fork()
that executes the
program given by the string PATHNAME
using the UNIX system call execv()
.
The PID of the new process is returned. If LIST
is not specified, then FILENAME
is passed to a program named by the environment variable SHELL
(or /bin/sh
,
if the variable is not defined), so usual argument expansion can take place.
[procedure] (process-signal PID [SIGNAL])
SIGNAL
to the process with the id PID
using the UNIX
system call kill()
. SIGNAL
defaults to the value of the variable
signal/term
.
[procedure] (process-wait [PID [NOHANG]])
PID
has terminated
using the UNIX system call waitpid()
. If PID
is not given, then
this procedure waits for any child process. If NOHANG
is given and not
#f
then the current process is not suspended.
This procedure returns three values:
PID
or 0, if NOHANG
is true and the child
process has not terminated yet;
#t
if the process exited normally or #f
otherwise;
[procedure] (create-symbolic-link OLDNAME NEWNAME)
NEWNAME
that points to the file named OLDNAME
.
[procedure] (read-symbolic-link FILENAME)
FILENAME
points.
[procedure] (file-owner FILENAME)
FILENAME
.
[procedure] (file-permissions FILENAME)
FILENAME
. You can test this value by
performing bitwise operations on the result and the perm/...
values.
[procedure] (file-read-access? FILENAME [REALUID]) [procedure] (file-write-access? FILENAME [REALUID]) [procedure] (file-execute-access? FILENAME [REALUID])
#t
if the owner of the file has read, write or execute permissions
on the file named FILENAME
. If the optional parameter REALUID
is given
and not false, then the real user id of the process is used for the test. Otherwise the effective user id is taken.
[procedure] (change-file-mode FILENAME MODE)
FILENAME
to MODE
using the chmod()
system call.
The perm/...
variables contain the various permission bits and can be combinded with the
bitwise-ior
procedure.
[procedure] (change-file-owner FILENAME UID GID)
FILENAME
to the user- and group-ids
UID
and GID
(which should be exact integers) using the
chown()
system call.
[procedure] (current-user-id) [procedure] (current-group-id) [procedure] (current-effective-user-id) [procedure] (current-effective-group-id)
[permission bits] perm/irusr [permission bits] perm/iwusr [permission bits] perm/ixusr [permission bits] perm/irgrp [permission bits] perm/iwgrp [permission bits] perm/ixgrp [permission bits] perm/iroth [permission bits] perm/iwoth [permission bits] perm/ixoth [permission bits] perm/irwxu [permission bits] perm/irwxg [permission bits] perm/irwxo [permission bits] perm/isvtx [permission bits] perm/isuid [permission bits] perm/isgid
change-file-mode
.
[procedure] (set-user-id! UID)
UID
, which should be a positive
integer.
[procedure] (file-lock PORT [START [LEN]])
PORT
for reading or writing (according to wether PORT
is an input- or output-port). START
specifies the starting position in the file to be locked and defaults to
0. LEN
specifies the length of the portion to be locked and defaults to #t
, which
means the complete file. file-lock
returns a "lock"-object.
[procedure] (file-test-lock PORT [START [LEN]])
PORT
is locked for reading or writing (according to wether
PORT
is an input- or output-port) and returns either #f
or the process-id of
the locking process.
[procedure] (file-unlock LOCK)
LOCK
.
[procedure] (set-alarm! SECONDS)
signal/alrm
after SECONDS
are elapsed.
You can use the set-signal-handler!
procedure to write a handler for this signal.
[procedure] (set-signal-handler! SIGNUM PROC [DISABLED])
PROC
as the handler for the signal
with the code SIGNAL
. PROC
is called with the signal number as
its sole argument. If the optional argument DISABLED
is given and not #f
then interrupts are disabled trough the execution of the signal handler. The default is to enable interrupts.
If the argument PROC
is #f
then this signal will be ignored.
[procedure] (set-signal-mask! SIGLIST)
SIGLIST
.
Signals masked in that way will not be delivered to the current process.
[signal code] signal/term [signal code] signal/kill [signal code] signal/int [signal code] signal/hup [signal code] signal/fpe [signal code] signal/ill [signal code] signal/segv [signal code] signal/abrt [signal code] signal/trap [signal code] signal/quit [signal code] signal/alrm [signal code] signal/vtalrm [signal code] signal/prof [signal code] signal/io [signal code] signal/urg [signal code] signal/chld [signal code] signal/cont [signal code] signal/stop [signal code] signal/tstp [signal code] signal/pipe [signal code] signal/xcpu [signal code] signal/xfsz [signal code] signal/usr1 [signal code] signal/usr2 [signal code] signal/winch
process-signal
or set-signal-handler!
.
[procedure] (current-environment)
[procedure] (setenv VARIABLE VALUE)
VARIABLE
to VALUE
. Both
arguments should be strings. If the variable is not defined in the environment, a new definition is created.
[procedure] (unsetenv VARIABLE)
VARIABLE
from the environment
of the current process. If the variable os not defined, nothing happens.
[procedure] (map-file-to-memory ADDRESS LEN PROTECTION FLAG FILENO [OFFSET])
mmap()
.
ADDRESS
should be a foreign pointer object or #f
;
LEN
specifies the size of the section to be mapped; PROTECTION
should be one or more of the flags prot/read, prot/write, prot/exec
or prot/none
bitwise-iored together; FLAG
should be one or more of the flags map/fixed, map/shared,
map/private, map/anonymous
or map/file
; FILENO
should be the
file-descriptor of the mapped file. The optional argument OFFSET
gives the offset of
the section of the file to be mapped and defaults to 0. This procedure returns an object representing
the mapped file section.
move-memory!
can be used to access the mapped memory.
[procedure] (unmap-file-from-memory MMAP [LEN])
munmap()
.
MMAP
should be a mapped file as returned by the procedure map-file-to-memory
.
The optional argument LEN
specifies the length of the section to be unmapped and defaults
to the complete length given when the file was mapped.
[procedure] (seconds->local-time SECONDS)
SECONDS
into a 10 element vector of the
form #(second minute hours mday month year wday yday dstflag timezone)
.
You can obtain the number of seconds using the library procedure
current-seconds
.
The last item in the result vector timezone
contains the difference between UTC and local time
in seconds west of UTC (using the C variable timezone
).
[procedure] (seconds->string SECONDS)
SECONDS
into a string of the form
"Tue May 21 13:46:22 1991\n"
.
[procedure] (seconds->utc-time SECONDS)
seconds->local-time
, but interpretes SECONDS
as
local time.
[procedure] (time->string VECTOR)
VECTOR
into a string of the form
"Tue May 21 13:46:22 1991\n"
.
[procedure] (_exit [CODE])
_exit
).
Note that the exit-handler
is not called when this procedure is invoked. The optional return-code CODE
defaults to 0
.
[error code] errno/perm [error code] errno/noent [error code] errno/srch [error code] errno/intr [error code] errno/io [error code] errno/noexec [error code] errno/badf [error code] errno/child [error code] errno/nomem [error code] errno/acces [error code] errno/fault [error code] errno/busy [error code] errno/notdir [error code] errno/isdir [error code] errno/inval [error code] errno/mfile [error code] errno/nospc [error code] errno/spipe [error code] errno/pipe [error code] errno/again [error code] errno/rofs
errno
.
[procedure] (file-truncate FILE OFFSET)
FILE
to the length OFFSET
, which
should be an integer. If the file-size is smaller or equal to OFFSET
then nothing is done.
FILE
should be a filename or a file-descriptor.
[procedure] (get-host-name)
[procedure] (set-buffering-mode! PORT MODE [BUFSIZE])
PORT
to MODE
, which
should be one of the keywords #:full, #:line
or #:none
. If BUFSIZE
is specified it determines the size of the buffer to be used (if any).
[procedure] (terminal-name PORT)
PORT
.
[procedure] (terminal-port? PORT)
#t
if PORT
is connected to a terminal and #f
otherwise.
[procedure] (system-information)
uname()
and returns 5 values: system-name, node-name,
OS release, OS version and machine.
[procedure] (user-information USER)
USER
specifes a valid username (as a string) or user ID, then the user database is consulted and
7 values are returned: the user-name, the encrypted password, the user ID, the group ID, a user-specific string, the
home directory and the default shell. If no user with this name or ID can be found, then #f
is
returned.
change-directory chdir
change-file-mode chmod
change-file-owner chown
create-directory mkdir
create-fifo mkfifo
create-pipe pipe
create-symbolic-link link
current-directory curdir
current-effective-groupd-id getegid
current-effective-user-id geteuid
current-group-id getgid
current-parent-id getppid
current-process-id getpid
current-user-id getuid
delete-directory rmdir
duplicate-fileno dup/dup2
_exit _exit
file-close close
file-execute-access? access
file-open open
file-lock fcntl
file-position ftell/lseek
file-read read
file-read-access? access
file-select select
file-test-lock fcntl
file-truncate truncate/ftruncate
file-unlock fcntl
file-write write
file-write-access? access
get-host-name gethostname
map-file-to-memory mmap
open-input-file* fdopen
open-output-file* fdopen
open-input-pipe popen
open-output-pipe popen
port->fileno fileno
process-execute execvp
process-fork fork
process-signal kill
process-wait waitpid
close-input-pipe pclose
close-output-pipe pclose
read-symbolic-link readlink
seconds->local-time localtime
seconds->string ctime
seconds->utc-time gmtime
set-alarm! alarm
set-buffering-mode! setvbuf
set-file-position! fseek/seek
set-signal-mask! sigprocmask
set-user-id! setuid
setenv setenv/putenv
system-information uname
terminal-name ttyname
terminal-port? isatty
time->string asctime
unsetenv putenv
unmap-file-from-memory munmap
user-information getpwnam/getpwuid
This unit provides a number of handy low-level operations. Use at your own risk.
This unit uses the srfi-4
and extras
units.
[procedure] (address->pointer ADDRESS)
ADDRESS
.
[procedure] (null-pointer)
(address->pointer 0)
.
[procedure] (null-pointer? PTR)
#t
if PTR
contains a NULL
pointer, or
#f
otherwise.
[procedure] (pointer? X)
#t
if X
is a foreign pointer object, and #f
otherwise.
[procedure] (pointer->address PTR)
PTR
points.
[procedure] (deserialize U32VECTOR [SAFE])
U32VECTOR
back into a Scheme object. If the optional
argument SAFE
is given and not #f
, then any attempt to deserialize
a process specific object like a closure, port or foreign pointer will signal an error.
[procedure] (serialize OBJECT)
OBJECT
into an u32vector and returns that vector.
[procedure] (extend-procedure PROCEDURE X)
PROCEDURE
which contains an additional data slot initialized
to X
.
[procedure] (extended-procedure? PROCEDURE)
#t
if PROCEDURE
is an extended procedure, or
#f
otherwise.
[procedure] (procedure-data PROCEDURE)
PROCEDURE
.
[procedure] (set-procedure-data! PROCEDURE X)
PROCEDURE
to X
.
(define foo (letrec ((f (lambda () (procedure-data x))) (x #f) ) (set! x (extend-procedure f 123)) x) ) (foo) ==> 123 (set-procedure-data! foo 'hello) (foo) ==> hello
[procedure] (byte-vector FIXNUM ...)
FIXNUM ...
as its initial contents.
[procedure] (byte-vector? X)
#t
if X
is a byte-vector object, or #f
otherwise.
[procedure] (byte-vector-fill! BYTE-VECTOR N)
BYTE-VECTOR
to N
, which should be an exact
integer.
[procedure] (byte-vector->list BYTE-VECTOR)
BYTE-VECTOR
.
[procedure] (byte-vector-length BYTE-VECTOR)
BYTE-VECTOR
.
[procedure] (byte-vector-ref BYTE-VECTOR INDEX)
INDEX
th position of BYTE-VECTOR
.
[procedure] (byte-vector-set! BYTE-VECTOR INDEX N)
INDEX
th position of BYTE-VECTOR
to the
value of the exact integer n
.
[procedure] (executable-byte-vector->procedure PBYTE-VECTOR)
PBYTE-VECTOR
, which
should have been allocated using make-executable-byte-vector
.
void <procedure>(int argc, C_word closure, C_word k, C_word arg1, ...)
argc
contains the number of arguments arg1, ...
that are passed plus 2
(including closure
and k
).
closure
is the procedure object itself.
k
is a continuation closure that should be called when the code is about to return.
typedef void (*CONTINUATION)(int argc, C_word closure, C_word result); ((CONTINUATION)k[ 1 ])(2, k, result)(
k
is a data object with the second word being the actual code pointer)
An example:
(define x (make-executable-byte-vector 17)) (move-memory! '#u8(#x8b #x44 #x24 #x0c ; movl 12(%esp), %eax - `k' #x8b #x5c #x24 #x10 ; movl 16(%esp), %ebx - `arg1' #x53 ; pushl %ebx - push result #x50 ; pushl %eax - push k #x6a #x02 ; pushl $2 - push argument count #x8b #x40 #x04 ; movl 4(%eax), %eax - fetch code pointer #xff #xd0) ; call *%eax x) (define y (executable-byte-vector->procedure x)) (y 123) ==> 123
The result of calling executable-byte-vector->procedure
with a non-executable statically allocated byte-vector
is undefined.
[procedure] (list->byte-vector LIST)
LIST
, where the elements of LIST
should be exact integers.
[procedure] (make-byte-vector SIZE [INIT])
SIZE
. If INIT
is given, then it
should be an exact integer with which every element of the byte-vector is initialized.
[procedure] (make-executable-byte-vector SIZE [INIT])
make-static-byte-vector
, but the code is suitable for execution.
[procedure] (make-static-byte-vector SIZE [INIT])
make-byte-vector
, but allocates the byte-vector in storage that is not subject to garbage collection.
To free the allocated memory, one has to call release
explicitly.
[procedure] (static-byte-vector->pointer PBYTE-VECTOR)
PBYTE-VECTOR
.
[procedure] (block-ref BLOCK INDEX)
INDEX
th slot of the object BLOCK
.
BLOCK
may be a vector, record structure, pair or symbol.
[procedure] (block-set! BLOCK INDEX X)
INDEX
th slot of the object BLOCK
to the value
of X
.
BLOCK
may be a vector, record structure, pair or symbol.
[procedure] (copy X)
X
recursively and returns the fresh copy. Objects allocated in static memory
are copied back into garbage collected storage.
[procedure] (evict X [ALLOCATOR])
X
recursively into the memory pointed to by the foreign pointer object returned
by ALLOCATOR
, which should be a procedure of a single argument (the number of bytes to
allocate). The freshly copied object is returned.
evict
is able to handle circular and shared structures, but evicted symbols are no longer unique:
a fresh copy of the symbol is created, so
(define x 'foo) (define y (evict 'foo)) y ==> foo (eq? x y) ==> #f (define z (evict '(bar bar))) (eq? (car z) (cadr z)) ==> #t
ALLOCATOR
defaults to the C-library malloc()
.
[procedure] (evicted? X)
#t
if X
is a non-immediate evicted data object, or
#f
otherwise.
[procedure] (move-memory! FROM TO [BYTES])
BYTES
bytes of memory from FROM
to TO
.
FROM
and TO
may be strings, primitive byte-vectors, SRFI-4 byte-vectors (see:
srfi-4
unit), memory mapped files or foreign pointers (as obtained from a call to
foreign-lambda
, for example). if BYTES
is not given and the size
of the source or destination operand is known then the maximal number of bytes will be copied.
[procedure] (number-of-slots BLOCK)
BLOCK
contains.
BLOCK
may be a vector, record structure, pair or symbol.
[procedure] (release X [RELEASER])
X
recursively.
RELEASER
should be a procedure of a single argument (a foreign pointer object to
the static memory to be freed) and defaults to the C-library free()
.
This unit is a port of Gregor Kiczales TinyCLOS with numerous modifications.
This unit uses the extras
unit.
[syntax] (define-class NAME (SUPERCLASS1 ...) (SLOTNAME1 ...) [METACLASS])
NAME
to a new class (a new instance of the
class <class>
). SUPERCLASS1 ...
is a list of superclasses
of the newly created class. If no superclasses are given, then <object>
is assumed.
SLOTNAME1 ...
are the names of the direct slots of
the class. if METACLASS
is provided, then the new class-instance is an instance of METACLASS
instead of <class>
.
(define-class NAME (SUPER) (SLOT1 SLOT2) META)is equivalent to
(define NAME (make META 'name 'NAME 'direct-supers (list SUPER) 'direct-slots (list 'SLOT1 'SLOT2)) )Note that slots-names are not required to by symbols, so the following is perfectly valid:
(define hidden-slot (list 'hidden)) (define <myclass> (make <class> 'direct-supers (list <object>) 'direct-slots (list hidden-slot) ) ) (define x1 (make <myclass>) (slot-set! x1 hidden-slot 99)
[syntax] (define-generic NAME)
NAME
to contain a fresh generic function object without associated
methods.
[syntax] (define-method (NAME (VARIABLE1 CLASS1) ... PARAMETERS ...) BODY ...)
BODY ...
to the generic function that was assigned to
the variable name
.
CLASS1 ...
is a list if classes that specialize this particular method. The method
can have additional parameters PARAMETERS
, which do not specialize the method any further.
call-next-method
names a procedure
of zero arguments that can be invoked to call the next applicable method with the same arguments.
NAME
.
[procedure] (add-method GENERIC METHOD)
METHOD
to the list of applicable methods for the
generic function GENERIC
.
[procedure] (instance? X)
#t
if X
is an instance of a non-primitive class.
[procedure] (make CLASS INITARG ...)
CLASS
and passes INITARG ...
to the
initialize
method of this class.
[procedure] (make-class SUPERCLASSES SLOTNAMES)
SUPERCLASSES
should be the list of direct superclass objects
and SLOTNAMES
should be a list of symbols naming the slots of this class.
[procedure] (make-generic [NAME])
NAME
is specified, then it should be a string.
[procedure] (make-method SPECIALIZERS PROC)
SPECIALIZERS
.
(define-method (foo (<bar> x)) 123) <=> (add-method foo (make-method (list <bar>) (lambda (call-next-method x) 123)))
[procedure] (slot-ref INSTANCE SLOTNAME)
SLOTNAME
of the object INSTANCE
.
[procedure] (slot-set! INSTANCE SLOTNAME VALUE)
SLOTNAME
of the object INSTANCE
to VALUE
.
[procedure] (class-cpl CLASS)
CLASS
as a list of classes.
[procedure] (class-direct-slots CLASS)
CLASS
as a list of lists, where each sublist
contains the name of the slot.
[procedure] (class-direct-supers CLASS)
CLASS
.
[procedure] (class-of X)
X
is an instance of.
[procedure] (class-name CLASS)
CLASS
.
[procedure] (class-slots CLASS)
CLASS
and it's superclasses as a list of lists, where each sublist
contains the name of the slot.
[procedure] (generic-methods GENERIC)
GENERIC
.
[procedure] (method-specializers METHOD)
METHOD
.
[procedure] (method-procedure METHOD)
METHOD
.
[procedure] (subclass? CLASS1 CLASS2)
#t
is CLASS1
is a subclass of CLASS2
, or
#f
otherwise. Note that the following holds:
(subclass? X X) ==> #t
[generic] (allocate-instance CLASS)
CLASS
and returns the instance.
[generic] (compute-apply-generic GENERIC) [generic] (compute-apply-methods GENERIC) [generic] (compute-methods GENERIC)
GENERIC
.
[generic] (compute-cpl CLASS)
CLASS
.
[generic] (compute-getter-and-setter CLASS SLOT ALLOCATOR)
SLOT
.
ALLOCATOR
is a procedure of one argument
(I currently don't know what it does).
[generic] (compute-method-more-specific? GENERIC)
#t
if the first method is more specific than the second one with respect to the list of arguments. Otherwise
the returned predicate returns #f
.
[generic] (compute-slots CLASS)
CLASS
.
[generic] (initialize INSTANCE INITARGS)
INSTANCE
. INITARGS
is the list of initialization
arguments that were passed to the make
procedure.
[generic] (describe-object INSTANCE PORT)
INSTANCE
to PORT
.
Execution of the interpreter command ,d
or calling describe
will invoke this generic function.
[generic] (print-object INSTANCE PORT)
INSTANCE
to PORT
.
Any output of an instance with display, write
and print will invoke
this generic function.
[procedure] (initialize-slots INSTANCE INITARGS)
INITARGS
and initializes the corresponding slots in INSTANCE
.
(define-class <pos> () (x y)) (define-method (initialize (<pos> pos) initargs) (call-next-method) (initialize-slots pos initargs)) (define p1 (make <pos> 'x 1 'y 2)) (define p2 (make <pos> 'x 3 'y 5))
The class hierarchy of builtin classes looks like this:
<top> <object> <class> <procedure-class> <procedure> <entity-class> <generic> <primitive-class> <primitive> <void> <boolean> <symbol> <char> <vector> <pair> <number> <exact> <inexact> <string> <port> <input-port> <output-port> <byte-vector> <u8vector> <s8vector> <u16vector> <s16vector> <u32vector> <s32vector> <f32vector> <f64vector> <structure> <environment> <hash-table> <queue> <time> <lock> <mmap> <condition> <end-of-file>
[class] <primitive> --> <top>
[class] <boolean> --> <primitive> [class] <symbol> --> <primitive> [class] <char> --> <primitive> [class] <vector> --> <primitive> [class] <null> --> <primitive> [class] <pair> --> <primitive> [class] <number> --> <primitive> [class] <exact> --> <number> [class] <inexact> --> <number> [class] <string> --> <primitive> [class] <port> --> <primitive> [class] <byte-vector> --> <primitive> [class] <structure> --> <primitive> [class] <environment> --> <structure> [class] <hash-table> --> <structure> [class] <queue> --> <structure> [class] <end-of-file> --> <primitive> [class] <input-port> --> <port> [class] <output-port> --> <port> [class] <procedure> --> <procedure-class>
[class] <class> --> <object>
[class] <entity-class> --> <class>
[class] <generic> --> <entity-class>
[class] <method> --> <class>
[class] <object> --> <class>
[class] <procedure-class> --> <class>
[class] <condition> --> <structure>
[class] <time> --> <structure>
[class] <char-set> --> <structure>
[class] <u8vector> --> <byte-vector> [class] <s8vector> --> <byte-vector> [class] <u16vector> --> <byte-vector> [class] <s16vector> --> <byte-vector> [class] <u32vector> --> <byte-vector> [class] <s32vector> --> <byte-vector> [class] <f32vector> --> <byte-vector> [class] <f64vector> --> <byte-vector>
[class] <lock> --> <structure> [class] <mmap> --> <structure>
unistd
library unit.
In addition to library units the following files are provided. Use them by including
the file in your code with the include
special form.
Some procedures for printing descriptions of arbitrary data objects.
(This file is autoload
ed into the interpreter csi on the first invocation of
describe
or dump
).
This include file defines a module named describe
, which exports the symbols
describe
and dump
.
[procedure] (describe EXP [PORT])
EXP
to PORT
or the value of
(current-output-port)
.
[procedure] (dump EXP [PORT])
EXP
to PORT
or
to the value of (current-output-port)
, if PORT
is not specified.
EXP
may be a byte-vector or a string.
A procedure to invoke a sub-process and communicate with it via it's standard I/O ports.
(Only available on UNIX-like systems)
This include file defines a module named process
, which exports the symbol
process
.
(This file is autoload
ed into the interpreter csi on the first invocation of
process
).
[procedure] (process COMMANDLINE)
COMMANDLINE
to the host-system's shell that is invoked as a subprocess
and returns three values: an input port from which data written by the sub-process can be read, an output port from which
any data written to it will be received as input from the sub-process and the process-id of the started sub-process.
Record types as defined by SRFI-9. See documentation for SRFI-9.
This include file defines a module named srfi-9
, which exports the symbol
define-record-type
.
This file provides a procedure to display some status information, like heap/stack-size, features, etc.
(This file is autoload
ed into the interpreter csi on the first invocation of
report
).
This include file defines a module named report
, which exports the symbol
report
.
[procedure] (report [PORT])
PORT
, or if not provided, to the value of
(current-output-port)
.
There exist two different kinds of data objects in the CHICKEN system: immediate and non-immediate objects. Immediate objects are represented by a tagged machine word, which is usually of 32 bits length (64 bits on 64-bit architectures). The immediate objects come in four different flavors:
C_CHARACTER_BITS
. The ASCII code of the character is encoded in bits 9 to 16, counting
from 1 and starting at the lowest order position.
C_BOOLEAN_BITS
. Bit 5 (counting from 0 and starting at the lowest order position) is one if the
boolean designates true, or 0 if it is false.
C_SPECIAL_BITS
. Bits 5 to 8 contain an identifying number for this type of object.
The following constants are defined:
C_SCHEME_END_OF_LIST C_SCHEME_UNDEFINED C_SCHEME_END_OF_FILE
Non-immediate objects are blocks of data represented by a pointer into the heap. The first word of the data block contains a header, which gives information about the type of the object. The header has the size of a machine word, usually 32 bits (64 bits on 64 bit architectures).
C_GC_FORWARDING_BIT
C_BYTEBLOCK_BIT
C_SPECIALBLOCK_BIT
C_8ALIGN_BIT
The actual data follows immediately after the header. Note that block-addresses are always aligned to the native machine-word boundary. Scheme data objects map to blocks in the following manner:
C_PAIR_TYPE
),
where the car and the cdr are contained in the first and second
slots, respectively.
C_VECTOR_TYPE
).
C_STRING_TYPE
).
C_CLOSURE_TYPE
). The first slot contains a pointer
to a compiled C function.
C_FLONUM_BITS
). Slots one and two (or a single slot on
64 bit architectures) contain a 64-bit floating-point number, in the representation used by the host systems C compiler.
C_SYMBOL_TYPE
). Slots one and two contain the toplevel variable
value and the print-name (a string) of the symbol, respectively.
C_PORT_TYPE
). The first slot contains a pointer to a file-
stream, if this is a file-pointer, or NULL if not. The other slots contain housekeeping data used for this port.
C_STRUCTURE_TYPE
). The first slot contains a symbol
that specifies the kind of structure this record is an instance of. The other slots contain the actual record items.
C_POINTER_TYPE
). The single slot contains a machine
pointer.
Data objects may be allocated outside of the garbage collected heap, as long as their layout follows the above mentioned scheme. But care has to be taken not to mutate these objects with heap-data (i.e. non-immediate objects), because this will confuse the garbage collector.
For more information see the header file chicken.h
.
chicken.h
if it is not in your current directory.
(declare (usual-integrations))
since this enables most
optimizations.
let-optionals, let-id-macro, define-id-macro, let-macro,
define-macro
and
define-entry-point
currently don't work in combination with the high-level macro system.
system
always returns 0 when compiled with Visual C++.
eval-when
doesn't allow toplevel definitions inside it's body in combination with
hygienic macros.
define-values
can not be used in internal definitions when the hygienic macro
system is used.
port-name
does not return the fully expanded pathname of a file-port, just the
filename that was used to open the file.
port-position
currently works only for input ports.
thread-sleep!
, then interrupts are effectively
disabled.
-inline
or -optimize-level 4
does sometimes take ridiculously long for very little performance gain.
eval
is invoked with scheme-report-environment
or
null-environment
, then non-standard syntax is still defined during evaluation.
#
character if it is not a script-file
(beginning with #!
).
Sven Hartrumpf helped porting CHICKEN to the UltraSparc and found a number of compiler bugs.
Kirill Lisovsky found a couple of bugs while porting Oleg Kiselyov's SSAX XML parser to CHICKEN.
Doug Quale contributed the configuration scripts for installation on UNIX-like systems, suggested numerous improvements and was generally very helpful.
Benedikt Rosenau found several bugs and spent a lot of time testing the system and pointing out improvements.
Bakul Shah and Chris Moline helped porting CHICKEN to FreeBSD.
Dennis Marti helped fixing a problem with the garbage collector under Mac OS X.
Thanks also to Dave Bodenstab, Franklin Chen, James Crippen, Brian Denheyer, Marc Feeley, Joey Gibson, Andreas Gustafsson, Karl M. Hegbloom, William P. Heinemann, Bruce Hoult, Dale Jordan, Ron Kneusel, Charles Martin, David Rush, Oskar Schirmer, Ronald Schröder, Jeffrey B. Siegal, Jason Songhurst, Mike Thomas, Christian Tismer, Shawn Wagner, Matthew Welland and Richard Zidlicky for bug-fixes, tips and suggestions.