mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
patches by Ludovic Courtès for symbol generation.
This commit is contained in:
parent
2ca2ffe6b2
commit
fd0a5bbcb7
7 changed files with 186 additions and 33 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
|
||||||
|
2005-12-19 Ludovic Courtès <ludovic.courtes@laas.fr>
|
||||||
|
|
||||||
|
* api-data.texi (Operations Related to Symbols):
|
||||||
|
Documented `scm_take_locale_symbol ()'.
|
||||||
|
|
||||||
|
|
||||||
2005-12-15 Kevin Ryde <user42@zip.com.au>
|
2005-12-15 Kevin Ryde <user42@zip.com.au>
|
||||||
|
|
||||||
* api-evaluation.texi (Fly Evaluation): Add scm_call_4, suggested by
|
* api-evaluation.texi (Fly Evaluation): Add scm_call_4, suggested by
|
||||||
|
|
|
@ -4551,6 +4551,16 @@ terminated; for @code{scm_from_locale_symboln} the length of @var{name} is
|
||||||
specified explicitly by @var{len}.
|
specified explicitly by @var{len}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deftypefn {C Function} SCM scm_take_locale_symbol (char *str)
|
||||||
|
@deftypefnx {C Function} SCM scm_take_locale_symboln (char *str, size_t len)
|
||||||
|
Like @code{scm_from_locale_symbol} and @code{scm_from_locale_symboln},
|
||||||
|
respectively, but also frees @var{str} with @code{free} eventually.
|
||||||
|
Thus, you can use this function when you would free @var{str} anyway
|
||||||
|
immediately after creating the Scheme string. In certain cases, Guile
|
||||||
|
can then use @var{str} directly as its internal representation.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
Finally, some applications, especially those that generate new Scheme
|
Finally, some applications, especially those that generate new Scheme
|
||||||
code dynamically, need to generate symbols for use in the generated
|
code dynamically, need to generate symbols for use in the generated
|
||||||
code. The @code{gensym} primitive meets this need:
|
code. The @code{gensym} primitive meets this need:
|
||||||
|
|
|
@ -1,3 +1,24 @@
|
||||||
|
2005-12-19 Ludovic Courtès <ludovic.courtes@laas.fr>
|
||||||
|
|
||||||
|
* strings.c (scm_i_take_stringbufn): New.
|
||||||
|
(scm_i_c_take_symbol): New.
|
||||||
|
(scm_take_locale_stringn): Use `scm_i_take_stringbufn ()'.
|
||||||
|
|
||||||
|
* strings.h (scm_i_c_take_symbol): New.
|
||||||
|
(scm_i_take_stringbufn): New.
|
||||||
|
|
||||||
|
* symbols.c (lookup_interned_symbol): New function.
|
||||||
|
(scm_i_c_mem2symbol): New function.
|
||||||
|
(scm_i_mem2symbol): Use `lookup_symbol ()'.
|
||||||
|
(scm_from_locale_symbol): Use `scm_i_c_mem2symbol ()'. This avoids
|
||||||
|
creating a new Scheme string.
|
||||||
|
(scm_from_locale_symboln): Likewise.
|
||||||
|
(scm_take_locale_symbol): New.
|
||||||
|
(scm_take_locale_symboln): New.
|
||||||
|
|
||||||
|
* symbols.h (scm_take_locale_symbol): New.
|
||||||
|
(scm_take_locale_symboln): New.
|
||||||
|
|
||||||
2006-01-18 Han-Wen Nienhuys <hanwen@xs4all.nl>
|
2006-01-18 Han-Wen Nienhuys <hanwen@xs4all.nl>
|
||||||
|
|
||||||
* gc-card.c ("sweep_card"): don't count scm_tc_free_cell for
|
* gc-card.c ("sweep_card"): don't count scm_tc_free_cell for
|
||||||
|
|
|
@ -122,6 +122,17 @@ make_stringbuf (size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a new stringbuf whose underlying storage consists of the LEN octets
|
||||||
|
pointed to by STR. */
|
||||||
|
SCM_C_INLINE SCM
|
||||||
|
scm_i_take_stringbufn (char *str, size_t len)
|
||||||
|
{
|
||||||
|
scm_gc_register_collectable_memory (str, len, "stringbuf");
|
||||||
|
|
||||||
|
return scm_double_cell (STRINGBUF_TAG, (scm_t_bits) str,
|
||||||
|
(scm_t_bits) len, (scm_t_bits) 0);
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_i_stringbuf_mark (SCM buf)
|
scm_i_stringbuf_mark (SCM buf)
|
||||||
{
|
{
|
||||||
|
@ -412,6 +423,29 @@ scm_i_make_symbol (SCM name, scm_t_bits flags,
|
||||||
(scm_t_bits) hash, SCM_UNPACK (props));
|
(scm_t_bits) hash, SCM_UNPACK (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCM
|
||||||
|
scm_i_c_make_symbol (const char *name, size_t len,
|
||||||
|
scm_t_bits flags, unsigned long hash, SCM props)
|
||||||
|
{
|
||||||
|
SCM buf = make_stringbuf (len);
|
||||||
|
memcpy (STRINGBUF_CHARS (buf), name, len);
|
||||||
|
|
||||||
|
return scm_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf),
|
||||||
|
(scm_t_bits) hash, SCM_UNPACK (props));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a new symbol that uses the LEN bytes pointed to by NAME as its
|
||||||
|
underlying storage. */
|
||||||
|
SCM
|
||||||
|
scm_i_c_take_symbol (char *name, size_t len,
|
||||||
|
scm_t_bits flags, unsigned long hash, SCM props)
|
||||||
|
{
|
||||||
|
SCM buf = scm_i_take_stringbufn (name, len);
|
||||||
|
|
||||||
|
return scm_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf),
|
||||||
|
(scm_t_bits) hash, SCM_UNPACK (props));
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
scm_i_symbol_length (SCM sym)
|
scm_i_symbol_length (SCM sym)
|
||||||
{
|
{
|
||||||
|
@ -842,12 +876,10 @@ scm_take_locale_stringn (char *str, size_t len)
|
||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = scm_double_cell (STRINGBUF_TAG, (scm_t_bits) str,
|
buf = scm_i_take_stringbufn (str, len);
|
||||||
(scm_t_bits) len, (scm_t_bits) 0);
|
|
||||||
res = scm_double_cell (STRING_TAG,
|
res = scm_double_cell (STRING_TAG,
|
||||||
SCM_UNPACK (buf),
|
SCM_UNPACK (buf),
|
||||||
(scm_t_bits) 0, (scm_t_bits) len);
|
(scm_t_bits) 0, (scm_t_bits) len);
|
||||||
scm_gc_register_collectable_memory (str, len+1, "string");
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,12 @@ SCM_API void scm_i_string_stop_writing (void);
|
||||||
|
|
||||||
SCM_API SCM scm_i_make_symbol (SCM name, scm_t_bits flags,
|
SCM_API SCM scm_i_make_symbol (SCM name, scm_t_bits flags,
|
||||||
unsigned long hash, SCM props);
|
unsigned long hash, SCM props);
|
||||||
|
SCM_API SCM
|
||||||
|
scm_i_c_make_symbol (const char *name, size_t len,
|
||||||
|
scm_t_bits flags, unsigned long hash, SCM props);
|
||||||
|
SCM_API SCM
|
||||||
|
scm_i_c_take_symbol (char *name, size_t len,
|
||||||
|
scm_t_bits flags, unsigned long hash, SCM props);
|
||||||
SCM_API const char *scm_i_symbol_chars (SCM sym);
|
SCM_API const char *scm_i_symbol_chars (SCM sym);
|
||||||
SCM_API size_t scm_i_symbol_length (SCM sym);
|
SCM_API size_t scm_i_symbol_length (SCM sym);
|
||||||
SCM_API SCM scm_i_symbol_substring (SCM sym, size_t start, size_t end);
|
SCM_API SCM scm_i_symbol_substring (SCM sym, size_t start, size_t end);
|
||||||
|
@ -144,6 +150,7 @@ SCM_API void scm_i_free_string_pointers (char **pointers);
|
||||||
SCM_API void scm_i_get_substring_spec (size_t len,
|
SCM_API void scm_i_get_substring_spec (size_t len,
|
||||||
SCM start, size_t *cstart,
|
SCM start, size_t *cstart,
|
||||||
SCM end, size_t *cend);
|
SCM end, size_t *cend);
|
||||||
|
SCM_API SCM scm_i_take_stringbufn (char *str, size_t len);
|
||||||
|
|
||||||
/* deprecated stuff */
|
/* deprecated stuff */
|
||||||
|
|
||||||
|
|
|
@ -85,18 +85,12 @@ scm_i_hash_symbol (SCM obj, unsigned long n, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
scm_i_mem2symbol (SCM str)
|
lookup_interned_symbol (const char *name, size_t len,
|
||||||
{
|
unsigned long raw_hash)
|
||||||
const char *name = scm_i_string_chars (str);
|
|
||||||
size_t len = scm_i_string_length (str);
|
|
||||||
|
|
||||||
size_t raw_hash = scm_string_hash ((const unsigned char *) name, len);
|
|
||||||
size_t hash = raw_hash % SCM_HASHTABLE_N_BUCKETS (symbols);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Try to find the symbol in the symbols table */
|
/* Try to find the symbol in the symbols table */
|
||||||
|
|
||||||
SCM l;
|
SCM l;
|
||||||
|
unsigned long hash = raw_hash % SCM_HASHTABLE_N_BUCKETS (symbols);
|
||||||
|
|
||||||
for (l = SCM_HASHTABLE_BUCKET (symbols, hash);
|
for (l = SCM_HASHTABLE_BUCKET (symbols, hash);
|
||||||
!scm_is_null (l);
|
!scm_is_null (l);
|
||||||
|
@ -121,8 +115,50 @@ scm_i_mem2symbol (SCM str)
|
||||||
next_symbol:
|
next_symbol:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SCM_BOOL_F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
scm_i_c_mem2symbol (const char *name, size_t len)
|
||||||
|
{
|
||||||
|
SCM symbol;
|
||||||
|
size_t raw_hash = scm_string_hash ((const unsigned char *) name, len);
|
||||||
|
size_t hash = raw_hash % SCM_HASHTABLE_N_BUCKETS (symbols);
|
||||||
|
|
||||||
|
symbol = lookup_interned_symbol (name, len, raw_hash);
|
||||||
|
if (symbol != SCM_BOOL_F)
|
||||||
|
return symbol;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* The symbol was not found - create it. */
|
||||||
|
SCM symbol = scm_i_c_make_symbol (name, len, 0, raw_hash,
|
||||||
|
scm_cons (SCM_BOOL_F, SCM_EOL));
|
||||||
|
|
||||||
|
SCM slot = SCM_HASHTABLE_BUCKET (symbols, hash);
|
||||||
|
SCM cell = scm_cons (symbol, SCM_UNDEFINED);
|
||||||
|
SCM_SET_HASHTABLE_BUCKET (symbols, hash, scm_cons (cell, slot));
|
||||||
|
SCM_HASHTABLE_INCREMENT (symbols);
|
||||||
|
if (SCM_HASHTABLE_N_ITEMS (symbols) > SCM_HASHTABLE_UPPER (symbols))
|
||||||
|
scm_i_rehash (symbols, scm_i_hash_symbol, 0, "scm_mem2symbol");
|
||||||
|
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
scm_i_mem2symbol (SCM str)
|
||||||
|
{
|
||||||
|
SCM symbol;
|
||||||
|
const char *name = scm_i_string_chars (str);
|
||||||
|
size_t len = scm_i_string_length (str);
|
||||||
|
size_t raw_hash = scm_string_hash ((const unsigned char *) name, len);
|
||||||
|
size_t hash = raw_hash % SCM_HASHTABLE_N_BUCKETS (symbols);
|
||||||
|
|
||||||
|
symbol = lookup_interned_symbol (name, len, raw_hash);
|
||||||
|
if (symbol != SCM_BOOL_F)
|
||||||
|
return symbol;
|
||||||
|
|
||||||
{
|
{
|
||||||
/* The symbol was not found - create it. */
|
/* The symbol was not found - create it. */
|
||||||
SCM symbol = scm_i_make_symbol (str, 0, raw_hash,
|
SCM symbol = scm_i_make_symbol (str, 0, raw_hash,
|
||||||
|
@ -139,6 +175,7 @@ scm_i_mem2symbol (SCM str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
scm_i_mem2uninterned_symbol (SCM str)
|
scm_i_mem2uninterned_symbol (SCM str)
|
||||||
{
|
{
|
||||||
|
@ -348,13 +385,50 @@ SCM_DEFINE (scm_symbol_pset_x, "symbol-pset!", 2, 0, 0,
|
||||||
SCM
|
SCM
|
||||||
scm_from_locale_symbol (const char *sym)
|
scm_from_locale_symbol (const char *sym)
|
||||||
{
|
{
|
||||||
return scm_string_to_symbol (scm_from_locale_string (sym));
|
return scm_i_c_mem2symbol (sym, strlen (sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_from_locale_symboln (const char *sym, size_t len)
|
scm_from_locale_symboln (const char *sym, size_t len)
|
||||||
{
|
{
|
||||||
return scm_string_to_symbol (scm_from_locale_stringn (sym, len));
|
return scm_i_c_mem2symbol (sym, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCM
|
||||||
|
scm_take_locale_symboln (char *sym, size_t len)
|
||||||
|
{
|
||||||
|
SCM res;
|
||||||
|
unsigned long raw_hash;
|
||||||
|
|
||||||
|
if (len == (size_t)-1)
|
||||||
|
len = strlen (sym);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ensure STR is null terminated. A realloc for 1 extra byte should
|
||||||
|
often be satisfied from the alignment padding after the block, with
|
||||||
|
no actual data movement. */
|
||||||
|
sym = scm_realloc (sym, len+1);
|
||||||
|
sym[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_hash = scm_string_hash ((unsigned char *)sym, len);
|
||||||
|
res = lookup_interned_symbol (sym, len, raw_hash);
|
||||||
|
if (res != SCM_BOOL_F)
|
||||||
|
{
|
||||||
|
free (sym);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = scm_i_c_take_symbol (sym, len, 0, raw_hash,
|
||||||
|
scm_cons (SCM_BOOL_F, SCM_EOL));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SCM
|
||||||
|
scm_take_locale_symbol (char *sym)
|
||||||
|
{
|
||||||
|
return scm_take_locale_symboln (sym, (size_t)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -56,6 +56,8 @@ SCM_API SCM scm_gensym (SCM prefix);
|
||||||
|
|
||||||
SCM_API SCM scm_from_locale_symbol (const char *str);
|
SCM_API SCM scm_from_locale_symbol (const char *str);
|
||||||
SCM_API SCM scm_from_locale_symboln (const char *str, size_t len);
|
SCM_API SCM scm_from_locale_symboln (const char *str, size_t len);
|
||||||
|
SCM_API SCM scm_take_locale_symbol (char *sym);
|
||||||
|
SCM_API SCM scm_take_locale_symboln (char *sym, size_t len);
|
||||||
|
|
||||||
/* internal functions. */
|
/* internal functions. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue