From bart at cs.pdx.edu Sun Dec 9 00:54:21 2007 From: bart at cs.pdx.edu (Barton C Massey) Date: Sun, 09 Dec 2007 00:54:21 -0800 Subject: [Nickle] Modulus is broken Message-ID: <200712090854.lB98sLCZ017912@adara.cs.pdx.edu> > q = 7 // -3 -3 > r = 7 % -3 1 > q * -3 + r 10 The manual page promises that the last number will be 7. Given the definition of //, this is what Warren in "Hacker's Delight" refers to as "floor division", except that we have the modulus wrong---it should be -2 in this example. I'll figure out and submit a patch if it's a bug---I think it is. Bart From keithp at keithp.com Sun Dec 9 21:08:54 2007 From: keithp at keithp.com (Keith Packard) Date: Sun, 9 Dec 2007 21:08:54 -0800 (PST) Subject: [Nickle] nickle: Branch 'master' Message-ID: <20071210050854.63484130027@keithp.com> float.c | 13 +------------ integer.c | 6 +++--- value.c | 23 ++++++++++++++++++++--- value.h | 1 + 4 files changed, 25 insertions(+), 18 deletions(-) New commits: commit f78bf021e6bff9f422188f068a7a1b4aaa28d57f Author: Keith Packard Date: Sun Dec 9 21:08:47 2007 -0800 Make // and % operators modulus division operators. Herry S Warren Jr. defines three kinds of division -- truncating, floor and modulus. For all three kinds he requires a simple invarient: dividend = quotient * divisor + remainder Modulus division additionaly requires 0 <= remainder < abs (divisor) Floor division sets: quotient = floor (dividend / divisor) remainder = dividend - quotient * divisor Truncating division has quotient = round_towards_zero (dividend / divisor) remainder = dividend - quotient * divisor We select modulus division as it makes the most sense when you treat the values as a ring centered at zero. diff --git a/float.c b/float.c index 1c7a33e..9b7281b 100644 --- a/float.c +++ b/float.c @@ -408,17 +408,6 @@ FloatDivide (Value av, Value bv, int expandOk) } static Value -FloatMod (Value av, Value bv, int expandOk) -{ - ENTER (); - Value q; - - q = Floor (Divide (av, bv)); - av = Minus (av, Times (q, bv)); - RETURN (av); -} - -static Value FloatLess (Value av, Value bv, int expandOk) { ENTER (); @@ -1006,7 +995,7 @@ ValueRep FloatRep = { FloatTimes, FloatDivide, NumericDiv, - FloatMod, + NumericMod, FloatLess, FloatEqual, 0, diff --git a/integer.c b/integer.c index 25646ad..266611e 100644 --- a/integer.c +++ b/integer.c @@ -144,10 +144,10 @@ IntegerDiv (Value av, Value bv, int expandOk) } quo = NaturalDivide (IMag(a), IMag(b), &rem); sign = Positive; - if ((ISign(a) == Positive) != (ISign(b) == Positive)) + if (ISign (a) != ISign (b)) sign = Negative; - if (sign == Negative && !NaturalZero (rem)) - quo = NaturalPlus (quo, one_natural); + if (ISign (a) == Negative && !NaturalZero (rem)) + quo = NaturalPlus (quo, one_natural); RETURN (NewInteger (sign, quo)); } diff --git a/value.c b/value.c index 1edf860..78024cf 100644 --- a/value.c +++ b/value.c @@ -163,8 +163,6 @@ BinaryOperate (Value av, Value bv, BinaryOp operator) break; case FirstPositive: r = - (a / -b); - if (a % -b) - --r; break; case SecondPositive: r = -(-a / b); @@ -174,6 +172,8 @@ BinaryOperate (Value av, Value bv, BinaryOp operator) case BothNegative: default: r = -a / -b; + if (-a % -b) + r++; break; } return NewInt (r); @@ -301,7 +301,24 @@ Value NumericDiv (Value av, Value bv, int expandOk) { ENTER (); - RETURN (Floor (Divide (av, bv))); + + av = Divide (av, bv); + if (Negativep (bv)) + av = Ceil (av); + else + av = Floor (av); + RETURN (av); +} + +Value +NumericMod (Value av, Value bv, int expandOk) +{ + ENTER (); + Value q; + + q = NumericDiv (av, bv, expandOk); + av = Minus (av, Times (q, bv)); + RETURN (av); } Value diff --git a/value.h b/value.h index e94428f..af33302 100644 --- a/value.h +++ b/value.h @@ -1035,6 +1035,7 @@ Type *BuildArrayType (Type *type, int ndim, ...); Value BinaryOperate (Value av, Value bv, BinaryOp operator); Value UnaryOperate (Value v, UnaryOp operator); Value NumericDiv (Value av, Value bv, int expandOk); +Value NumericMod (Value av, Value bv, int expandOk); # define OK_TRUNC 1 From keithp at keithp.com Sun Dec 9 21:36:01 2007 From: keithp at keithp.com (Keith Packard) Date: Sun, 9 Dec 2007 21:36:01 -0800 (PST) Subject: [Nickle] nickle: Branch 'master' - 4 commits Message-ID: <20071210053601.4AF7F130027@keithp.com> configure.in | 2 +- debian/changelog | 8 ++++++++ nickle.1.in | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) New commits: commit 16240c3265bd1991e6317901460a504499a12ac6 Author: Keith Packard Date: Sun Dec 9 21:20:44 2007 -0800 Update debian changelog to reflect doc change diff --git a/debian/changelog b/debian/changelog index 1a92cf1..b10c941 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ nickle (2.62-1) unstable; urgency=low * Add modulus test case * Fix % and // operators to follow modulus rules + * Update manual to fix // and % documentation * Bump to version 2.62 -- Keith Packard Sun, 09 Dec 2007 21:14:27 -0800 commit 44c2aa8ee30ea972eb852dec9d73075a569b273d Author: Keith Packard Date: Sun Dec 9 21:20:03 2007 -0800 Update documentation to reflect corrected // and % semantics diff --git a/nickle.1.in b/nickle.1.in index 6483121..7a6d88b 100644 --- a/nickle.1.in +++ b/nickle.1.in @@ -259,12 +259,12 @@ int. This is a notable departure from C, where integer division is implied by integer operands. Integer division is defined by .br - x // y == floor(x / y) + x // y == y > 0 ? floor (x / y) : ceil(x / y) .br -The sign and value of the remainder is defined +The remainder is always non-negative and is defined by: by .br - (x // y) * y + (x % y) == x + x % y = x - (x // y) * y .br .IP "=============" .IP "+ -" commit eb5604f803cf5d442f389d1cad60301095266596 Author: Keith Packard Date: Sun Dec 9 21:15:04 2007 -0800 Bump debian changelog to 2.62 diff --git a/debian/changelog b/debian/changelog index 8081efd..1a92cf1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nickle (2.62-1) unstable; urgency=low + * Add modulus test case + * Fix % and // operators to follow modulus rules + * Bump to version 2.62 + + -- Keith Packard Sun, 09 Dec 2007 21:14:27 -0800 + nickle (2.61-1) unstable; urgency=low * Allow '.' before struct elt in initializers * Update builtins, tests and examples to use the new syntax commit 4d90bffd79c2db94b377973321f552b4ee97e65f Author: Keith Packard Date: Sun Dec 9 21:10:38 2007 -0800 Bump version to 2.62 diff --git a/configure.in b/configure.in index 7616586..deb010b 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ dnl for licensing information. AC_PREREQ(2.59) AC_INIT([nickle], - 2.61, + 2.62, [http://nickle.org], nickle) From keithp at keithp.com Sun Dec 9 21:37:17 2007 From: keithp at keithp.com (Keith Packard) Date: Sun, 9 Dec 2007 21:37:17 -0800 (PST) Subject: [Nickle] nickle: Changes to 'refs/tags/2.62' Message-ID: <20071210053717.9D299130027@keithp.com> Tag '2.62' created by Keith Packard at 2007-12-10 05:36 -0800 Version 2.62 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQBHXNCCQp8BWwlsTdMRAlGFAJ4oL2maSlGHwes0t8zhvLeSq3l6zQCgpF2t NkdWqnvKN+EJ4PcLmEb+4Vo= =ZYte -----END PGP SIGNATURE----- Changes since 2.61-7: --- 0 files changed --- From keithp at keithp.com Sun Dec 9 22:09:35 2007 From: keithp at keithp.com (Keith Packard) Date: Sun, 9 Dec 2007 22:09:35 -0800 (PST) Subject: [Nickle] nickle: Branch 'master' Message-ID: <20071210060935.1F25B130027@keithp.com> configure.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) New commits: commit 0d16382a67a39d928150b1970cf5295633ba2a50 Author: Keith Packard Date: Sun Dec 9 22:09:30 2007 -0800 Avoid using extra libraries unless necessary diff --git a/configure.in b/configure.in index deb010b..53e7ecc 100644 --- a/configure.in +++ b/configure.in @@ -33,10 +33,10 @@ AC_PROG_AWK AC_CHECK_PROGS([DATE], date) dnl Checks for libraries. -AC_CHECK_LIB(m, log) -AC_CHECK_LIB(nsl, gethostbyname) -AC_CHECK_LIB(socket, socket) -AC_CHECK_LIB(resolv, hstrerror) +AC_CHECK_FUNC(log,,AC_CHECK_LIB(m, log)) +AC_CHECK_FUNC(gethostbyname,,AC_CHECK_LIB(nsl, gethostbyname)) +AC_CHECK_FUNC(socket,,AC_CHECK_LIB(socket, socket) + AC_CHECK_LIB(resolv, hstrerror)) AC_CHECK_LIB(dl, dlopen) dnl as-compiler-flag.m4 0.0.1 From keithp at keithp.com Sun Dec 9 22:26:24 2007 From: keithp at keithp.com (Keith Packard) Date: Sun, 9 Dec 2007 22:26:24 -0800 (PST) Subject: [Nickle] nickle: Branch 'master' Message-ID: <20071210062624.3F20C130027@keithp.com> configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit de73950c6dbad62d022378cf5e9e62b635458326 Author: Keith Packard Date: Sun Dec 9 22:26:21 2007 -0800 Use AC_LINK_IFELSE instead of AC_COMPILE_IFELSE to test linker flags. The -Wl,-E option is for the linker, so testing the compiler support isn't sufficient. diff --git a/configure.in b/configure.in index 53e7ecc..91cd2cc 100644 --- a/configure.in +++ b/configure.in @@ -46,12 +46,12 @@ dnl ds at schleef.org AC_DEFUN([AS_COMPILER_FLAG], [ - AC_MSG_CHECKING(to see if compiler understands $1) + AC_MSG_CHECKING([to see if compiler understands $1]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" - AC_COMPILE_IFELSE([ ], [flag_ok=yes], [flag_ok=no]) + AC_LINK_IFELSE(AC_LANG_PROGRAM(,), [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes; then From keithp at keithp.com Sat Dec 29 12:57:11 2007 From: keithp at keithp.com (Keith Packard) Date: Sat, 29 Dec 2007 12:57:11 -0800 Subject: [Nickle] array of union initializer syntax Message-ID: <1198961831.5663.27.camel@koto.keithp.com> We currently require that unions be initialized with braces around them: typedef union { int i; real r; } n_t; n_t x = { .i = 7 }; When you stick this in an array, it looks messy: n_t[*] r = { { .i = 7 }, { .r = 1.5 } }; Sure seems like it would be nice if this could be n_t[*] r = { .i = 7, .r = 1.5 }; This isn't a trivial change as the grammar has a strong separation between struct/union and array initializers. All of that would need to become semantic instead, which will probably clean things up quite a bit. Would this be a useful change? keith.packard at intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : /pipermail/nickle/attachments/20071229/635087c2/attachment.pgp From keithp at keithp.com Sat Dec 29 16:11:20 2007 From: keithp at keithp.com (Keith Packard) Date: Sat, 29 Dec 2007 16:11:20 -0800 (PST) Subject: [Nickle] nickle: Changes to 'refs/tags/2.63' Message-ID: <20071230001120.1BB57130021@keithp.com> Tag '2.63' created by Keith Packard at 2007-12-30 00:11 -0800 Version 2.63 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQBHduIeQp8BWwlsTdMRAiszAJ9v34a1qLkp+0hDnn3+bxZXB+1ROQCgufOF p/bRSTnlCss4SMULCn96TbM= =TQkt -----END PGP SIGNATURE----- Changes since 2.62-3: --- 0 files changed --- From keithp at keithp.com Sat Dec 29 16:15:50 2007 From: keithp at keithp.com (Keith Packard) Date: Sat, 29 Dec 2007 16:15:50 -0800 (PST) Subject: [Nickle] nickle: Branch 'master' - 2 commits Message-ID: <20071230001550.780BE130021@keithp.com> configure.in | 2 +- debian/changelog | 8 ++++++++ foreign.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) New commits: commit cafadd2f2655b30fcc86df0b76492ac5afbf4152 Author: Keith Packard Date: Sat Dec 29 16:08:07 2007 -0800 Update to version 2.63 diff --git a/configure.in b/configure.in index 91cd2cc..7eaa968 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ dnl for licensing information. AC_PREREQ(2.59) AC_INIT([nickle], - 2.62, + 2.63, [http://nickle.org], nickle) diff --git a/debian/changelog b/debian/changelog index b10c941..68c4aeb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +nickle (2.63-1) unstable; urgency=low + * Avoid using extra libraries unless necessary + * Fix -Wl,-E testing by using AC_LINK_IFELSE + * Make foreign objects equal when they point at the same data + * Bump to version 2.63 + + -- Keith Packard Sat, 29 Dec 2007 16:02:57 -0800 + nickle (2.62-1) unstable; urgency=low * Add modulus test case * Fix % and // operators to follow modulus rules commit b0638d82ad3ad22e6de8c0c371bf76330db489d3 Author: Keith Packard Date: Sat Dec 29 15:56:28 2007 -0800 Make foreign objects equal when they point at the same data. diff --git a/foreign.c b/foreign.c index 3ed8ee5..bcbe2f4 100644 --- a/foreign.c +++ b/foreign.c @@ -11,7 +11,7 @@ static Value ForeignEqual (Value av, Value bv, int expandOk) { - if (av == bv) + if (av->foreign.data == bv->foreign.data) return TrueVal; return FalseVal; } From keithp at keithp.com Sat Dec 29 16:16:03 2007 From: keithp at keithp.com (Keith Packard) Date: Sat, 29 Dec 2007 16:16:03 -0800 (PST) Subject: [Nickle] nickle: Branch 'refs/tags/2.63' - 3 commits Message-ID: <20071230001603.4787AE8024@keithp.com> Rebased ref, commits from common ancestor: commit cafadd2f2655b30fcc86df0b76492ac5afbf4152 Author: Keith Packard Date: Sat Dec 29 16:08:07 2007 -0800 Update to version 2.63 diff --git a/configure.in b/configure.in index 91cd2cc..7eaa968 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ dnl for licensing information. AC_PREREQ(2.59) AC_INIT([nickle], - 2.62, + 2.63, [http://nickle.org], nickle) diff --git a/debian/changelog b/debian/changelog index b10c941..68c4aeb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +nickle (2.63-1) unstable; urgency=low + * Avoid using extra libraries unless necessary + * Fix -Wl,-E testing by using AC_LINK_IFELSE + * Make foreign objects equal when they point at the same data + * Bump to version 2.63 + + -- Keith Packard Sat, 29 Dec 2007 16:02:57 -0800 + nickle (2.62-1) unstable; urgency=low * Add modulus test case * Fix % and // operators to follow modulus rules commit b0638d82ad3ad22e6de8c0c371bf76330db489d3 Author: Keith Packard Date: Sat Dec 29 15:56:28 2007 -0800 Make foreign objects equal when they point at the same data. diff --git a/foreign.c b/foreign.c index 3ed8ee5..bcbe2f4 100644 --- a/foreign.c +++ b/foreign.c @@ -11,7 +11,7 @@ static Value ForeignEqual (Value av, Value bv, int expandOk) { - if (av == bv) + if (av->foreign.data == bv->foreign.data) return TrueVal; return FalseVal; } commit 974283319c7ef54fa301df9b5eda26d3195e49e4 Author: Bart Massey Date: Sat Dec 29 00:59:41 2007 -0800 added newlines where missing in calls to panic() diff --git a/mem.c b/mem.c index 99993ff..984d884 100644 --- a/mem.c +++ b/mem.c @@ -272,7 +272,7 @@ MemAddRoot (void *object) RootSize *= 2; roots = malloc (sizeof (void *) * RootSize); if (!roots) - panic ("Out of memory"); + panic ("Out of memory\n"); memcpy (roots, Roots, RootCount * sizeof (void *)); if (Roots) free (Roots); diff --git a/stack.c b/stack.c index 32ce28a..e36157a 100644 --- a/stack.c +++ b/stack.c @@ -79,7 +79,7 @@ StackPop (StackObject *stack) } stack->current = previous; if (!stack->current) - panic ("Stack underflow"); + panic ("Stack underflow\n"); STACK_TOP(stack) = previous->elements; } return *STACK_TOP(stack)++; @@ -109,7 +109,7 @@ StackDrop (StackObject *stack, int i) } stack->current = previous; if (!stack->current) - panic ("Stack underflow"); + panic ("Stack underflow\n"); STACK_TOP(stack) = CHUNK_MIN(previous); } STACK_ASSERT (stack); @@ -130,7 +130,7 @@ StackReset (StackObject *stack, StackPointer stackPointer) } stack->current = previous; if (!stack->current) - panic ("Stack underflow"); + panic ("Stack underflow\n"); STACK_TOP(stack) = CHUNK_MIN(previous); } STACK_TOP(stack) = stackPointer; @@ -159,7 +159,7 @@ StackElt (StackObject *stack, int i) i -= CHUNK_MAX(chunk) - stackPointer; chunk = chunk->previous; if (!chunk) - panic ("StackElt underflow"); + panic ("StackElt underflow\n"); stackPointer = CHUNK_MIN(chunk); } return stackPointer[i]; From keithp at keithp.com Mon Dec 31 01:18:00 2007 From: keithp at keithp.com (Keith Packard) Date: Mon, 31 Dec 2007 01:18:00 -0800 Subject: [Nickle] Hash keys not copied? Message-ID: <1199092680.5663.40.camel@koto.keithp.com> I know this issue has come up, but it just bit me fairly hard and I thought I'd raise it again. The keys in hash objects are not copied, which means that future changes to the key invalidate the hash table -- the table uses a 32-bit hash of the key to distribute objects across the array, but with the value changing, it will not be moved in the table. Thus, lookups on the old value will fail (as the value is now different), but lookups on the *new* value will also fail (it will look under the wrong 32-bit hash key). I don't see any way to avoid copying the key. -- keith.packard at intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : /pipermail/nickle/attachments/20071231/0435fc39/attachment.pgp From bart at po8.org Mon Dec 31 10:19:37 2007 From: bart at po8.org (Bart Massey) Date: Mon, 31 Dec 2007 10:19:37 -0800 Subject: [Nickle] Hash keys not copied? In-Reply-To: <1199092680.5663.40.camel@koto.keithp.com> References: <1199092680.5663.40.camel@koto.keithp.com> Message-ID: In message <1199092680.5663.40.camel at koto.keithp.com> you wrote: > I know this issue has come up, but it just bit me fairly hard and I > thought I'd raise it again. > > The keys in hash objects are not copied, which means that future changes > to the key invalidate the hash table -- the table uses a 32-bit hash of > the key to distribute objects across the array, but with the value > changing, it will not be moved in the table. Thus, lookups on the old > value will fail (as the value is now different), but lookups on the > *new* value will also fail (it will look under the wrong 32-bit hash > key). > > I don't see any way to avoid copying the key. If you restrict keys to being immutable values you avoid the problem; there's a strong argument that keys should be values, not data structures. An alternative that gives them same semantics (with very very high probability) as copying the keys is just to make the hash much bigger and only compare hashes, not the actual keys; this will save space and time on large keys, but might make things worse on smaller ones. You would do this only with mutable keys; immutable keys don't need to be copied in any case, as they can just be referenced. You could also do it only with keys larger than a given size, although the user semantics get ugly here. If you want the semantics that mutable data structures are allowed and you always look up based on the current contents, then you can play complicated games with the mark bit on boxes to get what you want. When a box is used in a hash key, mark the box; when you store through a marked box, go look in a list of hash tables containing that box and do the updates. Uggh. I vote for immutable. My second choice would be key-copying and my third would be probabilistic, but it's close. I think current-value is confusing and ugly. Bart From keithp at keithp.com Mon Dec 31 13:57:51 2007 From: keithp at keithp.com (Keith Packard) Date: Mon, 31 Dec 2007 13:57:51 -0800 Subject: [Nickle] Hash keys not copied? In-Reply-To: References: <1199092680.5663.40.camel@koto.keithp.com> Message-ID: <1199138271.5663.47.camel@koto.keithp.com> On Mon, 2007-12-31 at 10:19 -0800, Bart Massey wrote: > If you restrict keys to being immutable values you avoid the > problem; there's a strong argument that keys should be > values, not data structures. Immutable keys are never a problem -- 'copying' is free too. > If you want the semantics that mutable data structures are > allowed and you always look up based on the current > contents, then you can play complicated games with the mark > bit on boxes to get what you want. I don't think I want this -- I think I want the 'key' to be the value of the data structure when the key is used. > I vote for immutable. My second choice would be key-copying > and my third would be probabilistic, but it's close. I > think current-value is confusing and ugly. I'll just copy keys when mutable then. Current value is crazy. The use case here was in adding memoization to a game solver; I just use the current state of the game as the hash key. My perfect tic-tac-toe player is now about 10 times faster. -- keith.packard at intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : /pipermail/nickle/attachments/20071231/6536b5cd/attachment.pgp