diff options
Diffstat (limited to 'libguile/hash.c')
-rw-r--r-- | libguile/hash.c | 97 |
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)); } |