* stacks.c (scm_init_stacks): Set name of stack type.
[bpt/guile.git] / libguile / struct.c
CommitLineData
7dc6e754 1/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd
JB
41\f
42
43#include <stdio.h>
44#include "_scm.h"
20e6290e 45#include "chars.h"
bafcafb2 46#include "genio.h"
916d65b1 47#include "eval.h"
98d5f601
MD
48#include "alist.h"
49#include "weaks.h"
50#include "hashtab.h"
20e6290e
JB
51
52#include "struct.h"
0f2d19dd 53
95b88819
GH
54#ifdef HAVE_STRING_H
55#include <string.h>
56#endif
57
0f2d19dd
JB
58\f
59
60static SCM required_vtable_fields = SCM_BOOL_F;
98d5f601 61SCM scm_struct_table;
0f2d19dd
JB
62
63\f
64SCM_PROC (s_struct_make_layout, "make-struct-layout", 1, 0, 0, scm_make_struct_layout);
1cc91f1b 65
0f2d19dd
JB
66SCM
67scm_make_struct_layout (fields)
68 SCM fields;
0f2d19dd
JB
69{
70 SCM new_sym;
71 SCM_ASSERT (SCM_NIMP (fields) && SCM_ROSTRINGP (fields),
72 fields, SCM_ARG1, s_struct_make_layout);
73
74 {
75 char * field_desc;
76 int len;
77 int x;
78
79 len = SCM_ROLENGTH (fields);
80 field_desc = SCM_ROCHARS (fields);
81 SCM_ASSERT (!(len & 1), fields, "odd length field specification", s_struct_make_layout);
82
83 for (x = 0; x < len; x += 2)
84 {
85 switch (field_desc[x])
86 {
87 case 'u':
88 case 'p':
89#if 0
90 case 'i':
91 case 'd':
92#endif
93 case 's':
94 break;
95 default:
96 SCM_ASSERT (0, SCM_MAKICHR (field_desc[x]) , "unrecognized field type", s_struct_make_layout);
97 }
98
99 switch (field_desc[x + 1])
100 {
101 case 'w':
2c36c351 102 SCM_ASSERT (field_desc[x] != 's', SCM_MAKICHR (field_desc[x + 1]),
0f2d19dd
JB
103 "self fields not writable", s_struct_make_layout);
104
105 case 'r':
106 case 'o':
107 break;
2c36c351
MD
108 case 'R':
109 case 'W':
110 case 'O':
111 SCM_ASSERT (field_desc[x] != 's', SCM_MAKICHR (field_desc[x + 1]),
112 "self fields not allowed in tail array",
113 s_struct_make_layout);
114 SCM_ASSERT (x == len - 2, SCM_MAKICHR (field_desc[x + 1]),
115 "tail array field must be last field in layout",
116 s_struct_make_layout);
117 break;
0f2d19dd
JB
118 default:
119 SCM_ASSERT (0, SCM_MAKICHR (field_desc[x]) , "unrecognized ref specification", s_struct_make_layout);
120 }
121#if 0
122 if (field_desc[x] == 'd')
123 {
124 SCM_ASSERT (field_desc[x + 2] == '-', SCM_MAKINUM (x / 2), "missing dash field", s_struct_make_layout);
125 x += 2;
126 goto recheck_ref;
127 }
128#endif
129 }
130 new_sym = SCM_CAR (scm_intern_obarray (field_desc, len, SCM_BOOL_F));
131 }
132 return scm_return_first (new_sym, fields);
133}
134
135\f
136
137
1cc91f1b 138
a5bfe84d
MD
139void
140scm_struct_init (handle, tail_elts, inits)
0f2d19dd 141 SCM handle;
2c36c351 142 int tail_elts;
0f2d19dd 143 SCM inits;
0f2d19dd
JB
144{
145 SCM layout;
146 SCM * data;
147 unsigned char * fields_desc;
35de7ebe 148 unsigned char prot = 0;
0f2d19dd
JB
149 int n_fields;
150 SCM * mem;
2c36c351
MD
151 int tailp = 0;
152
0f2d19dd
JB
153 layout = SCM_STRUCT_LAYOUT (handle);
154 data = SCM_STRUCT_DATA (handle);
2c36c351 155 fields_desc = (unsigned char *) SCM_CHARS (layout) - 2;
0f2d19dd
JB
156 n_fields = SCM_LENGTH (layout) / 2;
157 mem = SCM_STRUCT_DATA (handle);
158 while (n_fields)
159 {
2c36c351
MD
160 if (!tailp)
161 {
162 fields_desc += 2;
163 prot = fields_desc[1];
164 if (SCM_LAYOUT_TAILP (prot))
165 {
166 tailp = 1;
167 prot = prot == 'R' ? 'r' : prot == 'W' ? 'w' : 'o';
168 *mem++ = tail_elts;
169 n_fields += tail_elts - 1;
170 if (n_fields == 0)
171 break;
172 }
173 }
174
0f2d19dd
JB
175 switch (*fields_desc)
176 {
177#if 0
178 case 'i':
2c36c351 179 if ((prot != 'r' && prot != 'w') || inits == SCM_EOL)
0f2d19dd
JB
180 *mem = 0;
181 else
182 {
a5bfe84d 183 *mem = scm_num2long (SCM_CAR (inits), SCM_ARGn, "scm_struct_init");
0f2d19dd
JB
184 inits = SCM_CDR (inits);
185 }
186 break;
187#endif
188
189 case 'u':
2c36c351 190 if ((prot != 'r' && prot != 'w') || inits == SCM_EOL)
0f2d19dd
JB
191 *mem = 0;
192 else
193 {
a5bfe84d 194 *mem = scm_num2ulong (SCM_CAR (inits), SCM_ARGn, "scm_struct_init");
0f2d19dd
JB
195 inits = SCM_CDR (inits);
196 }
197 break;
198
199 case 'p':
2c36c351 200 if ((prot != 'r' && prot != 'w') || inits == SCM_EOL)
916d65b1 201 *mem = SCM_BOOL_F;
0f2d19dd
JB
202 else
203 {
204 *mem = SCM_CAR (inits);
205 inits = SCM_CDR (inits);
206 }
207
208 break;
209
210#if 0
211 case 'd':
2c36c351 212 if ((prot != 'r' && prot != 'w') || inits == SCM_EOL)
0f2d19dd
JB
213 *((double *)mem) = 0.0;
214 else
215 {
a5bfe84d 216 *mem = scm_num2dbl (SCM_CAR (inits), "scm_struct_init");
0f2d19dd
JB
217 inits = SCM_CDR (inits);
218 }
219 fields_desc += 2;
220 break;
221#endif
222
223 case 's':
224 *mem = handle;
225 break;
226 }
227
0f2d19dd
JB
228 n_fields--;
229 mem++;
230 }
231}
232
233
234SCM_PROC (s_struct_p, "struct?", 1, 0, 0, scm_struct_p);
1cc91f1b 235
0f2d19dd
JB
236SCM
237scm_struct_p (x)
238 SCM x;
0f2d19dd
JB
239{
240 return ((SCM_NIMP (x) && SCM_STRUCTP (x))
241 ? SCM_BOOL_T
242 : SCM_BOOL_F);
243}
244
245SCM_PROC (s_struct_vtable_p, "struct-vtable?", 1, 0, 0, scm_struct_vtable_p);
1cc91f1b 246
0f2d19dd
JB
247SCM
248scm_struct_vtable_p (x)
249 SCM x;
0f2d19dd
JB
250{
251 SCM layout;
252 SCM * mem;
253
254 if (SCM_IMP (x))
255 return SCM_BOOL_F;
256
257 if (!SCM_STRUCTP (x))
258 return SCM_BOOL_F;
259
260 layout = SCM_STRUCT_LAYOUT (x);
261
262 if (SCM_LENGTH (layout) < SCM_LENGTH (required_vtable_fields))
263 return SCM_BOOL_F;
264
265 if (strncmp (SCM_CHARS (layout), SCM_CHARS (required_vtable_fields),
266 SCM_LENGTH (required_vtable_fields)))
267 return SCM_BOOL_F;
268
269 mem = SCM_STRUCT_DATA (x);
270
271 if (mem[1] != 0)
272 return SCM_BOOL_F;
273
274 if (SCM_IMP (mem[0]))
275 return SCM_BOOL_F;
276
277 return (SCM_SYMBOLP (mem[0])
278 ? SCM_BOOL_T
279 : SCM_BOOL_F);
280}
281
14d1400f
JB
282
283/* All struct data must be allocated at an address whose bottom three
284 bits are zero. This is because the tag for a struct lives in the
285 bottom three bits of the struct's car, and the upper bits point to
286 the data of its vtable, which is a struct itself. Thus, if the
287 address of that data doesn't end in three zeros, tagging it will
288 destroy the pointer.
289
290 This function allocates a block of memory, and returns a pointer at
291 least scm_struct_n_extra_words words into the block. Furthermore,
292 it guarantees that that pointer's least three significant bits are
293 all zero.
294
295 The argument n_words should be the number of words that should
296 appear after the returned address. (That is, it shouldn't include
297 scm_struct_n_extra_words.)
298
299 This function initializes the following fields of the struct:
300
ad196599 301 scm_struct_i_ptr --- the actual start of the block of memory; the
14d1400f
JB
302 address you should pass to 'free' to dispose of the block.
303 This field allows us to both guarantee that the returned
304 address is divisible by eight, and allow the GC to free the
305 block.
306
307 scm_struct_i_n_words --- the number of words allocated to the
308 block, including the extra fields. This is used by the GC.
309
14d1400f
JB
310 Ugh. */
311
312
a5bfe84d
MD
313SCM *
314scm_alloc_struct (int n_words, int n_extra, char *who)
14d1400f 315{
a5bfe84d 316 int size = sizeof (SCM) * (n_words + n_extra) + 7;
14d1400f
JB
317 SCM *block = (SCM *) scm_must_malloc (size, who);
318
319 /* Adjust the pointer to hide the extra words. */
a5bfe84d 320 SCM *p = block + n_extra;
14d1400f
JB
321
322 /* Adjust it even further so it's aligned on an eight-byte boundary. */
323 p = (SCM *) (((SCM) p + 7) & ~7);
324
ad196599
MD
325 /* Initialize a few fields as described above. */
326 p[scm_struct_i_free] = (SCM) scm_struct_free_standard;
14d1400f 327 p[scm_struct_i_ptr] = (SCM) block;
ad196599
MD
328 p[scm_struct_i_n_words] = (SCM) n_words;
329 p[scm_struct_i_flags] = 0;
14d1400f
JB
330
331 return p;
332}
333
ad196599
MD
334size_t
335scm_struct_free_0 (SCM *vtable, SCM *data)
336{
337 return 0;
338}
339
340size_t
341scm_struct_free_light (SCM *vtable, SCM *data)
342{
343 free (data);
344 return vtable[scm_struct_i_size] & ~SCM_STRUCTF_MASK;
345}
346
347size_t
348scm_struct_free_standard (SCM *vtable, SCM *data)
349{
350 size_t n = ((data[scm_struct_i_n_words] + scm_struct_n_extra_words)
351 * sizeof (SCM) + 7);
352 free ((void *) data[scm_struct_i_ptr]);
353 return n;
354}
355
356size_t
357scm_struct_free_entity (SCM *vtable, SCM *data)
358{
359 size_t n = ((data[scm_struct_i_n_words] + scm_struct_entity_n_extra_words)
360 * sizeof (SCM) + 7);
361 free ((void *) data[scm_struct_i_ptr]);
362 return n;
363}
14d1400f 364
0f2d19dd 365SCM_PROC (s_make_struct, "make-struct", 2, 0, 1, scm_make_struct);
1cc91f1b 366
0f2d19dd
JB
367SCM
368scm_make_struct (vtable, tail_array_size, init)
369 SCM vtable;
370 SCM tail_array_size;
371 SCM init;
0f2d19dd
JB
372{
373 SCM layout;
374 int basic_size;
375 int tail_elts;
376 SCM * data;
377 SCM handle;
378
379 SCM_ASSERT ((SCM_BOOL_F != scm_struct_vtable_p (vtable)),
380 vtable, SCM_ARG1, s_make_struct);
14d1400f
JB
381 SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG2,
382 s_make_struct);
0f2d19dd 383
4bfdf158 384 layout = SCM_STRUCT_DATA (vtable)[scm_vtable_index_layout];
0f2d19dd
JB
385 basic_size = SCM_LENGTH (layout) / 2;
386 tail_elts = SCM_INUM (tail_array_size);
387 SCM_NEWCELL (handle);
388 SCM_DEFER_INTS;
a5bfe84d
MD
389 if (SCM_STRUCT_DATA (vtable)[scm_struct_i_flags] & SCM_STRUCTF_ENTITY)
390 {
391 data = scm_alloc_struct (basic_size + tail_elts,
98d5f601 392 scm_struct_entity_n_extra_words,
a5bfe84d
MD
393 "make-struct");
394 data[scm_struct_i_proc + 0] = SCM_BOOL_F;
395 data[scm_struct_i_proc + 1] = SCM_BOOL_F;
396 data[scm_struct_i_proc + 2] = SCM_BOOL_F;
397 data[scm_struct_i_proc + 3] = SCM_BOOL_F;
25c94826 398 data[scm_struct_i_setter] = SCM_BOOL_F;
a5bfe84d
MD
399 }
400 else
401 data = scm_alloc_struct (basic_size + tail_elts,
402 scm_struct_n_extra_words,
403 "make-struct");
0f2d19dd 404 SCM_SETCDR (handle, data);
35457f1e 405 SCM_SETCAR (handle, ((SCM)SCM_STRUCT_DATA (vtable)) + scm_tc3_cons_gloc);
a5bfe84d 406 scm_struct_init (handle, tail_elts, init);
0f2d19dd
JB
407 SCM_ALLOW_INTS;
408 return handle;
409}
410
411
412
413SCM_PROC (s_make_vtable_vtable, "make-vtable-vtable", 2, 0, 1, scm_make_vtable_vtable);
1cc91f1b 414
0f2d19dd
JB
415SCM
416scm_make_vtable_vtable (extra_fields, tail_array_size, init)
417 SCM extra_fields;
418 SCM tail_array_size;
419 SCM init;
0f2d19dd
JB
420{
421 SCM fields;
422 SCM layout;
423 int basic_size;
424 int tail_elts;
425 SCM * data;
426 SCM handle;
427
428 SCM_ASSERT (SCM_NIMP (extra_fields) && SCM_ROSTRINGP (extra_fields),
429 extra_fields, SCM_ARG1, s_make_vtable_vtable);
14d1400f
JB
430 SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG2,
431 s_make_vtable_vtable);
0f2d19dd
JB
432
433 fields = scm_string_append (scm_listify (required_vtable_fields,
434 extra_fields,
435 SCM_UNDEFINED));
436 layout = scm_make_struct_layout (fields);
437 basic_size = SCM_LENGTH (layout) / 2;
438 tail_elts = SCM_INUM (tail_array_size);
439 SCM_NEWCELL (handle);
440 SCM_DEFER_INTS;
a5bfe84d
MD
441 data = scm_alloc_struct (basic_size + tail_elts,
442 scm_struct_n_extra_words,
443 "make-vtable-vtable");
0f2d19dd 444 SCM_SETCDR (handle, data);
35457f1e 445 SCM_SETCAR (handle, ((SCM)data) + scm_tc3_cons_gloc);
0f2d19dd 446 SCM_STRUCT_LAYOUT (handle) = layout;
a5bfe84d 447 scm_struct_init (handle, tail_elts, scm_cons (layout, init));
0f2d19dd
JB
448 SCM_ALLOW_INTS;
449 return handle;
450}
451
452\f
453
454
455SCM_PROC (s_struct_ref, "struct-ref", 2, 0, 0, scm_struct_ref);
1cc91f1b 456
0f2d19dd
JB
457SCM
458scm_struct_ref (handle, pos)
459 SCM handle;
460 SCM pos;
0f2d19dd 461{
5e840c2e 462 SCM answer = SCM_UNDEFINED;
0f2d19dd
JB
463 SCM * data;
464 SCM layout;
465 int p;
466 int n_fields;
467 unsigned char * fields_desc;
f3667f52 468 unsigned char field_type = 0;
0f2d19dd
JB
469
470
471 SCM_ASSERT (SCM_NIMP (handle) && SCM_STRUCTP (handle), handle,
472 SCM_ARG1, s_struct_ref);
473 SCM_ASSERT (SCM_INUMP (pos), pos, SCM_ARG2, s_struct_ref);
474
475 layout = SCM_STRUCT_LAYOUT (handle);
476 data = SCM_STRUCT_DATA (handle);
477 p = SCM_INUM (pos);
478
ad196599
MD
479 fields_desc = (unsigned char *) SCM_CHARS (layout);
480 n_fields = data[scm_struct_i_n_words];
2c36c351
MD
481
482 SCM_ASSERT (p < n_fields, pos, SCM_OUTOFRANGE, s_struct_ref);
0f2d19dd 483
2c36c351
MD
484 if (p * 2 < SCM_LENGTH (layout))
485 {
486 unsigned char ref;
487 field_type = fields_desc[p * 2];
488 ref = fields_desc[p * 2 + 1];
489 if ((ref != 'r') && (ref != 'w'))
490 {
491 if ((ref == 'R') || (ref == 'W'))
492 field_type = 'u';
493 else
494 SCM_ASSERT (0, pos, "ref denied", s_struct_ref);
495 }
496 }
497 else if (fields_desc[SCM_LENGTH (layout) - 1] != 'O')
498 field_type = fields_desc[SCM_LENGTH (layout) - 2];
499 else
500 {
501 SCM_ASSERT (0, pos, "ref denied", s_struct_ref);
35de7ebe 502 abort ();
2c36c351
MD
503 }
504
0f2d19dd
JB
505 switch (field_type)
506 {
507 case 'u':
508 answer = scm_ulong2num (data[p]);
509 break;
510
511#if 0
512 case 'i':
513 answer = scm_long2num (data[p]);
514 break;
515
516 case 'd':
517 answer = scm_makdbl (*((double *)&(data[p])), 0.0);
518 break;
519#endif
520
521 case 's':
522 case 'p':
523 answer = data[p];
524 break;
525
526
527 default:
528 SCM_ASSERT (0, SCM_MAKICHR (field_type), "unrecognized field type", s_struct_ref);
529 break;
530 }
531
532 return answer;
533}
534
535
536SCM_PROC (s_struct_set_x, "struct-set!", 3, 0, 0, scm_struct_set_x);
1cc91f1b 537
0f2d19dd
JB
538SCM
539scm_struct_set_x (handle, pos, val)
540 SCM handle;
541 SCM pos;
542 SCM val;
0f2d19dd
JB
543{
544 SCM * data;
545 SCM layout;
546 int p;
547 int n_fields;
548 unsigned char * fields_desc;
f3667f52 549 unsigned char field_type = 0;
0f2d19dd
JB
550
551
552
553 SCM_ASSERT (SCM_NIMP (handle) && SCM_STRUCTP (handle), handle,
554 SCM_ARG1, s_struct_ref);
555 SCM_ASSERT (SCM_INUMP (pos), pos, SCM_ARG2, s_struct_ref);
556
557 layout = SCM_STRUCT_LAYOUT (handle);
558 data = SCM_STRUCT_DATA (handle);
559 p = SCM_INUM (pos);
560
561 fields_desc = (unsigned char *)SCM_CHARS (layout);
ad196599 562 n_fields = data[scm_struct_i_n_words];
0f2d19dd 563
2c36c351 564 SCM_ASSERT (p < n_fields, pos, SCM_OUTOFRANGE, s_struct_set_x);
0f2d19dd 565
2c36c351
MD
566 if (p * 2 < SCM_LENGTH (layout))
567 {
568 unsigned char set_x;
569 field_type = fields_desc[p * 2];
570 set_x = fields_desc [p * 2 + 1];
571 if (set_x != 'w')
572 SCM_ASSERT (0, pos, "set_x denied", s_struct_set_x);
573 }
574 else if (fields_desc[SCM_LENGTH (layout) - 1] == 'W')
575 field_type = fields_desc[SCM_LENGTH (layout) - 2];
576 else
577 {
578 SCM_ASSERT (0, pos, "set_x denied", s_struct_ref);
35de7ebe 579 abort ();
2c36c351
MD
580 }
581
0f2d19dd
JB
582 switch (field_type)
583 {
584 case 'u':
585 data[p] = (SCM)scm_num2ulong (val, (char *)SCM_ARG3, s_struct_set_x);
586 break;
587
588#if 0
589 case 'i':
590 data[p] = scm_num2long (val, (char *)SCM_ARG3, s_struct_set_x);
591 break;
592
593 case 'd':
594 *((double *)&(data[p])) = scm_num2dbl (val, (char *)SCM_ARG3);
595 break;
596#endif
597
598 case 'p':
599 data[p] = val;
600 break;
601
602 case 's':
603 SCM_ASSERT (0, SCM_MAKICHR (field_type), "self fields immutable", s_struct_set_x);
604 break;
605
606 default:
607 SCM_ASSERT (0, SCM_MAKICHR (field_type), "unrecognized field type", s_struct_set_x);
608 break;
609 }
610
611 return val;
612}
613
614
615SCM_PROC (s_struct_vtable, "struct-vtable", 1, 0, 0, scm_struct_vtable);
1cc91f1b 616
0f2d19dd
JB
617SCM
618scm_struct_vtable (handle)
619 SCM handle;
0f2d19dd
JB
620{
621 SCM_ASSERT (SCM_NIMP (handle) && SCM_STRUCTP (handle), handle,
622 SCM_ARG1, s_struct_vtable);
623 return SCM_STRUCT_VTABLE (handle);
624}
625
626
627SCM_PROC (s_struct_vtable_tag, "struct-vtable-tag", 1, 0, 0, scm_struct_vtable_tag);
1cc91f1b 628
0f2d19dd
JB
629SCM
630scm_struct_vtable_tag (handle)
631 SCM handle;
0f2d19dd 632{
98d5f601 633 SCM_ASSERT (SCM_NFALSEP (scm_struct_vtable_p (handle)),
0f2d19dd 634 handle, SCM_ARG1, s_struct_vtable_tag);
ad196599 635 return scm_long2num ((long) SCM_STRUCT_DATA (handle) >> 3);
98d5f601
MD
636}
637
638/* {Associating names and classes with vtables}
639 *
640 * The name of a vtable should probably be stored as a slot. This is
641 * a backward compatible solution until agreement has been achieved on
642 * how to associate names with vtables.
643 */
644
645unsigned int
646scm_struct_ihashq (SCM obj, unsigned int n)
647{
ad196599
MD
648 /* The length of the hash table should be a relative prime it's not
649 necessary to shift down the address. */
650 return obj % n;
98d5f601
MD
651}
652
653SCM
654scm_struct_create_handle (SCM obj)
655{
656 SCM handle = scm_hash_fn_create_handle_x (scm_struct_table,
657 obj,
658 SCM_BOOL_F,
659 scm_struct_ihashq,
660 scm_sloppy_assq,
661 0);
662 if (SCM_FALSEP (SCM_CDR (handle)))
663 SCM_SETCDR (handle, scm_cons (SCM_BOOL_F, SCM_BOOL_F));
664 return handle;
665}
666
667SCM_PROC (s_struct_vtable_name, "struct-vtable-name", 1, 0, 0, scm_struct_vtable_name);
668
669SCM
670scm_struct_vtable_name (SCM vtable)
671{
672 SCM_ASSERT (SCM_NFALSEP (scm_struct_vtable_p (vtable)),
673 vtable, SCM_ARG1, s_struct_vtable_name);
674
675 return SCM_STRUCT_TABLE_NAME (SCM_CDR (scm_struct_create_handle (vtable)));
676}
677
678SCM_PROC (s_set_struct_vtable_name_x, "set-struct-vtable-name!", 2, 0, 0, scm_set_struct_vtable_name_x);
679
680SCM
681scm_set_struct_vtable_name_x (SCM vtable, SCM name)
682{
683 SCM_ASSERT (SCM_NIMP (vtable) && SCM_NFALSEP (scm_struct_vtable_p (vtable)),
684 vtable, SCM_ARG1, s_set_struct_vtable_name_x);
685 SCM_ASSERT (SCM_NIMP (name) && SCM_SYMBOLP (name),
686 name, SCM_ARG2, s_set_struct_vtable_name_x);
687 SCM_SET_STRUCT_TABLE_NAME (SCM_CDR (scm_struct_create_handle (vtable)),
688 name);
689 return SCM_UNSPECIFIED;
0f2d19dd
JB
690}
691
692
693\f
694
bafcafb2
MV
695void
696scm_print_struct (exp, port, pstate)
697 SCM exp;
698 SCM port;
699 scm_print_state *pstate;
700{
4bfdf158
MD
701 if (SCM_NFALSEP (scm_procedure_p (SCM_STRUCT_PRINTER (exp))))
702 scm_printer_apply (SCM_STRUCT_PRINTER (exp), exp, port, pstate);
703 else
bafcafb2 704 {
b7f3516f 705 scm_lfwrite ("#<struct ", sizeof ("#<struct ") - 1, port);
4bfdf158 706 scm_intprint (SCM_STRUCT_VTABLE (exp), 16, port);
b7f3516f 707 scm_putc (':', port);
916d65b1 708 scm_intprint (exp, 16, port);
b7f3516f 709 scm_putc ('>', port);
bafcafb2 710 }
bafcafb2 711}
1cc91f1b 712
0f2d19dd
JB
713void
714scm_init_struct ()
0f2d19dd 715{
98d5f601
MD
716 scm_struct_table
717 = scm_permanent_object (scm_make_weak_key_hash_table (SCM_MAKINUM (31)));
4bfdf158 718 required_vtable_fields = SCM_CAR (scm_intern_obarray ("pruosrpw", sizeof ("pruosrpw") - 1, SCM_BOOL_F));
0f2d19dd 719 scm_permanent_object (required_vtable_fields);
4bfdf158
MD
720 scm_sysintern ("vtable-index-layout", SCM_MAKINUM (scm_vtable_index_layout));
721 scm_sysintern ("vtable-index-vtable", SCM_MAKINUM (scm_vtable_index_vtable));
722 scm_sysintern ("vtable-index-printer", SCM_MAKINUM (scm_vtable_index_printer));
723 scm_sysintern ("vtable-offset-user", SCM_MAKINUM (scm_vtable_offset_user));
0f2d19dd
JB
724#include "struct.x"
725}