summaryrefslogtreecommitdiff
path: root/libguile/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/hash.c')
-rw-r--r--libguile/hash.c97
1 files changed, 49 insertions, 48 deletions
diff --git a/libguile/hash.c b/libguile/hash.c
index d6e93dae0..c590dc56d 100644
--- a/libguile/hash.c
+++ b/libguile/hash.c
@@ -284,62 +284,63 @@ scm_raw_ihashq (scm_t_bits key)
static unsigned long
scm_raw_ihash (SCM obj, size_t depth)
{
- if (SCM_IMP (obj))
- return scm_raw_ihashq (SCM_UNPACK (obj));
-
- switch (SCM_TYP7(obj))
- {
- /* FIXME: do better for structs, variables, ... Also the hashes
- are currently associative, which ain't the right thing. */
- case scm_tc7_smob:
- return scm_raw_ihashq (SCM_TYP16 (obj));
- case scm_tc7_number:
- if (scm_is_integer (obj))
+ if (SCM_THOB_P (obj))
+ switch (SCM_TYP7(obj))
+ {
+ /* FIXME: do better for structs, variables, ... Also the hashes
+ are currently associative, which ain't the right thing. */
+ case scm_tc7_smob:
+ return scm_raw_ihashq (SCM_TYP16 (obj));
+ case scm_tc7_number:
+ if (scm_is_integer (obj))
+ {
+ SCM n = SCM_I_MAKINUM (SCM_MOST_POSITIVE_FIXNUM);
+ if (scm_is_inexact (obj))
+ obj = scm_inexact_to_exact (obj);
+ return scm_raw_ihashq (scm_to_ulong (scm_modulo (obj, n)));
+ }
+ else
+ return scm_i_string_hash (scm_number_to_string (obj, scm_from_int (10)));
+ case scm_tc7_string:
+ return scm_i_string_hash (obj);
+ case scm_tc7_symbol:
+ return scm_i_symbol_hash (obj);
+ case scm_tc7_pointer:
+ return scm_raw_ihashq ((uintptr_t) SCM_POINTER_VALUE (obj));
+ case scm_tc7_wvect:
+ case scm_tc7_vector:
{
- SCM n = SCM_I_MAKINUM (SCM_MOST_POSITIVE_FIXNUM);
- if (scm_is_inexact (obj))
- obj = scm_inexact_to_exact (obj);
- return scm_raw_ihashq (scm_to_ulong (scm_modulo (obj, n)));
+ size_t len = SCM_SIMPLE_VECTOR_LENGTH (obj);
+ size_t i = depth / 2;
+ unsigned long h = scm_raw_ihashq (SCM_CELL_WORD_0 (obj));
+ if (len)
+ while (i--)
+ h ^= scm_raw_ihash (scm_c_vector_ref (obj, h % len), i);
+ return h;
}
- else
- return scm_i_string_hash (scm_number_to_string (obj, scm_from_int (10)));
- case scm_tc7_string:
- return scm_i_string_hash (obj);
- case scm_tc7_symbol:
- return scm_i_symbol_hash (obj);
- case scm_tc7_pointer:
- return scm_raw_ihashq ((uintptr_t) SCM_POINTER_VALUE (obj));
- case scm_tc7_wvect:
- case scm_tc7_vector:
- {
- size_t len = SCM_SIMPLE_VECTOR_LENGTH (obj);
- size_t i = depth / 2;
- unsigned long h = scm_raw_ihashq (SCM_CELL_WORD_0 (obj));
- if (len)
- while (i--)
- h ^= scm_raw_ihash (scm_c_vector_ref (obj, h % len), i);
- return h;
- }
- case scm_tc7_syntax:
- {
- unsigned long h;
- h = scm_raw_ihash (scm_syntax_expression (obj), depth);
- h ^= scm_raw_ihash (scm_syntax_wrap (obj), depth);
- h ^= scm_raw_ihash (scm_syntax_module (obj), depth);
- return h;
+ case scm_tc7_syntax:
+ {
+ unsigned long h;
+ h = scm_raw_ihash (scm_syntax_expression (obj), depth);
+ h ^= scm_raw_ihash (scm_syntax_wrap (obj), depth);
+ h ^= scm_raw_ihash (scm_syntax_module (obj), depth);
+ return h;
+ }
+ case scm_tcs_struct:
+ return scm_i_struct_hash (obj, depth);
+ default:
+ return scm_raw_ihashq (SCM_CELL_WORD_0 (obj));
}
- case scm_tcs_cons_imcar:
- case scm_tcs_cons_nimcar:
+ else if (scm_is_pair (obj))
+ {
if (depth)
return (scm_raw_ihash (SCM_CAR (obj), depth / 2)
^ scm_raw_ihash (SCM_CDR (obj), depth / 2));
else
- return scm_raw_ihashq (scm_tc3_cons);
- case scm_tcs_struct:
- return scm_i_struct_hash (obj, depth);
- default:
- return scm_raw_ihashq (SCM_CELL_WORD_0 (obj));
+ return scm_raw_ihashq (0);
}
+ else /* immediate */
+ return scm_raw_ihashq (SCM_UNPACK (obj));
}