Using Scheme records in C
=========================

External C code can create records and access record slots positionally using these functions & macros.  Note, however, that named access to record fields is not supported, only indexed access, so C code must be synchronized carefully with the corresponding Scheme that defines record types.

 -- C function (may GC): s48_value s48_make_record (s48_value RECORD-TYPE)
 -- C macro: int S48_RECORD_P (s48_value OBJECT)
 -- C macro: s48_value S48_RECORD_TYPE (s48_value RECORD)
 -- C macro: s48_value S48_RECORD_REF (s48_value RECORD, long INDEX)
 -- C macro: void S48_RECORD_SET (s48_value RECORD, long INDEX, s48_value VALUE)
 -- C function: void s48_check_record_type (s48_value RECORD, s48_value TYPE-BINDING)
     s48_make_record allocates a record on Scheme's heap with the given record type; its arguments must be a shared binding whose value is a record type descriptor (see Records).    S48_RECORD_P is the type predicate for records.  S48_RECORD_TYPE returns the record type descriptor of RECORD.  S48_RECORD_REF & S48_RECORD_SET operate on records similarly to how S48_VECTOR_REF & S48_VECTOR_SET work on vectors. s48_check_record_type checks whether RECORD is a record whose type is the value of the shared binding TYPE_BINDING.  If this is not the case, it signals an exception.  (It also signals an exception if TYPE_BINDING's value is not a record.)  Otherwise, it returns normally.

For example, with this record type definition:

     (define-record-type thing :thing
       (make-thing a b)
       thing?
       (a thing-a)
       (b thing-b)) lisp

     the identifier :thing is bound to the record type and can be
     exported to C thus:

          (define-exported-binding "thing-record-type" :thing) lisp

          and thing records can be made in C:

               static s48_value thing_record_type = S48_FALSE;
               void initialize_things(void)
               {
                 S48_GC_PROTECT_GLOBAL(thing_record_type);
                 thing_record_type = s48_get_imported_binding("thing-record-type");
               }

               s48_value make_thing(s48_value a, s48_value b)
               {
                 s48_value thing;

                 S48_DECLARE_GC_PROTECT(2);
                 S48_GC_PROTECT_2(a, b);

                 thing = s48_make_record(thing_record_type);
                 S48_RECORD_SET(thing, 0, a);
                 S48_RECORD_SET(thing, 1, b);

                 S48_GC_UNPROTECT();

                 return thing;
               } example

               Note that the variables a & b must be protected against
               the possibility of a garbage collection occurring during the call to
               s48_make_record.