@node SFFI Reference
@subsection SFFI Reference
@cindex C/C++ code inlining
@cindex Static foreign function interface

@subsubheading Reference

@lspdef ffi:clines
@defspec ffi:clines c/c++-code*

Insert C declarations and definitions

@table @var
@item c/c++-code
One or more strings with C definitions. Not evaluated.
@item returns
No value.
@end table

@paragraph Description
This special form inserts C code from strings passed in the
@var{arguments} directly in the file that results from compiling lisp
sources. Contrary to @coderef{ffi:c-inline}, this function may have no
executable statements, accepts no input value and returns no value.

The main use of @coderef{ffi:clines} is to declare or define C variables
and functions that are going to be used later in other FFI
statements. All statements from @var{arguments} are grouped at the
beginning of the produced header file.

@coderef{ffi:clines} is a special form that can only be used in lisp
compiled files as a toplevel form. Other uses will lead to an error
being signaled, either at the compilation time or when loading the
file.

@paragraph Examples
@exindex @coderef{ffi:clines} adding c toplevel declarations
In this example the @coderef{ffi:clines} statement is required to get
access to the C function @code{cos}:
@lisp
(ffi:clines "#include <math.h>")
(defun cos (x)
  (ffi:c-inline (x) (:double) :double "cos(#0)" :one-liner t))
@end lisp
@end defspec

@lspdef ffi:c-inline
@defspec ffi:c-inline (lisp-values) (arg-c-types) return-type c/c++-code @
                      &key (side-effects t) (one-liner nil)

Inline C code in a lisp form

@table @var
@item lisp-values
One or more lisp expressions. Evaluated.
@item arg-c-types
One or more valid FFI types. Evaluated.
@item return-type
Valid FFI type or @code{(values ffi-type*)}.
@item c/c++-code
String containing valid C code plus some valid escape forms.
@item one-liner
Boolean indicating, if the expression is a valid R-value. Defaults to
@code{nil}.
@item side-effects
Boolean indicating, if the expression causes side effects. Defaults to
@code{t}.
@item returns
One or more lisp values.
@end table

@paragraph Description
This is a special form which can be only used in compiled code and whose
purpose is to execute some C code getting and returning values from and
to the lisp environment.

The first argument @var{lisp-values} is a list of lisp forms. These
forms are going to be evaluated and their lisp values will be
transformed to the corresponding C types denoted by the elements in the
list @var{arg-c-types}.

The input values are used to create a valid C expression using the
template in @var{C/C++-code}. This is a string of arbitrary size which
mixes C expressions with two kind of escape forms.

The first kind of escape form are made of a hash and a letter or a
number, as in: @code{#0}, @code{#1}, ..., until @code{#z}. These codes
are replaced by the corresponding input values. The second kind of
escape form has the format @code{@@(return [n])}, it can be used as
lvalue in a C expression and it is used to set the n-th output value of
the @coderef{ffi:c-inline} form.

When the parameter @var{one-liner} is true, then the C template must be
a simple C statement that outputs a value. In this case the use of
@code{@@(return)} is not allowed. When the parameter @var{one-liner} is
false, then the C template may be a more complicated block form, with
braces, conditionals, loops and spanning multiple lines. In this case
the output of the form can only be set using @code{@@(return)}.

Parameter @var{side-effects} set to false will indicate, that the
functions causes no side-effects. This information is used by the
compiler to optimize the resulting code. If @var{side-effects} is set to
false, but the function may cause the side effects, then results are
undefined.

Note that the conversion between lisp arguments and FFI types is
automatic. Note also that @coderef{ffi:c-inline} cannot be used in
interpreted or bytecompiled code! Such usage will signal an error.

@paragraph Examples
@exindex @coderef{ffi:c-inline} inlining c code
The following example implements the transcendental function SIN using
the C equivalent:

@lisp
(ffi:c-lines "#include <math.h>")
(defun mysin (x)
  (ffi:c-inline (x) (:double) :double
    "sin(#0)"
    :one-liner t
    :side-effects nil))
@end lisp

This function can also be implemented using the @code{@@(return)} form
as follows:

@lisp
@verbatim
(defun mysin (x)
  (ffi:c-inline (x) (:double) :double
    "@(return)=sin(#0);"
    :side-effects nil))
@end verbatim
@end lisp

The following example is slightly more complicated as it involves loops
and two output values:

@exindex @coderef{ffi:c-inline} returning multiple values
@lisp
@verbatim
(defun sample (x)
  (ffi:c-inline (x (+ x 2)) (:int :int) (values :int :int) "{
    int n1 = #0, n2 = #1, out1 = 0, out2 = 1;
    while (n1 <= n2) {
      out1 += n1;
      out2 *= n1;
      n1++;
    }
    @(return 0)= out1;
    @(return 1)= out2;
    }"
   :side-effects nil))
