Scheme objects
==============

There are two basic C data types to represent objects in guile:

- SCM:  SCM is the user level abstract C type that is used to represent all of
guile's scheme objects, no matter what the scheme object type is.  No C
operation except assignment is guaranteed to work with variables of type SCM.
Only use macros and functions to work with SCM values.  Values are converted
between C data types and the SCM type with utility functions and macros.

- scm_bits_t:  An integral data type that is guaranteed to be large enough to
hold all information that is required to represent any scheme object.  While
this data type is used to implement guile internals, the use of this type is
also necessary to write certain kinds of extensions to guile.


Relationship between SCM and scm_bits_t
=======================================

A variable of type SCM is guaranteed to hold a valid scheme object.  A
variable of type scm_bits_t, however, may either hold a representation of a
SCM value as a C integral type, but may also hold any C value, even if it does
not correspond to a valid scheme object.

For a variable x of type SCM, the scheme object's type information is stored
in a form that is not directly usable.  To be able to work on the type
encoding of the scheme value, the SCM variable has to be transformed into the 
corresponding representation as a scm_bits_t variable y by using the   
SCM_UNPACK macro.  After this has been done, the type of the scheme object x 
can be derived from the content of the bits of the scm_bits_t value y, as is
described in -->data-rep.  A valid bit encoding of a scheme value as a
scm_bits_t variable can be transformed into the corresponding SCM value by
using the SCM_PACK macro.

- scm_bits_t SCM_UNPACK (SCM x):  Transforms the SCM value x into it's
representation as an integral type.  Only after applying SCM_UNPACK it is
possible to access the bits and contents of the SCM value.

- SCM SCM_PACK (scm_bits_t x):  Takes a valid integral representation of a
scheme object and transforms it into its representation as a SCM value.


Immediate objects
=================

A scheme object may either be an immediate, i. e. carrying all necessary
information by itself, or it may contain a reference to a 'cell' with
additional information on the heap.  While the fact, whether an object is an
immediate or not should be irrelevant for user code, within guile's own code
the distinction is sometimes of importance.  Thus, the following low level
macro is provided:

- int SCM_IMP (SCM x):  A scheme object is an immediate if it fullfills the   
SCM_IMP predicate, otherwise it holds an encoded reference to a heap cell.
The result of the predicate is delivered as a C style boolean value.  User
code and code that extends guile should normally not be required to use this
macro.

Summary:
* For a scheme object x of unknown type, check first with SCM_IMP (x) if it is
an immediate object.  If so, all of the type and value information can be
determined from the scm_bits_t value that is delivered by SCM_UNPACK (x).


Non immediate objects
=====================

- (scm_t_cell *) SCM2PTR (SCM x)         (FIXME:: this name should be changed)
- SCM PTR2SCM (scm_t_cell * x)           (FIXME:: this name should be changed)

A scheme object of type SCM that does not fullfill the SCM_IMP predicate holds
an encoded reference to a heap cell.  This reference can be decoded to a C
pointer to a heap cell using the SCM2PTR macro.  The encoding of a pointer to
a heap cell into a SCM value is done using the PTR2SCM macro.

Note that it is also possible to transform a non immediate SCM value by using
SCM_UNPACK into a scm_bits_t variable.  Hower, the result of SCM_UNPACK may
not be used as a pointer to a scm_t_cell:  Only SCM2PTR is guaranteed to
transform a SCM object into a valid pointer to a heap cell.  Also, it is not
allowed to apply PTR2SCM to anything that is not a valid pointer to a heap
cell.

Summary:  
* Only use SCM2PTR for SCM values for which SCM_IMP is false!
* Don't use '(scm_t_cell*) SCM_UNPACK (x)'!  Use 'SCM2PTR (x)' instead!
* Don't use PTR2SCM for anything but a cell pointer!


Heap Cell Type Information
==========================

Heap cells contain a number of entries, each of which is either a scheme
object of type SCM or a raw C value of type scm_bits_t.  Which of the cell
entries contain scheme objects and which contain raw C values is determined by
the first entry of the cell, which holds the cell type information.

- scm_bits_t SCM_CELL_TYPE (SCM x):  For a non immediate scheme object x,
deliver the content of the first entry of the heap cell referenced by x.  This
value holds the information about the cell type as described in -->data-rep.

- void SCM_SET_CELL_TYPE (SCM x, scm_bits_t t):  For a non immediate scheme
object x, write the value t into the first entry of the heap cell referenced
by x.  The value t must hold a valid cell type as described in -->data-rep.


Accessing Cell Entries
======================

