To use crunch in your Scheme code, simply wrap toplevel forms to be compiled in a (crunch ...) expression. All toplevel procedure definitions are accessible as global or local (depending on the context where the crunch form occurs) procedures callable from Scheme. The crunch macro can only be used in compiled code. To use the macro, put

(require-extension crunch)

in your code.

Alternatively, the chicken-crunch program can be used to translate and compile code in the crunch Scheme dialect into C++. The generated code has no dependencies. Only the headerfile crunch.h must be available and in your C++ compiler's include path. When installing this extension with chicken-setup, the file will be located in your default include path, usually $PREFIX/include.

The compiler can also be used through its procedural API, see crunch-compile. In that case, load the runtime-part of the compiler with

(require-extension crunch-compiler)

Crunched procedures are in every respect identical to C/C++ functions called via the usual CHICKEN foreign function interface. Crunch does not know anything about Scheme data or memory management. Translated code can call back into Scheme (see define-crunch-callback) - callbacks are usually automatically detected and the generated Scheme wrapper function for a crunched procedure will be of the appropiate type, if required.

Crunch uses its own macro expander, a modified version of Al Petrofsky's alexpander, a R5RS compliant implementation of syntax-rules macros. See alexpander for a description of its numerous extensions. The crunch macro itself can be used in code that uses the default lowlevel macros, syntax-case or syntactic-closures.

No garbage collector is used. All dynamically allocated data (strings and number vectors) are reference counted.

The dialect of R5RS Scheme supported is extremely limited. See Bugs and limitations for more information.

Compiles the toplevel expression EXPRESSION into a C++ code, writing the generated code to PORT, which defaults to the value of (current-output-port). If DBGMODE is given, debugging output will be written to the current output port. DBGMODE can be a boolean or a number between 1 and 3. Debug mode 1 shows some information about each compiled procedure, debug mode 3 generates loads of diagnostic output about the type-inferencing process and expanded code.

If the entry-point name SYMBOL is given, then the (normally hidden) toplevel variable of the same name holding a pointer to the associated C++ function can be accessed from C/C++ code, i.e. it is exposed under the same name. Note that the exposed variable is a pointer to a function.

Each invocation of crunch-compile creates its own private namespace, global variables are not visible in subsequent compilation runs in the same process. Syntax definitions are persistent over several invocations, though.

Compiles the given toplevel expressions and expands into a set of function definitions and an invocation of compiled toplevel expressions in EXPRESSION. The form can be used in a definition context but ends in a non-definition form (and so can with some macro systems not be followed by other definitions). Calls to Scheme callbacks are detected automatically and generate the appropriate foreign-safe-lambda definition. The result of the executed toplevel code is unspecified.

Provided the file crunch.h is in the include path, the generated C++ code can be compiled by itself. To link, you may have to add the -lm switch to the linker, depending on the platform on which you are compiling the code.

The code generated by chicken-crunch can optionally use the libarena custom memory allocator interface. To use libarena, please supply the -use-arena option to chicken-crunch. By default, chicken-crunch expects that the libarena header files are installed in /usr/include, and that the libarena.so shared library is installed in /usr/lib. If you have installed the headers and library files in locations other than these defaults, please use -arena-include and -arena-lib options to tell the compiler where to find the respective libarena files.

When -use-arena is specified, chicken-crunch generates code to use the libarena pool allocator. The pool allocator keeps a pool of buffers of fixed size. Allocations that cannot be met from the existing buffers will result in the creation of a new buffer. Under the current implementation, the pool will never shrink, only grow. The user may define an initial pool to be initialized at program startup, via the -arena-pool option. The argument to that option is a comma separated list of the form:

SIZE:N,...

Where SIZE is buffer size in bytes, and N is how many buffers of that size should be created.

cond-expand recognizes the feature identifiers crunch, srfi-0, highlevel-macros and syntax-rules. When code is compiled to a standalone program with chicken-crunch, the feature identifier crunch-standalone is defined as well.

All primitives take a fixed number of arguments, optional or "rest" arguments are not supported. Primitives may not be redefined. Uses of primitives in non-operator position are treated as (lambda (tmp1 ...) (<primitive> tmp1 ...)).

The .../shared conversion procedures return data objects that share the actual storage with the argument objects, this can be used for interesting applications.

(flush-output)

(void)
(error S)
(exit N)
(argc)
(argv-ref K)

error shows a message and invokes abort(3). argc returns the number of arguments passed to the process (including the program name) and argv-ref returns the command line argument with the given index (or the program name, when the index is zero).

Lexical scope is not supported, only references to global variables and variables local to the current lambda construct (including let bound variables) are visible. Expressions of the form ((lambda (...) ...) ...) are converted in the corresponding let construct.

Continuations are not supported.

Multiple values are not supported.

Tail calls are only detected in self-recursive functions.

Rest-arguments (dotted lambda lists) are not supported.

Numeric overflow of fixnum operations is not detected.

Nearly no error checks are made at runtime.

Named let is always assumed to be a looping construct, calls to the loop variable must be in tail position.

do and named let loops always return an unspecified value.

I make no guarantuees about the correctness of the C++ template code. C++ is insane.

If a homogenous number vector or string is passed from Scheme to C++ code generated by crunch, then the length of the passed array is not known and the associated ...-length primitive and primitives that require the length of the vector will abort.

Copyright (c) 2007, Felix L. Winkelmann
The "alexpander" is Copyright (c) 2002-2004, Al Petrofsky
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
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.