فهرست منبع

Shave a few bytes

Justine Tunney 3 سال پیش
والد
کامیت
1b0a03013b
3فایلهای تغییر یافته به همراه20 افزوده شده و 99 حذف شده
  1. 17 95
      hash.c
  2. 1 0
      lisp.js
  3. 2 4
      sectorlisp.S

+ 17 - 95
hash.c

@@ -4,13 +4,6 @@
 #endif
 
 #define word unsigned long
-#define dubs unsigned __int128
-
-struct Bar {
-  dubs r;
-  word n;
-  char k;
-};
 
 static word Null;
 
@@ -18,23 +11,6 @@ static inline int IsTwoPow(word x) {
   return !(x & (x - 1));
 }
 
-static inline int Bsf(word x) {
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-  return __builtin_ctzll(x);
-#else
-  uint32_t l, r;
-  x &= -x;
-  l = x | x >> 32;
-  r = !!(x >> 32), r <<= 1;
-  r += !!(l & 0xffff0000), r <<= 1;
-  r += !!(l & 0xff00ff00), r <<= 1;
-  r += !!(l & 0xf0f0f0f0), r <<= 1;
-  r += !!(l & 0xcccccccc), r <<= 1;
-  r += !!(l & 0xaaaaaaaa);
-  return r;
-#endif
-}
-
 static inline int Bsr(word x) {
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
   return __builtin_clzll(x) ^ 63;
@@ -55,69 +31,6 @@ static inline int Bsr(word x) {
 #endif
 }
 
-static inline word Log(word x) {
-  return --x ? Bsr(x) + 1 : 0;
-}
-
-static struct Bar Bar(word n) {
-  struct Bar m;
-  m.r = 1;
-  m.n = n;
-  m.k = Log(n) << 1;
-  m.r = (m.r << m.k) / n;
-  return m;
-}
-
-static word Mod(struct Bar m, dubs x) {
-  dubs t;
-  t = x - ((x * m.r) >> m.k) * m.n;
-  if (t >= m.n) t -= m.n;
-  return t;
-}
-
-static word Mul(struct Bar m, word x, word y) {
-  dubs t = x;
-  return Mod(m, t * y);
-}
-
-static word Pow(struct Bar m, word a, word n) {
-  word p, r;
-  for (p = a, r = 1; n; n >>= 1) {
-    if (n & 1) r = Mul(m, r, p);
-    p = Mul(m, p, p);
-  }
-  return r;
-}
-
-static int W(struct Bar m, word a) {
-  word x, y, s;
-  s = Bsf(m.n >> 1) + 1;
-  x = Pow(m, a, m.n >> s);
-  for (y = 0; s; --s, x = y) {
-    y = Mul(m, x, x);
-    if (y == 1 && x != 1 && x != m.n - 1) {
-      return 0;
-    }
-  }
-  return y == 1;
-}
-
-static int MillerTime(word n) {
-  struct Bar m;
-  if (n < 2) return 0;
-  if (n <= 3) return 1;
-  if (~n & 1) return 0;
-  if (n % 3 == 0) return 0;
-  m = Bar(n);
-  if (n < 1373653) return W(m,2) && W(m,3);
-  if (n < 9080191) return W(m,31) && W(m,73);
-  if (n < 4759123141) return W(m,2) && W(m,7) && W(m,61);
-  if (n < 1122004669633) return W(m,2) && W(m,13) && W(m,23) && W(m,1662803);
-  if (n < 2152302898747) return W(m,2) && W(m,3) && W(m,5) && W(m,7) && W(m,11);
-  if (n < 3474749660383) return W(m,2) && W(m,3) && W(m,5) && W(m,7) && W(m,11) && W(m,13);
-  return W(m,2) && W(m,3) && W(m,5) && W(m,7) && W(m,11) && W(m,13) && W(m,17);
-}
-
 static word Hash(word h, word x, word a, word b, word c) {
   return (((h + x) * a + b) >> c) & (Null / 2 - 1);
 }
@@ -138,7 +51,7 @@ int main(int argc, char *argv[]) {
   word a, b, c;
   if (argc > 1) {
     Null = strtoul(argv[1], 0, 0);
-    if (Null < 128) {
+    if (Null < 64) {
       fprintf(stderr, "Error: Null is too small\n");
       return Usage(argv[0]);
     }
@@ -147,15 +60,24 @@ int main(int argc, char *argv[]) {
       return Usage(argv[0]);
     }
   } else {
-    Null = 040000;
+    /* Null = 040000; */
+    Null = 64;
   }
-  for (a = 2; a < Null; ++a) {
-    if (!MillerTime(a)) continue;
-    for (c = 0; c <= Bsr(Null / 2); ++c) {
-      for (b = 0; b < Null; ++b) {
+  for (;; Null <<= 1) {
+    printf("\n");
+    printf("#define Null %#lo\n", Null);
+    fflush(stdout);
+    for (a = 0; a < Null / 2; ++a) {
+      for (c = 0; c <= Bsr(Null / 2) / 2; ++c) {
+        /* for (b = 0; b < Null; ++b) { */
+        /* solve 1 = ('T' * a + b) / 2^c for b */
+        b = (((1<<c) - a * 'T') & (Null/2-1));
         if (Ok(a, b, c)) {
-          printf("return (((h + x) * %lu + %lu) >> %lu) & %#lo;\n", a, b, c,
-                 Null / 2 - 1);
+          if (c) {
+            printf("return (((h + x) * %lu + %lu) >> %lu) & (Null/2-1);\n", a, b, c);
+          } else {
+            printf("return ((h + x) * %lu + %lu) & (Null/2-1);\n", a, b);
+          }
         }
       }
     }

+ 1 - 0
lisp.js

@@ -56,6 +56,7 @@ function Cdr(x) {
 }
 
 function Cons(car, cdr) {
+  if (cx == -Null) Throw(kCons);
   Set(--cx, cdr);
   Set(--cx, car);
   if (cx < cHeap) cHeap = cx;

+ 2 - 4
sectorlisp.S

@@ -194,12 +194,10 @@ Pairlis:test	%di,%di				# Pairlis(x:di,y:si,a:dx):dx
 	test	%si,%si				# DEFAULT NIL ARGS
 	jz	1f
 	lodsw					# ax = Car(y)
+	mov	(%si),%si			# si = Cdr(y)
 1:	push	(%bx,%di)			# push Cdr(x)
 	mov	(%di),%di			# di = Car(x)
-	test	%si,%si
-	jz	1f
-	mov	(%si),%si			# si = Cdr(y)
-1:	call	Cons				# Cons(Car(x),Car(y))
+	call	Cons				# Cons(Car(x),Car(y))
 	xchg	%ax,%di
 	xchg	%dx,%ax
 	call	Cons				# Cons(Cons(Car(x),Car(y)),a)