-/* Copyright (C) 1996, 97, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice. */
-/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
- gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
\f
-#include <stdio.h>
#include "libguile/_scm.h"
#include "libguile/chars.h"
#include "libguile/eval.h"
"type, the second a field protection. Allowed types are 'p' for\n"
"GC-protected Scheme data, 'u' for unprotected binary data, and 's' for\n"
"a field that points to the structure itself. Allowed protections\n"
- "are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque \n"
+ "are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque\n"
"fields. The last field protection specification may be capitalized to\n"
"indicate that the field is a tail-array.")
#define FUNC_NAME s_scm_make_struct_layout
{
SCM new_sym;
SCM_VALIDATE_STRING (1, fields);
+
{ /* scope */
char * field_desc;
- int len;
+ size_t len;
int x;
len = SCM_STRING_LENGTH (fields);
+ if (len % 2 == 1)
+ SCM_MISC_ERROR ("odd length field specification: ~S",
+ scm_list_1 (fields));
+
field_desc = SCM_STRING_CHARS (fields);
- SCM_ASSERT (!(len & 1), fields, "odd length field specification", FUNC_NAME);
for (x = 0; x < len; x += 2)
{
case 's':
break;
default:
- SCM_ASSERT (0, SCM_MAKE_CHAR (field_desc[x]) , "unrecognized field type", FUNC_NAME);
+ SCM_MISC_ERROR ("unrecognized field type: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (field_desc[x])));
}
switch (field_desc[x + 1])
{
case 'w':
- SCM_ASSERT (field_desc[x] != 's', SCM_MAKE_CHAR (field_desc[x + 1]),
- "self fields not writable", FUNC_NAME);
-
+ if (field_desc[x] == 's')
+ SCM_MISC_ERROR ("self fields not writable", SCM_EOL);
case 'r':
case 'o':
break;
case 'R':
case 'W':
case 'O':
- SCM_ASSERT (field_desc[x] != 's', SCM_MAKE_CHAR (field_desc[x + 1]),
- "self fields not allowed in tail array",
- FUNC_NAME);
- SCM_ASSERT (x == len - 2, SCM_MAKE_CHAR (field_desc[x + 1]),
- "tail array field must be last field in layout",
- FUNC_NAME);
+ if (field_desc[x] == 's')
+ SCM_MISC_ERROR ("self fields not allowed in tail array",
+ SCM_EOL);
+ if (x != len - 2)
+ SCM_MISC_ERROR ("tail array field must be last field in layout",
+ SCM_EOL);
break;
default:
- SCM_ASSERT (0, SCM_MAKE_CHAR (field_desc[x]) , "unrecognized ref specification", FUNC_NAME);
+ SCM_MISC_ERROR ("unrecognized ref specification: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (field_desc[x + 1])));
}
#if 0
if (field_desc[x] == 'd')
{
- SCM_ASSERT (field_desc[x + 2] == '-', SCM_MAKINUM (x / 2), "missing dash field", FUNC_NAME);
+ if (field_desc[x + 2] != '-')
+ SCM_MISC_ERROR ("missing dash field at position ~A",
+ scm_list_1 (SCM_MAKINUM (x / 2)));
x += 2;
goto recheck_ref;
}
static void
-scm_struct_init (SCM handle, SCM layout, scm_bits_t * mem, int tail_elts, SCM inits)
+scm_struct_init (SCM handle, SCM layout, scm_t_bits * mem, int tail_elts, SCM inits)
{
unsigned char * fields_desc = (unsigned char *) SCM_SYMBOL_CHARS (layout) - 2;
unsigned char prot = 0;
SCM_DEFINE (scm_struct_p, "struct?", 1, 0, 0,
(SCM x),
- "Return #t iff @var{obj} is a structure object, else #f.")
+ "Return @code{#t} iff @var{x} is a structure object, else\n"
+ "@code{#f}.")
#define FUNC_NAME s_scm_struct_p
{
return SCM_BOOL(SCM_STRUCTP (x));
SCM_DEFINE (scm_struct_vtable_p, "struct-vtable?", 1, 0, 0,
(SCM x),
- "Return #t iff obj is a vtable structure.")
+ "Return @code{#t} iff @var{x} is a vtable structure.")
#define FUNC_NAME s_scm_struct_vtable_p
{
SCM layout;
- scm_bits_t * mem;
+ scm_t_bits * mem;
if (!SCM_STRUCTP (x))
return SCM_BOOL_F;
mem = SCM_STRUCT_DATA (x);
- if (mem[1] != 0)
- return SCM_BOOL_F;
-
- return SCM_BOOL (SCM_SYMBOLP (SCM_PACK (mem[0])));
+ return SCM_BOOL (SCM_SYMBOLP (SCM_PACK (mem[scm_vtable_index_layout])));
}
#undef FUNC_NAME
Ugh. */
-scm_bits_t *
-scm_alloc_struct (int n_words, int n_extra, char *who)
+scm_t_bits *
+scm_alloc_struct (int n_words, int n_extra, const char *what)
{
- int size = sizeof (scm_bits_t) * (n_words + n_extra) + 7;
- void * block = scm_must_malloc (size, who);
+ int size = sizeof (scm_t_bits) * (n_words + n_extra) + 7;
+ void * block = scm_gc_malloc (size, what);
/* Adjust the pointer to hide the extra words. */
- scm_bits_t * p = (scm_bits_t *) block + n_extra;
+ scm_t_bits * p = (scm_t_bits *) block + n_extra;
/* Adjust it even further so it's aligned on an eight-byte boundary. */
- p = (scm_bits_t *) (((scm_bits_t) p + 7) & ~7);
+ p = (scm_t_bits *) (((scm_t_bits) p + 7) & ~7);
/* Initialize a few fields as described above. */
- p[scm_struct_i_free] = (scm_bits_t) scm_struct_free_standard;
- p[scm_struct_i_ptr] = (scm_bits_t) block;
+ p[scm_struct_i_free] = (scm_t_bits) scm_struct_free_standard;
+ p[scm_struct_i_ptr] = (scm_t_bits) block;
p[scm_struct_i_n_words] = n_words;
p[scm_struct_i_flags] = 0;
return p;
}
-scm_sizet
-scm_struct_free_0 (scm_bits_t * vtable, scm_bits_t * data)
+void
+scm_struct_free_0 (scm_t_bits * vtable SCM_UNUSED,
+ scm_t_bits * data SCM_UNUSED)
{
- return 0;
}
-scm_sizet
-scm_struct_free_light (scm_bits_t * vtable, scm_bits_t * data)
+void
+scm_struct_free_light (scm_t_bits * vtable, scm_t_bits * data)
{
- scm_must_free (data);
- return vtable [scm_struct_i_size] & ~SCM_STRUCTF_MASK;
+ size_t n = vtable [scm_struct_i_size] & ~SCM_STRUCTF_MASK;
+ scm_gc_free (data, n, "struct");
}
-scm_sizet
-scm_struct_free_standard (scm_bits_t * vtable, scm_bits_t * data)
+void
+scm_struct_free_standard (scm_t_bits * vtable SCM_UNUSED, scm_t_bits * data)
{
size_t n = (data[scm_struct_i_n_words] + scm_struct_n_extra_words)
- * sizeof (scm_bits_t) + 7;
- scm_must_free ((void *) data[scm_struct_i_ptr]);
- return n;
+ * sizeof (scm_t_bits) + 7;
+ scm_gc_free ((void *) data[scm_struct_i_ptr], n, "heavy struct");
}
-scm_sizet
-scm_struct_free_entity (scm_bits_t * vtable, scm_bits_t * data)
+void
+scm_struct_free_entity (scm_t_bits * vtable SCM_UNUSED, scm_t_bits * data)
{
size_t n = (data[scm_struct_i_n_words] + scm_struct_entity_n_extra_words)
- * sizeof (scm_bits_t) + 7;
- scm_must_free ((void *) data[scm_struct_i_ptr]);
- return n;
+ * sizeof (scm_t_bits) + 7;
+ scm_gc_free ((void *) data[scm_struct_i_ptr], n, "entity struct");
}
static void *
-scm_struct_gc_init (void *dummy1, void *dummy2, void *dummy3)
+scm_struct_gc_init (void *dummy1 SCM_UNUSED,
+ void *dummy2 SCM_UNUSED,
+ void *dummy3 SCM_UNUSED)
{
scm_structs_to_free = SCM_EOL;
return 0;
}
static void *
-scm_free_structs (void *dummy1, void *dummy2, void *dummy3)
+scm_free_structs (void *dummy1 SCM_UNUSED,
+ void *dummy2 SCM_UNUSED,
+ void *dummy3 SCM_UNUSED)
{
SCM newchain = scm_structs_to_free;
do
{
/* Mark vtables in GC chain. GC mark set means delay freeing. */
SCM chain = newchain;
- while (SCM_NNULLP (chain))
+ while (!SCM_NULLP (chain))
{
SCM vtable = SCM_STRUCT_VTABLE (chain);
if (SCM_STRUCT_GC_CHAIN (vtable) != 0 && vtable != chain)
/* Free unmarked structs. */
chain = newchain;
newchain = SCM_EOL;
- while (SCM_NNULLP (chain))
+ while (!SCM_NULLP (chain))
{
SCM obj = chain;
chain = SCM_STRUCT_GC_CHAIN (chain);
}
else
{
- scm_bits_t word0 = SCM_CELL_WORD_0 (obj) - scm_tc3_cons_gloc;
- /* access as struct */
- scm_bits_t * vtable_data = (scm_bits_t *) word0;
- scm_bits_t * data = (scm_bits_t *) SCM_UNPACK (SCM_CDR (obj));
- scm_struct_free_t free_struct_data
- = ((scm_struct_free_t) vtable_data[scm_struct_i_free]);
+ /* XXX - use less explicit code. */
+ scm_t_bits word0 = SCM_CELL_WORD_0 (obj) - scm_tc3_struct;
+ scm_t_bits * vtable_data = (scm_t_bits *) word0;
+ scm_t_bits * data = SCM_STRUCT_DATA (obj);
+ scm_t_struct_free free_struct_data
+ = ((scm_t_struct_free) vtable_data[scm_struct_i_free]);
SCM_SET_CELL_TYPE (obj, scm_tc_free_cell);
free_struct_data (vtable_data, data);
}
}
}
- while (SCM_NNULLP (newchain));
+ while (!SCM_NULLP (newchain));
return 0;
}
SCM layout;
int basic_size;
int tail_elts;
- scm_bits_t * data;
+ scm_t_bits * data;
SCM handle;
- SCM_VALIDATE_VTABLE (1,vtable);
- SCM_VALIDATE_INUM (2,tail_array_size);
+ SCM_VALIDATE_VTABLE (1, vtable);
+ SCM_VALIDATE_INUM (2, tail_array_size);
SCM_VALIDATE_REST_ARGUMENT (init);
layout = SCM_PACK (SCM_STRUCT_DATA (vtable) [scm_vtable_index_layout]);
basic_size = SCM_SYMBOL_LENGTH (layout) / 2;
tail_elts = SCM_INUM (tail_array_size);
- SCM_NEWCELL2 (handle);
SCM_DEFER_INTS;
if (SCM_STRUCT_DATA (vtable)[scm_struct_i_flags] & SCM_STRUCTF_ENTITY)
{
data = scm_alloc_struct (basic_size + tail_elts,
scm_struct_entity_n_extra_words,
- "make-struct");
+ "entity struct");
data[scm_struct_i_procedure] = SCM_UNPACK (SCM_BOOL_F);
data[scm_struct_i_setter] = SCM_UNPACK (SCM_BOOL_F);
}
else
data = scm_alloc_struct (basic_size + tail_elts,
scm_struct_n_extra_words,
- "make-struct");
- SCM_SET_CELL_WORD_1 (handle, data);
- SCM_SET_STRUCT_GC_CHAIN (handle, 0);
+ "struct");
+ handle = scm_double_cell ((((scm_t_bits) SCM_STRUCT_DATA (vtable))
+ + scm_tc3_struct),
+ (scm_t_bits) data, 0, 0);
scm_struct_init (handle, layout, data, tail_elts, init);
- SCM_SET_CELL_WORD_0 (handle, (scm_bits_t) SCM_STRUCT_DATA (vtable) + scm_tc3_cons_gloc);
SCM_ALLOW_INTS;
return handle;
}
"sub-system: one vtable-vtable working as the root and one or several\n"
"\"types\", each with a set of \"instances\". (The vtable-vtable should be\n"
"compared to the class <class> which is the class of itself.)\n\n"
- "@example\n"
+ "@lisp\n"
"(define ball-root (make-vtable-vtable \"pr\" 0))\n\n"
"(define (make-ball-type ball-color)\n"
" (make-struct ball-root 0\n"
"(define (make-ball type owner) (make-struct type 0 owner))\n\n"
"(define ball (make-ball green 'Nisse))\n"
"ball @result{} #<a green ball owned by Nisse>\n"
- "@end example\n")
+ "@end lisp")
#define FUNC_NAME s_scm_make_vtable_vtable
{
SCM fields;
SCM layout;
int basic_size;
int tail_elts;
- scm_bits_t * data;
+ scm_t_bits * data;
SCM handle;
SCM_VALIDATE_STRING (1, user_fields);
SCM_VALIDATE_INUM (2, tail_array_size);
SCM_VALIDATE_REST_ARGUMENT (init);
- fields = scm_string_append (scm_listify (required_vtable_fields,
- user_fields,
- SCM_UNDEFINED));
+ fields = scm_string_append (scm_list_2 (required_vtable_fields,
+ user_fields));
layout = scm_make_struct_layout (fields);
basic_size = SCM_SYMBOL_LENGTH (layout) / 2;
tail_elts = SCM_INUM (tail_array_size);
- SCM_NEWCELL2 (handle);
SCM_DEFER_INTS;
data = scm_alloc_struct (basic_size + tail_elts,
scm_struct_n_extra_words,
- "make-vtable-vtable");
- SCM_SET_CELL_WORD_1 (handle, data);
- SCM_SET_STRUCT_GC_CHAIN (handle, 0);
+ "struct");
+ handle = scm_double_cell ((scm_t_bits) data + scm_tc3_struct,
+ (scm_t_bits) data, 0, 0);
data [scm_vtable_index_layout] = SCM_UNPACK (layout);
scm_struct_init (handle, layout, data, tail_elts, scm_cons (layout, init));
- SCM_SET_CELL_WORD_0 (handle, (scm_bits_t) data + scm_tc3_cons_gloc);
SCM_ALLOW_INTS;
return handle;
}
SCM_DEFINE (scm_struct_ref, "struct-ref", 2, 0, 0,
(SCM handle, SCM pos),
- "@deffnx primitive struct-set! struct n value\n"
+ "@deffnx {Scheme Procedure} struct-set! struct n value\n"
"Access (or modify) the @var{n}th field of @var{struct}.\n\n"
"If the field is of type 'p', then it can be set to an arbitrary value.\n\n"
"If the field is of type 'u', then it can only be set to a non-negative\n"
#define FUNC_NAME s_scm_struct_ref
{
SCM answer = SCM_UNDEFINED;
- scm_bits_t * data;
+ scm_t_bits * data;
SCM layout;
int p;
- scm_bits_t n_fields;
+ scm_t_bits n_fields;
char * fields_desc;
char field_type = 0;
- SCM_VALIDATE_STRUCT (1,handle);
- SCM_VALIDATE_INUM (2,pos);
+ SCM_VALIDATE_STRUCT (1, handle);
+ SCM_VALIDATE_INUM (2, pos);
layout = SCM_STRUCT_LAYOUT (handle);
data = SCM_STRUCT_DATA (handle);
fields_desc = SCM_SYMBOL_CHARS (layout);
n_fields = data[scm_struct_i_n_words];
- SCM_ASSERT_RANGE(1,pos, p < n_fields);
+ SCM_ASSERT_RANGE(1, pos, p < n_fields);
if (p * 2 < SCM_SYMBOL_LENGTH (layout))
{
if ((ref == 'R') || (ref == 'W'))
field_type = 'u';
else
- SCM_ASSERT (0, pos, "ref denied", FUNC_NAME);
+ SCM_MISC_ERROR ("ref denied for field ~A", scm_list_1 (pos));
}
}
else if (fields_desc[SCM_SYMBOL_LENGTH (layout) - 1] != 'O')
field_type = fields_desc[SCM_SYMBOL_LENGTH (layout) - 2];
else
- {
- SCM_ASSERT (0, pos, "ref denied", FUNC_NAME);
- abort ();
- }
+ SCM_MISC_ERROR ("ref denied for field ~A", scm_list_1 (pos));
switch (field_type)
{
default:
- SCM_ASSERT (0, SCM_MAKE_CHAR (field_type), "unrecognized field type", FUNC_NAME);
- break;
+ SCM_MISC_ERROR ("unrecognized field type: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (field_type)));
}
return answer;
"to.")
#define FUNC_NAME s_scm_struct_set_x
{
- scm_bits_t * data;
+ scm_t_bits * data;
SCM layout;
int p;
int n_fields;
char * fields_desc;
char field_type = 0;
- SCM_VALIDATE_STRUCT (1,handle);
- SCM_VALIDATE_INUM (2,pos);
+ SCM_VALIDATE_STRUCT (1, handle);
+ SCM_VALIDATE_INUM (2, pos);
layout = SCM_STRUCT_LAYOUT (handle);
data = SCM_STRUCT_DATA (handle);
fields_desc = SCM_SYMBOL_CHARS (layout);
n_fields = data[scm_struct_i_n_words];
- SCM_ASSERT_RANGE (1,pos, p < n_fields);
+ SCM_ASSERT_RANGE (1, pos, p < n_fields);
if (p * 2 < SCM_SYMBOL_LENGTH (layout))
{
field_type = fields_desc[p * 2];
set_x = fields_desc [p * 2 + 1];
if (set_x != 'w')
- SCM_ASSERT (0, pos, "set_x denied", FUNC_NAME);
+ SCM_MISC_ERROR ("set! denied for field ~A", scm_list_1 (pos));
}
else if (fields_desc[SCM_SYMBOL_LENGTH (layout) - 1] == 'W')
field_type = fields_desc[SCM_SYMBOL_LENGTH (layout) - 2];
else
- {
- SCM_ASSERT (0, pos, "set_x denied", FUNC_NAME);
- abort ();
- }
+ SCM_MISC_ERROR ("set! denied for field ~A", scm_list_1 (pos));
switch (field_type)
{
#if 0
case 'i':
- data[p] = SCM_NUM2LONG (3,val);
+ data[p] = SCM_NUM2LONG (3, val);
break;
case 'd':
break;
case 's':
- SCM_ASSERT (0, SCM_MAKE_CHAR (field_type), "self fields immutable", FUNC_NAME);
- break;
+ SCM_MISC_ERROR ("self fields immutable", SCM_EOL);
default:
- SCM_ASSERT (0, SCM_MAKE_CHAR (field_type), "unrecognized field type", FUNC_NAME);
- break;
+ SCM_MISC_ERROR ("unrecognized field type: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (field_type)));
}
return val;
"Return the vtable structure that describes the type of @var{struct}.")
#define FUNC_NAME s_scm_struct_vtable
{
- SCM_VALIDATE_STRUCT (1,handle);
+ SCM_VALIDATE_STRUCT (1, handle);
return SCM_STRUCT_VTABLE (handle);
}
#undef FUNC_NAME
"Return the vtable tag of the structure @var{handle}.")
#define FUNC_NAME s_scm_struct_vtable_tag
{
- SCM_VALIDATE_VTABLE (1,handle);
+ SCM_VALIDATE_VTABLE (1, handle);
return scm_long2num ((long) SCM_STRUCT_DATA (handle) >> 3);
}
#undef FUNC_NAME
* how to associate names with vtables.
*/
-unsigned int
-scm_struct_ihashq (SCM obj, unsigned int n)
+unsigned long
+scm_struct_ihashq (SCM obj, unsigned long n)
{
/* The length of the hash table should be a relative prime it's not
necessary to shift down the address. */
"Return the name of the vtable @var{vtable}.")
#define FUNC_NAME s_scm_struct_vtable_name
{
- SCM_VALIDATE_VTABLE (1,vtable);
+ SCM_VALIDATE_VTABLE (1, vtable);
return SCM_STRUCT_TABLE_NAME (SCM_CDR (scm_struct_create_handle (vtable)));
}
#undef FUNC_NAME
"Set the name of the vtable @var{vtable} to @var{name}.")
#define FUNC_NAME s_scm_set_struct_vtable_name_x
{
- SCM_VALIDATE_VTABLE (1,vtable);
- SCM_VALIDATE_SYMBOL (2,name);
+ SCM_VALIDATE_VTABLE (1, vtable);
+ SCM_VALIDATE_SYMBOL (2, name);
SCM_SET_STRUCT_TABLE_NAME (SCM_CDR (scm_struct_create_handle (vtable)),
name);
return SCM_UNSPECIFIED;
{
scm_struct_table
= scm_permanent_object (scm_make_weak_key_hash_table (SCM_MAKINUM (31)));
- required_vtable_fields = scm_makfrom0str ("pruosrpw");
+ required_vtable_fields = scm_makfrom0str ("prsrpw");
scm_permanent_object (required_vtable_fields);
- scm_sysintern ("vtable-index-layout", SCM_MAKINUM (scm_vtable_index_layout));
- scm_sysintern ("vtable-index-vtable", SCM_MAKINUM (scm_vtable_index_vtable));
- scm_sysintern ("vtable-index-printer", SCM_MAKINUM (scm_vtable_index_printer));
- scm_sysintern ("vtable-offset-user", SCM_MAKINUM (scm_vtable_offset_user));
-#ifndef SCM_MAGIC_SNARFER
+ scm_c_define ("vtable-index-layout", SCM_MAKINUM (scm_vtable_index_layout));
+ scm_c_define ("vtable-index-vtable", SCM_MAKINUM (scm_vtable_index_vtable));
+ scm_c_define ("vtable-index-printer",
+ SCM_MAKINUM (scm_vtable_index_printer));
+ scm_c_define ("vtable-offset-user", SCM_MAKINUM (scm_vtable_offset_user));
#include "libguile/struct.x"
-#endif
}
/*