A Scheme value is represented by a pointer-sized value. The low bit is a mark bit: a 1 in the low bit indicates an immediate integer, a 0 indicates a (word-aligned) pointer.
A pointer Scheme value references a structure that begins with a type tag. This type tag has the C type Scheme_Type. The rest of the structure, following the type tag, is type-dependent. Examples of Scheme_Type values include scheme_pair_type, scheme_symbol_type, and scheme_compiled_closure_type.
MzScheme's C interface gives Scheme values the type Scheme_Object *. (The ``object'' here does not refer to objects in the sense of MzLib's class library.) The struct type Scheme_Object is defined in scheme.h, but extension or embedding code should never access this structure directly. Instead, the code should use macros, such as SCHEME_CAR, that provide access to the data of common Scheme types. A Scheme_Object structure is actually only allocated for certain types (i.e., some of the built-in types that contain two words of data, in addition to the type tag), but Scheme_Object * is nevertheless used as the type of a generic Scheme value (for historical reasons).
For most Scheme types, a constructor is provided for creating values
of the type. For example, scheme_make_pair takes two
Scheme_Object * values and returns the cons of the
values.
The macro SCHEME_TYPE takes a Scheme_Object * and returns the type of the object. This macro performs the tag-bit check, and returns scheme_integer_type when the value is an immediate integer; otherwise, SCHEME_TYPE follows the pointer to get the type tag. Macros are provided to test for common Scheme types; for example, SCHEME_PAIRP returns 1 if the value is a cons cell, 0 otherwise.
In addition to providing constructors, MzScheme defines six global constant Scheme values: scheme_true, scheme_false, scheme_null, scheme_eof, scheme_void, and scheme_undefined. Each of these has a type tag, but each is normally recognized via its constant address.
An extension or embedding application can create new a primitive data type by calling scheme_make_type, which returns a fresh Scheme_Type value. To create a collectable instance of this type, allocate memory for the instance with scheme_malloc. From MzScheme's perspective, the only constraint on the data format of such an instance is that the first sizeof(Scheme_Type) bytes must contain the value returned by scheme_make_type. Extensions with modest needs can use scheme_make_cptr, instead.
Scheme values should never be allocated on the stack, and they should never contain pointers to values on the stack. Besides the problem of restricting the value's lifetime to that of the stack frame, allocating values on the stack creates problems for continuations and threads, both of which copy into and out of the stack.
The following are the Scheme_Type values for the standard types:
scheme_char_type -- SCHEME_CHAR_VAL extracts the character; test for this type with SCHEME_CHARP
scheme_integer_type -- fixnum integers, which are identified via the tag bit rather than following a pointer to this Scheme_Type value; SCHEME_INT_VAL extracts the integer; test for this type with SCHEME_INTP
scheme_double_type -- flonum inexact numbers; SCHEME_FLOAT_VAL or SCHEME_DBL_VAL extracts the floating-point value; test for this type with SCHEME_DBLP
scheme_float_type -- single-precision flonum inexact numbers, when specifically enabled when compiling MzScheme; SCHEME_FLOAT_VAL or SCHEME_FLT_VAL extracts the floating-point value; test for this type with SCHEME_FLTP
scheme_bignum_type -- test for this type with SCHEME_BIGNUMP
scheme_rational_type -- test for this type with SCHEME_RATIONALP
scheme_complex_type -- test for this type or scheme_complex_izi_type with SCHEME_COMPLEXP
scheme_complex_izi_type -- complex number with an inexact zero imaginary part (so it counts as a real number); test for this type specifically with SCHEME_COMPLEX_IZIP
scheme_string_type -- SCHEME_STR_VAL extracts the string (which is always null-terminated, but may also contain embedded nulls; the Scheme string is modified if this string is modified) and SCHEME_STRLEN_VAL extracts the string length (not counting the null terminator); test for this type with SCHEME_STRINGP
scheme_symbol_type -- SCHEME_SYM_VAL extracts the string (do not modify this string); test for this type with SCHEME_SYMBOLP
scheme_box_type -- SCHEME_BOX_VAL extracts/sets the boxed value; test for this type with SCHEME_BOXP
scheme_pair_type -- SCHEME_CAR extracts/sets the
car and SCHEME_CDR extracts/sets the cdr; test
for this type with SCHEME_PAIRP
scheme_vector_type -- SCHEME_VEC_SIZE extracts the length and SCHEME_VEC_ELS extracts the array of Scheme values (the Scheme vector is modified when this array is modified); test for this type with SCHEME_VECTORP
scheme_type_symbol_type -- SCHEME_TSYM_VAL extracts the symbol; test for this type with SCHEME_TSYMBOLP
scheme_object_type -- SCHEME_OBJ_CLASS extracts the class, SCHEME_OBJ_DATA extracts/sets the user pointer, and SCHEME_OBJ_FLAG extracts/sets the flag; test for this type with SCHEME_OBJP
scheme_structure_type -- structure instances; test for this type with SCHEME_STRUCTP
scheme_struct_type_type -- structure types; test for this type with SCHEME_STRUCT_TYPEP
scheme_struct_property_type -- structure type properties
scheme_input_port_type -- SCHEME_INPORT_VAL extracts/sets the user data pointer; test for this type with SCHEME_INPORTP
scheme_output_port_type -- SCHEME_OUTPORT_VAL extracts/sets the user data pointer; test for this type with SCHEME_OUTPORTP
scheme_thread_type -- thread descriptors; test for this type with SCHEME_THREADP
scheme_sema_type -- semaphores; test for this type with SCHEME_SEMAP
scheme_hash_table_type -- test for this type with SCHEME_HASHTP
scheme_bucket_table_type -- test for this type with SCHEME_BUCKTP
scheme_weak_box_type -- test for this type with SCHEME_WEAKP; SCHEME_WEAK_PTR extracts the contained object, or NULL after the content is collected; do not set the content of a weak box
scheme_namespace_type -- namespaces; test for this type with SCHEME_NAMESPACEP
scheme_c_pointer_type -- void pointer with a type-describing string; SCHEME_CPTR_VAL extracts the pointer and SCHEME_CPTR_TYPE extracts the type string; test for this type with SCHEME_CPTRP
The following are the procedure types:
scheme_prim_type -- a primitive procedure
scheme_closed_prim_type -- a primitive procedure with a data pointer
scheme_compiled_closure_type -- a Scheme procedure
scheme_cont_type -- a continuation
scheme_escaping_cont_type -- an escape continuation
scheme_case_closure_type -- a case-lambda procedure
The predicate SCHEME_PROCP returns 1 for all procedure types and 0 for anything else.
The following are additional number predicates:
SCHEME_NUMBERP -- all numerical types
SCHEME_REALP -- all non-complex numerical types, plus scheme_complex_izi_type
SCHEME_EXACT_INTEGERP -- fixnums and bignums
SCHEME_EXACT_REALP -- fixnums, bignums, and rationals
SCHEME_FLOATP -- both single-precision (when enabled) and double-precision flonums
There are six global constants:
scheme_null -- test for this value with SCHEME_NULLP
scheme_eof -- test for this value with SCHEME_EOFP
scheme_true
scheme_false -- test for this value with SCHEME_FALSEP; test against it with SCHEME_TRUEP
scheme_void -- test for this value with SCHEME_VOIDP
scheme_undefined
¤ Scheme_Object * scheme_make_char(char ch)
Returns the character value.
¤ Scheme_Object * scheme_make_character(char ch)
Returns the character value. (This is a macro.)
¤ Scheme_Object * scheme_make_integer(long i)
Returns the integer value; i must fit in a fixnum. (This is a macro.)
¤ Scheme_Object * scheme_make_integer_value(long i)
Returns the integer value. If i does not fit in a fixnum,
a bignum is returned.
¤ Scheme_Object * scheme_make_integer_value_from_unsigned(unsigned long i)
Like scheme_make_integer_value, but for unsigned integers.
¤ int scheme_get_int_val(Scheme_Object *o, long *i)
Extracts the integer value. Unlike the SCHEME_INT_VAL macro,
this procedure will extract an integer that fits in a long from
a Scheme bignum. If o fits in a long, the extracted
integer is placed in *i and 1 is returned; otherwise, 0 is
returned and *i is unmodified.
¤ int scheme_get_unsigned_int_val(Scheme_Object *o,
unsigned long *i)
Like scheme_get_int_val, but for unsigned integers.
¤ Scheme_Object * scheme_make_double(double d)
Creates a new floating-point value.
¤ Scheme_Object * scheme_make_float(float d)
Creates a new single-precision floating-point value. The procedure is available only when MzScheme is compiled with single-precision numbers enabled.
¤ double scheme_real_to_double(Scheme_Object *o)
Converts a Scheme real number to a double-precision floating-point value.
¤ Scheme_Object * scheme_make_pair(Scheme_Object *carv, Scheme_Object *cdrv)
¤ Scheme_Object * scheme_make_string(char *chars)
Makes a Scheme string from a null-terminated C string. The
chars string is copied.
¤ Scheme_Object * scheme_make_string_without_copying(char *chars)
Like scheme_make_string, but the string is not copied.
¤ Scheme_Object * scheme_make_sized_string(char *chars, long len, int copy)
Makes a string value with size len. A copy of chars is made
if copy is not 0. The string chars should contain len
characters; chars can contain the null character at any position,
and need not be null-terminated. However, if len is negative, then
the null-terminated length of chars is used for the length.
¤ Scheme_Object * scheme_make_sized_offset_string(char *chars, long d, long len, int copy)
Like scheme_make_sized_string, except the len characters
start from position d in chars.
¤ Scheme_Object * scheme_alloc_string(int size,
char fill)
Allocates a new Scheme string.
¤ Scheme_Object * scheme_append_string(Scheme_Object *a, Scheme_Object *b)
Creates a new string by appending the two given strings.
¤ Scheme_Object * scheme_intern_symbol(char *name)
Finds (or creates) the symbol matching the given null-terminated
string. The case of name is (non-destructively) normalized
before interning if scheme_case_sensitive is 0.
¤ Scheme_Object * scheme_intern_exact_symbol(char *name, int len)
Creates or finds a symbol given the symbol's length. The the case of
name is not normalized.
¤ Scheme_Object * scheme_make_symbol(char *name)
Creates an uninterned symbol from a null-terminated string.
¤ Scheme_Object * scheme_make_exact_symbol(char *name,
int len)
Creates an uninterned symbol given the symbol's length.
¤ Scheme_Object * scheme_make_vector(int size, Scheme_Object *fill)
Allocates a new vector.
¤ Scheme_Object * scheme_box(Scheme_Object *v)
Creates a new box containing the value v.
¤ Scheme_Object * scheme_make_weak_box(Scheme_Object *v)
Creates a new weak box containing the value v.
¤ Scheme_Type scheme_make_type(char *name)
Creates a new type (not a Scheme value).
¤ Scheme_Object * scheme_make_cptr(void *ptr, const char *name)
Creates a C-pointer object that encapuslates ptr and uses
name to identify the type of the pointer. The
SCHEME_CPTRP macro recognizes objects created by
scheme_make_cptr. The SCHEME_CPTR_VAL macro extracts
the original ptr from the Scheme object, and
SCHEME_CPTR_TYPE extracts the type string.