diff options
author | Andy Wingo <wingo@pobox.com> | 2009-12-05 10:07:07 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2009-12-05 10:07:07 +0100 |
commit | c99de5aa275b15af207c0dba9717d6b865684fc4 (patch) | |
tree | d1c78809bf4971a152fd3cd46bf77cf29a2f5621 | |
parent | 314b87163eac1358923cb84e7f2c87d06aa03756 (diff) |
hash tables have a tc7
* libguile/tags.h (scm_tc7_hashtable): Allocate a tc7 for hashtables.
* libguile/hashtab.h: Adjust macros accordingly.
(scm_i_hashtable_print, scm_i_hashtable_equal_p): New internal
functions.
(scm_hashtab_prehistory): Remove, no more need for this.
* libguile/hashtab.c (scm_hash_fn_remove_x): Fix a longstanding bug.
(make_hash_table): Adapt to the new hash table representation.
* libguile/eq.c (scm_equal_p)
* libguile/evalext.c (scm_self_evaluating_p)
* libguile/print.c (iprin1)
* libguile/gc.c (scm_i_tag_name): Add some tc7_hashtab cases.
* libguile/init.c: Remove unused environments init functions. Remove
call to hashtab_prehistory.
* libguile/goops.h (scm_class_hashtable)
* libguile/goops.c (scm_class_of, create_standard_classes): Have to
make a class for hash tables manually, because they aren't smobs any
more.
-rw-r--r-- | libguile/eq.c | 4 | ||||
-rw-r--r-- | libguile/evalext.c | 1 | ||||
-rw-r--r-- | libguile/gc.c | 2 | ||||
-rw-r--r-- | libguile/goops.c | 6 | ||||
-rw-r--r-- | libguile/goops.h | 4 | ||||
-rw-r--r-- | libguile/hashtab.c | 36 | ||||
-rw-r--r-- | libguile/hashtab.h | 13 | ||||
-rw-r--r-- | libguile/init.c | 11 | ||||
-rw-r--r-- | libguile/print.c | 3 | ||||
-rw-r--r-- | libguile/tags.h | 2 |
10 files changed, 39 insertions, 43 deletions
diff --git a/libguile/eq.c b/libguile/eq.c index 422f1a53d..9aa86a509 100644 --- a/libguile/eq.c +++ b/libguile/eq.c @@ -30,6 +30,7 @@ #include "libguile/smob.h" #include "libguile/arrays.h" #include "libguile/vectors.h" +#include "libguile/hashtab.h" #include "libguile/bytevectors.h" #include "libguile/struct.h" @@ -342,6 +343,9 @@ scm_equal_p (SCM x, SCM y) case scm_tc7_vector: case scm_tc7_wvect: return scm_i_vector_equal_p (x, y); + + case scm_tc7_hashtable: + return scm_i_hashtable_equal_p (x, y); } /* Check equality between structs of equal type (see cell-type test above). */ if (SCM_STRUCTP (x)) diff --git a/libguile/evalext.c b/libguile/evalext.c index 27dd98506..5a0c0e936 100644 --- a/libguile/evalext.c +++ b/libguile/evalext.c @@ -77,6 +77,7 @@ SCM_DEFINE (scm_self_evaluating_p, "self-evaluating?", 1, 0, 0, { case scm_tc7_vector: case scm_tc7_wvect: + case scm_tc7_hashtable: case scm_tc7_number: case scm_tc7_string: case scm_tc7_smob: diff --git a/libguile/gc.c b/libguile/gc.c index 6a702507c..4bedb0531 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -756,6 +756,8 @@ scm_i_tag_name (scm_t_bits tag) return "cons (non-immediate car)"; case scm_tc7_pws: return "pws"; + case scm_tc7_hashtable: + return "hashtable"; case scm_tc7_wvect: return "weak vector"; case scm_tc7_vector: diff --git a/libguile/goops.c b/libguile/goops.c index f6b18ace5..d02257bbc 100644 --- a/libguile/goops.c +++ b/libguile/goops.c @@ -133,7 +133,7 @@ static scm_t_rstate *goops_rstate; SCM scm_class_boolean, scm_class_char, scm_class_pair; SCM scm_class_procedure, scm_class_string, scm_class_symbol; SCM scm_class_procedure_with_setter, scm_class_primitive_generic; -SCM scm_class_vector, scm_class_null; +SCM scm_class_vector, scm_class_hashtable, scm_class_null; SCM scm_class_integer, scm_class_real, scm_class_complex, scm_class_fraction; SCM scm_class_unknown; SCM scm_class_top, scm_class_object, scm_class_class; @@ -210,6 +210,8 @@ SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0, case scm_tc7_vector: case scm_tc7_wvect: return scm_class_vector; + case scm_tc7_hashtable: + return scm_class_hashtable; case scm_tc7_string: return scm_class_string; case scm_tc7_number: @@ -2400,6 +2402,8 @@ create_standard_classes (void) scm_class_class, scm_class_top, SCM_EOL); make_stdcls (&scm_class_vector, "<vector>", scm_class_class, scm_class_top, SCM_EOL); + make_stdcls (&scm_class_hashtable, "<hashtable>", + scm_class_class, scm_class_top, SCM_EOL); make_stdcls (&scm_class_number, "<number>", scm_class_class, scm_class_top, SCM_EOL); make_stdcls (&scm_class_complex, "<complex>", diff --git a/libguile/goops.h b/libguile/goops.h index 914ab3c70..4c1b45bd5 100644 --- a/libguile/goops.h +++ b/libguile/goops.h @@ -179,7 +179,9 @@ SCM_API SCM scm_class_string; SCM_API SCM scm_class_symbol; SCM_API SCM scm_class_procedure_with_setter; SCM_API SCM scm_class_primitive_generic; -SCM_API SCM scm_class_vector, scm_class_null; +SCM_API SCM scm_class_vector; +SCM_API SCM scm_class_hashtable; +SCM_API SCM scm_class_null; SCM_API SCM scm_class_real; SCM_API SCM scm_class_complex; SCM_API SCM scm_class_integer; diff --git a/libguile/hashtab.c b/libguile/hashtab.c index f3b35485a..608d53466 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -50,10 +50,7 @@ * */ -/* Hash tables are either vectors of association lists or smobs - * containing such vectors. Currently, the vector version represents - * constant size tables while those wrapped in a smob represents - * resizing tables. +/* A hash table is a cell containing a vector of association lists. * * Growing or shrinking, with following rehashing, is triggered when * the load factor @@ -69,8 +66,6 @@ * hashtable_size. */ -scm_t_bits scm_tc16_hashtable; - static unsigned long hashtable_size[] = { 31, 61, 113, 223, 443, 883, 1759, 3517, 7027, 14051, 28099, 56197, 112363, 224717, 449419, 898823, 1797641, 3595271, 7190537, 14381041 @@ -230,7 +225,7 @@ weak_bucket_assoc (SCM table, SCM buckets, size_t bucket_index, static SCM make_hash_table (int flags, unsigned long k, const char *func_name) { - SCM table, vector; + SCM vector; scm_t_hashtable *t; int i = 0, n = k ? k : 31; while (i < HASHTABLE_SIZE_N && n > hashtable_size[i]) @@ -250,9 +245,9 @@ make_hash_table (int flags, unsigned long k, const char *func_name) t->flags = flags; t->hash_fn = NULL; - SCM_NEWSMOB2 (table, scm_tc16_hashtable, vector, t); - - return table; + /* FIXME: we just need two words of storage, not three */ + return scm_double_cell (scm_tc7_hashtable, SCM_UNPACK (vector), + (scm_t_bits)t, 0); } void @@ -342,8 +337,8 @@ scm_i_rehash (SCM table, } -static int -hashtable_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED) +void +scm_i_hashtable_print (SCM exp, SCM port, scm_print_state *pstate) { scm_puts ("#<", port); if (SCM_HASHTABLE_WEAK_KEY_P (exp)) @@ -358,7 +353,12 @@ hashtable_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED) scm_uintprint (SCM_SIMPLE_VECTOR_LENGTH (SCM_HASHTABLE_VECTOR (exp)), 10, port); scm_puts (">", port); - return 1; +} + +SCM +scm_i_hashtable_equal_p (SCM x, SCM y) +{ + return SCM_BOOL_F; } @@ -650,7 +650,7 @@ scm_hash_fn_remove_x (SCM table, SCM obj, SCM_ARG1, "hash_fn_remove_x"); buckets = table; } - if (SCM_SIMPLE_VECTOR_LENGTH (table) == 0) + if (SCM_SIMPLE_VECTOR_LENGTH (buckets) == 0) return SCM_EOL; k = hash_fn (obj, SCM_SIMPLE_VECTOR_LENGTH (buckets), closure); @@ -1259,14 +1259,6 @@ SCM_DEFINE (scm_hash_map_to_list, "hash-map->list", 2, 0, 0, void -scm_hashtab_prehistory () -{ - /* Initialize the hashtab SMOB type. */ - scm_tc16_hashtable = scm_make_smob_type (s_hashtable, 0); - scm_set_smob_print (scm_tc16_hashtable, hashtable_print); -} - -void scm_init_hashtab () { #include "libguile/hashtab.x" diff --git a/libguile/hashtab.h b/libguile/hashtab.h index b60cd4349..3fbcb90ef 100644 --- a/libguile/hashtab.h +++ b/libguile/hashtab.h @@ -32,14 +32,12 @@ #define SCM_HASHTABLEF_WEAK_CAR SCM_WVECTF_WEAK_KEY #define SCM_HASHTABLEF_WEAK_CDR SCM_WVECTF_WEAK_VALUE -SCM_API scm_t_bits scm_tc16_hashtable; - -#define SCM_HASHTABLE_P(x) SCM_SMOB_PREDICATE (scm_tc16_hashtable, x) +#define SCM_HASHTABLE_P(x) (!SCM_IMP (x) && SCM_TYP7(x) == scm_tc7_hashtable) #define SCM_VALIDATE_HASHTABLE(pos, arg) \ SCM_MAKE_VALIDATE_MSG (pos, arg, HASHTABLE_P, "hash-table") -#define SCM_HASHTABLE_VECTOR(h) SCM_SMOB_OBJECT (h) -#define SCM_SET_HASHTABLE_VECTOR(x, v) SCM_SET_SMOB_OBJECT ((x), (v)) -#define SCM_HASHTABLE(x) ((scm_t_hashtable *) SCM_SMOB_DATA_2 (x)) +#define SCM_HASHTABLE_VECTOR(h) SCM_CELL_OBJECT_1 (h) +#define SCM_SET_HASHTABLE_VECTOR(x, v) SCM_SET_CELL_OBJECT_1 ((x), (v)) +#define SCM_HASHTABLE(x) ((scm_t_hashtable *) SCM_CELL_WORD_2 (x)) #define SCM_HASHTABLE_FLAGS(x) (SCM_HASHTABLE (x)->flags) #define SCM_HASHTABLE_WEAK_KEY_P(x) \ (SCM_HASHTABLE_FLAGS (x) & SCM_HASHTABLEF_WEAK_CAR) @@ -158,7 +156,8 @@ SCM_API SCM scm_hash_fold (SCM proc, SCM init, SCM hash); SCM_API SCM scm_hash_for_each (SCM proc, SCM hash); SCM_API SCM scm_hash_for_each_handle (SCM proc, SCM hash); SCM_API SCM scm_hash_map_to_list (SCM proc, SCM hash); -SCM_INTERNAL void scm_hashtab_prehistory (void); +SCM_INTERNAL void scm_i_hashtable_print (SCM exp, SCM port, scm_print_state *pstate); +SCM_INTERNAL SCM scm_i_hashtable_equal_p (SCM x, SCM y); SCM_INTERNAL void scm_init_hashtab (void); #endif /* SCM_HASHTAB_H */ diff --git a/libguile/init.c b/libguile/init.c index 2180e456f..bbe88e88a 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -49,9 +49,6 @@ #include "libguile/deprecation.h" #include "libguile/dynl.h" #include "libguile/dynwind.h" -#if 0 -#include "libguile/environments.h" -#endif #include "libguile/eq.h" #include "libguile/error.h" #include "libguile/eval.h" @@ -443,8 +440,6 @@ scm_i_init_guile (SCM_STACKITEM *base) scm_smob_prehistory (); scm_fluids_prehistory (); scm_weaks_prehistory (); - scm_hashtab_prehistory (); /* requires storage_prehistory, and - weaks_prehistory */ #ifdef GUILE_DEBUG_MALLOC scm_debug_malloc_prehistory (); #endif @@ -455,9 +450,6 @@ scm_i_init_guile (SCM_STACKITEM *base) scm_struct_prehistory (); /* requires storage */ scm_symbols_prehistory (); /* requires storage */ -#if 0 - scm_environments_prehistory (); /* requires storage */ -#endif scm_modules_prehistory (); /* requires storage and hash tables */ scm_init_variable (); /* all bindings need variables */ scm_init_continuations (); @@ -466,9 +458,6 @@ scm_i_init_guile (SCM_STACKITEM *base) scm_init_gsubr (); scm_init_thread_procs (); /* requires gsubrs */ scm_init_procprop (); -#if 0 - scm_init_environments (); -#endif scm_init_alist (); scm_init_arbiters (); scm_init_async (); diff --git a/libguile/print.c b/libguile/print.c index a268a0c23..ea439a62f 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -709,6 +709,9 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) case scm_tc7_program: scm_i_program_print (exp, port, pstate); break; + case scm_tc7_hashtable: + scm_i_hashtable_print (exp, port, pstate); + break; case scm_tc7_wvect: ENTER_NESTED_DATA (pstate, exp, circref); if (SCM_IS_WHVEC (exp)) diff --git a/libguile/tags.h b/libguile/tags.h index 915f6f3ed..c22d927c0 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -417,7 +417,7 @@ typedef scm_t_uintptr scm_t_bits; #define scm_tc7_pws 31 -#define scm_tc7_unused_1 29 +#define scm_tc7_hashtable 29 #define scm_tc7_unused_2 37 #define scm_tc7_unused_3 45 #define scm_tc7_unused_4 47 |