[Nickle] nickle: Branch 'master' - 4 commits

Keith Packard keithp at keithp.com
Fri Jan 4 00:39:34 PST 2008


 float.c          |    8 +++++++
 hash.c           |    8 +++----
 test/Makefile.am |    5 +++-
 test/hashtest.5c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/round.5c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 128 insertions(+), 5 deletions(-)

New commits:
commit 0dde80f6dfed86346709a603499da6cbb2230e91
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Jan 4 00:38:41 2008 -0800

    Floating floor and ceil functions broken for values with no integer part.
    
    The ceiling of any positive fraction < 1 is 1, the floor of any negative
    fraction > -1 is -1. These cases were missing from the existing functions.

diff --git a/float.c b/float.c
index 9b7281b..12e49d6 100644
--- a/float.c
+++ b/float.c
@@ -531,7 +531,11 @@ FloatFloor (Value av, int expandOk)
     if (a->exp->sign == Positive)
 	RETURN (FloatInteger (av));
     if (NaturalLess (NewNatural (a->prec), a->exp->mag))
+    {
+	if (a->mant->sign == Negative)
+	    RETURN (NewInt (-1));
 	RETURN (Zero);
+    }
     d = NaturalToInt (a->exp->mag);
     mant = FpartRsl (a->mant, d);
     if (d && a->mant->sign == Negative)
@@ -555,7 +559,11 @@ FloatCeil (Value av, int expandOk)
     if (a->exp->sign == Positive)
 	RETURN (FloatInteger (av));
     if (NaturalLess (NewNatural (a->prec), a->exp->mag))
+    {
+	if (a->mant->sign == Positive && !NaturalZero (a->mant->mag))
+	    RETURN (One);
 	RETURN (Zero);
+    }
     d = NaturalToInt (a->exp->mag);
     mant = FpartRsl (a->mant, d);
     if (d && a->mant->sign == Positive)
commit b4a4b66be2ce66de162818cd94ae17d840b00c05
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Jan 4 00:36:58 2008 -0800

    Add test case for floor and ceil functions.
    
    Floating point floor and ceiling functions are broken, this demonstrates the
    bug.

diff --git a/test/Makefile.am b/test/Makefile.am
index bf7aaa0..a40c63c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,7 +5,9 @@ check_SCRIPTS=gcdtest.5c \
 	rattest.5c \
 	reftest.5c \
 	modtest.5c \
-	hashtest.5c
+	hashtest.5c \
+	round.5c
+
 TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) ../nickle
 TESTS=$(check_SCRIPTS)
 
diff --git a/test/round.5c b/test/round.5c
new file mode 100644
index 0000000..132fdac
--- /dev/null
+++ b/test/round.5c
@@ -0,0 +1,52 @@
+exception bad_round (int num, int den, int round);
+
+autoimport PRNG;
+
+void floor_check (int num, int den, int floor)
+{
+    if (num // den != floor)
+	raise bad_round (num, den, floor);
+}
+
+void ceil_check (int num, int den, int ceil)
+{
+    int compare;
+    
+    compare = num // den;
+    if (num % den != 0)
+	compare++;
+    if (compare != ceil)
+	raise bad_round (num, den, ceil);
+}
+
+void function round_random (int numbits, int denbits)
+{
+    int	num = randbits (numbits);
+    int den = randbits (numbits);
+
+    if (den == 0)
+	return;
+    
+    floor_check (num, den, floor (num / den));
+    ceil_check (num, den, ceil (num / den));
+    
+    floor_check (num, den, floor (imprecise (num / den)));
+    ceil_check (num, den, ceil (imprecise (num / den)));
+    
+    floor_check (-num, den, floor (-num / den));
+    ceil_check (-num, den, ceil (-num / den));
+    
+    floor_check (-num, den, floor (-imprecise (num / den)));
+    ceil_check (-num, den, ceil (-imprecise (num / den)));
+}
+
+void function round_test (int amin, int amax, int bmin, int bmax)
+{
+    int	a, b;
+
+    for (a = amin; a <= amax; a += randint(30))
+	for (b = bmin; b <= bmax; b += randint(30))
+	    round_random (a, b);
+}
+
+round_test (2, 512, 2, 512)
commit 0d645e8090c135b451949a844fdd53f8ebfc1575
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 31 14:23:56 2007 -0800

    Copy hash keys on insertion.
    
    Mutable hash keys must be copied when placed into the table as any changes
    to the original key value must not change the hash mapping.

diff --git a/hash.c b/hash.c
index 6e61d5d..8a8dd3d 100644
--- a/hash.c
+++ b/hash.c
@@ -359,7 +359,7 @@ HashGet (Value hv, Value key)
 	}
 	ht->count++;
 	HashEltHash(he) = hash;
