1
/*===========================================================================
3
* About : Scheme Symbol handling
5
* Copyright (C) 2005 Kazuki Ohta <mover AT hct.zaq.ne.jp>
6
* Copyright (C) 2005 Jun Inoue <jun.lambda AT gmail.com>
7
* Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
8
* Copyright (c) 2007-2008 SigScheme Project <uim-en AT googlegroups.com>
10
* All rights reserved.
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
16
* 1. Redistributions of source code must retain the above copyright
17
* notice, this list of conditions and the following disclaimer.
18
* 2. Redistributions in binary form must reproduce the above copyright
19
* notice, this list of conditions and the following disclaimer in the
20
* documentation and/or other materials provided with the distribution.
21
* 3. Neither the name of authors nor the names of its contributors
22
* may be used to endorse or promote products derived from this software
23
* without specific prior written permission.
25
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
26
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
29
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
===========================================================================*/
43
#include "sigscheme.h"
44
#include "sigschemeinternal.h"
46
/*=======================================
47
File Local Macro Definitions
48
=======================================*/
50
/*=======================================
51
File Local Type Definitions
52
=======================================*/
54
/*=======================================
56
=======================================*/
57
SCM_DEFINE_EXPORTED_VARS(symbol);
59
/*=======================================
60
File Local Function Declarations
61
=======================================*/
62
static void initialize_symbol_hash(const ScmStorageConf *conf);
63
static void finalize_symbol_hash(void);
64
static uint32_t symbol_name_hash(const char *name);
66
/*=======================================
68
=======================================*/
70
scm_intern(const char *name)
72
ScmObj sym, lst, rest;
75
DECLARE_INTERNAL_FUNCTION("scm_intern");
77
#if (SCM_USE_R6RS_CHARS && SCM_STRICT_ARGCHECK)
79
/* FIXME: detect error correctly */
80
if (scm_mb_bare_c_strlen(scm_identifier_codec, name) <= 0)
81
ERR("invalid string for identifier: ~S", name);
85
hash = symbol_name_hash(name);
86
lst = scm_symbol_hash[hash];
89
FOR_EACH (sym, rest) {
90
if (strcmp(SCM_SYMBOL_NAME(sym), name) == 0)
94
/* if not found, allocate new symbol object and prepend it into the list */
95
copied = scm_strdup(name);
96
sym = MAKE_SYMBOL(copied, SCM_UNBOUND);
97
scm_symbol_hash[hash] = CONS(sym, lst);
102
/* lookup the symbol bound to an obj reversely */
104
scm_symbol_bound_to(ScmObj obj)
106
ScmObj lst, sym, val;
108
DECLARE_INTERNAL_FUNCTION("scm_symbol_bound_to");
110
for (i = 0; i < scm_symbol_hash_size; i++) {
111
lst = scm_symbol_hash[i];
112
FOR_EACH (sym, lst) {
113
val = SCM_SYMBOL_VCELL(sym);
114
if (!EQ(val, SCM_UNBOUND) && EQ(val, obj))
123
scm_init_symbol(const ScmStorageConf *conf)
125
SCM_GLOBAL_VARS_INIT(symbol);
127
initialize_symbol_hash(conf);
133
finalize_symbol_hash();
135
SCM_GLOBAL_VARS_FIN(symbol);
138
/*===========================================================================
140
===========================================================================*/
142
initialize_symbol_hash(const ScmStorageConf *conf)
146
scm_symbol_hash_size = conf->symbol_hash_size;
147
SCM_ASSERT(scm_symbol_hash_size <= (UINT32_MAX / sizeof(ScmObj)));
148
scm_symbol_hash = scm_malloc(sizeof(ScmObj) * scm_symbol_hash_size);
150
for (i = 0; i < scm_symbol_hash_size; i++)
151
scm_symbol_hash[i] = SCM_NULL;
155
finalize_symbol_hash(void)
157
free(scm_symbol_hash);
161
symbol_name_hash(const char *name)
165
for (hash = 0; (c = *(const scm_byte_t *)name); name++)
166
hash = ((hash * 17) ^ c) % scm_symbol_hash_size;