[[tags: manual]]
[[toc:]]


== C interface

The following functions and macros are available for C code that invokes
Scheme or foreign procedures that are called by Scheme:

=== Temporary stack

==== C_save

 [C macro] void C_save (C_word x) :

Saves the Scheme data object {{x}} on the temporary stack.

==== C_restore

 [C macro] void C_restore

Pops and returns the topmost value from the temporary stack.


=== Type/value predicates

When writing C code that accepts Scheme objects you often need to do
checking what type of object is passed.  These can help you determine
the type of an object.

==== C predicates

These return regular C integer values (ie, zero is false, nonzero true).

===== C_truep

 [C macro] int C_truep(C_word x)

Is {{x}} a truthy value, i.e. anything except {{C_SCHEME_FALSE}}?

===== C_immediatep

 [C macro] int C_immediatep(C_word x)

Is {{x}} an immediate object?
(see [[#constructors-for-immediate-scheme-objects|below]] for a definition)

===== C_fitsinfixnump

 [C macro] int C_fitsinfixnump(int number)

Will {{number}} fit in a fixnum?  It will fit when there is room for
one additional type bit to tag it as a fixnum (assuming one bit is
already used for the sign). In practice this means that the number's
top two bits must be identical.

===== C_ufitsinfixnump

 [C macro] int C_ufitsinfixnump(unsigned int number)

Like {{C_fitsinfixnump}} but for unsigned integers.  This checks the
top ''two'' bits are zero, since fixnums '''always''' carry a sign.


==== Scheme predicates

These return Scheme booleans (ie, C_SCHEME_TRUE or C_SCHEME_FALSE).
This means they can be used directly from Scheme using {{##core#inline}}.

===== C_zero_length_p

 [C macro] C_word C_zero_length_p(C_word x)

Is {{x}} a Scheme object of zero length?  Only accepts non-immediate objects.

===== C_unboundvaluep

 [C macro] C_word C_unboundvaluep(C_word x)

Is {{x}} the special unbound variable placeholder {{C_SCHEME_UNBOUND}}?

===== C_boundp

 [C macro] C_word C_boundp(C_word x)

Is {{x}} a bound value?  Only accepts non-immediate objects.

===== C_blockp

 [C macro] C_word C_blockp(C_word x)

Is {{x}} a "block" value?

A "block" value is a value that contains a memory block, i.e. is not
an immediate value.

===== C_immp

 [C macro] C_word C_immp(C_word x)

Is {{x}} an immediate value?

===== C_forwardedp

 [C macro] C_word C_forwardedp(C_word x)

Is {{x}} a GC-forwarded object?

===== C_flonump

 [C macro] C_word C_flonump(C_word x)

Is {{x}} a Scheme flonum object?  Accepts only non-immediate objects.

===== C_stringp

 [C macro] C_word C_stringp(C_word x)

Is {{x}} a Scheme string object?  Accepts only non-immediate objects.

===== C_symbolp

 [C macro] C_word C_symbolp(C_word x)

Is {{x}} a symbol?  Accepts only non-immediate objects.

===== C_pairp

 [C macro] C_word C_pairp(C_word x)

Is {{x}} a pair?  Accepts only non-immediate objects.

===== C_closurep

 [C macro] C_word C_closurep(C_word x)

Is {{x}} a closure?  Accepts only non-immediate objects.

===== C_vectorp

 [C macro] C_word C_vectorp(C_word x)

Is {{x}} any kind of vector?  Accepts only non-immediate objects.

This returns true for both regular heterogenous R5RS vectors and
bytevectors ("blobs").  However, it does ''not'' return true for
SRFI-4 vectors, as those are actually bytevectors wrapped in a
structure with a type tag.

===== C_bytevectorp

 [C macro] C_word C_bytevectorp(C_word x)

Is {{x}} a bytevector ("blob")? Accepts only non-immediate objects.

===== C_portp

 [C macro] C_word C_portp(C_word x)

Is {{x}} a port object?  Accepts only non-immediate objects.

===== C_structurep

 [C macro] C_word C_structure(C_word x)

Is {{x}} a structure (record) object?  Accepts only non-immediate objects.

===== C_locativep

 [C macro] C_word C_locativep(C_word x)

Is {{x}} a locative object?  Accepts only non-immediate objects.

===== C_charp

 [C macro] C_word C_charp(C_word x)

Is {{x}} a character object?

===== C_booleanp

 [C macro] C_word C_booleanp(C_word x)

Is {{x}} a boolean object?

===== C_eofp

 [C macro] C_word C_eofp(C_word x)

Is {{x}} the {{#!eof}} object?

===== C_undefinedp

 [C macro] C_word C_undefinedp(C_word x)

Is {{x}} the undefined value?

===== C_fixnump

 [C macro] C_word C_fixnump(C_word x)

Is {{x}} a fixnum object?

===== C_nfixnump

 [C macro] C_word C_nfixnump(C_word x)

Is {{x}} ''not'' a fixnum object?

===== C_i_numberp

 [C function] C_word C_i_numberp(C_word x)

Is {{x}} a number object (fixnum or flonum)?

===== C_pointerp

 [C macro] C_word C_pointerp(C_word x)

Is {{x}} a C pointer object?  Only accepts non-immediate objects.

===== C_taggedpointerp

 [C macro] C_word C_taggedpointerp(C_word x)

Is {{x}} a tagged pointer object?  Only accepts non-immediate objects.

===== C_swigpointerp

 [C macro] C_word C_swigpointerp(C_word x)

Is {{x}} a SWIG pointer object?  Only accepts non-immediate objects.

===== C_anypointerp

 [C macro] C_word C_anypointerp(C_word x)

Is {{x}} any type of pointer object?  Only accepts non-immediate objects.

===== C_lambdainfop

 [C macro] C_word C_lambdainfop(C_word x)

Is {{x}} a lambda-info object?  Only accepts non-immediate objects.

===== C_byteblockp

 [C macro] C_word C_byteblockp(C_word x)

Is {{x}} a "byteblock" object?  Only accepts non-immediate objects.

Strings, flonums, bytevectors and lambda-info objects are considered
"byteblock" objects, as they are not containers for Scheme objects but
simply point to contiguous memory ranges of bytes.

===== C_specialp

 [C macro] C_word C_specialp(C_word x)

Is {{x}} a "special" object?  Only accepts non-immediate objects.

Closures, ports, pointers and locatives are considered "special"
objects, as they are not containers for Scheme objects (and they are
not byte blocks either), so they have to be treated specially by the GC.

===== C_nullp

 [C macro] C_word C_nullp(C_word x)

Is {{x}} the empty list, i.e. is it {{C_SCHEME_END_OF_LIST}}?

===== C_anyp

 [C macro] C_word C_anyp(C_word x)

Always returns {{C_SCHEME_TRUE}}.


=== Constructors

==== Constructors for immediate Scheme objects

"immediate" Scheme objects are objects that are represented directly
by a {{C_word}}.  There's no additional memory used by them.

===== C_fix

 [C macro] C_word C_fix (int integer)

===== C_make_character

 [C macro] C_word C_make_character (int char_code)

===== C_mk_bool

 [C macro] C_word C_mk_bool(int truth_value)

===== C_mk_nbool

 [C macro] C_word C_mk_nbool(int truth_value_to_negate)

===== C_SCHEME_END_OF_LIST

 [C macro] C_SCHEME_END_OF_LIST

===== C_SCHEME_END_OF_FILE

 [C macro] C_SCHEME_END_OF_FILE

===== C_SCHEME_FALSE

 [C macro] C_SCHEME_FALSE

===== C_SCHEME_TRUE

 [C macro] C_SCHEME_TRUE


==== Constructors for non-immediate Scheme objects

Non-immediate Scheme objects are still represented and passed around
by a single {{C_word}}, but this is basically just a pointer to the
start of the object (which should never be treated as such, use the
accessor macros instead).

===== C_string

 [C function] C_word C_string (C_word **ptr, int length, char *string)

===== C_string2

 [C function] C_word C_string2 (C_word **ptr, char *zero_terminated_string)

===== C_intern2

 [C function] C_word C_intern2 (C_word **ptr, char *zero_terminated_string)

===== C_intern3

 [C function] C_word C_intern3 (C_word **ptr, char *zero_terminated_string, C_word initial_value)

===== C_pair

 [C function] C_word C_pair (C_word **ptr, C_word car, C_word cdr)

===== C_flonum

 [C function] C_word C_flonum (C_word **ptr, double number)

===== C_int_to_num

 [C function] C_word C_int_to_num (C_word **ptr, int integer)

===== C_mpointer

 [C function] C_word C_mpointer (C_word **ptr, void *pointer)

===== C_vector

 [C function] C_word C_vector (C_word **ptr, int length, ...)

===== C_list

 [C function] C_word C_list (C_word **ptr, int length, ...)

===== C_closure

 [C function] C_word C_closure (C_word **ptr, int length, C_word procedure, ...)

These functions allocate memory from {{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}}.

To find out how big the memory block should be, use the {{C_SIZEOF_*}}
macros described below.

Here's an example how to create a closure that accepts a vector,
stores the Scheme numbers 1, 2 and 3 and a given string in it and
returns that vector to its continuation:

<enscript highlight=scheme>
#>

#include <assert.h>

void fill_vector(C_word c, C_word closure, C_word vec)
{
  C_word kontinuation = C_block_item(closure, 1);

  C_block_item(vec, 0) = C_fix(1);
  C_block_item(vec, 1) = C_fix(2);
  C_block_item(vec, 2) = C_fix(3);
  C_block_item(vec, 3) = C_block_item(closure, 2);

  C_kontinue(kontinuation, vec);
}

void one_two_three(C_word c, C_word self, C_word k, C_word str)
{
  /*
   * Allocate room on the stack to hold the closure:  1 word for
   * the type tag, 1 word for the procedure and 2 words for the
   * values "closed over"; this procedure's continuation "k" and
   * the argument "str".  We could also use C_alloc(4).
   */
  C_word closure[4], *cp = closure;

  /* Create the closure.  It holds 3 values, not counting the tag */
  C_word closure_object = C_closure(&cp, 3, (C_word)fill_vector, k, str);

  /*
   * After this, cp points just beyond the last word of the allocated
   * data and closure_object is an opaque representation of the newly
   * created closure as a whole, i.e. the following relations hold:
   */
  assert(  (closure + 4) == cp  );
  assert(  C_block_header(closure_object) == (*closure)  );
  assert(  C_data_pointer(closure_object) == (closure + 1)  );
  assert(  C_block_item(closure_object, 0) == (*(closure + 1))  );

  /* Make a vector of 4 objects and use closure_object as continuation */
  C_allocate_vector(6, (C_word)NULL, closure_object, C_fix(4),
                    C_SCHEME_FALSE,  /* not a byte vector */
                    C_SCHEME_FALSE,  /* initialization value. Don't care */
                    C_SCHEME_FALSE); /* don't align at 8 bytes */
  /* .. C_allocate_vector does not return ... */
}
<#


(define one-two-three
   (foreign-primitive ((scheme-object str)) "one_two_three(C_c, C_self, C_k, str);"))

(print (one-two-three "hi"))
</enscript>

This is equivalent to the following in Scheme:

<enscript highlight=scheme>
(define (one-two-three str)
  (let ((fill-vector (lambda (vec)
                       (vector-set! vec 0 1)
                       (vector-set! vec 1 2)
                       (vector-set! vec 2 3)
                       (vector-set! vec 3 str)
                       vec)))
    (fill-vector (make-vector 4 #f))))

(print (one-two-three "hi"))
</enscript>


==== Memory allocation

These can be used to allocate memory for non-immediate objects.

===== C_alloc

 [C macro] C_word* C_alloc (int words)

Allocates memory from the C stack ({{C_alloc}}) and returns a pointer to
it. {{words}} should be the number of words needed for all data
objects that are to be created in this function.  Note that stack-allocated
data objects have to be passed to Scheme callback functions, or they will
not be seen by the garbage collector. This is really only usable for
callback procedure invocations, make sure not to use it in normal code,
because the allocated memory will be re-used after the foreign procedure
returns. When invoking Scheme callback procedures a minor garbage
collection is performed, so data allocated with {{C_alloc}}
will already have moved to a safe place.

Note that {{C_alloc}} is really just a wrapper around {{alloca}},
and can also be simulated by declaring a stack-allocated array of
{{C_word}}s:


===== C_SIZEOF_LIST

 [C macro] int C_SIZEOF_LIST (int length)

===== C_SIZEOF_STRING

 [C macro] int C_SIZEOF_STRING (int length)

===== C_SIZEOF_VECTOR

 [C macro] int C_SIZEOF_VECTOR (int length)

===== C_SIZEOF_INTERNED_SYMBOL

 [C macro] int C_SIZEOF_INTERNED_SYMBOL (int length)

===== C_SIZEOF_PAIR

 [C macro] int C_SIZEOF_PAIR

===== C_SIZEOF_FLONUM

 [C macro] int C_SIZEOF_FLONUM

===== C_SIZEOF_POINTER

 [C macro] int C_SIZEOF_POINTER

===== C_SIZEOF_LOCATIVE

 [C macro] int C_SIZEOF_LOCATIVE

===== C_SIZEOF_TAGGED_POINTER

 [C macro] int C_SIZEOF_TAGGED_POINTER

These are macros that return the size in words needed for a data object
of a given type.

=== Accessors

==== C_character_code

 [C macro] int C_character_code (C_word character)

==== C_unfix

 [C macro] int C_unfix (C_word fixnum)

==== C_flonum_magnitude

 [C macro] double C_flonum_magnitude (C_word flonum)

==== C_c_string

 [C function] char* C_c_string (C_word string)

==== C_num_to_int

 [C function] int C_num_to_int (C_word fixnum_or_flonum)

==== C_pointer_address

 [C function] void* C_pointer_address (C_word pointer)

These macros and functions can be used to convert Scheme data objects
back to C data. Note that {{C_c_string()}} returns a pointer
to the character buffer of the actual Scheme object and is not
zero-terminated.

==== C_header_size

 [C macro] int C_header_size (C_word x)

==== C_header_bits

 [C macro] int C_header_bits (C_word x)

Return the number of elements and the type-bits of the non-immediate
Scheme data object {{x}}.


==== C_block_item

 [C macro] C_word C_block_item (C_word x, int index)

This macro can be used to access slots of the non-immediate Scheme data
object {{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_u_i_car

 [C macro] C_word C_u_i_car (C_word x)

==== C_u_i_cdr

 [C macro] C_word C_u_i_cdr (C_word x)

Aliases for {{C_block_item(x, 0)}} and {{C_block_item(x, 1)}}, respectively.

==== C_port_file

 [C macro] C_word C_port_file (C_word x)

Alias for {{(FILE *)C_block_item(x, 0)}}.  To be used with port
objects representing files (but will not work on sockets, for example).


==== C_data_pointer

 [C macro] void* C_data_pointer (C_word x)

Returns a pointer to the data-section of a non-immediate Scheme object.


=== C_make_header

 [C macro] C_word C_make_header (C_word bits, C_word size)

A macro to build a Scheme object header from its bits and size parts.


=== C_mutate

 [C function] C_word C_mutate (C_word *slot, C_word val)

Assign the Scheme value {{val}} to the location specified by
{{slot}}.  If the value points to data inside the nursery (the first
heap-generation), then the garbage collector will remember to handle the
data appropriately. Assigning nursery-pointers directly will otherwise
result in lost data. Note that no copying takes place at the moment
when {{C_mutate}} is called, but later - at the next (minor) garbage
collection.


=== C_symbol_value

 [C macro] C_word C_symbol_value (C_word symbol)

Returns the global value of the variable with the name {{symbol}}. If the
variable is unbound {{C_SCHEME_UNBOUND}} is returned. You can set a variable's
value with {{C_mutate(&C_symbol_value(SYMBOL), VALUE)}}.


=== GC interface

==== C_gc_protect

 [C function] void C_gc_protect (C_word *ptrs[], int n)

Registers {{n}} variables at address {{ptrs}} to be garbage collection roots.
The locations should not contain pointers to data allocated in the nursery, only
immediate values or pointers to heap-data are valid. Any
assignment of potential nursery data into a root-array should be done
via {{C_mutate()}}. The variables have to be initialized to sensible values
before the next garbage collection starts (when in doubt, set all locations
in {{ptrs}} to {{C_SCHEME_UNDEFINED}})
{{C_gc_protect}} may not called before the runtime system has been
initialized (either by {{CHICKEN_initialize}}, {{CHICKEN_run}} or
{{CHICKEN_invoke}}.

For a slightly simpler interface to creating and using GC roots see
{{CHICKEN_new_gc_root}}.


==== C_gc_unprotect

 [C function] void C_gc_unprotect (int n)

Removes the last {{n}} registered variables from the set of
root variables.


==== C_pre_gc_hook

 [C Variable] void (*C_pre_gc_hook)(int mode)

If not {{NULL}}, the function pointed to by this variable will be
called before each garbage collection with a flag indicating what kind
of collection was performed (either {{0}} for a minor or major
collection or {{2}} for a resizing collection). A "resizing"
collection means a secondary collection that moves all live data into
a enlarged (or shrinked) heap-space. Minor collections happen very
frequently, so the hook function should not consume too much time. The
hook function may not invoke Scheme callbacks.

Note that resizing collections may be nested in normal major collections.

==== C_post_gc_hook

 [C Variable] void (*C_post_gc_hook)(int mode, long ms)

If not {{NULL}}, the function pointed to by this variable will be
called after each garbage collection with a flag indicating what kind
of collection was performed (either {{0}} for a minor collection,
{{1}} for a major collection or {{2}} for a resizing
collection). Minor collections happen very frequently, so the hook
function should not consume too much time. The hook function may not
invoke Scheme callbacks. The {{ms}} argument records the number of
milliseconds required for the garbage collection, if the collection
was a major one. For minor collections the value of the {{ms}} argument
is undefined.

=== Type-specific macros and functions

The following are macros and functions to ask information or perform
operations on objects once their types are already known.  If you call
it on any object of another type, it is not defined what will happen
and likely your program will crash, especially if you pass immediates
to procedures expecting non-immediates.

==== Vectors

===== C_vemptyp

 [C macro] C_word C_vemptyp(C_word v)

Is the (byte- or heterogenous) vector {{v}} empty?

===== C_notvemptyp

 [C macro] C_word C_notvemptyp(C_word v)

Is the (byte- or heterogenous) vector {{v}} nonempty?

==== Numbers

These procedures accept any type of number, so you can pass in either
a fixnum or a flonum.  You shouldn't pass in another type though,
since that could crash your program.

===== C_u_i_exactp

 [C macro] C_word C_u_i_exactp(C_word x)

Is {{x}} an exact number (i.e., a fixnum)?

===== C_u_i_inexactp

 [C macro] C_word C_u_i_inexactp(C_word x)

Is {{x}} an inexact number (i.e., not a fixnum)?

===== C_i_finitep

 [C function] C_word C_i_finitep(C_word x)

Is {{x}} a finite number?  This returns false only when {{x}} is a
flonum representing {{-inf}} or {{+inf}}.

==== Fixnums

Note: Fixnums are immediates, so there is no {{C_fixnum_equalp}}
macro.  You can just compare them without hassle (or use
[[#c-eqp|C_eqp]] if you prefer).

===== C_i_fixnumevenp

 [C macro] C_word C_i_fixnumevenp(C_word x)

Is {{x}} an even fixnum?

===== C_i_fixnumoddp

 [C macro] C_word C_i_fixnumoddp(C_word x)

Is {{x}} an odd fixnum?

===== C_fixnum_times

 [C macro] C_word C_fixnum_times(C_word n1, C_word n2)

Multiply fixnum n1 by fixnum n2.

===== C_fixnum_plus

 [C macro] C_word C_fixnum_plus(C_word n1, C_word n2)

Add fixnum {{n1}} to fixnum {{n2}}.

===== C_u_fixnum_plus

 [C macro] C_word C_u_fixnum_plus(C_word n1, C_word n2)

Like {{C_fixnum_plus}}, but unsafe (assumes no overflow/underflow).

===== C_fixnum_difference

 [C macro] C_word C_fixnum_difference(C_word n1, C_word n2)

Calculate {{n1}} - {{n2}}.

===== C_u_fixnum_difference

 [C macro] C_word C_u_fixnum_difference(C_word n1, C_word n2)

Like {{C_fixnum_difference}}, but unsafe (assumes no overflow/underflow).

===== C_fixnum_divide
===== C_u_fixnum_divide

 [C macro] C_word C_fixnum_divide(C_word n1, C_word n2)
 [C macro] C_word C_u_fixnum_divide(C_word n1, C_word n2)

Divide {{n1}} by {{n2}}, returning the quotient (i.e., integer
division). {{C_fixnum_divide}} signals an error if {{n2}} is zero.

===== C_fixnum_modulo
===== C_u_fixnum_modulo

 [C macro] C_word C_fixnum_modulo(C_word n1, C_word n2)
 [C macro] C_word C_u_fixnum_modulo(C_word n1, C_word n2)

Calculate {{n1}} modulo {{n2}}. {{C_fixnum_modulo}} signals an error if {{n2}} is zero.

===== C_fixnum_and

 [C macro] C_word C_fixnum_and(C_word n1, C_word n2)

Calculate the bitwise {{AND}} of the integral values of {{n1}} and {{n2}}.

===== C_u_fixnum_and

 [C macro] C_word C_u_fixnum_and(C_word n1, C_word n2)

Like {{C_fixnum_and}}, but unsafe.

===== C_fixnum_or

 [C macro] C_word C_fixnum_or(C_word n1, C_word n2)

Calculate the bitwise {{OR}} of the integral values of {{n1}} and {{n2}}.

===== C_u_fixnum_or

 [C macro] C_word C_u_fixnum_or(C_word n1, C_word n2)

Like {{C_fixnum_or}}, but unsafe.

===== C_fixnum_xor

 [C macro] C_word C_fixnum_xor(C_word n1, C_word n2)

Calculate the bitwise {{XOR}} of the integral values of {{n1}} and {{n2}}.

===== C_fixnum_not

 [C macro] C_word C_fixnum_not(C_word n)

Calculate the bitwise {{NOT}} (inversion of bits) of the integral
value of {{n}}.

===== C_fixnum_shift_left

 [C macro] C_word C_fixnum_shift_left(C_word n1, C_word n2)

Shift the integral value of {{n1}} left by {{n2}} positions.

===== C_fixnum_shift_right

 [C macro] C_word C_fixnum_shift_right(C_word n1, C_word n2)

Shift the integral value of {{n1}} right by {{n2}}

===== C_fixnum_negate

 [C macro] C_word C_fixnum_negate(C_word n)

Negate {{n}}, i.e. return {{-n}}.

===== C_fixnum_greaterp

 [C macro] C_word C_fixnum_greaterp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is greater than {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_fixnum_greater_or_equal_p

 [C macro] C_word C_fixnum_greater_or_equalp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is greater than or equal to
{{n2}}, {{C_SCHEME_FALSE}} if not.

===== C_fixnum_lessp

 [C macro] C_word C_fixnum_lessp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is less than {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_fixnum_less_or_equal_p

 [C macro] C_word C_fixnum_less_or_equalp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is less than or equal to
{{n2}}, {{C_SCHEME_FALSE}} if not.

===== C_fixnum_increase

 [C macro] C_word C_fixnum_increase(C_word n)

Adds 1 to {{n}}

===== C_u_fixnum_increase

 [C macro] C_word C_u_fixnum_increase(C_word n)

As {{C_fixnum_increase}}, but unsafe (assumes the result will not overflow).

===== C_fixnum_decrease

 [C macro] C_word C_fixnum_decrease(C_word n)

Subtracts 1 from {{n}}

===== C_u_fixnum_decrease

 [C macro] C_word C_u_fixnum_decrease(C_word n)

As {{C_fixnum_increase}}, but unsafe (assumes the result will not underflow).

===== C_fixnum_abs

 [C macro] C_word C_fixnum_abs(C_word n)

Returns the absolute value of {{n}}.

===== C_i_fixnum_min

 [C function] C_word C_fixnum_min(C_word n1, C_word n2)

Returns the smallest of the two fixnums {{n1}} and {{n2}}.

===== C_i_fixnum_max

 [C function] C_word C_fixnum_max(C_word n1, C_word n2)

Returns the largest of the two fixnums {{n1}} and {{n2}}.


==== Flonums

===== C_flonum_equalp

 [C macro] C_word C_flonum_equalp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} and {{n2}} are equal flonums,
{{C_SCHEME_FALSE}} otherwise.

===== C_flonum_greaterp

 [C macro] C_word C_flonum_greaterp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is greater than {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_flonum_greater_or_equal_p

 [C macro] C_word C_flonum_greater_or_equal_p(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is greater than or equal to {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_flonum_lessp

 [C macro] C_word C_flonum_lessp(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is less than {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_flonum_less_or_equal_p

 [C macro] C_word C_flonum_less_or_equal_p(C_word n1, C_word n2)

Returns {{C_SCHEME_TRUE}} when {{n1}} is less than or equal to {{n2}},
{{C_SCHEME_FALSE}} if not.

===== C_a_i_flonum_plus

 [C macro] C_word C_a_i_flonum_plus(C_word **ptr, int c, C_word n1, C_word n2)

Adds the flonum {{n1}} to the flonum {{n2}}, using the storage at
{{ptr}}.  {{c}} should always be 2.

Example:

<enscript highlight=scheme>
#include <chicken.h>
#include <stdio.h>

int main(void)
{
  C_word *mema, *memb, *memresult;
  C_word a, b, result;

  mema = C_alloc(C_SIZEOF_FLONUM);
  memb = C_alloc(C_SIZEOF_FLONUM);
  memresult = C_alloc(C_SIZEOF_FLONUM);
  a = C_flonum(&mema, 1.2);
  b = C_flonum(&memb, 4.7);
  result = C_a_i_flonum_plus(&memresult, 2, a, b);
  printf("%lf\n", C_flonum_magnitude(result));
  return 0;
}
</enscript>

This will print {{5.9}}

===== C_a_i_flonum_difference

 [C macro] C_word C_a_i_flonum_difference(C_word **ptr, int c, C_word n1, C_word n2)

Subtracts the flonum {{n2}} from the flonum {{n1}}, using the storage at
{{ptr}}.  {{c}} should always be 2.

===== C_a_i_flonum_times

 [C macro] C_word C_a_i_flonum_times(C_word **ptr, int c, C_word n1, C_word n2)

Multiplies the flonum {{n1}} by the flonum {{n2}}, using the storage at
{{ptr}}.  {{c}} should always be 2.

===== C_a_i_flonum_quotient

 [C macro] C_word C_a_i_flonum_quotient(C_word **ptr, int c, C_word n1, C_word n2)

Calculates the quotient of the flonum {{n1}} divided by the flonum
{{n2}}, using the storage at {{ptr}}.  {{c}} should always be 2.

===== C_a_i_flonum_negate

 [C macro] C_word C_a_i_flonum_negate(C_word **ptr, int c, C_word n)

Negates the flonum {{n}}, using the storage at {{ptr}}. {{c}} should
always be 1.

===== C_a_i_flonum_truncate

 [C macro] C_word C_a_i_flonum_truncate(C_word **ptr, int c, C_word n)

Truncate the flonum {{n}}, using the storage at {{ptr}}. {{c}} should
always be 1.

===== C_a_i_flonum_ceiling

 [C macro] C_word C_a_i_flonum_ceiling(C_word **ptr, int c, C_word n)

Round the flonum {{n}}, rounding upwards, using the storage at
{{ptr}}. {{c}} should always be 1.

===== C_a_i_flonum_floor

 [C macro] C_word C_a_i_flonum_floor(C_word **ptr, int c, C_word n)

Round the flonum {{n}}, rounding downwards, using the storage at
{{ptr}}. {{c}} should always be 1.

===== C_a_i_flonum_round

 [C macro] C_word C_a_i_flonum_round(C_word **ptr, int c, C_word n)

Round the flonum {{n}}, rounding towards the nearest integer, using
the storage at {{ptr}}. {{c}} should always be 1.

This macro returns the value like returned by C's {{round()}}
function.  That means it rounds to the larger value (away from 0) when
rounding numbers halfway between two integers.

===== C_a_i_flonum_round_proper

 [C macro] C_word C_a_i_flonum_round_proper(C_word **ptr, int c, C_word n)

Round the flonum {{n}}, rounding towards the nearest integer, using
the storage at {{ptr}}. {{c}} should always be 1.

This macro returns the value like returned by Scheme's {{round}}
procedure.  That means it rounds to even numbers when rounding
numbers halfway between two integers.

===== C_a_i_flonum_sin

 [C macro] C_word C_a_i_flonum_sin(C_word **ptr, int c, C_word n)

Calculates the sine of {{n}} (in radians).

===== C_a_i_flonum_cos

 [C macro] C_word C_a_i_flonum_cos(C_word **ptr, int c, C_word n)

Calculates the cosine of {{n}} (in radians).

===== C_a_i_flonum_tan

 [C macro] C_word C_a_i_flonum_tan(C_word **ptr, int c, C_word n)

Calculates the tangent of {{n}} (in radians).

===== C_a_i_flonum_asin

 [C macro] C_word C_a_i_flonum_asin(C_word **ptr, int c, C_word n)

Calculates the arc sine of {{n}} (in radians, in the range -pi/2 through +pi/2).

===== C_a_i_flonum_acos

 [C macro] C_word C_a_i_flonum_acos(C_word **ptr, int c, C_word n)

Calculates the arc cosine of {{n}} (in radians, in the range 0 through pi).

===== C_a_i_flonum_atan

 [C macro] C_word C_a_i_flonum_atan(C_word **ptr, int c, C_word n)

Calculates the arc tangent of {{n}} (in radians, in the range -pi/2 through +pi/2).

Like C's {{atan()}} or Scheme's unary {{atan}}.

===== C_a_i_flonum_atan2

 [C macro] C_word C_a_i_flonum_atan2(C_word **ptr, int c, C_word n1, C_word n2)

Calculates the arc tangent of {{n1/n2}} (in radians), using the sign of both
to determine the quadrant of the result.

Like C's {{atan2()}} or Scheme's binary {{atan}}.

===== C_a_i_flonum_log

 [C macro] C_word C_a_i_flonum_log(C_word **ptr, int c, C_word n)

Calculate the natural (base {{e}}) logarithm of {{n}}.

===== C_a_i_flonum_exp

 [C macro] C_word C_a_i_flonum_exp(C_word **ptr, int c, C_word n)

Calculates the base {{e}} exponent of {{n}} (i.e., the inverse
operation of {{C_a_i_flonum_log}}).

===== C_a_i_flonum_expt

 [C macro] C_word C_a_i_flonum_expt(C_word **ptr, int c, C_word n1, C_word n2)

Calculates {{n1}} raised to the power {{n2}}.

===== C_a_i_flonum_sqrt

 [C macro] C_word C_a_i_flonum_sqrt(C_word **ptr, int c, C_word n)

Calculates the square root of {{n}}.

===== C_a_i_flonum_abs

 [C macro] C_word C_a_i_flonum_abs(C_word **ptr, int c, C_word n)

Calculates the absolute value of {{n}}.


==== Pointers

===== C_null_pointerp

 [C macro] C_word C_null_pointerp(C_word x)

Is {{x}} a NULL pointer?

===== C_a_i_address_to_pointer

 [C macro] C_word C_a_i_address_to_pointer(C_word **ptr, int c, C_word addr)

Convert {{addr}} to a pointer object using the storage at {{ptr}}.
{{addr}} is can be either a flonum or a fixnum representing a memory
address.

===== C_a_i_pointer_to_address

 [C macro] C_word C_a_i_pointer_to_address(C_word **ptr, int c, C_word pptr)

Convert back the pointer {{pptr}} to an address number, possibly using
the storage at {{ptr}}.  The number returned can be either a fixnum or
a flonum, so you will have to pass a memory storage that can hold a
flonum at {{ptr}}.  Whether it is actually used depends on the size of
the address.


==== Ports

===== C_tty_portp

 [C macro] C_word C_tty_portp(C_word x)

Is {{x}} a TTY port object?

==== Structures

===== C_i_structurep

 [C macro] C_word C_i_structurep(C_word x, C_word s)

Is {{x}} a structure (record) object with type tag {{s}}?  This is
completely safe to use, because it checks whether x is an immediate or
not.

==== Characters

These understand only ASCII characters.

===== C_u_i_char_alphabeticp

 [C macro] C_word C_u_i_char_alphabeticp(C_word c)

Is {{c}} an alphabetic character?

===== C_u_i_char_numericp

 [C macro] C_word C_u_i_char_numericp(C_word c)

Is {{c}} a numeric character?

===== C_u_i_char_whitespacep

 [C macro] C_word C_u_i_char_whitespacep(C_word c)

Is {{c}} a whitespace character?

===== C_u_i_char_upper_casep

 [C macro] C_word C_u_i_char_upper_casep(C_word c)

Is {{c}} an uppercase character?

===== C_u_i_char_lower_casep

 [C macro] C_word C_u_i_char_lower_casep(C_word c)

Is {{c}} a lowercase character?


=== Other Scheme procedures from C

There are a number of Scheme procedures that have a direct C
implementation, so you can call them from C too.

==== C_eqp

 [C macro] C_word C_eqp(C_word a, C_word b)

The C version of {{(eq? a b)}}.

==== C_equalp

 [C macro] C_word C_equalp(C_word a, C_word b)

The C version of {{(equal? a b)}}.

==== C_i_pairp

 [C function] C_word C_i_pair_p(C_word x)

The C version of {{(pair? x)}}.

==== C_i_not_pair_p

 [C macro] C_word C_i_not_pair_p(C_word x)

The C version of {{(not (pair? x))}}.


=== An example for simple calls to foreign code involving callbacks

 % cat foo.scm
 #>
 extern int callout(int, int, int);
 <#
 
 (define callout (foreign-safe-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);  /* Note: `callin' will have GC'd the data in `ptr' */
 }

 % csc foo.scm bar.c -o foo
 % foo
 This is 'callout': 1, 2, 3
 This is 'callin': (1 2 3)
 123


=== Notes:

* Scheme procedures can call C functions, and C functions can call
  Scheme procedures, but for every pending C stack frame, the available
  size of the first heap generation (the ''nursery'') will be decreased,
  because the C stack is identical to the nursery. On systems with a small
  nursery this might result in thrashing, since the C code between the
  invocation of C from Scheme and the actual calling back to Scheme might
  build up several stack-frames or allocates large amounts of stack data.
  To prevent this it is advisable to increase the default nursery size,
  either when compiling the file (using the {{-nursery}} option)
  or when running the executable (using the {{-:s}} runtime option).
* Calls to Scheme/C may be nested arbitrarily, and Scheme
  continuations can be invoked as usual, but keep in mind that C stack
  frames will not be recovered, when a Scheme procedure call from C does
  not return normally.
* When multiple threads are running concurrently, and control switches
  from one thread to another, then the continuation of the current thread
  is captured and saved. Any pending C stack frame still active from a
  callback will remain on the stack until the threads is re-activated
  again. This means that in a multithreading situation, when C callbacks
  are involved, the available nursery space can be smaller than expected.
  So doing many nested Scheme->C->Scheme calls can reduce the available
  memory up to the point of thrashing. It is advisable to have only a
  single thread with pending C stack-frames at any given time.
* Pointers to Scheme data objects should not be stored in local or
  global variables while calling back to Scheme.  Any Scheme object not
  passed back to Scheme will be reclaimed or moved by the garbage collector.
* Calls from C to Scheme are never tail-recursive.
* Continuations captured via {{call-with-current-continuation}}
  and passed to C code can be invoked like any other Scheme procedure.


---
Previous: [[Other support procedures]]

Next: [[Extensions]]
