summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-03-19 02:00:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-03-19 02:00:45 -0700
commit16414f430caa17fccb2e15611a367bb9236ac0ee (patch)
treea7245ff2952647a5106406f99c0dcf243a9a9d58 /hash.c
parent9d06c8e9b36e94295c62eb0598cff7afae0c5a45 (diff)
downloadtxr-16414f430caa17fccb2e15611a367bb9236ac0ee.tar.gz
txr-16414f430caa17fccb2e15611a367bb9236ac0ee.tar.bz2
txr-16414f430caa17fccb2e15611a367bb9236ac0ee.zip
* configure (uintptr): New variable. Indicates whether unsigned
version of intptr_t is available and should be generated in config.h as uintptr_t. * eval.c (eval_init): New intrinsic functions floatp, integerp, flo-str. * gc.c (finalize): Handle FLNUM case. Rearranged cases so that all trivially returning cases are together. (mark): Handle FLNUM case. * hash.c (hash_double): New function. (equal_hash): Handle FLNUM via hash_double. (eql_hash): Likewise. * lib.c: <math.h> is included. (float_s): New symbol variable. (code2type, equal): Handle FLNUM case in switch. (integerp): New function; does the same thing as integerp before. (numberp): Returns t for floats. (flo, floatp, flo_str): New functions. (obj_init): Initialize new float_s variable. (obj_print, obj_pprint): Handle FLNUM case in switch. Printing does not work yet; needs work in stream.c. * lib.h (enum type): New enumeration FLNUM. (struct flonum): New struct type. (union obj): New member, fl. (float_s, flo, floatp, integerp, flo_str): Declared. * parser.l (FLO): New token pattern definition. Scans to a NUMBER token. Corrected uses of yylval.num to yylval.val. * parser.y (%union): Removed num member from yystype.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/hash.c b/hash.c
index c9e69261..f6c5a69c 100644
--- a/hash.c
+++ b/hash.c
@@ -90,6 +90,24 @@ static unsigned long hash_c_str(const wchar_t *str)
return h;
}
+static cnum hash_double(double n)
+{
+#ifdef HAVE_UINTPTR_T
+ uint_ptr_t h = 0;
+#else
+ unsigned long h = 0;
+#endif
+
+ mem_t *p = (mem_t *) &n, *q = p + sizeof(double);
+
+ while (p < q) {
+ h = h << 8 | h >> (8 * sizeof h - 1);
+ h += *p++;
+ }
+
+ return h & NUM_MAX;
+}
+
static cnum equal_hash(val obj)
{
switch (type(obj)) {
@@ -135,6 +153,8 @@ static cnum equal_hash(val obj)
return equal_hash(obj->ls.prefix);
case BGNUM:
return mp_hash(mp(obj)) & NUM_MAX;
+ case FLNUM:
+ return hash_double(obj->fl.n);
case COBJ:
return obj->co.ops->hash(obj) & NUM_MAX;
}
@@ -150,6 +170,8 @@ static cnum eql_hash(val obj)
return NUM_MAX;
if (obj->t.type == BGNUM)
return mp_hash(mp(obj)) & NUM_MAX;
+ if (obj->t.type == FLNUM)
+ return hash_double(obj->fl.n);
switch (sizeof (mem_t *)) {
case 4:
return (((cnum) obj) >> 4) & NUM_MAX;