1 /* Copyright (C) 1995,1996,1997,1998, 2000 Free Software Foundation, Inc.
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)
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.
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
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
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.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
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.
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.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
48 #include "libguile/_scm.h"
49 #include "libguile/chars.h"
50 #include "libguile/eval.h"
51 #include "libguile/smob.h"
52 #include "libguile/variable.h"
53 #include "libguile/alist.h"
54 #include "libguile/fluids.h"
55 #include "libguile/strings.h"
56 #include "libguile/vectors.h"
57 #include "libguile/weaks.h"
58 #include "libguile/modules.h"
60 #include "libguile/validate.h"
61 #include "libguile/symbols.h"
70 /* NUM_HASH_BUCKETS is the number of symbol scm_hash table buckets.
72 #define NUM_HASH_BUCKETS 137
82 scm_strhash (const unsigned char *str
, scm_sizet len
, unsigned long n
)
87 unsigned long h
= 264 % n
;
89 h
= ((h
<< 8) + ((unsigned) (scm_downcase (str
[h
% len
])))) % n
;
97 h
= ((h
<< 8) + ((unsigned) (scm_downcase (str
[--i
])))) % n
;
102 int scm_symhash_dim
= NUM_HASH_BUCKETS
;
106 * looks up the symbol in the symhash table.
110 scm_sym2vcell (SCM sym
, SCM thunk
, SCM definep
)
112 if (SCM_NIMP (thunk
))
116 if (SCM_EVAL_CLOSURE_P (thunk
))
117 /* Bypass evaluator in the standard case. */
118 var
= scm_eval_closure_lookup (thunk
, sym
, definep
);
120 var
= scm_apply (thunk
, sym
, scm_cons (definep
, scm_listofnull
));
122 if (SCM_FALSEP (var
))
126 if (SCM_IMP(var
) || !SCM_VARIABLEP (var
))
127 scm_wta (sym
, "strangely interned symbol? ", "");
128 return SCM_VARVCELL (var
);
136 scm_sizet scm_hash
= scm_strhash (SCM_UCHARS (sym
), (scm_sizet
) SCM_LENGTH (sym
),
137 (unsigned long) scm_symhash_dim
);
140 for (lsym
= SCM_VELTS (scm_symhash
)[scm_hash
]; SCM_NIMP (lsym
); lsym
= SCM_CDR (lsym
))
143 if (SCM_EQ_P (SCM_CAR (z
), sym
))
150 for (lsym
= *(lsymp
= &SCM_VELTS (scm_weak_symhash
)[scm_hash
]);
152 lsym
= *(lsymp
= SCM_CDRLOC (lsym
)))
155 if (SCM_EQ_P (SCM_CAR (z
), sym
))
157 if (SCM_NFALSEP (definep
))
159 /* Move handle from scm_weak_symhash to scm_symhash. */
160 *lsymp
= SCM_CDR (lsym
);
161 SCM_SETCDR (lsym
, SCM_VELTS(scm_symhash
)[scm_hash
]);
162 SCM_VELTS(scm_symhash
)[scm_hash
] = lsym
;
169 return scm_wta (sym
, "uninterned symbol? ", "");
174 * looks up the symbol in an arbitrary obarray.
178 scm_sym2ovcell_soft (SCM sym
, SCM obarray
)
183 scm_hash
= scm_strhash (SCM_UCHARS (sym
),
184 (scm_sizet
) SCM_LENGTH (sym
),
185 SCM_LENGTH (obarray
));
187 for (lsym
= SCM_VELTS (obarray
)[scm_hash
];
189 lsym
= SCM_CDR (lsym
))
192 if (SCM_EQ_P (SCM_CAR (z
), sym
))
204 scm_sym2ovcell (SCM sym
, SCM obarray
)
207 answer
= scm_sym2ovcell_soft (sym
, obarray
);
208 if (!SCM_FALSEP (answer
))
210 scm_wta (sym
, "uninterned symbol? ", "");
211 return SCM_UNSPECIFIED
; /* not reached */
214 /* Intern a symbol whose name is the LEN characters at NAME in OBARRAY.
216 OBARRAY should be a vector of lists, indexed by the name's hash
217 value, modulo OBARRAY's length. Each list has the form
218 ((SYMBOL . VALUE) ...), where SYMBOL is a symbol, and VALUE is the
219 value associated with that symbol (in the current module? in the
222 To "intern" a symbol means: if OBARRAY already contains a symbol by
223 that name, return its (SYMBOL . VALUE) pair; otherwise, create a
224 new symbol, add the pair (SYMBOL . SCM_UNDEFINED) to the
225 appropriate list of the OBARRAY, and return the pair.
227 If softness is non-zero, don't create a symbol if it isn't already
228 in OBARRAY; instead, just return #f.
230 If OBARRAY is SCM_BOOL_F, create a symbol listed in no obarray and
231 return (SYMBOL . SCM_UNDEFINED).
233 If OBARRAY is scm_symhash, and that doesn't contain the symbol,
234 check scm_weak_symhash instead. */
238 scm_intern_obarray_soft (const char *name
,scm_sizet len
,SCM obarray
,int softness
)
242 register scm_sizet i
;
243 register unsigned char *tmp
;
248 if (SCM_FALSEP (obarray
))
250 scm_hash
= scm_strhash ((unsigned char *) name
, len
, 1019);
251 goto uninterned_symbol
;
254 scm_hash
= scm_strhash ((unsigned char *) name
, len
, SCM_LENGTH (obarray
));
256 /* softness == -1 used to mean that it was known that the symbol
257 wasn't already in the obarray. I don't think there are any
258 callers that use that case any more, but just in case...
264 for (lsym
= SCM_VELTS (obarray
)[scm_hash
]; SCM_NIMP (lsym
); lsym
= SCM_CDR (lsym
))
268 tmp
= SCM_UCHARS (z
);
269 if (SCM_LENGTH (z
) != len
)
272 if (((unsigned char *) name
)[i
] != tmp
[i
])
283 if (SCM_EQ_P (obarray
, scm_symhash
))
285 obarray
= scm_weak_symhash
;
286 goto retry_new_obarray
;
296 lsym
= scm_makfromstr (name
, len
, SCM_SYMBOL_SLOTS
);
298 SCM_SETLENGTH (lsym
, (long) len
, scm_tc7_msymbol
);
299 SCM_SYMBOL_HASH (lsym
) = scm_hash
;
300 SCM_SET_SYMBOL_PROPS (lsym
, SCM_EOL
);
301 if (SCM_FALSEP (obarray
))
305 SCM_NEWCELL (answer
);
307 SCM_SETCAR (answer
, lsym
);
308 SCM_SETCDR (answer
, SCM_UNDEFINED
);
319 SCM_SETCAR (a
, lsym
);
320 SCM_SETCDR (a
, SCM_UNDEFINED
);
322 SCM_SETCDR (b
, SCM_VELTS(obarray
)[scm_hash
]);
323 SCM_VELTS(obarray
)[scm_hash
] = b
;
331 scm_intern_obarray (const char *name
,scm_sizet len
,SCM obarray
)
333 return scm_intern_obarray_soft (name
, len
, obarray
, 0);
338 scm_intern (const char *name
,scm_sizet len
)
340 return scm_intern_obarray (name
, len
, scm_symhash
);
345 scm_intern0 (const char * name
)
347 return scm_intern (name
, strlen (name
));
351 /* Intern the symbol named NAME in scm_symhash, NAME is null-terminated. */
353 scm_sysintern0_no_module_lookup (const char *name
)
357 easy_answer
= scm_intern_obarray_soft (name
, strlen (name
), scm_symhash
, 1);
358 if (SCM_NIMP (easy_answer
))
366 scm_sizet len
= strlen (name
);
367 scm_sizet scm_hash
= scm_strhash ((unsigned char *) name
,
369 (unsigned long) scm_symhash_dim
);
371 SCM_SETLENGTH (lsym
, (long) len
, scm_tc7_ssymbol
);
372 SCM_SETCHARS (lsym
, name
);
373 lsym
= scm_cons (lsym
, SCM_UNDEFINED
);
374 SCM_VELTS (scm_symhash
)[scm_hash
] = scm_cons (lsym
, SCM_VELTS (scm_symhash
)[scm_hash
]);
380 /* Intern the symbol named NAME in scm_symhash, and give it the value
381 VAL. NAME is null-terminated. Use the current top_level lookup
382 closure to give NAME its value.
385 scm_sysintern (const char *name
, SCM val
)
387 SCM vcell
= scm_sysintern0 (name
);
388 SCM_SETCDR (vcell
, val
);
393 scm_sysintern0 (const char *name
)
396 if (scm_module_system_booted_p
397 && SCM_NIMP (lookup_proc
= SCM_TOP_LEVEL_LOOKUP_CLOSURE
))
399 SCM sym
= SCM_CAR (scm_intern0 (name
));
400 SCM vcell
= scm_sym2vcell (sym
, lookup_proc
, SCM_BOOL_T
);
401 if (SCM_FALSEP (vcell
))
402 scm_misc_error ("sysintern0", "can't define variable", sym
);
406 return scm_sysintern0_no_module_lookup (name
);
409 /* Lookup the value of the symbol named by the nul-terminated string
410 NAME in the current module. */
412 scm_symbol_value0 (const char *name
)
414 /* This looks silly - we look up the symbol twice. But it is in
415 fact necessary given the current module system because the module
416 lookup closures are written in scheme which needs real symbols. */
417 SCM symbol
= scm_intern_obarray_soft (name
, strlen (name
), scm_symhash
, 0);
418 SCM vcell
= scm_sym2vcell (SCM_CAR (symbol
),
419 SCM_TOP_LEVEL_LOOKUP_CLOSURE
,
421 if (SCM_FALSEP (vcell
))
422 return SCM_UNDEFINED
;
423 return SCM_CDR (vcell
);
426 SCM_DEFINE (scm_symbol_p
, "symbol?", 1, 0, 0,
428 "Returns @t{#t} if @var{obj} is a symbol, otherwise returns @t{#f}. (r5rs)")
429 #define FUNC_NAME s_scm_symbol_p
431 if SCM_IMP(obj
) return SCM_BOOL_F
;
432 return SCM_BOOL(SCM_SYMBOLP(obj
));
436 SCM_DEFINE (scm_symbol_to_string
, "symbol->string", 1, 0, 0,
438 "Returns the name of @var{symbol} as a string. If the symbol was part of\n"
439 "an object returned as the value of a literal expression (section\n"
440 "@pxref{Literal expressions,,,r4rs, The Revised^4 Report on Scheme}) or\n"
441 "by a call to the @samp{read} procedure, and its name contains alphabetic\n"
442 "characters, then the string returned will contain characters in the\n"
443 "implementation's preferred standard case---some implementations will\n"
444 "prefer upper case, others lower case. If the symbol was returned by\n"
445 "@samp{string->symbol}, the case of characters in the string returned\n"
446 "will be the same as the case in the string that was passed to\n"
447 "@samp{string->symbol}. It is an error to apply mutation procedures like\n"
448 "@code{string-set!} to strings returned by this procedure. (r5rs)\n\n"
449 "The following examples assume that the implementation's standard case is\n"
452 "@t{(symbol->string 'flying-fish) \n"
453 " ==> \"flying-fish\"\n"
454 "(symbol->string 'Martin) ==> \"martin\"\n"
456 " (string->symbol \"Malvina\")) \n"
460 #define FUNC_NAME s_scm_symbol_to_string
462 SCM_VALIDATE_SYMBOL (1,s
);
463 return scm_makfromstr(SCM_CHARS(s
), (scm_sizet
)SCM_LENGTH(s
), 0);
468 SCM_DEFINE (scm_string_to_symbol
, "string->symbol", 1, 0, 0,
470 "Returns the symbol whose name is @var{string}. This procedure can\n"
471 "create symbols with names containing special characters or letters in\n"
472 "the non-standard case, but it is usually a bad idea to create such\n"
473 "symbols because in some implementations of Scheme they cannot be read as\n"
474 "themselves. See @samp{symbol->string}.\n\n"
475 "The following examples assume that the implementation's standard case is\n"
478 "@t{(eq? 'mISSISSIppi 'mississippi) \n"
480 "(string->symbol \"mISSISSIppi\") \n"
482 " @r{}the symbol with name \"mISSISSIppi\"\n"
483 "(eq? 'bitBlt (string->symbol \"bitBlt\")) \n"
487 " (symbol->string 'JollyWog))) \n"
489 "(string=? \"K. Harper, M.D.\"\n"
491 " (string->symbol \"K. Harper, M.D.\"))) \n"
495 #define FUNC_NAME s_scm_string_to_symbol
500 SCM_VALIDATE_ROSTRING (1,s
);
501 vcell
= scm_intern(SCM_ROCHARS(s
), (scm_sizet
)SCM_LENGTH(s
));
502 answer
= SCM_CAR (vcell
);
508 SCM_DEFINE (scm_string_to_obarray_symbol
, "string->obarray-symbol", 2, 1, 0,
509 (SCM o
, SCM s
, SCM softp
),
510 "Intern a new symbol in @var{obarray}, a symbol table, with name\n"
512 "If @var{obarray} is @code{#f}, use the default system symbol table. If\n"
513 "@var{obarray} is @code{#t}, the symbol should not be interned in any\n"
514 "symbol table; merely return the pair (@var{symbol}\n"
515 ". @var{#<undefined>}).\n\n"
516 "The @var{soft?} argument determines whether new symbol table entries\n"
517 "should be created when the specified symbol is not already present in\n"
518 "@var{obarray}. If @var{soft?} is specified and is a true value, then\n"
519 "new entries should not be added for symbols not already present in the\n"
520 "table; instead, simply return @code{#f}.")
521 #define FUNC_NAME s_scm_string_to_obarray_symbol
527 SCM_VALIDATE_ROSTRING (2,s
);
528 SCM_ASSERT (SCM_BOOLP (o
) || SCM_VECTORP (o
), o
, SCM_ARG1
, FUNC_NAME
);
530 softness
= (!SCM_UNBNDP (softp
) && !SCM_FALSEP(softp
));
531 /* iron out some screwy calling conventions */
534 else if (SCM_EQ_P (o
, SCM_BOOL_T
))
537 vcell
= scm_intern_obarray_soft (SCM_ROCHARS(s
),
538 (scm_sizet
)SCM_ROLENGTH(s
),
541 if (SCM_FALSEP (vcell
))
543 answer
= SCM_CAR (vcell
);
548 SCM_DEFINE (scm_intern_symbol
, "intern-symbol", 2, 0, 0,
550 "Add a new symbol to @var{obarray} with name @var{string}, bound to an\n"
551 "unspecified initial value. The symbol table is not modified if a symbol\n"
552 "with this name is already present.")
553 #define FUNC_NAME s_scm_intern_symbol
556 SCM_VALIDATE_SYMBOL (2,s
);
559 SCM_VALIDATE_VECTOR (1,o
);
560 hval
= scm_strhash (SCM_UCHARS (s
), SCM_LENGTH (s
), SCM_LENGTH(o
));
561 /* If the symbol is already interned, simply return. */
566 for (lsym
= SCM_VELTS (o
)[hval
];
568 lsym
= SCM_CDR (lsym
))
570 sym
= SCM_CAR (lsym
);
571 if (SCM_EQ_P (SCM_CAR (sym
), s
))
574 return SCM_UNSPECIFIED
;
577 SCM_VELTS (o
)[hval
] =
578 scm_acons (s
, SCM_UNDEFINED
, SCM_VELTS (o
)[hval
]);
581 return SCM_UNSPECIFIED
;
585 SCM_DEFINE (scm_unintern_symbol
, "unintern-symbol", 2, 0, 0,
587 "Remove the symbol with name @var{string} from @var{obarray}. This\n"
588 "function returns @code{#t} if the symbol was present and @code{#f}\n"
590 #define FUNC_NAME s_scm_unintern_symbol
593 SCM_VALIDATE_SYMBOL (2,s
);
596 SCM_VALIDATE_VECTOR (1,o
);
597 hval
= scm_strhash (SCM_UCHARS (s
), SCM_LENGTH (s
), SCM_LENGTH(o
));
603 for (lsym
= SCM_VELTS (o
)[hval
], lsym_follow
= SCM_BOOL_F
;
605 lsym_follow
= lsym
, lsym
= SCM_CDR (lsym
))
607 sym
= SCM_CAR (lsym
);
608 if (SCM_EQ_P (SCM_CAR (sym
), s
))
610 /* Found the symbol to unintern. */
611 if (SCM_FALSEP (lsym_follow
))
612 SCM_VELTS(o
)[hval
] = lsym
;
614 SCM_SETCDR (lsym_follow
, SCM_CDR(lsym
));
625 SCM_DEFINE (scm_symbol_binding
, "symbol-binding", 2, 0, 0,
627 "Look up in @var{obarray} the symbol whose name is @var{string}, and\n"
628 "return the value to which it is bound. If @var{obarray} is @code{#f},\n"
629 "use the global symbol table. If @var{string} is not interned in\n"
630 "@var{obarray}, an error is signalled.")
631 #define FUNC_NAME s_scm_symbol_binding
634 SCM_VALIDATE_SYMBOL (2,s
);
637 SCM_VALIDATE_VECTOR (1,o
);
638 vcell
= scm_sym2ovcell (s
, o
);
639 return SCM_CDR(vcell
);
644 SCM_DEFINE (scm_symbol_interned_p
, "symbol-interned?", 2, 0, 0,
646 "Return @var{#t} if @var{obarray} contains a symbol with name\n"
647 "@var{string}, and @var{#f} otherwise.")
648 #define FUNC_NAME s_scm_symbol_interned_p
651 SCM_VALIDATE_SYMBOL (2,s
);
654 SCM_VALIDATE_VECTOR (1,o
);
655 vcell
= scm_sym2ovcell_soft (s
, o
);
656 if (SCM_IMP (vcell
) && SCM_EQ_P (o
, scm_symhash
))
657 vcell
= scm_sym2ovcell_soft (s
, scm_weak_symhash
);
658 return (SCM_NIMP(vcell
)
665 SCM_DEFINE (scm_symbol_bound_p
, "symbol-bound?", 2, 0, 0,
667 "Return @var{#t} if @var{obarray} contains a symbol with name\n"
668 "@var{string} bound to a defined value. This differs from\n"
669 "@var{symbol-bound?} in that the mere mention of a symbol usually causes\n"
670 "it to be interned; @code{symbol-bound?} determines whether a symbol has\n"
671 "been given any meaningful value.")
672 #define FUNC_NAME s_scm_symbol_bound_p
675 SCM_VALIDATE_SYMBOL (2,s
);
678 SCM_VALIDATE_VECTOR (1,o
);
679 vcell
= scm_sym2ovcell_soft (s
, o
);
680 return SCM_BOOL (SCM_NIMP (vcell
) && !SCM_UNBNDP (SCM_CDR (vcell
)));
685 SCM_DEFINE (scm_symbol_set_x
, "symbol-set!", 3, 0, 0,
686 (SCM o
, SCM s
, SCM v
),
687 "Find the symbol in @var{obarray} whose name is @var{string}, and rebind\n"
688 "it to @var{value}. An error is signalled if @var{string} is not present\n"
690 #define FUNC_NAME s_scm_symbol_set_x
693 SCM_VALIDATE_SYMBOL (2,s
);
696 SCM_VALIDATE_VECTOR (1,o
);
697 vcell
= scm_sym2ovcell (s
, o
);
698 SCM_SETCDR (vcell
, v
);
699 return SCM_UNSPECIFIED
;
707 string
= scm_makfromstr (SCM_CHARS (s
), SCM_LENGTH (s
), SCM_SYMBOL_SLOTS
);
708 SCM_SETCHARS (s
, SCM_CHARS (string
));
709 SCM_SETLENGTH (s
, SCM_LENGTH (s
), scm_tc7_msymbol
);
710 SCM_SETCDR (string
, SCM_EOL
);
711 SCM_SETCAR (string
, SCM_EOL
);
712 SCM_SET_SYMBOL_PROPS (s
, SCM_EOL
);
713 /* If it's a tc7_ssymbol, it comes from scm_symhash */
714 SCM_SYMBOL_HASH (s
) = scm_strhash (SCM_UCHARS (s
),
715 (scm_sizet
) SCM_LENGTH (s
),
716 SCM_LENGTH (scm_symhash
));
720 SCM_DEFINE (scm_symbol_fref
, "symbol-fref", 1, 0, 0,
722 "Return the contents of @var{symbol}'s @dfn{function slot}.")
723 #define FUNC_NAME s_scm_symbol_fref
725 SCM_VALIDATE_SYMBOL (1,s
);
727 if (SCM_TYP7(s
) == scm_tc7_ssymbol
)
730 return SCM_SYMBOL_FUNC (s
);
735 SCM_DEFINE (scm_symbol_pref
, "symbol-pref", 1, 0, 0,
737 "Return the @dfn{property list} currently associated with @var{symbol}.")
738 #define FUNC_NAME s_scm_symbol_pref
740 SCM_VALIDATE_SYMBOL (1,s
);
742 if (SCM_TYP7(s
) == scm_tc7_ssymbol
)
745 return SCM_SYMBOL_PROPS (s
);
750 SCM_DEFINE (scm_symbol_fset_x
, "symbol-fset!", 2, 0, 0,
752 "Change the binding of @var{symbol}'s function slot.")
753 #define FUNC_NAME s_scm_symbol_fset_x
755 SCM_VALIDATE_SYMBOL (1,s
);
757 if (SCM_TYP7(s
) == scm_tc7_ssymbol
)
760 SCM_SET_SYMBOL_FUNC (s
, val
);
761 return SCM_UNSPECIFIED
;
766 SCM_DEFINE (scm_symbol_pset_x
, "symbol-pset!", 2, 0, 0,
768 "Change the binding of @var{symbol}'s property slot.")
769 #define FUNC_NAME s_scm_symbol_pset_x
771 SCM_VALIDATE_SYMBOL (1,s
);
773 if (SCM_TYP7(s
) == scm_tc7_ssymbol
)
775 SCM_SET_SYMBOL_PROPS (s
, val
);
777 return SCM_UNSPECIFIED
;
782 SCM_DEFINE (scm_symbol_hash
, "symbol-hash", 1, 0, 0,
784 "Return the hash value derived from @var{symbol}'s name, i.e. the integer\n"
785 "index into @var{symbol}'s obarray at which it is stored.")
786 #define FUNC_NAME s_scm_symbol_hash
788 SCM_VALIDATE_SYMBOL (1,s
);
789 if (SCM_TYP7(s
) == scm_tc7_ssymbol
)
791 return SCM_MAKINUM (SCM_UNPACK (s
) ^ SCM_SYMBOL_HASH (s
));
797 copy_and_prune_obarray (SCM from
, SCM to
)
800 int length
= SCM_LENGTH (from
);
801 for (i
= 0; i
< length
; ++i
)
803 SCM head
= SCM_VELTS (from
)[i
]; /* GC protection */
807 while (SCM_NIMP (ls
))
809 if (!SCM_UNBNDP (SCM_CDAR (ls
)))
811 *lloc
= scm_cons (SCM_CAR (ls
), SCM_EOL
);
812 lloc
= SCM_CDRLOC (*lloc
);
816 SCM_VELTS (to
)[i
] = res
;
821 SCM_DEFINE (scm_builtin_bindings
, "builtin-bindings", 0, 0, 0,
823 "Create and return a copy of the global symbol table, removing all\n"
825 #define FUNC_NAME s_scm_builtin_bindings
827 int length
= SCM_LENGTH (scm_symhash
);
828 SCM obarray
= scm_make_vector (SCM_MAKINUM (length
), SCM_EOL
);
829 copy_and_prune_obarray (scm_symhash
, obarray
);
835 SCM_DEFINE (scm_builtin_weak_bindings
, "builtin-weak-bindings", 0, 0, 0,
838 #define FUNC_NAME s_scm_builtin_weak_bindings
840 int length
= SCM_LENGTH (scm_weak_symhash
);
841 SCM obarray
= scm_make_doubly_weak_hash_table (SCM_MAKINUM (length
));
842 copy_and_prune_obarray (scm_weak_symhash
, obarray
);
847 static int gensym_counter
;
848 static SCM gensym_prefix
;
850 /* :FIXME:OPTIMIZE */
851 SCM_DEFINE (scm_gensym
, "gensym", 0, 2, 0,
852 (SCM name
, SCM obarray
),
853 "Create a new, unique symbol in @var{obarray}, using the global symbol\n"
854 "table by default. If @var{name} is specified, it should be used as a\n"
855 "prefix for the new symbol's name. The default prefix is @code{%%gensym}.")
856 #define FUNC_NAME s_scm_gensym
859 if (SCM_UNBNDP (name
))
860 name
= gensym_prefix
;
863 SCM_VALIDATE_SYMBOL (1, name
);
864 name
= scm_symbol_to_string (name
);
868 if (SCM_UNBNDP (obarray
))
870 obarray
= SCM_BOOL_F
;
874 SCM_ASSERT ((SCM_VECTORP (obarray
) || SCM_WVECTP (obarray
)),
878 while (!SCM_FALSEP (scm_string_to_obarray_symbol (obarray
, new, SCM_BOOL_T
)))
880 new = scm_string_append
882 scm_number_to_string (SCM_MAKINUM (gensym_counter
++),
885 return scm_string_to_obarray_symbol (obarray
, new, SCM_BOOL_F
);
893 gensym_prefix
= scm_permanent_object (scm_makfrom0str ("%%gensym"));
894 #include "libguile/symbols.x"