~ chicken-core (chicken-5) cfa1d11eced2bae8ddf0437c1bdda0a31e5634eb


commit cfa1d11eced2bae8ddf0437c1bdda0a31e5634eb
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Wed Apr 14 16:46:25 2010 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Wed Apr 14 16:46:25 2010 +0200

    merged manual changes from wiki

diff --git a/manual/Accessing external objects b/manual/Accessing external objects
index 8d1771b6..e81ef6c4 100644
--- a/manual/Accessing external objects	
+++ b/manual/Accessing external objects	
@@ -84,8 +84,21 @@ accessed in the current compilation unit, but the name can be
 lexically shadowed.  Note that {{STRING}} can name an arbitrary C
 expression. If no assignments are performed, then {{STRING}} doesn't
 even have to specify an lvalue.
-
-
+See that {{define-foreign-variable}} will not generate C declarations
+or memory allocation code; use it to include references to variables
+in external C code. To actually create Scheme variables visible from C,
+use {{define-external}} (see the Manual section on
+[[http://chicken.wiki.br/man/4/Callbacks|Callbacks]]).
+For example, the following code:
+<enscript lang="scheme">
+(import foreign)
+(define-foreign-variable x double "var_x")
+(print x)
+</enscript>
+will not work, because a reference to {{var_x}} will be inserted in the C code,
+but no declaration will be included (this can be easily verified by translating
+the program into C with {{csc -t program.scm}}). Changing the second line to
+{{(define-external x double 0.5)}} will work (and the value 0.5 will be printed).
 === foreign-lambda
 
 <macro>(foreign-lambda RETURNTYPE NAME ARGTYPE ...)</macro>
@@ -141,7 +154,7 @@ function to call Scheme functions and allocate Scheme data-objects. See [[Callba
 
 This is also similar to {{foreign-lambda*}} but the code will be executed
 in a ''primitive'' CPS context, which means it will not actually return, but
-call it's continuation on exit. This means that code inside this form may
+call its continuation on exit. This means that code inside this form may
 allocate Scheme data on the C stack (the ''nursery'') with {{C_alloc}}
 (see below). If the {{RETURNTYPE}} is omitted it defaults to {{void}}.
 You can return multiple values inside the body of the {{foreign-primitive}}
diff --git a/manual/C interface b/manual/C interface
index d85501c0..1fd00c9d 100644
--- a/manual/C interface	
+++ b/manual/C interface	
@@ -62,6 +62,220 @@ 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_vectorp
+
+ [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
@@ -81,6 +295,10 @@ by a {{C_word}}.  There's no additional memory used by them.
 
  [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
@@ -461,6 +679,568 @@ 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 macro] C_word C_fixnum_divide(C_word n1, C_word n2)
+
+Divide {{n1}} by {{n2}}, returning the quotient (i.e., integer
+division).
+
+===== C_fixnum_modulo
+
+ [C macro] C_word C_fixnum_modulo(C_word n1, C_word n2)
+
+Calculate {{n1}} modulo {{n2}}.
+
+===== 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
diff --git a/manual/Extensions b/manual/Extensions
index f069aeea..eb392a3a 100644
--- a/manual/Extensions
+++ b/manual/Extensions
@@ -333,6 +333,8 @@ macro.
 
 === Examples for extensions
 
+==== A simple library
+
 The simplest case is a single file that does not export any syntax. For example
 
 <enscript highlight=scheme>
@@ -384,12 +386,14 @@ execute the any files with the {{.setup}} extension it can find.
 Use it like any other CHICKEN extension:
 
  $ csi -q
- #;1> (require-extension hello)
+ #;1> (require-library hello)
  ; loading /usr/local/lib/chicken/4/hello.so ...
  #;2> (hello "me")
  Hello, me!
  #;3>
 
+==== An application
+
 Here we create a simple application:
 
 <enscript highlight=scheme>
@@ -430,11 +434,113 @@ normally be {{/usr/local/bin}}.  Note that you need write-permissions
 for those locations and may have to run {{chicken-install}} with
 administrative rights or use the {{-sudo}} option.
 
+The extension can be used from the command line:
+
+ $ hello2 one two three
+ Hello, 
+ one two three !
+
 De-installation is just as easy - use the {{chicken-uninstall}}
 program to remove one or more extensions from the local repository:
 
  $ chicken-uninstall hello2
 
+==== A module exporting syntax
+
+The hello module was just a shared library, and not a module.
+
+To create an extension that exports syntax see the chapter on
+[[http://chicken.wiki.br/man/4/Modules%20and%20macros|Modules and
+macros]].  We will show a simple example here: a module {{my-lib}}
+that exports one macro ({{prog1}}) and one procedure ({{my-sum}}):
+
+<enscript highlight=scheme>
+;;; my-lib.scm
+
+(module my-lib
+  *
+  (import scheme chicken)
+
+(define-syntax prog1
+  (syntax-rules ()
+    ((_ e1 e2 ...)
+     (let ((result e1))
+       (begin e2 ...)
+       result))))
+
+(define my-sum
+  (lambda (numbers)
+    (prog1
+      (apply + numbers)
+      (display "my-sum used one more time!")
+      (newline))))
+
+)
+</enscript>
+
+The {{prog1}} macro is similar to Common Lisp's {{prog1}}: it
+evaluates a list of forms, but returns the value of the first form.
+
+The meta file:
+
+<enscript highlight=scheme>
+;;; my-lib.meta
+
+((files "my-lib.setup"
+        "my-lib.scm")
+ (licence "BSD")
+ (author "Me again")
+ (synopsis "My own cool libraries"))
+</enscript>
+
+The setup file is:
+
+<enscript highlight=scheme>
+;;; my-lib.setup
+
+(compile -s -O3 -d1 "my-lib.scm" -j my-lib)
+(compile -c -O3 -d1 "my-lib.scm" -unit my-lib)
+(compile -s -O3 -d0 "my-lib.import.scm")
+
+(install-extension
+ 'my-lib
+ '("my-lib.o" "my-lib.so" "my-lib.import.so")
+ '((version 1.0)
+   (static "my-lib.o")))
+</enscript>
+
+The first line tells the compiler to create a shared ({{-s}}) library
+and to create an import file ({{my-lib.import.scm}}, because of the
+{{-j}} flag).  The second line creates a static library
+{{my-lib.o}}. The third line compiles the import file created by the
+first one.
+
+IMPORTANT: the module name exported by my-lib.scm must be the same
+module name passed to the compiler using the -j option, otherwise the
+imports file will not be generated!
+
+Running {{chicken-install}} on the same directory will install the extension.
+
+Next, it should be possible to load the library:
+
+ $ csi -q
+ #;1> (use my-lib)
+ ; loading /usr/local/lib/chicken/5/my-lib.import.so ...
+ ; loading /usr/local/lib/chicken/5/scheme.import.so ...
+ ; loading /usr/local/lib/chicken/5/chicken.import.so ...
+ ; loading /usr/local/lib/chicken/5/my-lib.so ...
+ #;2> (my-sum '(10 20 30))
+ my-sum used one more time!
+ 60
+ #;3> (my-sum '(-1 1 0))
+ my-sum used one more time!
+ 0
+ #;4> (prog1 (+ 2 2) (print "---"))
+ ---
+ 4
+
+==== Notes on chicken-install
+
 When running {{chicken-install}} with an argument {{NAME}}, for which
 no associated {{.setup}} file exists, then it will try to download the
 extension via HTTP from the CHICKEN code repository at
@@ -500,16 +606,59 @@ code is going to be evaluated. When {{chicken-install}} is run as
 extension mechanism).
 
 Security-conscious users should never run {{chicken-install}} as root.
-A simple remedy is to set the environment variable
-{{CHICKEN_REPOSITORY}}, which will transparently place the repository
-at an arbitrary user-selected location (don't forget to initialize it
-first with {{chicken-install -init <directory>}}).  Alternatively
-obtain write/execute access to the default location of the repository
+A simple remedy is to keep the repository inside a user's home
+directory (see the section "Changing repository location" below).
+Alternatively obtain write/execute access to the default location of the repository
 (usually {{/usr/local/lib/chicken}}) to avoid running as
 root. {{chicken-install}} also provides a {{-sudo}} option to perform
 the last installation steps as root user, but do building and other
-.setup script processing as normal.
+.setup script processing as normal. A third solution is to 
+override {{VARDIR}} when building the system
+(for example by passing {{"VARDIR=/foo/bar"}} on the make command line,
+or by modifying {{config.make}}. Eggs will then be installed in
+{{$(VARDIR)/chicken/5}}.
+
+=== Changing repository location
+
+When Chicken is installed a repository for eggs is created and initialized
+in a default location (usually something like {{/usr/local/lib/chicken/5/}}).
+It is possible to keep an eggs repository in another location. This can be
+configured at build-time by passing {{VARDIR=<directory>}} to {{make(3)}}
+or by modifying the {{config.make}} configuration file. If you want to
+override this location after chicken is installed, you can create an
+initial repository directory with some default extensions and set the
+{{CHICKEN_REPOSITORY}} environment variable:
+
+First, initialize the new repository with
+
+  chicken-install -init ~/myeggs/lib/chicken/5
+
+Then set this environment variable:
+
+  export CHICKEN_REPOSITORY=~/myeggs/lib/chicken/5
+
+{{CHICKEN_REPOSITORY}} is the place where extensions are to be
+loaded from for all chicken-based programs (which includes all
+the tools).
+
+You can install eggs with
+
+  chicken-install -p ~/my_eggs <package>
+
+See that the argument to chicken-install is just {{~/myeggs}}, while everywhere else it's
+{{~/myeggs/lib/chicken/5}}.
+
+When you load eggs from the interpreter, you will see messages showing
+where libraries are being loaded from:
 
+ #;1> (use numbers)
+ ; loading /home/jdoe/myeggs/lib/chicken/5/numbers.import.so ...
+ ; loading /home/jdoe/myeggs/lib/chicken/5/scheme.import.so ...
+ ; loading /home/jdoe/myeggs/lib/chicken/5/chicken.import.so ...
+ ; loading /home/jdoe/myeggs/lib/chicken/5/foreign.import.so ...
+ ; loading /home/jdoe/myeggs/lib/chicken/5/regex.import.so ...
+ ; loading /home/jdoe/myeggs/lib/chicken/5/numbers.so ...
+ #;2> 
 
 === Other modes of installation
 
diff --git a/manual/Getting started b/manual/Getting started
index b359d2ef..255803af 100644
--- a/manual/Getting started	
+++ b/manual/Getting started	
@@ -241,16 +241,6 @@ can pretty much ignore the C compiler once you have installed it.)
   that comes with mingw.  {{Makefile.mingw-msys}} 
   uses unix commands such as {{cp}} and {{rm}}.  The end product is the
   same.
-** Microsoft Visual Studio will soon be supported, including the
-  Express edition, which is a non-free but no-cost compiler suite
-  available from Microsoft
-  ([[http://www.microsoft.com/express/vc]]). Chicken supports
-  command-line building using the command-line C/C++ compiler. 
-*** Visual
-  Studio users will want to install the Unix Utilities, available at
-  [[http://www.call-with-current-continuation.org/tarballs/UnxUtils.zip]],
-  in order to get suitable versions of {{make}}, {{tar}}, {{gzip}}, and
-  similar commands.  
 
 Refer to the {{README}} file for the version you're installing for
 more information on the installation process. 
@@ -284,11 +274,8 @@ proportional fonts, in particular.)
 
 * Emacs ([[http://www.gnu.org/software/emacs]]) is an
 extensible, customizable, self-documenting editor available for
-Linux/Unix, Macintosh, and Windows systems; CHICKEN provides Emacs
-support out of the box, with the {{hen.el}} Emacs Lisp file. Consult
-the `Emacs Guide for Chicken Users' (which will be available on the
-Chicken Wiki soon) for information on setting up and using Emacs with
-Chicken.  
+Linux/Unix, Macintosh, and Windows systems; See
+[[/emacs]] for more information about the available options. 
 
 * Epsilon ([[http://www.lugaru.com]]) is a commercial (proprietary) text
 editor whose design was inspired by Emacs. Although Scheme support
diff --git a/manual/Modules and macros b/manual/Modules and macros
index 9f901994..4c7addf6 100644
--- a/manual/Modules and macros	
+++ b/manual/Modules and macros	
@@ -22,7 +22,9 @@ a {{syntax-rules}} form. If {{syntax-rules}} is used, the usual R5RS
 semantics apply. If {{TRANSFORMER}} is a procedure, then it will
 be called on expansion with the complete s-expression of the macro
 invocation, a rename procedure that hygienically renames identifiers
-and a comparison procedure that compares (possibly renamed) identifiers.
+and a comparison procedure that compares (possibly renamed) identifiers
+(see the section "Explicit renaming macros" below for a detailed explanation
+on non-R5RS macros).
 
 {{define-syntax}} may be used to define local macros that are visible
 throughout the rest of the body in which the definition occurred, i.e.
diff --git a/manual/Unit library b/manual/Unit library
index a152cd2a..697de3fa 100644
--- a/manual/Unit library	
+++ b/manual/Unit library	
@@ -688,20 +688,21 @@ subprocess is returned unaltered.
 
 On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status.    It is 0 on success.  To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this: 
 
- ;; Returns two values: #t if the process exited normally or #f otherwise;
- ;; and either the exit status, or the signal number if terminated via signal.
- (define (process-status rc)
-   (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
-   (define (wait-signal x) (bitwise-and x 127))
-   (define (wait-exit-status x) (arithmetic-shift x -8))
-   (if (wait-signaled? rc)
-       (values #f (wait-signal rc))
-       (values #t (wait-exit-status rc))))
-
- #;> (process-status (system "exit 42"))
- #t
- 42
-
+<enscript highlight='scheme'>
+;; Returns two values: #t if the process exited normally or #f otherwise;
+;; and either the exit status, or the signal number if terminated via signal.
+(define (process-status rc)
+  (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
+  (define (wait-signal x) (bitwise-and x 127))
+  (define (wait-exit-status x) (arithmetic-shift x -8))
+  (if (wait-signaled? rc)
+      (values #f (wait-signal rc))
+      (values #t (wait-exit-status rc))))
+
+#;> (process-status (system "exit 42"))
+#t
+42
+</enscript>
 === Execution time
 
 
diff --git a/manual/Using the compiler b/manual/Using the compiler
index 97f662d8..7fac33a5 100644
--- a/manual/Using the compiler	
+++ b/manual/Using the compiler	
@@ -130,7 +130,7 @@ Possible options are:
 
 ; -inline-limit THRESHOLD : Sets the maximum size of a potentially inlinable procedure. The default threshold is {{20}}.
 
-; -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp), {{suffix}} (as in DSSSL) or {{none}}. Any other value is ignored. The default is {{suffix}}.
+; -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp, e.g. :keyword), {{suffix}} (as in DSSSL, e.g. keyword:) or {{none}}. Any other value is ignored. The default is {{suffix}}.
 
 ; -keep-shadowed-macros : Do not remove macro definitions with the same name as assigned toplevel variables (the default is to remove the macro definition).
 
diff --git a/manual/Using the interpreter b/manual/Using the interpreter
index 743eb2c2..c1804906 100644
--- a/manual/Using the interpreter	
+++ b/manual/Using the interpreter	
@@ -37,7 +37,7 @@ The options recognized by the interpreter are:
 
 ; -I  -include-path PATHNAME : Specifies an alternative 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 {{;}}.
 
-; -k  -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp) or {{suffix}} (as in DSSSL). Any other value is ignored.
+; -K  -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp) or {{suffix}} (as in DSSSL). Any other value is ignored.
 
 ; -n  -no-init : Do not load initialization-file. If this option is not given and the file {{./.csirc}} or {{$HOME/.csirc}} exists, then it is loaded before the read-eval-print loop commences.
 
diff --git a/manual/faq b/manual/faq
index 57324258..d4a54820 100644
--- a/manual/faq
+++ b/manual/faq
@@ -596,15 +596,16 @@ See the [[Extensions]] chapter for more information.
 You can just set the {{CHICKEN_REPOSITORY}} environment variable.
 It should contain the path where you want eggs to be installed:
 
- $ export CHICKEN_REPOSITORY=~/chicken/
- $ chicken-install -init
- $ chicken-install extensionname
+ $ export CHICKEN_REPOSITORY=~/eggs/lib/chicken/5
+ $ chicken-install -init ~/eggs/lib/chicken/5
+ $ chicken-install -p ~/eggs/ extensionname
+
+In order to make programs (including csi) see these eggs, you should set this variable when you run them. See the [[http://chicken.wiki.br/man/4/Extensions#changing-repository-location|Extensions/Changing repository location]] section of the manual for more information on that.
 
-In order to make programs (including csi) see these eggs, you should set this variable when you run them.
 Alternatively, you can call the {{repository-path}} Scheme procedure before loading the eggs, as in:
 
 <enscript highlight=scheme>
-(repository-path "/home/azul/chicken")
+(repository-path "/home/azul/eggs")
 (use format-modular)
 </enscript>
 
Trap