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.