@end verbatim
@end lisp
@end defspec

@lspdef ffi:c-progn
@defspec ffi:c-progn args &body body

Interleave C statements with the Lisp code

@table @var
@item args
Lisp arguments. Evaluated.
@item returns
No value.
@end table

@paragraph Description
This form is used for it's side effects. It allows for interleaving C
statements with the Lisp code. The argument types doesn't have to be
declared – in such case the objects type in the C world will be
@code{cl_object}.

@paragraph Examples
@exindex @coderef{ffi:c-progn} interleaving c and lisp code
@lisp
@verbatim
(lambda (i)
  (let* ((limit i)
         (iterator 0)
         (custom-var (cons 1 2)))
    (declare (:int limit iterator))
    (ffi:c-progn (limit iterator custom-var)
                 "cl_object cv = #2;"
                 "ecl_print(cv, ECL_T);"
                 "for (#1 = 0; #1 < #0; #1++) {"
                 (format t "~&Iterator: ~A, I: ~A~%" iterator i)
                 "}")))
@end verbatim
@end lisp
@end defspec

@c XXX: SFFI returns one-element list pointer, while DFFI returns just a
@c pointer. This is probably a bug.

@lspdef ffi:defcallback
@defspec ffi:defcallback name ret-type arg-desc &body body

@table @var
@item name
Name of the lisp function.
@item ret-type
Declaration of the return type which function returns.
@item arg-desc
List of pairs @code{(arg-name arg-type)}.
@item body
Function body.
@item returns
Pointer to the defined callback.
@end table

@paragraph Description
Defines Lisp function and generates a callback for the C world, which
may be passed to these functions. Note, that this special operator has
also a dynamic variant (with the same name and interface).
@end defspec

@lspdef ffi:defcbody
@defmac ffi:defcbody name arg-types result-type c-expression

Define C function under the lisp name

@table @var
@item name
Defined function name.
@item arg-types
Argument types of the defined Lisp function.
@item result-type
Result type of the C function (may be @code{(values ...)}.
@item returns
Defined function name.
@end table

@paragraph Description
The compiler defines a Lisp function named by @var{name} whose body
consists of the C code of the string @var{c-expression}. In the
@var{c-expression} one can reference the arguments of the function as
@code{#0}, @code{#1}, etc.

The interpreter ignores this form.
@end defmac

@lspdef ffi:defentry
@defmac ffi:defentry name arg-types c-name &key no-interrupts

@table @var
@item name
Lisp name for the function.

@item arg-types
Argument types of the C function.

@item c-name 
If @var{c-name} is a list, then C function result type is declared as
@code{(car c-name)} and its name is @code{(string (cdr c-name))}.

If it's an atom, then the result type is @code{:object}, and function
name is @code{(string c-name)}.

@item returns
Lisp function @code{name}.
@end table

@paragraph Description
The compiler defines a Lisp function named by @var{name} whose body
consists of a calling sequence to the C language function named by
@var{c-name}.

The interpreter ignores this form.
@end defmac

@c XXX> note sure if this works
@c @paragraph @code{definline}
@c @lspindex ffi:definline
@c @defmac ffi:definline fun arg-types result-type code
@c @table @var
@c @item args
@c Lisp arguments. Evaluated.
@c @item returns
@c No value.
@c @end table
@c @end defmac

@c @paragraph Description
@c DEFINLINE behaves like a DEFCBODY (see), but also instructs the LISP
@c compiler to expand inline any call to function SYMBOL into code
@c corresponding to the C language expression C/C++-CODE, whenever it can
@c determine that the actual arguments are of the specified type.
@c <XXX

@lspdef ext:with-backend
@defspec ext:with-backend &key bytecodes c/c++

Use different code depending on the backend.

@paragraph Description
Depending on whether the bytecodes or C compiler is used, this form will
emit the code given in the corresponding keyword argument.

@paragraph Examples
@exindex @coderef{ext:with-backend} use different code for c and bytecodes compiler
@verbatim
CL-USER> (defmacro test ()
           '(ext:with-backend :c/c++ "c/c++" :bytecodes "bytecodes"))
TEST
CL-USER> (test)
"bytecodes"
CL-USER> (funcall (compile nil (lambda () (test))))

;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=3
"c/c++"

@end verbatim
@end defspec

@lspdef ffi:defla
@defmac ffi:defla name args &body body

Provide Lisp alternative for interpreted code. 

@paragraph Description
Used to DEFine Lisp Alternative. For the interpreter,
@coderef{ffi:defla} is equivalent to @code{defun}, but the compiler
ignores this form.
@end defmac
