From 87d3ed5c7bab83de529b26665cde9475b8d7b975 Mon Sep 17 00:00:00 2001 From: ESL Date: Sun, 2 Feb 2025 18:29:29 -0500 Subject: [PATCH] v0.5.1: fixes/improvements (issues #6,7,8,9,10,11) #11: extend flonum->string to support optional precision arg to support SRFI-48; improve flonum printing accordingly #10: bug: (floor-quotient 1 -1) actual: -2 expected: -1 #9: immediate-hash should hash flonums even if they are boxed #8: string-append and vector-append with 1 arg must copy the arg #7: stop advertising built-in support for SRFI-48, allowing full external implementation #6: expt should fall back to flonums on fixnum range overflow --- i.c | 51 ++++++++++++++----- i.h | 2 +- misc/test.scm | 50 +++++++++++++------ n.c | 88 ++++++++++++++++++--------------- n.h | 5 +- pre/n.sf | 97 ++++++++++++++++++++++--------------- pre/s.scm | 34 +++++++------ pre/t.scm | 4 +- s.c | 64 ++++++++++++------------ t.c | 132 +++++++++++++++++++++++++------------------------- 10 files changed, 307 insertions(+), 220 deletions(-) diff --git a/i.c b/i.c index 236788a..047d59c 100644 --- a/i.c +++ b/i.c @@ -1681,12 +1681,25 @@ define_instruction(itoc) { } define_instruction(jtos) { - char buf[30], *s; double d; ckj(ac); - d = get_flonum(ac); sprintf(buf, "%.15g", d); - for (s = buf; *s != 0; s++) if (strchr(".eE", *s)) break; - if (d != d) strcpy(buf, "+nan.0"); else if (d <= -HUGE_VAL) strcpy(buf, "-inf.0"); - else if (d >= HUGE_VAL) strcpy(buf, "+inf.0"); else if (*s == 'E') *s = 'e'; - else if (*s == 0) { *s++ = '.'; *s++ = '0'; *s = 0; } + char buf[50], *s; double d; long pr = -1; + obj arg = spop(); ckj(ac); d = get_flonum(ac); + if (d != d) { ac = string_obj(newstring("+nan.0")); gonexti(); } + if (d <= -HUGE_VAL) { ac = string_obj(newstring("-inf.0")); gonexti(); } + if (d >= HUGE_VAL) { ac = string_obj(newstring("+inf.0")); gonexti(); } + /* since double can't hold more than 17 decimal digits, limit fixed representation length */ + if (is_fixnum(arg) && fabs(d) <= 9007199254740992.0 && (pr = get_fixnum(arg)) >= 0 && pr < 18) + sprintf(buf, "%.*f", (int)pr, d); else sprintf(buf, "%.16g", d); + for (s = buf; *s != 0; ++s) { if (strchr(".e", *s)) break; } + if (*s == '.' || *s == 'e') { + if (*s == '.') s = strchr(s+1, 'e'); + if (s) { /* remove + and leading 0s from expt */ + char *t = ++s; if (*s == '-') ++s, ++t; + while (*s == '+' || (*s == '0' && s[1])) ++s; + while (*s) *t++ = *s++; *t = 0; + } + } else if (*s == 0 && pr <= 0) { + *s++ = '.'; if (pr < 0) *s++ = '0'; *s = 0; + } ac = string_obj(newstring(buf)); gonexti(); } @@ -1706,6 +1719,7 @@ define_instruction(stoj) { define_instruction(ntos) { if (is_fixnum(ac)) goi(itos); if (unlikely(spop() != fixnum_obj(10))) fail("non-10 radix in flonum conversion"); + spush(0); /* #f: use default precision */ goi(jtos); } @@ -1861,13 +1875,15 @@ define_instruction(igcd) { } define_instruction(ipow) { - obj x = ac, y = spop(); cki(x); cki(y); - ac = fixnum_obj(fxpow(get_fixnum(x), get_fixnum(y))); + obj x = ac, y = spop(); long ly; cki(x); cki(y); + ly = get_fixnum(y); if (ly < 0) fail("negative power"); + ac = fixnum_obj(fxpow(get_fixnum(x), ly)); /* can overflow */ gonexti(); } define_instruction(isqrt) { - cki(ac); /* TODO: check for negative */ + obj x = ac; cki(x); /* TODO: check for negative */ + if (x < 0) fail("square root of a negative fixnum"); ac = fixnum_obj(fxsqrt(get_fixnum(ac))); gonexti(); } @@ -2564,8 +2580,11 @@ define_instruction(gcd) { define_instruction(pow) { obj x = ac, y = spop(); if (likely(are_fixnums(x, y))) { - /* fixme: this will either overflow, or fail on negative y */ - ac = fixnum_obj(fxpow(get_fixnum(x), get_fixnum(y))); + /* if fxpow fails or overflows, it returns 0 */ + long fx = get_fixnum(x), fy = get_fixnum(y), fz; + if (unlikely(fx == 0 && fy < 0)) fail("division by zero"); + fz = ((fx | fy)) ? fxpow(fx, fy) : 1; /* 0^0 == 1! */ + ac = (!fz && fx) ? flonum_obj(pow((double)fx, (double)fy)) : fixnum_obj(fz); } else { double dx, dy; if (likely(is_flonum(x))) dx = get_flonum(x); @@ -3519,8 +3538,16 @@ define_instruction(vmclo) { define_instruction(hshim) { unsigned long long v = (unsigned long long)ac, base = 0; obj b = spop(); - if (v && isaptr(v)) { ac = fixnum_obj(0); gonexti(); } if (b) { ckk(b); base = get_fixnum(b); } + if (ac && isaptr(ac)) { +#ifdef FLONUMS_BOXED + if (is_flonum_obj(ac)) { + union { unsigned long long ull; double d; } u; + u.d = flonum_from_obj(ac); v = u.ull; + } else +#endif + { ac = fixnum_obj(0); gonexti(); } + } if (!base) base = 1 + (unsigned long long)FIXNUM_MAX; ac = fixnum_obj((fixnum_t)(v % base)); gonexti(); diff --git a/i.h b/i.h index c136ddb..cb1131b 100644 --- a/i.h +++ b/i.h @@ -452,7 +452,7 @@ declare_instruction(stoi, "X7\0'(i10)", 0, "string->fixnum", declare_instruction(ctoi, "X8", 0, "char->integer", '1', AUTOGL) declare_instruction(itoc, "X9", 0, "integer->char", '1', AUTOGL) declare_instruction(ltob, "E1", 0, "list->bytevector", '1', AUTOGL) -declare_instruction(jtos, "E6", 0, "flonum->string", '1', AUTOGL) +declare_instruction(jtos, "E6\0f", 0, "flonum->string", 'b', AUTOGL) declare_instruction(stoj, "E7", 0, "string->flonum", '1', AUTOGL) declare_instruction(ntos, "E8\0'(i10)", 0, "number->string", 'b', AUTOGL) declare_instruction(ston, "E9\0'(i10)", 0, "string->number", 'b', AUTOGL) diff --git a/misc/test.scm b/misc/test.scm index bbea29a..7a51695 100644 --- a/misc/test.scm +++ b/misc/test.scm @@ -58,7 +58,7 @@ (display " out of ") (write *tests-run*) (display " passed (") - (write (* (/ *tests-passed* *tests-run*) 100)) + (write (/ (floor (* (/ *tests-passed* *tests-run*) 10000)) 100)) (display "%)") (newline)) @@ -1482,7 +1482,7 @@ ;(test #i1/3 (rationalize .3 1/10)) (test 1.0 (inexact (exp 0))) ;; may return exact number -(test~= 20.0855369231877 (exp 3)) +(test~= 20.08553692318767 (exp 3)) (test 0.0 (inexact (log 1))) ;; may return exact number (test 1.0 (log (exp 1))) @@ -1495,33 +1495,33 @@ (test 1.0 (inexact (cos 0))) ;; may return exact number (test -1.0 (cos 3.14159265358979)) (test 0.0 (inexact (tan 0))) ;; may return exact number -(test~= 1.5574077246549 (tan 1)) +(test~= 1.557407724654902 (tan 1)) (test 0.0 (inexact (asin 0))) ;; may return exact number -(test~= 1.5707963267949 (asin 1)) +(test~= 1.570796326794897 (asin 1)) (test 0.0 (inexact (acos 1))) ;; may return exact number -(test~= 3.14159265358979 (acos -1)) +(test~= 3.141592653589793 (acos -1)) ;; (test 0.0-0.0i (asin 0+0.0i)) ;; (test 1.5707963267948966+0.0i (acos 0+0.0i)) (test 0.0 (atan 0.0 1.0)) (test -0.0 (atan -0.0 1.0)) -(test~= 0.785398163397448 (atan 1.0 1.0)) -(test~= 1.5707963267949 (atan 1.0 0.0)) -(test~= 2.35619449019234 (atan 1.0 -1.0)) -(test~= 3.14159265358979 (atan 0.0 -1.0)) -(test~= -3.14159265358979 (atan -0.0 -1.0)) ; -(test~= -2.35619449019234 (atan -1.0 -1.0)) -(test~= -1.5707963267949 (atan -1.0 0.0)) -(test~= -0.785398163397448 (atan -1.0 1.0)) +(test~= 0.7853981633974483 (atan 1.0 1.0)) +(test~= 1.570796326794897 (atan 1.0 0.0)) +(test~= 2.356194490192345 (atan 1.0 -1.0)) +(test~= 3.141592653589793 (atan 0.0 -1.0)) +(test~= -3.141592653589793 (atan -0.0 -1.0)) ; +(test~= -2.356194490192345 (atan -1.0 -1.0)) +(test~= -1.570796326794897 (atan -1.0 0.0)) +(test~= -0.7853981633974483 (atan -1.0 1.0)) ;; (test undefined (atan 0.0 0.0)) (test 1764 (square 42)) (test 4 (square 2)) (test 3.0 (inexact (sqrt 9))) -(test~= 1.4142135623731 (sqrt 2)) +(test~= 1.414213562373095 (sqrt 2)) ;(test 0.0+1.0i (inexact (sqrt -1))) (test '(0 0) (call-with-values (lambda () (exact-integer-sqrt 0)) list)) @@ -3078,6 +3078,28 @@ ;; Skint extras +(define s "foo") +(define v #(foo)) +(test #f (eq? (string-append s) s)) +(test #f (eq? (vector-append v) v)) + +; expt should overflow +(test 1 (expt 0 0)) +(test 0.1 (expt 10 -1)) +(test 0.0009765625 (expt 2 -10)) +(test -32768 (expt -2 15)) +(test -536870912 (expt -2 29)) +(test 536870912.0 (expt 2 29)) +(test 6.80564733841877e+038 (expt 2 129)) + +; fixnum ops shouldn't fail on overflow, but may return whatever +(test #t (fixnum? (fx- -536870912 1))) +(test #t (fixnum? (fx* -536870912 -1))) +(test #t (fixnum? (fx* 536870911 536870911))) + +; floor division + + ; _ and ... as literals: (define-syntax test-specials (syntax-rules (_ ...) ((_ _ ...) '(_ ...)) ((_ x y) (vector x y)))) (test (list (test-specials _ ...) (test-specials 1 2)) diff --git a/n.c b/n.c index e596780..e5f33c4 100644 --- a/n.c +++ b/n.c @@ -96,129 +96,129 @@ obj* typedref(obj o, int i) { #ifndef NDEBUG long fxneg(long x) { - assert(x != FIXNUM_MIN); + ASSERT(x != FIXNUM_MIN); return -x; } long fxabs(long x) { - assert(x != FIXNUM_MIN); + ASSERT(x != FIXNUM_MIN); return labs(x); } long fxadd(long x, long y) { long z = x + y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return z; } long fxsub(long x, long y) { long z = x - y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return z; } long fxmul(long x, long y) { double z = (double)x * (double)y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return x * y; } /* exact integer division */ long fxdiv(long x, long y) { - assert(y); - assert(x != FIXNUM_MIN || y != -1); - assert(x % y == 0); + ASSERT(y); + ASSERT(x != FIXNUM_MIN || y != -1); + ASSERT(x % y == 0); return x / y; } /* truncated division (common/C99) */ long fxquo(long x, long y) { - assert(y); assert(x != FIXNUM_MIN || y != -1); + ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); return x / y; } long fxrem(long x, long y) { - assert(y); + ASSERT(y); return x % y; } /* floor division */ long fxmqu(long x, long y) { - long q; assert(y); assert(x != FIXNUM_MIN || y != -1); - q = x / y; - return ((x < 0 && y > 0) || (x > 0 && y < 0)) ? q - 1 : q; + long q, r; ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); + q = x / y, r = x % y; + return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? q - 1 : q; } long fxmlo(long x, long y) { - long r; assert(y); r = x % y; + long r; ASSERT(y); r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? r + y : r; } /* euclidean division */ long fxeuq(long x, long y) { - long q, r; assert(y); assert(x != FIXNUM_MIN || y != -1); + long q, r; ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); q = x / y, r = x % y; return (r < 0) ? ((y > 0) ? q - 1 : q + 1) : q; } long fxeur(long x, long y) { - long r; assert(y); r = x % y; + long r; ASSERT(y); r = x % y; return (r < 0) ? ((y > 0) ? r + y : r - y) : r; } long fxgcd(long x, long y) { long a = labs(x), b = labs(y), c; while (b) c = a%b, a = b, b = c; - assert(a <= FIXNUM_MAX); + ASSERT(a <= FIXNUM_MAX); return a; } long fxasl(long x, long y) { - assert(y >= 0 && y < FIXNUM_BIT); + ASSERT(y >= 0 && y < FIXNUM_BIT); return x << y; } long fxasr(long x, long y) { - assert(y >= 0 && y < FIXNUM_BIT); - assert(!y || x >= 0); /* >> of negative x is undefined */ + ASSERT(y >= 0 && y < FIXNUM_BIT); + ASSERT(!y || x >= 0); /* >> of negative x is undefined */ return x >> y; } long fxflo(double f) { - long l = (long)f; assert((double)l == f); - assert(l >= FIXNUM_MIN && l <= FIXNUM_MAX); + long l = (long)f; ASSERT((double)l == f); + ASSERT(l >= FIXNUM_MIN && l <= FIXNUM_MAX); return l; } #endif long fxpow(long x, long y) { - assert(y >= 0); + if (y < 0 || x == 0) return 0; retry: if (y == 0) return 1; if (y == 1) return x; - if (y % 2 == 1) x *= fxpow(x, y-1); - else { x *= x; y /= 2; assert(FIXNUM_MIN <= x && x <= FIXNUM_MAX); goto retry; } - assert(FIXNUM_MIN <= x && x <= FIXNUM_MAX); return x; + if (y % 2 == 1) { x *= fxpow(x, y-1); if (!(FIXNUM_MIN <= x && x <= FIXNUM_MAX)) return 0; } + else { x *= x; y /= 2; if (!(FIXNUM_MIN <= x && x <= FIXNUM_MAX)) return 0; goto retry; } + return (FIXNUM_MIN <= x && x <= FIXNUM_MAX) ? x : 0; } long fxsqrt(long x) { - assert(x >= 0); if (x < 2) return x; + if (x < 0) return 0; if (x < 2) return x; else { long s = fxsqrt(x >> 2) << 1, l = s + 1; return l*l > x ? s : l; } } int fxifdv(long x, long y, long *pi, double *pd) { - assert(y); assert(x != FIXNUM_MIN || y != -1); + ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); if (x % y == 0) { *pi = x / y; return 1; } else { *pd = (double)x / (double)y; return 0; } } double flquo(double x, double y) { - double z; assert(y != 0.0 && flisint(x) && flisint(y)); + double z; ASSERT(y != 0.0 && flisint(x) && flisint(y)); modf(x / y, &z); return z; } double flrem(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return fmod(x, y); } double flmqu(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return floor(x / y); } double flmlo(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return x - y * floor(x / y); } double flgcd(double x, double y) { double a = fabs(x), b = fabs(y), c; - assert(flisint(a) && flisint(b)); + ASSERT(flisint(a) && flisint(b)); while (b > 0.0) c = fmod(a, b), a = b, b = c; return a; } @@ -866,12 +866,22 @@ static void wrdatum(obj o, wenv_t *e) { } else if (is_fixnum_obj(o)) { char buf[30]; sprintf(buf, "%ld", fixnum_from_obj(o)); wrs(buf, e); } else if (is_flonum_obj(o)) { - char buf[30], *s; double d = flonum_from_obj(o); sprintf(buf, "%.15g", d); - for (s = buf; *s != 0; s++) if (strchr(".eE", *s)) break; - if (d != d) strcpy(buf, "+nan.0"); else if (d <= -HUGE_VAL) strcpy(buf, "-inf.0"); - else if (d >= HUGE_VAL) strcpy(buf, "+inf.0"); else if (*s == 'E') *s = 'e'; - else if (*s == 0) { *s++ = '.'; *s++ = '0'; *s = 0; } - wrs(buf, e); + char buf[30], *s; double d = flonum_from_obj(o); + if (d != d) wrs("+nan.0", e); + else if (d <= -HUGE_VAL) wrs("-inf.0", e); + else if (d >= HUGE_VAL) wrs("+inf.0", e); + else { sprintf(buf, "%.16g", d); + for (s = buf; *s != 0; ++s) { if (strchr(".e", *s)) break; } + if (*s == '.' || *s == 'e') { + if (*s == '.') s = strchr(s+1, 'e'); + if (s) { /* remove + and leading 0s from expt */ + char *t = ++s; if (*s == '-') ++s, ++t; + while (*s == '+' || (*s == '0' && s[1])) ++s; + while (*s) *t++ = *s++; *t = 0; + } + } else if (*s == 0) { *s++ = '.'; *s++ = '0'; *s = 0; } + wrs(buf, e); + } } else if (iseof(o)) { wrs("#", e); } else if (isvoid(o)) { diff --git a/n.h b/n.h index bfb4c92..b916715 100644 --- a/n.h +++ b/n.h @@ -174,6 +174,7 @@ typedef int bool_t; #define FIXNUM_BIT 30 #define FIXNUM_MIN -536870912 #define FIXNUM_MAX 536870911 +#define ASSERT(x) (void)(0) #ifdef NDEBUG #define fxneg(x) (-(x)) #define fxabs(x) (labs(x)) @@ -187,7 +188,7 @@ typedef int bool_t; #define fxrem(x, y) ((x) % (y)) /* floor division */ static long fxmqu(long x, long y) { - long q = x / y; return ((x < 0 && y > 0) || (x > 0 && y < 0)) ? q - 1 : q; + long q = x / y, r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? q - 1 : q; } static long fxmlo(long x, long y) { long r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? r + y : r; @@ -225,7 +226,9 @@ extern long fxasr(long x, long y); extern long fxflo(double f); #endif static int flisint(double f) { return f > -HUGE_VAL && f < HUGE_VAL && f == floor(f); } +/* returns 0 if result is not representable as a fixnum */ extern long fxpow(long x, long y); +/* returns 0 if result is not representable as a fixnum */ extern long fxsqrt(long x); extern int fxifdv(long x, long y, long *pi, double *pd); extern double flquo(double x, double y); diff --git a/pre/n.sf b/pre/n.sf index 3c60dc2..9bdbe5f 100644 --- a/pre/n.sf +++ b/pre/n.sf @@ -219,10 +219,15 @@ obj* typedref(obj o, int i) { ; numerical helpers +; these operations may return garbage on over/underflow, but are not allowed to fail +; except for a few apriori obvious reasons such as division by zero; they do contain +; ASSERTs, but those are for documentation only + (%definition "/* numbers */") (%definition "#define FIXNUM_BIT 30") (%definition "#define FIXNUM_MIN -536870912") (%definition "#define FIXNUM_MAX 536870911") +(%definition "#define ASSERT(x) (void)(0)") (%definition "#ifdef NDEBUG #define fxneg(x) (-(x)) #define fxabs(x) (labs(x)) @@ -236,7 +241,7 @@ obj* typedref(obj o, int i) { #define fxrem(x, y) ((x) % (y)) /* floor division */ static long fxmqu(long x, long y) { - long q = x / y; return ((x < 0 && y > 0) || (x > 0 && y < 0)) ? q - 1 : q; + long q = x / y, r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? q - 1 : q; } static long fxmlo(long x, long y) { long r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? r + y : r; @@ -276,135 +281,137 @@ extern long fxflo(double f); (%localdef "#ifndef NDEBUG long fxneg(long x) { - assert(x != FIXNUM_MIN); + ASSERT(x != FIXNUM_MIN); return -x; } long fxabs(long x) { - assert(x != FIXNUM_MIN); + ASSERT(x != FIXNUM_MIN); return labs(x); } long fxadd(long x, long y) { long z = x + y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return z; } long fxsub(long x, long y) { long z = x - y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return z; } long fxmul(long x, long y) { double z = (double)x * (double)y; - assert(z >= FIXNUM_MIN && z <= FIXNUM_MAX); + ASSERT(z >= FIXNUM_MIN && z <= FIXNUM_MAX); return x * y; } /* exact integer division */ long fxdiv(long x, long y) { - assert(y); - assert(x != FIXNUM_MIN || y != -1); - assert(x % y == 0); + ASSERT(y); + ASSERT(x != FIXNUM_MIN || y != -1); + ASSERT(x % y == 0); return x / y; } /* truncated division (common/C99) */ long fxquo(long x, long y) { - assert(y); assert(x != FIXNUM_MIN || y != -1); + ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); return x / y; } long fxrem(long x, long y) { - assert(y); + ASSERT(y); return x % y; } /* floor division */ long fxmqu(long x, long y) { - long q; assert(y); assert(x != FIXNUM_MIN || y != -1); - q = x / y; - return ((x < 0 && y > 0) || (x > 0 && y < 0)) ? q - 1 : q; + long q, r; ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); + q = x / y, r = x % y; + return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? q - 1 : q; } long fxmlo(long x, long y) { - long r; assert(y); r = x % y; + long r; ASSERT(y); r = x % y; return ((r < 0 && y > 0) || (r > 0 && y < 0)) ? r + y : r; } /* euclidean division */ long fxeuq(long x, long y) { - long q, r; assert(y); assert(x != FIXNUM_MIN || y != -1); + long q, r; ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); q = x / y, r = x % y; return (r < 0) ? ((y > 0) ? q - 1 : q + 1) : q; } long fxeur(long x, long y) { - long r; assert(y); r = x % y; + long r; ASSERT(y); r = x % y; return (r < 0) ? ((y > 0) ? r + y : r - y) : r; } long fxgcd(long x, long y) { long a = labs(x), b = labs(y), c; while (b) c = a%b, a = b, b = c; - assert(a <= FIXNUM_MAX); + ASSERT(a <= FIXNUM_MAX); return a; } long fxasl(long x, long y) { - assert(y >= 0 && y < FIXNUM_BIT); + ASSERT(y >= 0 && y < FIXNUM_BIT); return x << y; } long fxasr(long x, long y) { - assert(y >= 0 && y < FIXNUM_BIT); - assert(!y || x >= 0); /* >> of negative x is undefined */ + ASSERT(y >= 0 && y < FIXNUM_BIT); + ASSERT(!y || x >= 0); /* >> of negative x is undefined */ return x >> y; } long fxflo(double f) { - long l = (long)f; assert((double)l == f); - assert(l >= FIXNUM_MIN && l <= FIXNUM_MAX); + long l = (long)f; ASSERT((double)l == f); + ASSERT(l >= FIXNUM_MIN && l <= FIXNUM_MAX); return l; } #endif") (%definition "static int flisint(double f) { return f > -HUGE_VAL && f < HUGE_VAL && f == floor(f); }") +(%definition "/* returns 0 if result is not representable as a fixnum */") (%definition "extern long fxpow(long x, long y);") (%localdef "long fxpow(long x, long y) { - assert(y >= 0); + if (y < 0 || x == 0) return 0; retry: if (y == 0) return 1; if (y == 1) return x; - if (y % 2 == 1) x *= fxpow(x, y-1); - else { x *= x; y /= 2; assert(FIXNUM_MIN <= x && x <= FIXNUM_MAX); goto retry; } - assert(FIXNUM_MIN <= x && x <= FIXNUM_MAX); return x; + if (y % 2 == 1) { x *= fxpow(x, y-1); if (!(FIXNUM_MIN <= x && x <= FIXNUM_MAX)) return 0; } + else { x *= x; y /= 2; if (!(FIXNUM_MIN <= x && x <= FIXNUM_MAX)) return 0; goto retry; } + return (FIXNUM_MIN <= x && x <= FIXNUM_MAX) ? x : 0; }") +(%definition "/* returns 0 if result is not representable as a fixnum */") (%definition "extern long fxsqrt(long x);") (%localdef "long fxsqrt(long x) { - assert(x >= 0); if (x < 2) return x; + if (x < 0) return 0; if (x < 2) return x; else { long s = fxsqrt(x >> 2) << 1, l = s + 1; return l*l > x ? s : l; } }") (%definition "extern int fxifdv(long x, long y, long *pi, double *pd);") (%localdef "int fxifdv(long x, long y, long *pi, double *pd) { - assert(y); assert(x != FIXNUM_MIN || y != -1); + ASSERT(y); ASSERT(x != FIXNUM_MIN || y != -1); if (x % y == 0) { *pi = x / y; return 1; } else { *pd = (double)x / (double)y; return 0; } }") (%definition "extern double flquo(double x, double y);") (%localdef "double flquo(double x, double y) { - double z; assert(y != 0.0 && flisint(x) && flisint(y)); + double z; ASSERT(y != 0.0 && flisint(x) && flisint(y)); modf(x / y, &z); return z; }") (%definition "extern double flrem(double x, double y);") (%localdef "double flrem(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return fmod(x, y); }") (%definition "extern double flmqu(double x, double y);") (%localdef "double flmqu(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return floor(x / y); }") (%definition "extern double flmlo(double x, double y);") (%localdef "double flmlo(double x, double y) { - assert(y != 0.0 && flisint(x) && flisint(y)); + ASSERT(y != 0.0 && flisint(x) && flisint(y)); return x - y * floor(x / y); }") (%definition "extern double flgcd(double x, double y);") (%localdef "double flgcd(double x, double y) { double a = fabs(x), b = fabs(y), c; - assert(flisint(a) && flisint(b)); + ASSERT(flisint(a) && flisint(b)); while (b > 0.0) c = fmod(a, b), a = b, b = c; return a; }") @@ -1381,12 +1388,22 @@ static void wrdatum(obj o, wenv_t *e) { } else if (is_fixnum_obj(o)) { char buf[30]; sprintf(buf, \"%ld\", fixnum_from_obj(o)); wrs(buf, e); } else if (is_flonum_obj(o)) { - char buf[30], *s; double d = flonum_from_obj(o); sprintf(buf, \"%.15g\", d); - for (s = buf; *s != 0; s++) if (strchr(\".eE\", *s)) break; - if (d != d) strcpy(buf, \"+nan.0\"); else if (d <= -HUGE_VAL) strcpy(buf, \"-inf.0\"); - else if (d >= HUGE_VAL) strcpy(buf, \"+inf.0\"); else if (*s == 'E') *s = 'e'; - else if (*s == 0) { *s++ = '.'; *s++ = '0'; *s = 0; } - wrs(buf, e); + char buf[30], *s; double d = flonum_from_obj(o); + if (d != d) wrs(\"+nan.0\", e); + else if (d <= -HUGE_VAL) wrs(\"-inf.0\", e); + else if (d >= HUGE_VAL) wrs(\"+inf.0\", e); + else { sprintf(buf, \"%.16g\", d); + for (s = buf; *s != 0; ++s) { if (strchr(\".e\", *s)) break; } + if (*s == '.' || *s == 'e') { + if (*s == '.') s = strchr(s+1, 'e'); + if (s) { /* remove + and leading 0s from expt */ + char *t = ++s; if (*s == '-') ++s, ++t; + while (*s == '+' || (*s == '0' && s[1])) ++s; + while (*s) *t++ = *s++; *t = 0; + } + } else if (*s == 0) { *s++ = '.'; *s++ = '0'; *s = 0; } + wrs(buf, e); + } } else if (iseof(o)) { wrs(\"#\", e); } else if (isvoid(o)) { diff --git a/pre/s.scm b/pre/s.scm index 36fca94..2904e97 100644 --- a/pre/s.scm +++ b/pre/s.scm @@ -893,7 +893,8 @@ (define-syntax string-append (syntax-rules () - [(_) ""] [(_ x) (%cks x)] + [(_) ""] + [(_ x) (string-cat x "")] [(_ x y) (string-cat x y)] [(_ . r) (%string-append . r)] [_ %string-append])) @@ -1011,7 +1012,8 @@ (define-syntax vector-append (syntax-rules () - [(_) '#()] [(_ x) (%ckv x)] + [(_) '#()] + [(_ x) (vector-cat x '#())] [(_ x y) (vector-cat x y)] [(_ . r) (%vector-append . r)] [_ %vector-append])) @@ -2085,10 +2087,12 @@ (define (fprintf p fs . args) (define (hd args) (if (pair? args) (car args) (error "format: no argument for ~ directive"))) + (define (tl args) + (if (pair? args) (cdr args) (error "format: not enough arguments for ~ directive"))) (define (fhd fl) (if (pair? fl) (car fl) (error "format: incomplete ~ directive"))) (define (write-num rx arg p) - (if (number? arg) (display (number->string arg rx) p) (write arg p))) + (if (number? arg) (display (number->string arg rx) p) (display arg p))) (define (memd fl &w &d) (let loop ([fl fl] [c (fhd fl)] [&n &w]) (cond [(char-numeric? c) @@ -2104,25 +2108,25 @@ (when (null? (cdr fl)) (error "format: incomplete escape sequence")) (let* ([w -1] [d -1] [fl (memd (cdr fl) (set& w) (set& d))]) (case (char-downcase (car fl)) - [(#\*) (lp (cdr fl) (cddr args))] ;+ CL, skips 1 arg + [(#\*) (lp (cdr fl) (tl args))] ;+ CL, skips 1 arg [(#\~) (write-char #\~ p) (lp (cdr fl) args)] [(#\%) (newline p) (lp (cdr fl) args)] [(#\t) (write-char #\tab p) (lp (cdr fl) args)] [(#\_) (write-char #\space p) (lp (cdr fl) args)] [(#\&) ((format-fresh-line) p) (lp (cdr fl) args)] [(#\!) (flush-output-port p) (lp (cdr fl) args)] ;+ common - [(#\s) (write (hd args) p) (lp (cdr fl) (cdr args))] - [(#\a) (display (hd args) p) (lp (cdr fl) (cdr args))] - [(#\w) (write-shared (hd args) p) (lp (cdr fl) (cdr args))] - [(#\c) (write-char (hd args) p) (lp (cdr fl) (cdr args))] - [(#\b) (write-num 2 (hd args) p) (lp (cdr fl) (cdr args))] - [(#\o) (write-num 8 (hd args) p) (lp (cdr fl) (cdr args))] - [(#\d) (write-num 10 (hd args) p) (lp (cdr fl) (cdr args))] - [(#\x) (write-num 16 (hd args) p) (lp (cdr fl) (cdr args))] + [(#\s) (write (hd args) p) (lp (cdr fl) (tl args))] + [(#\a) (display (hd args) p) (lp (cdr fl) (tl args))] + [(#\w) (write-shared (hd args) p) (lp (cdr fl) (tl args))] + [(#\c) (write-char (hd args) p) (lp (cdr fl) (tl args))] + [(#\b) (write-num 2 (hd args) p) (lp (cdr fl) (tl args))] + [(#\o) (write-num 8 (hd args) p) (lp (cdr fl) (tl args))] + [(#\d) (write-num 10 (hd args) p) (lp (cdr fl) (tl args))] + [(#\x) (write-num 16 (hd args) p) (lp (cdr fl) (tl args))] [(#\h) (display (format-help-string) p) (lp (cdr fl) args)] - [(#\y) ((format-pretty-print) (hd args) p) (lp (cdr fl) (cdr args))] - [(#\f) ((format-fixed-print) (hd args) w d p) (lp (cdr fl) (cdr args))] - [(#\? #\k) (lp (string->list (hd args)) (hd (hd args))) (lp (cdr fl) (cddr args))] + [(#\y) ((format-pretty-print) (hd args) p) (lp (cdr fl) (tl args))] + [(#\f) ((format-fixed-print) (hd args) w d p) (lp (cdr fl) (tl args))] + [(#\? #\k) (lp (string->list (hd args)) (hd (tl args))) (lp (cdr fl) (tl (tl args)))] [else (error "format: unrecognized ~ directive" (car fl))]))] [else (write-char (car fl) p) (lp (cdr fl) args)]))) diff --git a/pre/t.scm b/pre/t.scm index e441450..115733c 100644 --- a/pre/t.scm +++ b/pre/t.scm @@ -2135,7 +2135,7 @@ ; these are special forms in skint! (define-library) (import) ; selected extracts from r7rs-large and srfis - (box? x 111) (box x 111) (unbox x 111) (set-box! x 111) (format 28 48) + (box? x 111) (box x 111) (unbox x 111) (set-box! x 111) (format 28) (fprintf) (format-pretty-print) (format-fixed-print) (format-fresh-line) (format-help-string) ; skint extras go into repl and (skint) library; the rest goes to (skint hidden) (set&) (lambda*) (body) (letcc) (withcc) (syntax-lambda) (syntax-length) @@ -2712,7 +2712,7 @@ [help "-h" "--help" #f "Display this help"] )) -(define *skint-version* "0.5.0") +(define *skint-version* "0.5.1") (define (implementation-version) *skint-version*) (define (implementation-name) "SKINT") diff --git a/s.c b/s.c index ba238ca..8337e57 100644 --- a/s.c +++ b/s.c @@ -424,9 +424,10 @@ char *s_code[] = { "to!)[12", "S", "string-append", - "l7:y12:syntax-rules;n;l2:l1:y1:_;;s0:;;l2:l2:y1:_;y1:x;;l2:y4:%25cks;y" - "1:x;;;l2:l3:y1:_;y1:x;y1:y;;l3:y10:string-cat;y1:x;y1:y;;;l2:py1:_;y1:" - "r;;py14:%25string-append;y1:r;;;l2:y1:_;y14:%25string-append;;", + "l7:y12:syntax-rules;n;l2:l1:y1:_;;s0:;;l2:l2:y1:_;y1:x;;l3:y10:string-" + "cat;y1:x;s0:;;;l2:l3:y1:_;y1:x;y1:y;;l3:y10:string-cat;y1:x;y1:y;;;l2:" + "py1:_;y1:r;;py14:%25string-append;y1:r;;;l2:y1:_;y14:%25string-append;" + ";", "P", "string-trim-whitespace", "%1.0S3,'0,,#0.3,.1,&2{%2.1,.1list", "%3n,'1,.4I-,,#0.3,.1,.6,&3{%2:0,.1I?;" - ";l1:y5:fx>=?;;l1:y4:fx=?;;l1:y5:fx!=?;;l1:y5:fxmin;;l1:y5:fxmax;;l1:y5" - ":fxneg;;l1:y5:fxabs;;l1:y5:fxgcd;;l1:y6:fxexpt;;l1:y6:fxsqrt;;l1:y5:fx" - "not;;l1:y5:fxand;;l1:y5:fxior;;l1:y5:fxxor;;l1:y5:fxsll;;l1:y5:fxsrl;;" - "l1:y14:fixnum->flonum;;l1:y14:fixnum->string;;l1:y14:string->fixnum;;l" - "1:y7:flonum?;;l1:y7:flzero?;;l1:y11:flpositive?;;l1:y11:flnegative?;;l" - "1:y10:flinteger?;;l1:y6:flnan?;;l1:y11:flinfinite?;;l1:y9:flfinite?;;l" - "1:y7:fleven?;;l1:y6:flodd?;;l1:y3:fl+;;l1:y3:fl*;;l1:y3:fl-;;l1:y3:fl/" - ";;l1:y5:flneg;;l1:y5:flabs;;l1:y5:flgcd;;l1:y6:flexpt;;l1:y6:flsqrt;;l" - "1:y7:flfloor;;l1:y9:flceiling;;l1:y10:fltruncate;;l1:y7:flround;;l1:y5" - ":flexp;;l1:y5:fllog;;l1:y5:flsin;;l1:y5:flcos;;l1:y5:fltan;;l1:y6:flas" - "in;;l1:y6:flacos;;l1:y6:flatan;;l1:y4:fl?;;l" - "1:y5:fl>=?;;l1:y4:fl=?;;l1:y5:fl!=?;;l1:y5:flmin;;l1:y5:flmax;;l1:y11:" - "flremainder;;l1:y8:flmodulo;;l1:y10:flquotient;;l1:y8:flmodquo;;l1:y14" - ":flonum->fixnum;;l1:y14:flonum->string;;l1:y14:string->flonum;;l1:y8:l" - "ist-cat;;l1:y9:last-pair;;l1:y9:list-head;;l1:y4:meme;;l1:y4:asse;;l1:" - "y4:memp;;l1:y4:assp;;l1:y8:reverse!;;l1:y9:circular?;;l1:y5:cons*;;l1:" - "y5:list*;;l1:y8:char-cmp;;l1:y11:char-ci-cmp;;l1:y10:string-cat;;l1:y1" - "5:string-position;;l1:y10:string-cmp;;l1:y13:string-ci-cmp;;l1:y10:vec" - "tor-cat;;l1:y12:bytevector=?;;l1:y16:bytevector->list;;l1:y16:list->by" - "tevector;;l1:y13:subbytevector;;l1:y19:standard-input-port;;l1:y20:sta" - "ndard-output-port;;l1:y19:standard-error-port;;l1:y9:tty-port?;;l1:y15" - ":port-fold-case?;;l1:y19:set-port-fold-case!;;l1:y11:rename-file;;l1:y" - "17:current-directory;;l1:y19:directory-separator;;l1:y4:void;;l1:y5:vo" - "id?;;l1:y19:implementation-name;;l1:y22:implementation-version;;py20:*" - "user-name-registry*;y6:hidden;;py25:make-readonly-environment;y6:hidde" - "n;;py27:make-controlled-environment;y6:hidden;;py20:make-sld-environme" - "nt;y6:hidden;;py21:make-repl-environment;y6:hidden;;py19:find-library-" - "in-env;y6:hidden;;py16:root-environment;y6:hidden;;py16:repl-environme" - "nt;y6:hidden;;py17:empty-environment;y6:hidden;;py32:make-historic-rep" - "ort-environment;y6:hidden;;py16:r5rs-environment;y6:hidden;;py21:r5rs-" - "null-environment;y6:hidden;;py9:*verbose*;y6:hidden;;py7:*quiet*;y6:hi" - "dden;;py25:compile-and-run-core-expr;y6:hidden;;py17:evaluate-top-form" - ";y6:hidden;;py10:run-script;y6:hidden;;py11:run-program;y6:hidden;;py2" - "2:repl-evaluate-top-form;y6:hidden;;py9:repl-read;y6:hidden;;py17:repl" - "-exec-command;y6:hidden;;py14:repl-from-port;y6:hidden;;py13:run-bench" - "mark;y6:hidden;;py4:repl;y6:hidden;;),&0{%1,,,,#0#1#2#3&0{%1.0,'(y1:w)" - ",.1v?{'(l2:y6:scheme;y5:write;)]2}'(y1:t),.1v?{'(l2:y6:scheme;y4:time;" - ")]2}'(y1:p),.1v?{'(l2:y6:scheme;y4:repl;)]2}'(y1:r),.1v?{'(l2:y6:schem" - "e;y4:read;)]2}'(y1:v),.1v?{'(l2:y6:scheme;y4:r5rs;)]2}'(y1:u),.1v?{'(l" - "2:y6:scheme;y9:r5rs-null;)]2}'(y1:d),.1v?{'(l2:y6:scheme;y4:load;)]2}'" - "(y1:z),.1v?{'(l2:y6:scheme;y4:lazy;)]2}'(y1:s),.1v?{'(l2:y6:scheme;y15" - ":process-context;)]2}'(y1:i),.1v?{'(l2:y6:scheme;y7:inexact;)]2}'(y1:f" - "),.1v?{'(l2:y6:scheme;y4:file;)]2}'(y1:e),.1v?{'(l2:y6:scheme;y4:eval;" - ")]2}'(y1:o),.1v?{'(l2:y6:scheme;y7:complex;)]2}'(y1:h),.1v?{'(l2:y6:sc" - "heme;y4:char;)]2}'(y1:l),.1v?{'(l2:y6:scheme;y11:case-lambda;)]2}'(y1:" - "a),.1v?{'(l2:y6:scheme;y3:cxr;)]2}'(y1:b),.1v?{'(l2:y6:scheme;y4:base;" - ")]2}'(y1:x),.1v?{'(l2:y6:scheme;y3:box;)]2}.1I0?{.1,'(y4:srfi),l2]2}.1" - ",l1]2}.!0&0{%1${&0{%1n,'(l1:y5:begin;),V12]1},.3,@(y20:*root-name-regi" - "stry*),@(y11:name-lookup)[03}z]1}.!1&0{%3'1,.1V4,.0,.3A3,.0?{.4,.1sd]5" - "}.1,.5,.5cc,'1,.4V5]5}.!2&0{%1&0{%1.0,'(y5:const),l2]1},.1,@(y20:*root" - "-name-registry*),@(y11:name-lookup)[13}.!3.4d,.5a,,#0.0,.6,.5,.7,.(i10" - "),&5{%2.1u?{${.2,:0^[01},.1,${'(l1:y5:skint;),:1^[01},:3^[23}.1p~?{${." - "2,:0^[01},.1,${n,.6c,'(y5:skint)c,:1^[01},:3^[23}${${.4,:0^[01},.3,${$" - "{.9a,:2^[01},:1^[01},:3^[03}.1d,.1,:4^[22}.!0.0^_1[52},@(y10:%25for-ea" - "ch1)[02}", + ";l3:y8:set-box!;y1:x;i111;;l2:y6:format;i28;;l1:y7:fprintf;;l1:y19:for" + "mat-pretty-print;;l1:y18:format-fixed-print;;l1:y17:format-fresh-line;" + ";l1:y18:format-help-string;;l1:y4:set&;;l1:y7:lambda*;;l1:y4:body;;l1:" + "y5:letcc;;l1:y6:withcc;;l1:y13:syntax-lambda;;l1:y13:syntax-length;;l1" + ":y7:record?;;l1:y11:make-record;;l1:y13:record-length;;l1:y10:record-r" + "ef;;l1:y11:record-set!;;l1:y6:expand;;l1:y7:fixnum?;;l1:y11:fxpositive" + "?;;l1:y11:fxnegative?;;l1:y7:fxeven?;;l1:y6:fxodd?;;l1:y7:fxzero?;;l1:" + "y3:fx+;;l1:y3:fx*;;l1:y3:fx-;;l1:y3:fx/;;l1:y10:fxquotient;;l1:y11:fxr" + "emainder;;l1:y8:fxmodquo;;l1:y8:fxmodulo;;l1:y8:fxeucquo;;l1:y8:fxeucr" + "em;;l1:y5:fxneg;;l1:y5:fxabs;;l1:y4:fx?;;l1:" + "y5:fx>=?;;l1:y4:fx=?;;l1:y5:fx!=?;;l1:y5:fxmin;;l1:y5:fxmax;;l1:y5:fxn" + "eg;;l1:y5:fxabs;;l1:y5:fxgcd;;l1:y6:fxexpt;;l1:y6:fxsqrt;;l1:y5:fxnot;" + ";l1:y5:fxand;;l1:y5:fxior;;l1:y5:fxxor;;l1:y5:fxsll;;l1:y5:fxsrl;;l1:y" + "14:fixnum->flonum;;l1:y14:fixnum->string;;l1:y14:string->fixnum;;l1:y7" + ":flonum?;;l1:y7:flzero?;;l1:y11:flpositive?;;l1:y11:flnegative?;;l1:y1" + "0:flinteger?;;l1:y6:flnan?;;l1:y11:flinfinite?;;l1:y9:flfinite?;;l1:y7" + ":fleven?;;l1:y6:flodd?;;l1:y3:fl+;;l1:y3:fl*;;l1:y3:fl-;;l1:y3:fl/;;l1" + ":y5:flneg;;l1:y5:flabs;;l1:y5:flgcd;;l1:y6:flexpt;;l1:y6:flsqrt;;l1:y7" + ":flfloor;;l1:y9:flceiling;;l1:y10:fltruncate;;l1:y7:flround;;l1:y5:fle" + "xp;;l1:y5:fllog;;l1:y5:flsin;;l1:y5:flcos;;l1:y5:fltan;;l1:y6:flasin;;" + "l1:y6:flacos;;l1:y6:flatan;;l1:y4:fl?;;l1:y5" + ":fl>=?;;l1:y4:fl=?;;l1:y5:fl!=?;;l1:y5:flmin;;l1:y5:flmax;;l1:y11:flre" + "mainder;;l1:y8:flmodulo;;l1:y10:flquotient;;l1:y8:flmodquo;;l1:y14:flo" + "num->fixnum;;l1:y14:flonum->string;;l1:y14:string->flonum;;l1:y8:list-" + "cat;;l1:y9:last-pair;;l1:y9:list-head;;l1:y4:meme;;l1:y4:asse;;l1:y4:m" + "emp;;l1:y4:assp;;l1:y8:reverse!;;l1:y9:circular?;;l1:y5:cons*;;l1:y5:l" + "ist*;;l1:y8:char-cmp;;l1:y11:char-ci-cmp;;l1:y10:string-cat;;l1:y15:st" + "ring-position;;l1:y10:string-cmp;;l1:y13:string-ci-cmp;;l1:y10:vector-" + "cat;;l1:y12:bytevector=?;;l1:y16:bytevector->list;;l1:y16:list->byteve" + "ctor;;l1:y13:subbytevector;;l1:y19:standard-input-port;;l1:y20:standar" + "d-output-port;;l1:y19:standard-error-port;;l1:y9:tty-port?;;l1:y15:por" + "t-fold-case?;;l1:y19:set-port-fold-case!;;l1:y11:rename-file;;l1:y17:c" + "urrent-directory;;l1:y19:directory-separator;;l1:y4:void;;l1:y5:void?;" + ";l1:y19:implementation-name;;l1:y22:implementation-version;;py20:*user" + "-name-registry*;y6:hidden;;py25:make-readonly-environment;y6:hidden;;p" + "y27:make-controlled-environment;y6:hidden;;py20:make-sld-environment;y" + "6:hidden;;py21:make-repl-environment;y6:hidden;;py19:find-library-in-e" + "nv;y6:hidden;;py16:root-environment;y6:hidden;;py16:repl-environment;y" + "6:hidden;;py17:empty-environment;y6:hidden;;py32:make-historic-report-" + "environment;y6:hidden;;py16:r5rs-environment;y6:hidden;;py21:r5rs-null" + "-environment;y6:hidden;;py9:*verbose*;y6:hidden;;py7:*quiet*;y6:hidden" + ";;py25:compile-and-run-core-expr;y6:hidden;;py17:evaluate-top-form;y6:" + "hidden;;py10:run-script;y6:hidden;;py11:run-program;y6:hidden;;py22:re" + "pl-evaluate-top-form;y6:hidden;;py9:repl-read;y6:hidden;;py17:repl-exe" + "c-command;y6:hidden;;py14:repl-from-port;y6:hidden;;py13:run-benchmark" + ";y6:hidden;;py4:repl;y6:hidden;;),&0{%1,,,,#0#1#2#3&0{%1.0,'(y1:w),.1v" + "?{'(l2:y6:scheme;y5:write;)]2}'(y1:t),.1v?{'(l2:y6:scheme;y4:time;)]2}" + "'(y1:p),.1v?{'(l2:y6:scheme;y4:repl;)]2}'(y1:r),.1v?{'(l2:y6:scheme;y4" + ":read;)]2}'(y1:v),.1v?{'(l2:y6:scheme;y4:r5rs;)]2}'(y1:u),.1v?{'(l2:y6" + ":scheme;y9:r5rs-null;)]2}'(y1:d),.1v?{'(l2:y6:scheme;y4:load;)]2}'(y1:" + "z),.1v?{'(l2:y6:scheme;y4:lazy;)]2}'(y1:s),.1v?{'(l2:y6:scheme;y15:pro" + "cess-context;)]2}'(y1:i),.1v?{'(l2:y6:scheme;y7:inexact;)]2}'(y1:f),.1" + "v?{'(l2:y6:scheme;y4:file;)]2}'(y1:e),.1v?{'(l2:y6:scheme;y4:eval;)]2}" + "'(y1:o),.1v?{'(l2:y6:scheme;y7:complex;)]2}'(y1:h),.1v?{'(l2:y6:scheme" + ";y4:char;)]2}'(y1:l),.1v?{'(l2:y6:scheme;y11:case-lambda;)]2}'(y1:a),." + "1v?{'(l2:y6:scheme;y3:cxr;)]2}'(y1:b),.1v?{'(l2:y6:scheme;y4:base;)]2}" + "'(y1:x),.1v?{'(l2:y6:scheme;y3:box;)]2}.1I0?{.1,'(y4:srfi),l2]2}.1,l1]" + "2}.!0&0{%1${&0{%1n,'(l1:y5:begin;),V12]1},.3,@(y20:*root-name-registry" + "*),@(y11:name-lookup)[03}z]1}.!1&0{%3'1,.1V4,.0,.3A3,.0?{.4,.1sd]5}.1," + ".5,.5cc,'1,.4V5]5}.!2&0{%1&0{%1.0,'(y5:const),l2]1},.1,@(y20:*root-nam" + "e-registry*),@(y11:name-lookup)[13}.!3.4d,.5a,,#0.0,.6,.5,.7,.(i10),&5" + "{%2.1u?{${.2,:0^[01},.1,${'(l1:y5:skint;),:1^[01},:3^[23}.1p~?{${.2,:0" + "^[01},.1,${n,.6c,'(y5:skint)c,:1^[01},:3^[23}${${.4,:0^[01},.3,${${.9a" + ",:2^[01},:1^[01},:3^[03}.1d,.1,:4^[22}.!0.0^_1[52},@(y10:%25for-each1)" + "[02}", "C", 0, "@(y20:*root-name-registry*),${f,'(l1:y5:skint;),.4,@(y11:name-lookup)[" @@ -1720,7 +1720,7 @@ char *t_code[] = { "kint-options*)", "C", 0, - "'(s5:0.5.0)@!(y15:*skint-version*)", + "'(s5:0.5.1)@!(y15:*skint-version*)", "P", "implementation-version", "%0@(y15:*skint-version*)]0",