For a non immediate scheme object x, the object type can be determined by
reading the cell type entry using the SCM_CELL_TYPE macro.  For the different
types of cells it is known which cell entry holds scheme objects and which cell
entry holds raw C data.  To access the different cell entries appropriately,
the following macros are provided:

- scm_bits_t SCM_CELL_WORD (SCM x, unsigned int n):  Deliver the cell entry n
of the heap cell referenced by the non immediate scheme object x as raw data.
It is illegal, to access cell entries that hold scheme objects by using these
macros.  For convenience, the following macros are also provided:
  SCM_CELL_WORD_0 (x)  -->  SCM_CELL_WORD (x, 0)
  SCM_CELL_WORD_1 (x)  -->  SCM_CELL_WORD (x, 1)
  ...
  SCM_CELL_WORD_n (x)  -->  SCM_CELL_WORD (x, n)

- SCM SCM_CELL_OBJECT (SCM x, unsigned int n):  Deliver the cell entry n of
the heap cell referenced by the non immediate scheme object x as a scheme
object.  It is illegal, to access cell entries that do not hold scheme objects
by using these macros.  For convenience, the following macros are also
provided:
  SCM_CELL_OBJECT_0 (x)  -->  SCM_CELL_OBJECT (x, 0)
  SCM_CELL_OBJECT_1 (x)  -->  SCM_CELL_OBJECT (x, 1)
  ...
  SCM_CELL_OBJECT_n (x)  -->  SCM_CELL_OBJECT (x, n)

- void SCM_SET_CELL_WORD (SCM x, unsigned int n, scm_bits_t w):  Write the raw
C value w into entry number n of the heap cell referenced by the non immediate
scheme value x.  Values that are written into cells this way may only be read
from the cells using the SCM_CELL_WORD macros or, in case cell entry 0 is
written, using the SCM_CELL_TYPE macro.  For the special case of cell entry 0 
it has to be made sure that w contains a cell type information (see
-->data-rep) which does not describe a scheme object.  For convenience, the
following macros are also provided:
  SCM_SET_CELL_WORD_0 (x, w)  -->  SCM_SET_CELL_WORD (x, 0, w)
  SCM_SET_CELL_WORD_1 (x, w)  -->  SCM_SET_CELL_WORD (x, 1, w)
  ...
  SCM_SET_CELL_WORD_n (x, w)  -->  SCM_SET_CELL_WORD (x, n, w)

- void SCM_SET_CELL_OBJECT (SCM x, unsigned int n, SCM o):  Write the scheme
object o into entry number n of the heap cell referenced by the non immediate
scheme value x.  Values that are written into cells this way may only be read
from the cells using the SCM_CELL_OBJECT macros or, in case cell entry 0 is
written, using the SCM_CELL_TYPE macro.  For the special case of cell entry 0
the writing of a scheme object into this cell is only allowed, if the cell
forms a scheme pair.  For convenience, the following macros are also provided:
  SCM_SET_CELL_OBJECT_0 (x, o)  -->  SCM_SET_CELL_OBJECT (x, 0, o)
  SCM_SET_CELL_OBJECT_1 (x, o)  -->  SCM_SET_CELL_OBJECT (x, 1, o)
  ...
  SCM_SET_CELL_OBJECT_n (x, o)  -->  SCM_SET_CELL_OBJECT (x, n, o)

Summary:
* For a non immediate scheme object x of unknown type, get the type
  information by using SCM_CELL_TYPE (x).
* As soon as the cell type information is available, only use the appropriate
  access methods to read and write data to the different cell entries.


Basic Rules for Accessing Cell Entries
======================================

For each cell type it is generally up to the implementation of that type which
of the corresponding cell entries hold scheme objects and which hold raw C
values.  However, there is one basic rules that has to be followed:  Scheme
pairs consist of exactly two cell entries, which both contain scheme objects.
Further, a cell which contains a scheme object in it first entry has to be a
scheme pair.  In other words, it is not allowed to store a scheme object in
the first cell entry and a non scheme object in the second cell entry.

Fixme:shouldn't this rather be SCM_PAIRP / SCM_PAIR_P ?
- int SCM_CONSP (SCM x):  Determine, whether the scheme object x is a scheme 
pair, i. e. whether x references a heap cell consisting of exactly two
entries, where both entries contain a scheme object.  In this case, both
entries will have to be accessed using the SCM_CELL_OBJECT macros.  On the
contrary, if the SCM_CONSP predicate is not fulfilled, the first entry of the
scheme cell is guaranteed not to be a scheme value and thus the first cell
entry must be accessed using the SCM_CELL_WORD_0 macro.