-	HashEltKey(he) = key;
+	HashEltKey(he) = Copy (key);
 	HashEltValue(he) = Copy(ht->def);
     }
     value = HashEltValue (he);
@@ -388,8 +388,8 @@ HashSet (Value hv, Value key, Value value)
     if (!HashEltValid (he))
 	ht->count++;
     HashEltHash (he) = hash;
-    HashEltKey (he) = key;
-    HashEltValue (he) = value;
+    HashEltKey (he) = Copy (key);
+    HashEltValue (he) = Copy (value);
 }
 
 void
@@ -418,7 +418,7 @@ HashRef (Value hv, Value key)
     {
 	ht->count++;
 	HashEltHash (he) = hash;
-	HashEltKey (he) = key;
+	HashEltKey (he) = Copy (key);
 	if (ht->def)
 	    HashEltValue (he) = Copy(ht->def);
     }
commit 2727d3ade55570c172a6fd6d22a92287503c917a
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 31 14:23:01 2007 -0800

    Add tests for hash tables, including mutable key copying.
    
    Test hash tables. Has test that checks correct behaviour with mutable keys
    where the key is copied when placed into the table.

diff --git a/test/Makefile.am b/test/Makefile.am
index 38fbb11..bf7aaa0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -4,7 +4,8 @@ check_SCRIPTS=gcdtest.5c \
 	orderofoptest.5c \
 	rattest.5c \
 	reftest.5c \
-	modtest.5c
+	modtest.5c \
+	hashtest.5c
 TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) ../nickle
 TESTS=$(check_SCRIPTS)
 
diff --git a/test/hashtest.5c b/test/hashtest.5c
new file mode 100644
index 0000000..f93ab05
--- /dev/null
+++ b/test/hashtest.5c
@@ -0,0 +1,60 @@
+exception bad_result (string reason, poly[poly] h, poly key, poly value);
+
+poly[*][2] values = {
+    { "hello", "world" },
+    { 1, "one" },
+    { (int[*]) { 1, 2, 3, 4 }, (struct { int x, y; }) { x = 1, y = 2 } },
+};
+
+void hash_tests ()
+{
+    poly[poly]	h;
+
+    /*
+     * Test basic insert/find
+     */
+    for (int i = 0; i < dim(values); i++)
+	h[values[i][0]] = values[i][1];
+    for (int i = 0; i < dim(values); i++)
+	if (h[values[i][0]] != values[i][1])
+	    raise bad_result ("wrong value returned", h, values[i][0], values[i][1]);
+    /*
+     * check list of keys
+     */
+    poly[*] keys = hash_keys (h);
+    if (dim (keys) != dim (values))
+	raise bad_result ("wrong number of keys", h, dim(keys), dim (values));
+    for (int i = 0; i < dim (values); i++) {
+	int j;
+	for (j = 0; j < dim (keys); j++)
+	    if (keys[j] == values[i][0])
+		break;
+	if (j == dim (keys))
+	    raise bad_result ("missing key", h, values[i][0], â—Š);
+    }
+    /*
+     * test delete
+     */
+    for (int i = 0; i < dim (values); i++)
+	hash_del (h, values[i][0]);
+    if (dim (hash_keys(h)) != 0)
+	raise bad_result ("couldn't delete all keys", h, â—Š, â—Š);
+
+    /*
+     * test mutable keys
+     */
+
+    int[*] a = { 1, 2, 3 };
+    int[*] b = a;
+    h[a] = "hello";
+    if (h[b] != "hello")
+	raise bad_result ("couldn't find mutable key", h, a, "hello");
+    a[0] = 12;
+    if (hash_test (h, a))
+	raise bad_result ("hash contains mutated key", h, a, h[a]);
+    if (h[b] != "hello")
+	raise bad_result ("couldn't find unmutated key", h, b, h[b]);
+    
+}
+
+hash_tests ();


More information about the Nickle mailing list