]> Cypherpunks repositories - keks.git/commitdiff
Bigints
authorSergey Matveev <stargrave@stargrave.org>
Thu, 7 Nov 2024 06:48:33 +0000 (09:48 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Thu, 7 Nov 2024 08:20:44 +0000 (11:20 +0300)
22 files changed:
cyac/cmd/test-vector/test-vector.c
cyac/lib/atoms.h
cyac/lib/dec.c
cyac/lib/dec.h
cyac/lib/enc.c
cyac/lib/err.c
cyac/lib/err.h
gyac/atomtype_string.go
gyac/cmd/test-vector-anys/main.go
gyac/cmd/test-vector-manual/main.go
gyac/dec.go
gyac/enc.go
gyac/itemtype_string.go
gyac/reflect.go
pyac/pyac.py
pyac/test-vector.py
spec/encoding/cont.texi
spec/encoding/index.texi
spec/encoding/int.texi
spec/encoding/table.texi
tyac/test-vector.tcl
tyac/tyac.tcl

index b68260449c4f8a5c7661f71277865f7bc3ce8377046216bb00ad0241925b58d6..f6a4d66310b6971cf81a5fd117bf1682caf59a8a7aed09768e86683bd5edfcac 100644 (file)
@@ -117,9 +117,25 @@ main(int argc, char **argv) // NOLINT(misc-unused-parameters)
         &Got,
         buf + Off,
         len - Off,
-        YACAtomIntNeg10,
-        (const unsigned char *)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
-        10));
+        YACAtomNint,
+        (const unsigned char *)"\x8A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+        11));
+    adder(YACAtomRawEncode(
+        &Got,
+        buf + Off,
+        len - Off,
+        YACAtomNint,
+        (const unsigned char
+             *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        18));
+    adder(YACAtomRawEncode(
+        &Got,
+        buf + Off,
+        len - Off,
+        YACAtomNint,
+        (const unsigned char
+             *)"\xBE\x00\xA1\xE5\xA4\x61\x28\x03\x41\x85\x6D\x4A\xD9\x08\xA6\x9E\xA5\xF3\xCC\xC1\x0C\x78\x82\x14\x2B\xB7\xD8\x01\xCC\x38\x0F\x26\xB6\xB4\xD6\x96\x32\x02\x4E\xE5\x21\xF8\xCF\xAF\xB4\x43\xD4\x9A\x2A\x3D\x0C\xC7\x3B\xB4\x75\x7E\x88\x2F\x53\x96\xED\x30\x2B\x41\x82\x10\xD0\xD4\x9D\x71\xBE\x86\xCA\x69\x9C\xF5\xEE\x3B\xD6\xD5\x7E\xD6\x58\xE6\x93\x16\x22\x96\x44\xBA\x65\x0C\x92\xD7\xF0\xD4\xDB\x29\xC3\xAD\x1D\xFA\x99\x79\x16\x6F\x4C\x6E\x79\x56\x1A\x58\xF8\xE2\xC6\x3D\x08\xDF\x4E\x22\x46\xED\x1F\x64\xD2\xD6\x13\xA1\x9D\x8C\x9A\x68\x70\xE6\x18\x8E\x2F\x3A\xD4\x0C\x03\x8F\xDA\x30\x45\x2F\x8D\xDF\xCD\x21\x2A\x6A\x97\x4B\xC2\x5E\xC6\xA0\x56\x4C\x66\xA7\xD2\x87\x50\xFF\x9D\xB4\x58\xB7\x44\x41\xE4\x9E\xE5\xE8\x2D\xBF\x49\x74\xD6\x45\x67\x8E\x0A\xD0\x31\xF9\x7A\xAB\xA8\x55\x45\x1E\xEF\x17\xA8\x9B\x42\x82\x1E\x53\x08\x16\xDD\x57\x93\xA8\x3B\x7A\x82\xE8\xED\xE8\x1E\x7F\x33\x95\x69\x1F\x76\x17\x84\xF8\xBC\x62\x79\x61\xCD\x40\x84\x5E\xE9\x08\xA4\x0B\x9D\x1F\x01\x92\x7B\x38\xEB\x1A\x7D\x4E\xFD\x60\xDB\x09\x44\xF7\xEC\x1B\x83\x2B\x7E\x6E\xB1\x83\x3F\x9A\x35\x15\x76\xAD\x5D\xE5\x71\xFA\xE8\x86\x5D\xA7\x51\x4F\x06\xB0\xFB\xF3\x8C\x1F\x2A\x85\x38\xF5\xD3\x8B\x4E\x18\x00\x1C\xCB\xB9\xDD\xCB\x48\x85\x30\xF6\x08\x6D\x14\x74\x4D\x8B\x56\x72\x16\x6E\x48\xE9\xEF\x93\x77\x25\x75\xDB\x66\xB6\xF2\x57\xC6\xFF\xAD\x6E\x2C\x29\x15\x10\xC5\xED\x02\xE1\xA8\xB2\x4B\x44\xEC\x1E\x2A\x91\x68\x62\x38\xE8\xDE\xFD\x18\xC0\x19\x98\x63\x4A\x50\x76\xA6\xB7\xF8\x5F\xC8\x1A\x1D\x61\xA1\x5B\x2C\x52\x8D\xFA\x08\x2C\xE3\xE3\xE2\xCA\x64\x9A\xC0\x48\x17\xEC\x5C\x12\x3E\x0B\x76\x1A\xB1\x03\xF7\x80\xC0\x14\xF0\x21\xBB\xEB\x7E\xA3\xB8\x6E\x0C\xA1\xC8\x33\xE3\x8E\xF5\xC8\x97\xA6\xD7\xE1\xF4\xA2\x39\x8C\x49\x0B\x3D\x65\xE2\xF4\x5C\x7F\xAE\x40\x2D\x1D\xF1\x69\x8B\x6F\xDD\xB1\x85\x48\x16\x64\x87\x1C\x26\x64\xBF\xD1\x68\x6B\x2B\x33\x72\x78\x3F\x18\x56\xF6\x24\x7A\x3F\x84\x37\xA2\x81\x8F\x68\xB7\xC4\xEA\x13\xA5\xF5\x7B\x73\xC7\x28\x70\xB6\x84\x04\x5F\x14",
+        481));
     adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.neg
 
     adder(
@@ -136,9 +152,17 @@ main(int argc, char **argv) // NOLINT(misc-unused-parameters)
         &Got,
         buf + Off,
         len - Off,
-        YACAtomIntPos11,
-        (const unsigned char *)"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-        11));
+        YACAtomPint,
+        (const unsigned char *)"\x8B\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        12));
+    adder(YACAtomRawEncode(
+        &Got,
+        buf + Off,
+        len - Off,
+        YACAtomPint,
+        (const unsigned char
+             *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        18));
     adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.pos
 
     adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints
index df8977d19addd17a3428d4ac3403ef3aff9d48be70ec4d4a4bdb47df0f041213..bf3c255a7149922bc9f70bfdbfc548b8ce7b88d5d4d7add6ac7ef6b184d80b4e 100644 (file)
@@ -10,6 +10,8 @@ enum YACAtomType {
     YACAtomList = 0x08,
     YACAtomMap = 0x09,
     YACAtomBlob = 0x0B,
+    YACAtomPint = 0x0C,
+    YACAtomNint = 0x0D,
     YACAtomFloat16 = 0x10,
     YACAtomFloat32 = 0x11,
     YACAtomFloat64 = 0x12,
@@ -18,102 +20,6 @@ enum YACAtomType {
     YACAtomTAI64 = 0x18,
     YACAtomTAI64N = 0x19,
     YACAtomTAI64NA = 0x1A,
-    YACAtomIntPos1 = 0x20,
-    YACAtomIntPos2 = 0x21,
-    YACAtomIntPos3 = 0x22,
-    YACAtomIntPos4 = 0x23,
-    YACAtomIntPos5 = 0x24,
-    YACAtomIntPos6 = 0x25,
-    YACAtomIntPos7 = 0x26,
-    YACAtomIntPos8 = 0x27,
-    YACAtomIntPos9 = 0x28,
-    YACAtomIntPos10 = 0x29,
-    YACAtomIntPos11 = 0x2A,
-    YACAtomIntPos12 = 0x2B,
-    YACAtomIntPos13 = 0x2C,
-    YACAtomIntPos14 = 0x2D,
-    YACAtomIntPos15 = 0x2E,
-    YACAtomIntPos16 = 0x2F,
-    YACAtomIntNeg1 = 0x30,
-    YACAtomIntNeg2 = 0x31,
-    YACAtomIntNeg3 = 0x32,
-    YACAtomIntNeg4 = 0x33,
-    YACAtomIntNeg5 = 0x34,
-    YACAtomIntNeg6 = 0x35,
-    YACAtomIntNeg7 = 0x36,
-    YACAtomIntNeg8 = 0x37,
-    YACAtomIntNeg9 = 0x38,
-    YACAtomIntNeg10 = 0x39,
-    YACAtomIntNeg11 = 0x3A,
-    YACAtomIntNeg12 = 0x3B,
-    YACAtomIntNeg13 = 0x3C,
-    YACAtomIntNeg14 = 0x3D,
-    YACAtomIntNeg15 = 0x3E,
-    YACAtomIntNeg16 = 0x3F,
-    YACAtomInt0 = 0x40,
-    YACAtomInt1 = 0x41,
-    YACAtomInt2 = 0x42,
-    YACAtomInt3 = 0x43,
-    YACAtomInt4 = 0x44,
-    YACAtomInt5 = 0x45,
-    YACAtomInt6 = 0x46,
-    YACAtomInt7 = 0x47,
-    YACAtomInt8 = 0x48,
-    YACAtomInt9 = 0x49,
-    YACAtomInt10 = 0x4A,
-    YACAtomInt11 = 0x4B,
-    YACAtomInt12 = 0x4C,
-    YACAtomInt13 = 0x4D,
-    YACAtomInt14 = 0x4E,
-    YACAtomInt15 = 0x4F,
-    YACAtomInt16 = 0x50,
-    YACAtomInt17 = 0x51,
-    YACAtomInt18 = 0x52,
-    YACAtomInt19 = 0x53,
-    YACAtomInt20 = 0x54,
-    YACAtomInt21 = 0x55,
-    YACAtomInt22 = 0x56,
-    YACAtomInt23 = 0x57,
-    YACAtomInt24 = 0x58,
-    YACAtomInt25 = 0x59,
-    YACAtomInt26 = 0x5A,
-    YACAtomInt27 = 0x5B,
-    YACAtomInt28 = 0x5C,
-    YACAtomInt29 = 0x5D,
-    YACAtomInt30 = 0x5E,
-    YACAtomInt31 = 0x5F,
-    YACAtomIntN1 = 0x60,
-    YACAtomIntN2 = 0x61,
-    YACAtomIntN3 = 0x62,
-    YACAtomIntN4 = 0x63,
-    YACAtomIntN5 = 0x64,
-    YACAtomIntN6 = 0x65,
-    YACAtomIntN7 = 0x66,
-    YACAtomIntN8 = 0x67,
-    YACAtomIntN9 = 0x68,
-    YACAtomIntN10 = 0x69,
-    YACAtomIntN11 = 0x6A,
-    YACAtomIntN12 = 0x6B,
-    YACAtomIntN13 = 0x6C,
-    YACAtomIntN14 = 0x6D,
-    YACAtomIntN15 = 0x6E,
-    YACAtomIntN16 = 0x6F,
-    YACAtomIntN17 = 0x70,
-    YACAtomIntN18 = 0x71,
-    YACAtomIntN19 = 0x72,
-    YACAtomIntN20 = 0x73,
-    YACAtomIntN21 = 0x74,
-    YACAtomIntN22 = 0x75,
-    YACAtomIntN23 = 0x76,
-    YACAtomIntN24 = 0x77,
-    YACAtomIntN25 = 0x78,
-    YACAtomIntN26 = 0x79,
-    YACAtomIntN27 = 0x7A,
-    YACAtomIntN28 = 0x7B,
-    YACAtomIntN29 = 0x7C,
-    YACAtomIntN30 = 0x7D,
-    YACAtomIntN31 = 0x7E,
-    YACAtomIntN32 = 0x7F,
 
     YACAtomStrings = 0x80,
     YACAtomIsUTF8 = 0x40,
index abd04ecb317c1754e2b9d70a2fcba45e7e4226f740be008c7fe4b493e374952c..d9327a008c1b5276c5a41f12f5962989faac83b1a331f6b9f5e5a20f7bf695e7 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <string.h>
 
 #include "atoms.h"
 #include "dec.h"
@@ -23,7 +24,7 @@
 #include "utf8.h"
 
 enum YACErr
-YACAtomDecode(
+YACAtomDecode( // NOLINT(misc-no-recursion)
     size_t *got,
     struct YACAtom *atom,
     const unsigned char *buf,
@@ -94,53 +95,6 @@ YACAtomDecode(
         return YACErrNo;
     }
 
-    if ((atom->tag >= YACAtomInt0) && (atom->tag < YACAtomInt0 + 32)) {
-        atom->typ = YACItemPint;
-        atom->v.pint = (uint64_t)(atom->tag - YACAtomInt0);
-        return YACErrNo;
-    }
-    if ((atom->tag >= YACAtomIntN1) && (atom->tag < YACAtomIntN1 + 32)) {
-        atom->typ = YACItemNint;
-        atom->v.nint = -1 - (int64_t)(atom->tag - YACAtomIntN1);
-        return YACErrNo;
-    }
-    switch (atom->tag & (uint8_t)0xF0) {
-    case YACAtomIntPos1:
-    case YACAtomIntNeg1: {
-        atom->typ = ((atom->tag & (uint8_t)YACAtomIntNeg1) == YACAtomIntNeg1) ?
-                        YACItemNint :
-                        YACItemPint;
-        const size_t l = (atom->tag & (uint8_t)0x0F) + 1;
-        (*got) += l;
-        if (len < (*got)) {
-            return YACErrNotEnough;
-        }
-        if (buf[1] == 0) {
-            return YACErrIntNonMinimal;
-        }
-        if (l > 8) {
-            atom->typ = YACItemRaw;
-            atom->v.str.len = l;
-            atom->v.str.ptr = buf + 1;
-        } else {
-            atom->v.pint = yacFromBE(buf + 1, l);
-            if ((atom->v.pint) < 32) {
-                return YACErrIntNonMinimal;
-            }
-            if (atom->typ == YACItemNint) {
-                if (atom->v.pint >= ((uint64_t)1 << (uint8_t)63)) {
-                    atom->typ = YACItemRaw;
-                    atom->v.str.len = l;
-                    atom->v.str.ptr = buf + 1;
-                } else {
-                    atom->v.nint = -1 - (int64_t)(atom->v.pint);
-                }
-            }
-        }
-        return YACErrNo;
-    }
-    }
-
     switch (atom->tag) {
     case YACAtomEOC:
         atom->typ = YACItemEOC;
@@ -183,6 +137,50 @@ YACAtomDecode(
         break;
     }
 
+    case YACAtomPint:
+    case YACAtomNint: {
+        atom->typ = (atom->tag == YACAtomPint) ? YACItemPint : YACItemNint;
+        size_t binGot = 0;
+        struct YACAtom bin;
+        memset(&bin, 0, sizeof(struct YACAtom));
+        enum YACErr err = YACAtomDecode(&binGot, &bin, buf + 1, len - 1);
+        if (err != YACErrNo) {
+            return err;
+        }
+        (*got) += binGot;
+        if (bin.typ != YACItemBin) {
+            return YACErrIntNonBin;
+        }
+        if (bin.v.str.len == 0) {
+            if (atom->typ == YACItemPint) {
+                atom->v.pint = 0;
+            } else {
+                atom->v.nint = -1;
+            }
+            return YACErrNo;
+        }
+        if (bin.v.str.ptr[0] == 0) {
+            return YACErrIntNonMinimal;
+        }
+        if (bin.v.str.len > 8) {
+            atom->typ = YACItemRaw;
+            atom->v.str.len = binGot;
+            atom->v.str.ptr = buf + 1;
+            return YACErrNo;
+        }
+        atom->v.pint = yacFromBE(bin.v.str.ptr, bin.v.str.len);
+        if (atom->typ == YACItemNint) {
+            if (atom->v.pint >= ((uint64_t)1 << (uint8_t)63)) {
+                atom->typ = YACItemRaw;
+                atom->v.str.len = binGot;
+                atom->v.str.ptr = buf + 1;
+            } else {
+                atom->v.nint = -1 - (int64_t)(atom->v.pint);
+            }
+        }
+        return YACErrNo;
+    }
+
     case YACAtomFloat16:
     case YACAtomFloat32:
     case YACAtomFloat64:
index c06d8ab4a1ab6471eb3f958b96155f09b600218ea8b10454b5c94f08929ea061..c582ac7c963005c7ace796b13f45f2f9d564e8070fc6e94561f8433d1c8e75f5 100644 (file)
@@ -73,9 +73,9 @@ enum YACItemType {
 //     @code{.chunkLen} is the length of the chunk. @code{.chunks} is
 //     the number of chunks, including the terminating binary string.
 // @item .v.str
-//     @code{.ptr} points to the start of the binary/UTF-8 string.
-//     @code{.len} is its length in bytes. TAI64 datetimes are stored as
-//     strings too. Raw values use it as a payload.
+//     @code{.ptr} points to the start of the binary/UTF-8/TAI64*
+//     string. @code{.len} is its length in bytes.
+//     Raw values use it as a payload.
 // @end table
 // @end deftp
 struct YACAtom {
index 81df522b155c34a145c3bc82752021966cc032e168df6d3dd4d0972c55e13b09..36cbbe2d522e8dbbf40eb9027b87a4d8ae21c6b14e45203c843c14d76187049b 100644 (file)
@@ -74,31 +74,28 @@ YACAtomUUIDEncode(
 static bool
 yacAtomIntEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
 {
-    if (v < 32) {
-        (*len) = 1;
-        if (cap < 1) {
-            return false;
-        }
-        buf[0] = (unsigned char)v;
-        return true;
+    if (cap < 1) {
+        return false;
+    }
+    if (v == 0) {
+        const bool ok =
+            YACAtomBinEncode(len, buf + 1, cap - 1, (const unsigned char *)"", 0);
+        (*len)++;
+        return ok;
     }
-    size_t bits = 8;
     size_t l = 0;
     for (;;) {
-        if (v < ((uint64_t)1 << bits)) {
+        if (v < ((uint64_t)1 << ((l + 1) * 8))) {
             break;
         }
         l++;
-        bits += 8;
     }
-    if (cap < (1 + l)) {
-        return false;
-    }
-    buf[0] = (unsigned char)l;
     l++;
-    yacToBE(buf + 1, l, v);
-    (*len) = 1 + l;
-    return true;
+    unsigned char be[8] = {0};
+    yacToBE(be, l, v);
+    const bool ok = YACAtomBinEncode(len, buf + 1, cap - 1, be, l);
+    (*len)++;
+    return ok;
 }
 
 bool
@@ -106,7 +103,7 @@ YACAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, const uint6
 {
     bool ok = yacAtomIntEncode(len, buf, cap, v);
     if (ok) {
-        buf[0] |= (unsigned char)((v < 32) ? YACAtomInt0 : YACAtomIntPos1);
+        buf[0] = YACAtomPint;
     }
     return ok;
 }
@@ -120,7 +117,7 @@ YACAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int64
     const uint64_t vp = (uint64_t)(-(v + 1));
     bool ok = yacAtomIntEncode(len, buf, cap, vp);
     if (ok) {
-        buf[0] |= (unsigned char)((vp < 32) ? YACAtomIntN1 : YACAtomIntNeg1);
+        buf[0] = YACAtomNint;
     }
     return ok;
 }
index 6f547482b4e9d25e7dba4ac43f1a9a2b541b745ffc42d0740b1eb5ee13797b1a..8e199c57d8ea16b6e47d1dccdfcf8b9c1209a65251cd505786cea9faf8248330 100644 (file)
@@ -16,6 +16,8 @@ YACErr2Str(const enum YACErr err)
         return "LenTooBig";
     case YACErrBadUTF8:
         return "BadUTF8";
+    case YACErrIntNonBin:
+        return "IntNonBin";
     case YACErrIntNonMinimal:
         return "IntNonMinimal";
     case YACErrBlobBadAtom:
index 7ee9570510dd96cb7324548e2f286385d31254d90035ee6698c735f94b1973fa..f3b8c28bb644e2eafe776713f82272a28911a0aa357a95c7b6227f0b1941ea29 100644 (file)
@@ -48,6 +48,7 @@ enum YACErr {
     YACErrUnknownType,
     YACErrLenTooBig,
     YACErrBadUTF8,
+    YACErrIntNonBin,
     YACErrIntNonMinimal,
     YACErrBlobBadAtom,
     YACErrBlobBadTerm,
index ebb5f944f3ee1dc808714bd404c9e1735bf55f3437d6056c549c3ef7407b8a3e..dab86b4a957729a3d411a660e1c7459acd2c706c4e6d64c8abd7a55fe70025f1 100644 (file)
@@ -16,6 +16,8 @@ func _() {
        _ = x[AtomList-8]
        _ = x[AtomMap-9]
        _ = x[AtomBlob-11]
+       _ = x[AtomPInt-12]
+       _ = x[AtomNInt-13]
        _ = x[AtomFloat16-16]
        _ = x[AtomFloat32-17]
        _ = x[AtomFloat64-18]
@@ -24,119 +26,22 @@ func _() {
        _ = x[AtomTAI64-24]
        _ = x[AtomTAI64N-25]
        _ = x[AtomTAI64NA-26]
-       _ = x[AtomIntPos1-32]
-       _ = x[AtomIntPos2-33]
-       _ = x[AtomIntPos3-34]
-       _ = x[AtomIntPos4-35]
-       _ = x[AtomIntPos5-36]
-       _ = x[AtomIntPos6-37]
-       _ = x[AtomIntPos7-38]
-       _ = x[AtomIntPos8-39]
-       _ = x[AtomIntPos9-40]
-       _ = x[AtomIntPos10-41]
-       _ = x[AtomIntPos11-42]
-       _ = x[AtomIntPos12-43]
-       _ = x[AtomIntPos13-44]
-       _ = x[AtomIntPos14-45]
-       _ = x[AtomIntPos15-46]
-       _ = x[AtomIntPos16-47]
-       _ = x[AtomIntNeg1-48]
-       _ = x[AtomIntNeg2-49]
-       _ = x[AtomIntNeg3-50]
-       _ = x[AtomIntNeg4-51]
-       _ = x[AtomIntNeg5-52]
-       _ = x[AtomIntNeg6-53]
-       _ = x[AtomIntNeg7-54]
-       _ = x[AtomIntNeg8-55]
-       _ = x[AtomIntNeg9-56]
-       _ = x[AtomIntNeg10-57]
-       _ = x[AtomIntNeg11-58]
-       _ = x[AtomIntNeg12-59]
-       _ = x[AtomIntNeg13-60]
-       _ = x[AtomIntNeg14-61]
-       _ = x[AtomIntNeg15-62]
-       _ = x[AtomIntNeg16-63]
-       _ = x[AtomInt0-64]
-       _ = x[AtomInt1-65]
-       _ = x[AtomInt2-66]
-       _ = x[AtomInt3-67]
-       _ = x[AtomInt4-68]
-       _ = x[AtomInt5-69]
-       _ = x[AtomInt6-70]
-       _ = x[AtomInt7-71]
-       _ = x[AtomInt8-72]
-       _ = x[AtomInt9-73]
-       _ = x[AtomInt10-74]
-       _ = x[AtomInt11-75]
-       _ = x[AtomInt12-76]
-       _ = x[AtomInt13-77]
-       _ = x[AtomInt14-78]
-       _ = x[AtomInt15-79]
-       _ = x[AtomInt16-80]
-       _ = x[AtomInt17-81]
-       _ = x[AtomInt18-82]
-       _ = x[AtomInt19-83]
-       _ = x[AtomInt20-84]
-       _ = x[AtomInt21-85]
-       _ = x[AtomInt22-86]
-       _ = x[AtomInt23-87]
-       _ = x[AtomInt24-88]
-       _ = x[AtomInt25-89]
-       _ = x[AtomInt26-90]
-       _ = x[AtomInt27-91]
-       _ = x[AtomInt28-92]
-       _ = x[AtomInt29-93]
-       _ = x[AtomInt30-94]
-       _ = x[AtomInt31-95]
-       _ = x[AtomIntN1-96]
-       _ = x[AtomIntN2-97]
-       _ = x[AtomIntN3-98]
-       _ = x[AtomIntN4-99]
-       _ = x[AtomIntN5-100]
-       _ = x[AtomIntN6-101]
-       _ = x[AtomIntN7-102]
-       _ = x[AtomIntN8-103]
-       _ = x[AtomIntN9-104]
-       _ = x[AtomIntN10-105]
-       _ = x[AtomIntN11-106]
-       _ = x[AtomIntN12-107]
-       _ = x[AtomIntN13-108]
-       _ = x[AtomIntN14-109]
-       _ = x[AtomIntN15-110]
-       _ = x[AtomIntN16-111]
-       _ = x[AtomIntN17-112]
-       _ = x[AtomIntN18-113]
-       _ = x[AtomIntN19-114]
-       _ = x[AtomIntN20-115]
-       _ = x[AtomIntN21-116]
-       _ = x[AtomIntN22-117]
-       _ = x[AtomIntN23-118]
-       _ = x[AtomIntN24-119]
-       _ = x[AtomIntN25-120]
-       _ = x[AtomIntN26-121]
-       _ = x[AtomIntN27-122]
-       _ = x[AtomIntN28-123]
-       _ = x[AtomIntN29-124]
-       _ = x[AtomIntN30-125]
-       _ = x[AtomIntN31-126]
-       _ = x[AtomIntN32-127]
 }
 
 const (
        _AtomType_name_0 = "AtomEOCAtomNILAtomFalseAtomTrueAtomUUID"
        _AtomType_name_1 = "AtomListAtomMap"
-       _AtomType_name_2 = "AtomBlob"
+       _AtomType_name_2 = "AtomBlobAtomPIntAtomNInt"
        _AtomType_name_3 = "AtomFloat16AtomFloat32AtomFloat64AtomFloat128AtomFloat256"
        _AtomType_name_4 = "AtomTAI64AtomTAI64NAtomTAI64NA"
-       _AtomType_name_5 = "AtomIntPos1AtomIntPos2AtomIntPos3AtomIntPos4AtomIntPos5AtomIntPos6AtomIntPos7AtomIntPos8AtomIntPos9AtomIntPos10AtomIntPos11AtomIntPos12AtomIntPos13AtomIntPos14AtomIntPos15AtomIntPos16AtomIntNeg1AtomIntNeg2AtomIntNeg3AtomIntNeg4AtomIntNeg5AtomIntNeg6AtomIntNeg7AtomIntNeg8AtomIntNeg9AtomIntNeg10AtomIntNeg11AtomIntNeg12AtomIntNeg13AtomIntNeg14AtomIntNeg15AtomIntNeg16AtomInt0AtomInt1AtomInt2AtomInt3AtomInt4AtomInt5AtomInt6AtomInt7AtomInt8AtomInt9AtomInt10AtomInt11AtomInt12AtomInt13AtomInt14AtomInt15AtomInt16AtomInt17AtomInt18AtomInt19AtomInt20AtomInt21AtomInt22AtomInt23AtomInt24AtomInt25AtomInt26AtomInt27AtomInt28AtomInt29AtomInt30AtomInt31AtomIntN1AtomIntN2AtomIntN3AtomIntN4AtomIntN5AtomIntN6AtomIntN7AtomIntN8AtomIntN9AtomIntN10AtomIntN11AtomIntN12AtomIntN13AtomIntN14AtomIntN15AtomIntN16AtomIntN17AtomIntN18AtomIntN19AtomIntN20AtomIntN21AtomIntN22AtomIntN23AtomIntN24AtomIntN25AtomIntN26AtomIntN27AtomIntN28AtomIntN29AtomIntN30AtomIntN31AtomIntN32"
 )
 
 var (
        _AtomType_index_0 = [...]uint8{0, 7, 14, 23, 31, 39}
        _AtomType_index_1 = [...]uint8{0, 8, 15}
+       _AtomType_index_2 = [...]uint8{0, 8, 16, 24}
        _AtomType_index_3 = [...]uint8{0, 11, 22, 33, 45, 57}
        _AtomType_index_4 = [...]uint8{0, 9, 19, 30}
-       _AtomType_index_5 = [...]uint16{0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 123, 135, 147, 159, 171, 183, 194, 205, 216, 227, 238, 249, 260, 271, 282, 294, 306, 318, 330, 342, 354, 366, 374, 382, 390, 398, 406, 414, 422, 430, 438, 446, 455, 464, 473, 482, 491, 500, 509, 518, 527, 536, 545, 554, 563, 572, 581, 590, 599, 608, 617, 626, 635, 644, 653, 662, 671, 680, 689, 698, 707, 716, 725, 735, 745, 755, 765, 775, 785, 795, 805, 815, 825, 835, 845, 855, 865, 875, 885, 895, 905, 915, 925, 935, 945, 955}
 )
 
 func (i AtomType) String() string {
@@ -146,17 +51,15 @@ func (i AtomType) String() string {
        case 8 <= i && i <= 9:
                i -= 8
                return _AtomType_name_1[_AtomType_index_1[i]:_AtomType_index_1[i+1]]
-       case i == 11:
-               return _AtomType_name_2
+       case 11 <= i && i <= 13:
+               i -= 11
+               return _AtomType_name_2[_AtomType_index_2[i]:_AtomType_index_2[i+1]]
        case 16 <= i && i <= 20:
                i -= 16
                return _AtomType_name_3[_AtomType_index_3[i]:_AtomType_index_3[i+1]]
        case 24 <= i && i <= 26:
                i -= 24
                return _AtomType_name_4[_AtomType_index_4[i]:_AtomType_index_4[i+1]]
-       case 32 <= i && i <= 127:
-               i -= 32
-               return _AtomType_name_5[_AtomType_index_5[i]:_AtomType_index_5[i+1]]
        default:
                return "AtomType(" + strconv.FormatInt(int64(i), 10) + ")"
        }
index 0dadf2b3f0a28aa4432d646c2dc83653c3d0334f880d891fabcceee3da5488a1..1cc4e8c34d5e7fb49f07eadcb0c04e2f6335ca8086489a15e920baf3dc0cdd30 100644 (file)
@@ -4,13 +4,36 @@ import (
        "bytes"
        "encoding/hex"
        "fmt"
+       "math/big"
        "time"
 
        "github.com/google/uuid"
        "go.cypherpunks.su/yac/gyac"
 )
 
+func mustHexDec(s string) []byte {
+       b, err := hex.DecodeString(s)
+       if err != nil {
+               panic(err)
+       }
+       return b
+}
+
 func main() {
+       bigint80 := big.NewInt(0)
+       bigint80.SetBytes(mustHexDec("0100000000000000000000"))
+       bigintFF := big.NewInt(0)
+       bigintFF.SetBytes(mustHexDec("0100000000000000000000000000000000"))
+       bigintN80 := big.NewInt(0)
+       bigintN80.SetBytes(mustHexDec("0100000000000000000000"))
+       bigintN80 = bigintN80.Neg(bigintN80)
+       bigintNFF := big.NewInt(0)
+       bigintNFF.SetBytes(mustHexDec("0100000000000000000000000000000001"))
+       bigintNFF = bigintNFF.Neg(bigintNFF)
+       bigintN := big.NewInt(0)
+       bigintN.SetBytes(mustHexDec("e5a461280341856d4ad908a69ea5f3ccc10c7882142bb7d801cc380f26b6b4d69632024ee521f8cfafb443d49a2a3d0cc73bb4757e882f5396ed302b418210d0d49d71be86ca699cf5ee3bd6d57ed658e69316229644ba650c92d7f0d4db29c3ad1dfa9979166f4c6e79561a58f8e2c63d08df4e2246ed1f64d2d613a19d8c9a6870e6188e2f3ad40c038fda30452f8ddfcd212a6a974bc25ec6a0564c66a7d28750ff9db458b74441e49ee5e82dbf4974d645678e0ad031f97aaba855451eef17a89b42821e530816dd5793a83b7a82e8ede81e7f3395691f761784f8bc627961cd40845ee908a40b9d1f01927b38eb1a7d4efd60db0944f7ec1b832b7e6eb1833f9a351576ad5de571fae8865da7514f06b0fbf38c1f2a8538f5d38b4e18001ccbb9ddcb488530f6086d14744d8b5672166e48e9ef93772575db66b6f257c6ffad6e2c291510c5ed02e1a8b24b44ec1e2a91686238e8defd18c01998634a5076a6b7f85fc81a1d61a15b2c528dfa082ce3e3e2ca649ac04817ec5c123e0b761ab103f780c014f021bbeb7ea3b86e0ca1c833e38ef5c897a6d7e1f4a2398c490b3d65e2f45c7fae402d1df1698b6fddb185481664871c2664bfd1686b2b3372783f1856f6247a3f8437a2818f68b7c4ea13a5f57b73c72870b684045f15"))
+       bigintN = bigintN.Neg(bigintN)
+
        data := map[string]any{
                "ints": map[string]any{
                        "pos": []any{
@@ -21,7 +44,8 @@ func main() {
                                uint64(123),
                                uint64(1234),
                                uint64(12345678),
-                               &gyac.Raw{T: gyac.AtomIntPos11, V: []byte("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")},
+                               bigint80,
+                               bigintFF,
                        },
                        "neg": []any{
                                int64(-1),
@@ -31,7 +55,9 @@ func main() {
                                int64(-123),
                                int64(-1234),
                                int64(-12345678),
-                               &gyac.Raw{T: gyac.AtomIntNeg10, V: []byte("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")},
+                               bigintN80,
+                               bigintNFF,
+                               bigintN,
                        },
                },
                "nil":  nil,
index 5f7b0f4a833fe98dbde3549218a27158a2c105c629527b141012ebb3e3daedf2..64fa841eb53317eb0649e08b8563cbae6e40da12429e315481ae17b578b3c16e 100644 (file)
@@ -4,6 +4,7 @@ import (
        "bytes"
        "encoding/hex"
        "fmt"
+       "math/big"
        "time"
 
        "github.com/google/uuid"
@@ -11,6 +12,14 @@ import (
        "go.cypherpunks.su/yac/gyac"
 )
 
+func mustHexDec(s string) []byte {
+       b, err := hex.DecodeString(s)
+       if err != nil {
+               panic(err)
+       }
+       return b
+}
+
 func main() {
        buf := make([]byte, 0, 68*1024)
        {
@@ -88,10 +97,17 @@ func main() {
                                buf = gyac.AtomIntEncode(buf, -123)
                                buf = gyac.AtomIntEncode(buf, -1234)
                                buf = gyac.AtomIntEncode(buf, -12345678)
-                               buf = gyac.AtomRawEncode(buf, &gyac.Raw{
-                                       T: gyac.AtomIntNeg10,
-                                       V: []byte("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"),
-                               })
+
+                               b := big.NewInt(0)
+                               b.SetBytes(mustHexDec("0100000000000000000000"))
+                               b = b.Neg(b)
+                               buf = gyac.AtomBigIntEncode(buf, b)
+                               b.SetBytes(mustHexDec("0100000000000000000000000000000001"))
+                               b = b.Neg(b)
+                               buf = gyac.AtomBigIntEncode(buf, b)
+                               b.SetBytes(mustHexDec("e5a461280341856d4ad908a69ea5f3ccc10c7882142bb7d801cc380f26b6b4d69632024ee521f8cfafb443d49a2a3d0cc73bb4757e882f5396ed302b418210d0d49d71be86ca699cf5ee3bd6d57ed658e69316229644ba650c92d7f0d4db29c3ad1dfa9979166f4c6e79561a58f8e2c63d08df4e2246ed1f64d2d613a19d8c9a6870e6188e2f3ad40c038fda30452f8ddfcd212a6a974bc25ec6a0564c66a7d28750ff9db458b74441e49ee5e82dbf4974d645678e0ad031f97aaba855451eef17a89b42821e530816dd5793a83b7a82e8ede81e7f3395691f761784f8bc627961cd40845ee908a40b9d1f01927b38eb1a7d4efd60db0944f7ec1b832b7e6eb1833f9a351576ad5de571fae8865da7514f06b0fbf38c1f2a8538f5d38b4e18001ccbb9ddcb488530f6086d14744d8b5672166e48e9ef93772575db66b6f257c6ffad6e2c291510c5ed02e1a8b24b44ec1e2a91686238e8defd18c01998634a5076a6b7f85fc81a1d61a15b2c528dfa082ce3e3e2ca649ac04817ec5c123e0b761ab103f780c014f021bbeb7ea3b86e0ca1c833e38ef5c897a6d7e1f4a2398c490b3d65e2f45c7fae402d1df1698b6fddb185481664871c2664bfd1686b2b3372783f1856f6247a3f8437a2818f68b7c4ea13a5f57b73c72870b684045f15"))
+                               b = b.Neg(b)
+                               buf = gyac.AtomBigIntEncode(buf, b)
                                buf = gyac.AtomEOCEncode(buf)
                        }
                        {
@@ -104,10 +120,11 @@ func main() {
                                buf = gyac.AtomUIntEncode(buf, 123)
                                buf = gyac.AtomUIntEncode(buf, 1234)
                                buf = gyac.AtomUIntEncode(buf, 12345678)
-                               buf = gyac.AtomRawEncode(buf, &gyac.Raw{
-                                       T: gyac.AtomIntPos11,
-                                       V: []byte("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
-                               })
+                               b := big.NewInt(0)
+                               b.SetBytes(mustHexDec("0100000000000000000000"))
+                               buf = gyac.AtomBigIntEncode(buf, b)
+                               b.SetBytes(mustHexDec("0100000000000000000000000000000000"))
+                               buf = gyac.AtomBigIntEncode(buf, b)
                                buf = gyac.AtomEOCEncode(buf)
                        }
                        buf = gyac.AtomEOCEncode(buf)
index 860915593f23323e0f7af06cd214148d027be7a8e449a37268fee0a7b35976c3..d9dc3e622f748ec932bb8e82229713417c783ca8d754ed374e6cf9fe84fe9cab 100644 (file)
@@ -19,6 +19,7 @@ import (
        "encoding/hex"
        "errors"
        "fmt"
+       "math/big"
        "strings"
        "unicode/utf8"
        "unsafe"
@@ -36,6 +37,7 @@ const (
        ItemUUID
        ItemUInt
        ItemInt
+       ItemBigInt
        ItemList
        ItemMap
        ItemBlob
@@ -138,55 +140,6 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) {
                }
                return
        }
-       if AtomType(item.T) >= AtomInt0 && AtomType(item.T) < AtomInt0+32 {
-               item.V = uint64(item.T - byte(AtomInt0))
-               item.T = byte(ItemUInt)
-               return
-       }
-       if AtomType(item.T) >= AtomIntN1 && AtomType(item.T) < AtomIntN1+32 {
-               item.V = -1 - int64(item.T-byte(AtomIntN1))
-               item.T = byte(ItemInt)
-               return
-       }
-       switch item.T & 0xF0 {
-       case byte(AtomIntPos1), byte(AtomIntNeg1):
-               l := int((item.T & 0x0F) + 1)
-               if (item.T & byte(AtomIntNeg1)) == byte(AtomIntNeg1) {
-                       item.T = byte(ItemInt)
-               } else {
-                       item.T = byte(ItemUInt)
-               }
-               off += l
-               if len(buf) < off {
-                       err = ErrNotEnough
-                       return
-               }
-               if buf[1] == 0 {
-                       err = ErrIntNonMinimal
-                       return
-               }
-               if l > 8 {
-                       item.T = byte(ItemRaw)
-                       item.V = &Raw{T: AtomType(buf[0]), V: buf[1 : 1+l]}
-                       return
-               }
-               v := FromBE(buf[1 : 1+l])
-               if v < 32 {
-                       err = ErrIntNonMinimal
-                       return
-               }
-               if item.Typ() == ItemUInt {
-                       item.V = v
-               } else {
-                       if v >= (1 << 63) {
-                               item.T = byte(ItemRaw)
-                               item.V = &Raw{T: AtomType(buf[0]), V: buf[1 : 1+l]}
-                       } else {
-                               item.V = -1 - int64(v)
-                       }
-               }
-               return
-       }
        switch AtomType(item.T) {
        case AtomEOC:
                item.T = byte(ItemEOC)
@@ -226,6 +179,64 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) {
                chunkLen++
                item.V = chunkLen
 
+       case AtomPInt, AtomNInt:
+               if AtomType(item.T) == AtomPInt {
+                       item.T = byte(ItemUInt)
+               } else {
+                       item.T = byte(ItemInt)
+               }
+               var bin *Item
+               var binOff int
+               bin, binOff, err = AtomDecode(buf[1:])
+               off += binOff
+               if err != nil {
+                       return
+               }
+               if ItemType(bin.T) != ItemBin {
+                       err = errors.New("wrong int value")
+                       return
+               }
+               raw := bin.V.([]byte)
+               if len(raw) == 0 {
+                       if item.Typ() == ItemUInt {
+                               item.V = uint64(0)
+                       } else {
+                               item.V = int64(-1)
+                       }
+                       return
+               }
+               if raw[0] == 0 {
+                       err = ErrIntNonMinimal
+                       return
+               }
+               if len(raw) > 8 {
+                       bi := big.NewInt(0)
+                       bi = bi.SetBytes(raw)
+                       if item.Typ() == ItemInt {
+                               n1 := big.NewInt(-1)
+                               bi = bi.Sub(n1, bi)
+                       }
+                       item.T = byte(ItemBigInt)
+                       item.V = bi
+                       return
+               }
+               v := FromBE(raw)
+               if item.Typ() == ItemUInt {
+                       item.V = v
+               } else {
+                       if v >= (1 << 63) {
+                               bi := big.NewInt(0)
+                               bi = bi.SetBytes(raw)
+                               n1 := big.NewInt(-1)
+                               bi = bi.Sub(n1, bi)
+                               item.T = byte(ItemBigInt)
+                               item.V = bi
+                       } else {
+                               item.V = -1 - int64(v)
+                       }
+               }
+               return
+
        case AtomFloat16, AtomFloat32, AtomFloat64, AtomFloat128, AtomFloat256:
                var l int
                switch AtomType(item.T) {
index 05ffc1375108838917df42c5c6956007fd2361eeabae2a40940d1d63510651f6..38afc9cd5f2e9a37324ae64c76f23922e16cc22282ea1f9b46af916bc27dfdce 100644 (file)
 package gyac
 
 import (
+       "math/big"
        "sort"
 
        "github.com/google/uuid"
 )
 
+var BigIntZero = big.NewInt(0)
+
 type AtomType byte
 
 //go:generate stringer -type=AtomType
@@ -33,6 +36,8 @@ const (
        AtomList     AtomType = 0x08
        AtomMap      AtomType = 0x09
        AtomBlob     AtomType = 0x0B
+       AtomPInt     AtomType = 0x0C
+       AtomNInt     AtomType = 0x0D
        AtomFloat16  AtomType = 0x10
        AtomFloat32  AtomType = 0x11
        AtomFloat64  AtomType = 0x12
@@ -41,102 +46,6 @@ const (
        AtomTAI64    AtomType = 0x18
        AtomTAI64N   AtomType = 0x19
        AtomTAI64NA  AtomType = 0x1A
-       AtomIntPos1  AtomType = 0x20
-       AtomIntPos2  AtomType = 0x21
-       AtomIntPos3  AtomType = 0x22
-       AtomIntPos4  AtomType = 0x23
-       AtomIntPos5  AtomType = 0x24
-       AtomIntPos6  AtomType = 0x25
-       AtomIntPos7  AtomType = 0x26
-       AtomIntPos8  AtomType = 0x27
-       AtomIntPos9  AtomType = 0x28
-       AtomIntPos10 AtomType = 0x29
-       AtomIntPos11 AtomType = 0x2A
-       AtomIntPos12 AtomType = 0x2B
-       AtomIntPos13 AtomType = 0x2C
-       AtomIntPos14 AtomType = 0x2D
-       AtomIntPos15 AtomType = 0x2E
-       AtomIntPos16 AtomType = 0x2F
-       AtomIntNeg1  AtomType = 0x30
-       AtomIntNeg2  AtomType = 0x31
-       AtomIntNeg3  AtomType = 0x32
-       AtomIntNeg4  AtomType = 0x33
-       AtomIntNeg5  AtomType = 0x34
-       AtomIntNeg6  AtomType = 0x35
-       AtomIntNeg7  AtomType = 0x36
-       AtomIntNeg8  AtomType = 0x37
-       AtomIntNeg9  AtomType = 0x38
-       AtomIntNeg10 AtomType = 0x39
-       AtomIntNeg11 AtomType = 0x3A
-       AtomIntNeg12 AtomType = 0x3B
-       AtomIntNeg13 AtomType = 0x3C
-       AtomIntNeg14 AtomType = 0x3D
-       AtomIntNeg15 AtomType = 0x3E
-       AtomIntNeg16 AtomType = 0x3F
-       AtomInt0     AtomType = 0x40
-       AtomInt1     AtomType = 0x41
-       AtomInt2     AtomType = 0x42
-       AtomInt3     AtomType = 0x43
-       AtomInt4     AtomType = 0x44
-       AtomInt5     AtomType = 0x45
-       AtomInt6     AtomType = 0x46
-       AtomInt7     AtomType = 0x47
-       AtomInt8     AtomType = 0x48
-       AtomInt9     AtomType = 0x49
-       AtomInt10    AtomType = 0x4A
-       AtomInt11    AtomType = 0x4B
-       AtomInt12    AtomType = 0x4C
-       AtomInt13    AtomType = 0x4D
-       AtomInt14    AtomType = 0x4E
-       AtomInt15    AtomType = 0x4F
-       AtomInt16    AtomType = 0x50
-       AtomInt17    AtomType = 0x51
-       AtomInt18    AtomType = 0x52
-       AtomInt19    AtomType = 0x53
-       AtomInt20    AtomType = 0x54
-       AtomInt21    AtomType = 0x55
-       AtomInt22    AtomType = 0x56
-       AtomInt23    AtomType = 0x57
-       AtomInt24    AtomType = 0x58
-       AtomInt25    AtomType = 0x59
-       AtomInt26    AtomType = 0x5A
-       AtomInt27    AtomType = 0x5B
-       AtomInt28    AtomType = 0x5C
-       AtomInt29    AtomType = 0x5D
-       AtomInt30    AtomType = 0x5E
-       AtomInt31    AtomType = 0x5F
-       AtomIntN1    AtomType = 0x60
-       AtomIntN2    AtomType = 0x61
-       AtomIntN3    AtomType = 0x62
-       AtomIntN4    AtomType = 0x63
-       AtomIntN5    AtomType = 0x64
-       AtomIntN6    AtomType = 0x65
-       AtomIntN7    AtomType = 0x66
-       AtomIntN8    AtomType = 0x67
-       AtomIntN9    AtomType = 0x68
-       AtomIntN10   AtomType = 0x69
-       AtomIntN11   AtomType = 0x6A
-       AtomIntN12   AtomType = 0x6B
-       AtomIntN13   AtomType = 0x6C
-       AtomIntN14   AtomType = 0x6D
-       AtomIntN15   AtomType = 0x6E
-       AtomIntN16   AtomType = 0x6F
-       AtomIntN17   AtomType = 0x70
-       AtomIntN18   AtomType = 0x71
-       AtomIntN19   AtomType = 0x72
-       AtomIntN20   AtomType = 0x73
-       AtomIntN21   AtomType = 0x74
-       AtomIntN22   AtomType = 0x75
-       AtomIntN23   AtomType = 0x76
-       AtomIntN24   AtomType = 0x77
-       AtomIntN25   AtomType = 0x78
-       AtomIntN26   AtomType = 0x79
-       AtomIntN27   AtomType = 0x7A
-       AtomIntN28   AtomType = 0x7B
-       AtomIntN29   AtomType = 0x7C
-       AtomIntN30   AtomType = 0x7D
-       AtomIntN31   AtomType = 0x7E
-       AtomIntN32   AtomType = 0x7F
 
        AtomStrings = 0x80
        AtomIsUTF8  = 0x40
@@ -162,46 +71,42 @@ func AtomUUIDEncode(buf []byte, v uuid.UUID) []byte {
 }
 
 func atomUintEncode(v uint64) (buf []byte) {
-       if v < 32 {
-               return []byte{byte(v)}
+       if v == 0 {
+               return AtomBinEncode(nil, []byte{})
        }
-       bits := 8
        l := 0
        for {
-               if v < (1 << bits) {
+               if v < (1 << ((l + 1) * 8)) {
                        break
                }
                l++
-               bits += 8
        }
-       buf = make([]byte, 1+l+1)
-       buf[0] = byte(l)
-       ToBE(buf[1:], v)
-       return
+       buf = make([]byte, l+1)
+       ToBE(buf, v)
+       return AtomBinEncode(nil, buf)
 }
 
 func AtomUIntEncode(buf []byte, v uint64) []byte {
-       b := atomUintEncode(v)
-       if v < 32 {
-               b[0] |= byte(AtomInt0)
-       } else {
-               b[0] |= byte(AtomIntPos1)
-       }
-       return append(buf, b...)
+       return append(buf, append([]byte{byte(AtomPInt)}, atomUintEncode(v)...)...)
 }
 
 func AtomIntEncode(buf []byte, v int64) []byte {
        if v >= 0 {
                return AtomUIntEncode(buf, uint64(v))
        }
-       vp := uint64(-(v + 1))
-       b := atomUintEncode(vp)
-       if vp < 32 {
-               b[0] |= byte(AtomIntN1)
-       } else {
-               b[0] |= byte(AtomIntNeg1)
+       return append(buf, append([]byte{byte(AtomNInt)},
+               atomUintEncode(uint64(-(v+1)))...)...)
+}
+
+func AtomBigIntEncode(buf []byte, v *big.Int) []byte {
+       // TODO: fallback to U?IntEncode for small values
+       if v.Cmp(BigIntZero) >= 0 {
+               return append(buf, AtomBinEncode([]byte{byte(AtomPInt)}, v.Bytes())...)
        }
-       return append(buf, b...)
+       n1 := big.NewInt(-1)
+       v = v.Abs(v)
+       v = v.Add(v, n1)
+       return append(buf, AtomBinEncode([]byte{byte(AtomNInt)}, v.Bytes())...)
 }
 
 func AtomListEncode(buf []byte) []byte {
@@ -284,6 +189,8 @@ func EncodeItem(buf []byte, item *Item) []byte {
                return AtomUIntEncode(buf, item.V.(uint64))
        case ItemInt:
                return AtomIntEncode(buf, item.V.(int64))
+       case ItemBigInt:
+               return AtomBigIntEncode(buf, item.V.(*big.Int))
        case ItemList:
                buf = AtomListEncode(buf)
                for _, v := range item.V.([]*Item) {
index 7016888a9ea29928501a8b740185e1f78a16e40dc81c74a9e15ddf3b485fb750..cd99d5022856db92a3e69d60e2f704a60b79b4aa8cfcdc5504a296f0759ebcc3 100644 (file)
@@ -14,19 +14,20 @@ func _() {
        _ = x[ItemUUID-3]
        _ = x[ItemUInt-4]
        _ = x[ItemInt-5]
-       _ = x[ItemList-6]
-       _ = x[ItemMap-7]
-       _ = x[ItemBlob-8]
-       _ = x[ItemFloat-9]
-       _ = x[ItemTAI64-10]
-       _ = x[ItemBin-11]
-       _ = x[ItemStr-12]
-       _ = x[ItemRaw-13]
+       _ = x[ItemBigInt-6]
+       _ = x[ItemList-7]
+       _ = x[ItemMap-8]
+       _ = x[ItemBlob-9]
+       _ = x[ItemFloat-10]
+       _ = x[ItemTAI64-11]
+       _ = x[ItemBin-12]
+       _ = x[ItemStr-13]
+       _ = x[ItemRaw-14]
 }
 
-const _ItemType_name = "ItemEOCItemNILItemBoolItemUUIDItemUIntItemIntItemListItemMapItemBlobItemFloatItemTAI64ItemBinItemStrItemRaw"
+const _ItemType_name = "ItemEOCItemNILItemBoolItemUUIDItemUIntItemIntItemBigIntItemListItemMapItemBlobItemFloatItemTAI64ItemBinItemStrItemRaw"
 
-var _ItemType_index = [...]uint8{0, 7, 14, 22, 30, 38, 45, 53, 60, 68, 77, 86, 93, 100, 107}
+var _ItemType_index = [...]uint8{0, 7, 14, 22, 30, 38, 45, 55, 63, 70, 78, 87, 96, 103, 110, 117}
 
 func (i ItemType) String() string {
        if i >= ItemType(len(_ItemType_index)-1) {
index 3d21c3f5b63beb2c5e8a5ed3a722e3ae127efee5e94cc296104e876f2b1ec261..8e990207fd50505626ebd2d3f5486c57e7ebe32814e8be5ec096ac56b6afbcce 100644 (file)
@@ -18,6 +18,7 @@ package gyac
 import (
        "errors"
        "fmt"
+       "math/big"
        "reflect"
        "strings"
        "time"
@@ -53,6 +54,8 @@ func (v *Item) ToGo() any {
                return ret
        case ItemBlob:
                return v.V.(*Blob)
+       case ItemBigInt:
+               return v.V.(*big.Int)
        case ItemFloat:
                panic("float is unsupported")
        case ItemTAI64:
@@ -114,6 +117,8 @@ func ItemFromGo(v any) *Item {
                return &Item{T: byte(ItemTAI64), V: taiRaw}
        case *Raw:
                return &Item{T: byte(ItemRaw), V: v}
+       case *big.Int:
+               return &Item{T: byte(ItemBigInt), V: v}
        }
        switch reflect.TypeOf(v).Kind() {
        case reflect.Pointer:
index 3be038c827c37ee588fc2ec6c821675d80b6587324f2d4c99e9b070c269a1128..0e909faa2775d1422ead679e5816deb53286692e257cbb51f8746f0ac02792ba 100644 (file)
@@ -136,12 +136,13 @@ class UUID:
         return self.v
 
 
+from math import ceil
+
+
 class Int:
-    tags = tuple(v for v in range(0x20, 0x80))
-    tagLenPositive = 0x20
-    tagLenNegative = 0x30
-    tagValPositive = 0x40
-    tagValNegative = 0x60
+    tagPositive = 0x0C
+    tagNegative = 0x0D
+    tags = (tagPositive, tagNegative)
 
     def __init__(self, v=0):
         if isinstance(v, Int):
@@ -149,43 +150,32 @@ class Int:
         self.v = v
 
     def encode(self):
-        neg = False
+        tag = self.tagPositive
         v = self.v
         if v < 0:
-            neg = True
+            tag = self.tagNegative
             v = (-v) - 1
-        if v < 32:
-            return (
-                (self.tagValNegative if neg else self.tagValPositive) | v
-            ).to_bytes(1, "big")
-        tag = self.tagLenNegative if neg else self.tagLenPositive
-        for l, bits in enumerate(range(8, 128, 8)):
-            if v < (1<<bits):
-                break
-        else:
-            l = 15
-        return (tag | l).to_bytes(1, "big") + v.to_bytes(l+1, "big")
+        if v == 0:
+            return tag.to_bytes(1, "big") + Bin(b"").encode()
+        return tag.to_bytes(1, "big") + Bin(
+            v.to_bytes(ceil(v.bit_length() / 8), "big")
+        ).encode()
 
     @classmethod
     def decode(klass, data):
-        if (data[0] >= klass.tagValPositive) and (data[0] < (klass.tagValPositive+32)):
-            v = data[0] - klass.tagValPositive
-            return klass(v), data[1:]
-        if (data[0] >= klass.tagValNegative) and (data[0] < (klass.tagValNegative+32)):
-            return klass(-1 - (data[0] - klass.tagValNegative)), data[1:]
-        if (data[0] & 0xF0) not in (klass.tagLenPositive, klass.tagLenNegative):
+        if data[0] not in klass.tags:
             raise WrongTag
-        neg = (data[0] & 0xF0) == klass.tagLenNegative
-        l = (data[0] & 0x0F) + 1
-        data = data[1:]
-        if len(data) < l:
-            raise NotEnoughData(l)
-        v = int.from_bytes(data[:l], "big")
-        if v < 32:
+        neg = data[0] == klass.tagNegative
+        raw, data = Bin.decode(data[1:])
+        raw = bytes(raw)
+        if raw == b"":
+            return (Int(-1) if neg else Int(0)), data
+        if raw[0] == 0:
             raise DecodeError("non-miminal encoding")
+        v = int.from_bytes(raw, "big")
         if neg:
             v = -1 - v
-        return klass(v), data[l:]
+        return klass(v), data
 
     def __repr__(self):
         return "INT(%d)" % self.v
index beb87103a0cd4af56f8f7d039469caefca0c35d1cd7c441128fc30db36d83ede..7fd79b0926d7535c8145eba21d27bebc2f15eff4b2796a85fefe9f9e85284146 100644 (file)
@@ -3,8 +3,15 @@ from pyac import *
 
 data = {
     "ints": {
-        "pos": [0, 1, 31, 32, 123, 1234, 12345678, 1<<80],
-        "neg": [-1, -2, -32, -33, -123, -1234, -12345678, -1<<80],
+        "pos": [
+            0, 1, 31, 32, 123, 1234, 12345678, 1<<80,
+            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 1,
+        ],
+        "neg": [
+            -1, -2, -32, -33, -123, -1234, -12345678, -1<<80,
+            -(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 2),
+            -123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789,
+        ],
     },
     "floats": [Raw((Float.tags[1], b"\x01\x02\x03\x04"))],
     "nil": None,
index c915bb49379c5a01739abe687a6119a1d61f370f243620cb86ef9a230a048c07..5a53d3de92ab96fe424b004bdbfa8c94f93ac135ea715507653440fc40979560 100644 (file)
@@ -33,7 +33,7 @@ Example representations:
 @multitable @columnfractions .5 .5
 
 @item LIST[] @tab @code{08 00}
-@item LIST[INT(123) FALSE] @tab @code{08 207B 02 00}
+@item LIST[INT(123) FALSE] @tab @code{08 0C817B 02 00}
 @item MAP[foo: LIST["bar"]] @tab @code{09 C3666F6F 08 C3626172 00 00}
 @item SET[sig, dh] @tab @code{09 C26468 01 C3736967 01 00}
 
index 0dfd7f018bfa9a431b5a764547a7fa53e6b631d9736cbde49a7c92f914caa9e9..7c421c42e39d4fff1983d8fa111b3f50e7cf2e1fc323115964a43c9447f5c051 100644 (file)
@@ -20,7 +20,9 @@ Possible values for the tag:
 @item 008 @tab 08 @tab @code{00001000} @tab 0 @tab @ref{Containers, LIST}
 @item 009 @tab 09 @tab @code{00001001} @tab 0 @tab @ref{Containers, MAP}
 @item 010 @tab 0A @tab @code{00001010} @tab
-@item 011 @tab 0B @tab @code{00001011} @tab 8 @tab @ref{Blobs, BLOB}
+@item 011 @tab 0B @tab @code{00001011} @tab 8+~ @tab @ref{Blobs, BLOB}
+@item 012 @tab 0C @tab @code{00001100} @tab 1+~ @tab @ref{Integers, +INT}
+@item 013 @tab 0D @tab @code{00001101} @tab 1+~ @tab @ref{Integers, -INT}
 @item [...]
 @item 016 @tab 10 @tab @code{00010000} @tab 2 @tab @ref{Floats, FLOAT16}
 @item 017 @tab 11 @tab @code{00010001} @tab 4 @tab @ref{Floats, FLOAT32}
@@ -32,18 +34,6 @@ Possible values for the tag:
 @item 025 @tab 19 @tab @code{00011001} @tab 12 @tab @ref{TAI64, TAI64N}
 @item 026 @tab 1A @tab @code{00011010} @tab 16 @tab @ref{TAI64, TAI64NA}
 @item [...]
-@item 032 @tab 20 @tab @code{0010LLLL} @tab 1 @tab @ref{Integers, +INT(len=1)}
-@item [...]
-@item 047 @tab 2F @tab @code{0010LLLL} @tab 16 @tab @ref{Integers, +INT(len=16)}
-@item 048 @tab 30 @tab @code{0011LLLL} @tab 1 @tab @ref{Integers, -INT(len=1)}
-@item [...]
-@item 063 @tab 3F @tab @code{0011LLLL} @tab 16 @tab @ref{Integers, -INT(len=16)}
-@item 064 @tab 40 @tab @code{010VVVVV} @tab 0 @tab @ref{Integers, INT=0}
-@item [...]
-@item 095 @tab 5F @tab @code{010VVVVV} @tab 0 @tab @ref{Integers, INT=31}
-@item 096 @tab 60 @tab @code{011VVVVV} @tab 0 @tab @ref{Integers, INT=-1}
-@item [...]
-@item 127 @tab 7F @tab @code{011VVVVV} @tab 0 @tab @ref{Integers, INT=-32}
 @item 128 @tab 80 @tab @code{10LLLLLL} @tab 0 @tab @ref{Strings, BIN(len=0)}
 @item [...]
 @item 188 @tab BC @tab @code{10111100} @tab 60 @tab @ref{Strings, BIN(len=60)}
index df312552b45430570c5537d550ae35f2c2b2d80e197d8f6753fd26e4b4085047..874efd67a3c02f35b731d58831aa1cbc9d164e9df32aca13e0813e3fc1403eca 100644 (file)
@@ -2,51 +2,33 @@
 @cindex INT
 @section Integers
 
-Integers can be encoded in short or long form. Separate types are used
-for positive and negative values.
+Integers are encoded as ordinary binary string, that has prepended byte
+indicating is it positive or negative integer. Negative integers store
+their absolute value the same way as positive integers. After decoding,
+their value is subtracted from -1. Negative value encoded as @code{0x02}
+means @code{-1 - 0x02 => -3}.
 
-Short form eats five bits of the tag
-for positive values in @code{[0..32)} range,
-and negative ones in @code{[-1..-32]} range.
-
-Long form is encoded as a big-endian number of varying length.
-@code{*INT(len=1)..*INT(len=16)} types are for 8-, 16-, 24-, ...,
-128-bit integer representations.
-
-Shortest possible form @strong{must} be used, that means no leading zero byte.
-Short values (<32) @strong{must} be encoded in a short form.
-
-Negative integers store their absolute value the same way as positive
-integers. After decoding, their value is subtracted from -1. Negative
-value encoded as @code{0x02} means @code{-1 - 0x02 => -3}.
-
-Hint: both positive and negative long integer tag's value keeps the
-length in the last 16 bits. So there is no need in dealing with every
-tag's reserved value. You can check first 4 bits of the header to
-determine is it positive or negative integer, and then treat remaining 4
-bits as a length (+1).
+Shortest possible form @strong{must} be used, that means no leading zero
+byte. 0 and -1 values are empty strings, so even they won't have leading
+zero.
 
 Example representations:
 
 @multitable @columnfractions .5 .5
 
-@item 0 @tab @code{40}
-@item 1 @tab @code{41}
-@item 10 @tab @code{4A}
-@item 31 @tab @code{5F}
-@item 32 @tab @code{20 20}
-@item 100 @tab @code{20 64}
-@item 65536 @tab @code{22 01 00 00}
-@item 1000000000000 @tab @code{24 E8 D4 A5 10 00}
-@item 18446744073709551615 @tab @code{27 FF FF FF FF FF FF FF FF}
-@item 18446744073709551616 @tab @code{28 01 00 00 00 00 00 00 00 00}
-@item -18446744073709551616 @tab @code{37 FF FF FF FF FF FF FF FF}
-@item -18446744073709551617 @tab @code{38 01 00 00 00 00 00 00 00 00}
-@item -1 @tab @code{60}
-@item -10 @tab @code{69}
-@item -32 @tab @code{7F}
-@item -33 @tab @code{30 20}
-@item -100 @tab @code{30 63}
-@item -65536 @tab @code{31 FF FF}
+@item 0 @tab @code{0C 80}
+@item 1 @tab @code{0C 81 01}
+@item 10 @tab @code{0C 81 0A}
+@item 100 @tab @code{0C 01 64}
+@item 65536 @tab @code{0C 83 010000}
+@item 1000000000000 @tab @code{0C 85 E8D4A51000}
+@item 18446744073709551615 @tab @code{0C 88 FFFFFFFFFFFFFFFF}
+@item 18446744073709551616 @tab @code{0C 89 010000000000000000}
+@item -18446744073709551616 @tab @code{0D 88 FFFFFFFFFFFFFFFF}
+@item -18446744073709551617 @tab @code{0D 89 010000000000000000}
+@item -1 @tab @code{0D 80}
+@item -10 @tab @code{0D 81 09}
+@item -100 @tab @code{0D 81 63}
+@item -65536 @tab @code{0D 82 FFFF}
 
 @end multitable
index 6365a74f35bb75f72a91429342110ba82545cf2799b891036e05e89711819971..aedc196c28b171c20cdb8e85f9874fe47b49f567c1adb6ea8205b94b7c473a43 100644 (file)
@@ -15,9 +15,9 @@
 @item 008 @tab 08 @tab @code{00001000} @tab 0 @tab @ref{Containers, LIST}
 @item 009 @tab 09 @tab @code{00001001} @tab 0 @tab @ref{Containers, MAP}
 @item 010 @tab 0A @tab @code{00001010} @tab 0 @tab
-@item 011 @tab 0B @tab @code{00001011} @tab 8 @tab @ref{Blobs, BLOB}
-@item 012 @tab 0C @tab @code{00001100} @tab 0 @tab
-@item 013 @tab 0D @tab @code{00001101} @tab 0 @tab
+@item 011 @tab 0B @tab @code{00001011} @tab 8+~ @tab @ref{Blobs, BLOB}
+@item 012 @tab 0C @tab @code{00001100} @tab 1+~ @tab @ref{Integers, +INT}
+@item 013 @tab 0D @tab @code{00001101} @tab 1+~ @tab @ref{Integers, -INT}
 @item 014 @tab 0E @tab @code{00001110} @tab 0 @tab
 @item 015 @tab 0F @tab @code{00001111} @tab 0 @tab
 @item 016 @tab 10 @tab @code{00010000} @tab 2 @tab @ref{Floats, FLOAT16}
 @item 029 @tab 1D @tab @code{00011101} @tab 0 @tab
 @item 030 @tab 1E @tab @code{00011110} @tab 0 @tab
 @item 031 @tab 1F @tab @code{00011111} @tab 0 @tab
-@item 032 @tab 20 @tab @code{00100000} @tab 1 @tab @ref{Integers, +INT(len=1)}
-@item 033 @tab 21 @tab @code{00100001} @tab 2 @tab @ref{Integers, +INT(len=2)}
-@item 034 @tab 22 @tab @code{00100010} @tab 3 @tab @ref{Integers, +INT(len=3)}
-@item 035 @tab 23 @tab @code{00100011} @tab 4 @tab @ref{Integers, +INT(len=4)}
-@item 036 @tab 24 @tab @code{00100100} @tab 5 @tab @ref{Integers, +INT(len=5)}
-@item 037 @tab 25 @tab @code{00100101} @tab 6 @tab @ref{Integers, +INT(len=6)}
-@item 038 @tab 26 @tab @code{00100110} @tab 7 @tab @ref{Integers, +INT(len=7)}
-@item 039 @tab 27 @tab @code{00100111} @tab 8 @tab @ref{Integers, +INT(len=8)}
-@item 040 @tab 28 @tab @code{00101000} @tab 9 @tab @ref{Integers, +INT(len=9)}
-@item 041 @tab 29 @tab @code{00101001} @tab 10 @tab @ref{Integers, +INT(len=10)}
-@item 042 @tab 2A @tab @code{00101010} @tab 11 @tab @ref{Integers, +INT(len=11)}
-@item 043 @tab 2B @tab @code{00101011} @tab 12 @tab @ref{Integers, +INT(len=12)}
-@item 044 @tab 2C @tab @code{00101100} @tab 13 @tab @ref{Integers, +INT(len=13)}
-@item 045 @tab 2D @tab @code{00101101} @tab 14 @tab @ref{Integers, +INT(len=14)}
-@item 046 @tab 2E @tab @code{00101110} @tab 15 @tab @ref{Integers, +INT(len=15)}
-@item 047 @tab 2F @tab @code{00101111} @tab 16 @tab @ref{Integers, +INT(len=16)}
-@item 048 @tab 30 @tab @code{00110000} @tab 1 @tab @ref{Integers, -INT(len=1)}
-@item 049 @tab 31 @tab @code{00110001} @tab 2 @tab @ref{Integers, -INT(len=2)}
-@item 050 @tab 32 @tab @code{00110010} @tab 3 @tab @ref{Integers, -INT(len=3)}
-@item 051 @tab 33 @tab @code{00110011} @tab 4 @tab @ref{Integers, -INT(len=4)}
-@item 052 @tab 34 @tab @code{00110100} @tab 5 @tab @ref{Integers, -INT(len=5)}
-@item 053 @tab 35 @tab @code{00110101} @tab 6 @tab @ref{Integers, -INT(len=6)}
-@item 054 @tab 36 @tab @code{00110110} @tab 7 @tab @ref{Integers, -INT(len=7)}
-@item 055 @tab 37 @tab @code{00110111} @tab 8 @tab @ref{Integers, -INT(len=8)}
-@item 056 @tab 38 @tab @code{00111000} @tab 9 @tab @ref{Integers, -INT(len=9)}
-@item 057 @tab 39 @tab @code{00111001} @tab 10 @tab @ref{Integers, -INT(len=10)}
-@item 058 @tab 3A @tab @code{00111010} @tab 11 @tab @ref{Integers, -INT(len=11)}
-@item 059 @tab 3B @tab @code{00111011} @tab 12 @tab @ref{Integers, -INT(len=12)}
-@item 060 @tab 3C @tab @code{00111100} @tab 13 @tab @ref{Integers, -INT(len=13)}
-@item 061 @tab 3D @tab @code{00111101} @tab 14 @tab @ref{Integers, -INT(len=14)}
-@item 062 @tab 3E @tab @code{00111110} @tab 15 @tab @ref{Integers, -INT(len=15)}
-@item 063 @tab 3F @tab @code{00111111} @tab 16 @tab @ref{Integers, -INT(len=16)}
-@item 064 @tab 40 @tab @code{01000000} @tab 0 @tab @ref{Integers, INT=0}
-@item 065 @tab 41 @tab @code{01000001} @tab 0 @tab @ref{Integers, INT=1}
-@item 066 @tab 42 @tab @code{01000010} @tab 0 @tab @ref{Integers, INT=2}
-@item 067 @tab 43 @tab @code{01000011} @tab 0 @tab @ref{Integers, INT=3}
-@item 068 @tab 44 @tab @code{01000100} @tab 0 @tab @ref{Integers, INT=4}
-@item 069 @tab 45 @tab @code{01000101} @tab 0 @tab @ref{Integers, INT=5}
-@item 070 @tab 46 @tab @code{01000110} @tab 0 @tab @ref{Integers, INT=6}
-@item 071 @tab 47 @tab @code{01000111} @tab 0 @tab @ref{Integers, INT=7}
-@item 072 @tab 48 @tab @code{01001000} @tab 0 @tab @ref{Integers, INT=8}
-@item 073 @tab 49 @tab @code{01001001} @tab 0 @tab @ref{Integers, INT=9}
-@item 074 @tab 4A @tab @code{01001010} @tab 0 @tab @ref{Integers, INT=10}
-@item 075 @tab 4B @tab @code{01001011} @tab 0 @tab @ref{Integers, INT=11}
-@item 076 @tab 4C @tab @code{01001100} @tab 0 @tab @ref{Integers, INT=12}
-@item 077 @tab 4D @tab @code{01001101} @tab 0 @tab @ref{Integers, INT=13}
-@item 078 @tab 4E @tab @code{01001110} @tab 0 @tab @ref{Integers, INT=14}
-@item 079 @tab 4F @tab @code{01001111} @tab 0 @tab @ref{Integers, INT=15}
-@item 080 @tab 50 @tab @code{01010000} @tab 0 @tab @ref{Integers, INT=16}
-@item 081 @tab 51 @tab @code{01010001} @tab 0 @tab @ref{Integers, INT=17}
-@item 082 @tab 52 @tab @code{01010010} @tab 0 @tab @ref{Integers, INT=18}
-@item 083 @tab 53 @tab @code{01010011} @tab 0 @tab @ref{Integers, INT=19}
-@item 084 @tab 54 @tab @code{01010100} @tab 0 @tab @ref{Integers, INT=20}
-@item 085 @tab 55 @tab @code{01010101} @tab 0 @tab @ref{Integers, INT=21}
-@item 086 @tab 56 @tab @code{01010110} @tab 0 @tab @ref{Integers, INT=22}
-@item 087 @tab 57 @tab @code{01010111} @tab 0 @tab @ref{Integers, INT=23}
-@item 088 @tab 58 @tab @code{01011000} @tab 0 @tab @ref{Integers, INT=24}
-@item 089 @tab 59 @tab @code{01011001} @tab 0 @tab @ref{Integers, INT=25}
-@item 090 @tab 5A @tab @code{01011010} @tab 0 @tab @ref{Integers, INT=26}
-@item 091 @tab 5B @tab @code{01011011} @tab 0 @tab @ref{Integers, INT=27}
-@item 092 @tab 5C @tab @code{01011100} @tab 0 @tab @ref{Integers, INT=28}
-@item 093 @tab 5D @tab @code{01011101} @tab 0 @tab @ref{Integers, INT=29}
-@item 094 @tab 5E @tab @code{01011110} @tab 0 @tab @ref{Integers, INT=30}
-@item 095 @tab 5F @tab @code{01011111} @tab 0 @tab @ref{Integers, INT=31}
-@item 096 @tab 60 @tab @code{01100000} @tab 0 @tab @ref{Integers, INT=-1}
-@item 097 @tab 61 @tab @code{01100001} @tab 0 @tab @ref{Integers, INT=-2}
-@item 098 @tab 62 @tab @code{01100010} @tab 0 @tab @ref{Integers, INT=-3}
-@item 099 @tab 63 @tab @code{01100011} @tab 0 @tab @ref{Integers, INT=-4}
-@item 100 @tab 64 @tab @code{01100100} @tab 0 @tab @ref{Integers, INT=-5}
-@item 101 @tab 65 @tab @code{01100101} @tab 0 @tab @ref{Integers, INT=-6}
-@item 102 @tab 66 @tab @code{01100110} @tab 0 @tab @ref{Integers, INT=-7}
-@item 103 @tab 67 @tab @code{01100111} @tab 0 @tab @ref{Integers, INT=-8}
-@item 104 @tab 68 @tab @code{01101000} @tab 0 @tab @ref{Integers, INT=-9}
-@item 105 @tab 69 @tab @code{01101001} @tab 0 @tab @ref{Integers, INT=-10}
-@item 106 @tab 6A @tab @code{01101010} @tab 0 @tab @ref{Integers, INT=-11}
-@item 107 @tab 6B @tab @code{01101011} @tab 0 @tab @ref{Integers, INT=-12}
-@item 108 @tab 6C @tab @code{01101100} @tab 0 @tab @ref{Integers, INT=-13}
-@item 109 @tab 6D @tab @code{01101101} @tab 0 @tab @ref{Integers, INT=-14}
-@item 110 @tab 6E @tab @code{01101110} @tab 0 @tab @ref{Integers, INT=-15}
-@item 111 @tab 6F @tab @code{01101111} @tab 0 @tab @ref{Integers, INT=-16}
-@item 112 @tab 70 @tab @code{01110000} @tab 0 @tab @ref{Integers, INT=-17}
-@item 113 @tab 71 @tab @code{01110001} @tab 0 @tab @ref{Integers, INT=-18}
-@item 114 @tab 72 @tab @code{01110010} @tab 0 @tab @ref{Integers, INT=-19}
-@item 115 @tab 73 @tab @code{01110011} @tab 0 @tab @ref{Integers, INT=-20}
-@item 116 @tab 74 @tab @code{01110100} @tab 0 @tab @ref{Integers, INT=-21}
-@item 117 @tab 75 @tab @code{01110101} @tab 0 @tab @ref{Integers, INT=-22}
-@item 118 @tab 76 @tab @code{01110110} @tab 0 @tab @ref{Integers, INT=-23}
-@item 119 @tab 77 @tab @code{01110111} @tab 0 @tab @ref{Integers, INT=-24}
-@item 120 @tab 78 @tab @code{01111000} @tab 0 @tab @ref{Integers, INT=-25}
-@item 121 @tab 79 @tab @code{01111001} @tab 0 @tab @ref{Integers, INT=-26}
-@item 122 @tab 7A @tab @code{01111010} @tab 0 @tab @ref{Integers, INT=-27}
-@item 123 @tab 7B @tab @code{01111011} @tab 0 @tab @ref{Integers, INT=-28}
-@item 124 @tab 7C @tab @code{01111100} @tab 0 @tab @ref{Integers, INT=-29}
-@item 125 @tab 7D @tab @code{01111101} @tab 0 @tab @ref{Integers, INT=-30}
-@item 126 @tab 7E @tab @code{01111110} @tab 0 @tab @ref{Integers, INT=-31}
-@item 127 @tab 7F @tab @code{01111111} @tab 0 @tab @ref{Integers, INT=-32}
+@item 032 @tab 20 @tab @code{00100000} @tab 0 @tab
+@item 033 @tab 21 @tab @code{00100001} @tab 0 @tab
+@item 034 @tab 22 @tab @code{00100010} @tab 0 @tab
+@item 035 @tab 23 @tab @code{00100011} @tab 0 @tab
+@item 036 @tab 24 @tab @code{00100100} @tab 0 @tab
+@item 037 @tab 25 @tab @code{00100101} @tab 0 @tab
+@item 038 @tab 26 @tab @code{00100110} @tab 0 @tab
+@item 039 @tab 27 @tab @code{00100111} @tab 0 @tab
+@item 040 @tab 28 @tab @code{00101000} @tab 0 @tab
+@item 041 @tab 29 @tab @code{00101001} @tab 0 @tab
+@item 042 @tab 2A @tab @code{00101010} @tab 0 @tab
+@item 043 @tab 2B @tab @code{00101011} @tab 0 @tab
+@item 044 @tab 2C @tab @code{00101100} @tab 0 @tab
+@item 045 @tab 2D @tab @code{00101101} @tab 0 @tab
+@item 046 @tab 2E @tab @code{00101110} @tab 0 @tab
+@item 047 @tab 2F @tab @code{00101111} @tab 0 @tab
+@item 048 @tab 30 @tab @code{00110000} @tab 0 @tab
+@item 049 @tab 31 @tab @code{00110001} @tab 0 @tab
+@item 050 @tab 32 @tab @code{00110010} @tab 0 @tab
+@item 051 @tab 33 @tab @code{00110011} @tab 0 @tab
+@item 052 @tab 34 @tab @code{00110100} @tab 0 @tab
+@item 053 @tab 35 @tab @code{00110101} @tab 0 @tab
+@item 054 @tab 36 @tab @code{00110110} @tab 0 @tab
+@item 055 @tab 37 @tab @code{00110111} @tab 0 @tab
+@item 056 @tab 38 @tab @code{00111000} @tab 0 @tab
+@item 057 @tab 39 @tab @code{00111001} @tab 0 @tab
+@item 058 @tab 3A @tab @code{00111010} @tab 0 @tab
+@item 059 @tab 3B @tab @code{00111011} @tab 0 @tab
+@item 060 @tab 3C @tab @code{00111100} @tab 0 @tab
+@item 061 @tab 3D @tab @code{00111101} @tab 0 @tab
+@item 062 @tab 3E @tab @code{00111110} @tab 0 @tab
+@item 063 @tab 3F @tab @code{00111111} @tab 0 @tab
+@item 064 @tab 40 @tab @code{01000000} @tab 0 @tab
+@item 065 @tab 41 @tab @code{01000001} @tab 0 @tab
+@item 066 @tab 42 @tab @code{01000010} @tab 0 @tab
+@item 067 @tab 43 @tab @code{01000011} @tab 0 @tab
+@item 068 @tab 44 @tab @code{01000100} @tab 0 @tab
+@item 069 @tab 45 @tab @code{01000101} @tab 0 @tab
+@item 070 @tab 46 @tab @code{01000110} @tab 0 @tab
+@item 071 @tab 47 @tab @code{01000111} @tab 0 @tab
+@item 072 @tab 48 @tab @code{01001000} @tab 0 @tab
+@item 073 @tab 49 @tab @code{01001001} @tab 0 @tab
+@item 074 @tab 4A @tab @code{01001010} @tab 0 @tab
+@item 075 @tab 4B @tab @code{01001011} @tab 0 @tab
+@item 076 @tab 4C @tab @code{01001100} @tab 0 @tab
+@item 077 @tab 4D @tab @code{01001101} @tab 0 @tab
+@item 078 @tab 4E @tab @code{01001110} @tab 0 @tab
+@item 079 @tab 4F @tab @code{01001111} @tab 0 @tab
+@item 080 @tab 50 @tab @code{01010000} @tab 0 @tab
+@item 081 @tab 51 @tab @code{01010001} @tab 0 @tab
+@item 082 @tab 52 @tab @code{01010010} @tab 0 @tab
+@item 083 @tab 53 @tab @code{01010011} @tab 0 @tab
+@item 084 @tab 54 @tab @code{01010100} @tab 0 @tab
+@item 085 @tab 55 @tab @code{01010101} @tab 0 @tab
+@item 086 @tab 56 @tab @code{01010110} @tab 0 @tab
+@item 087 @tab 57 @tab @code{01010111} @tab 0 @tab
+@item 088 @tab 58 @tab @code{01011000} @tab 0 @tab
+@item 089 @tab 59 @tab @code{01011001} @tab 0 @tab
+@item 090 @tab 5A @tab @code{01011010} @tab 0 @tab
+@item 091 @tab 5B @tab @code{01011011} @tab 0 @tab
+@item 092 @tab 5C @tab @code{01011100} @tab 0 @tab
+@item 093 @tab 5D @tab @code{01011101} @tab 0 @tab
+@item 094 @tab 5E @tab @code{01011110} @tab 0 @tab
+@item 095 @tab 5F @tab @code{01011111} @tab 0 @tab
+@item 096 @tab 60 @tab @code{01100000} @tab 0 @tab
+@item 097 @tab 61 @tab @code{01100001} @tab 0 @tab
+@item 098 @tab 62 @tab @code{01100010} @tab 0 @tab
+@item 099 @tab 63 @tab @code{01100011} @tab 0 @tab
+@item 100 @tab 64 @tab @code{01100100} @tab 0 @tab
+@item 101 @tab 65 @tab @code{01100101} @tab 0 @tab
+@item 102 @tab 66 @tab @code{01100110} @tab 0 @tab
+@item 103 @tab 67 @tab @code{01100111} @tab 0 @tab
+@item 104 @tab 68 @tab @code{01101000} @tab 0 @tab
+@item 105 @tab 69 @tab @code{01101001} @tab 0 @tab
+@item 106 @tab 6A @tab @code{01101010} @tab 0 @tab
+@item 107 @tab 6B @tab @code{01101011} @tab 0 @tab
+@item 108 @tab 6C @tab @code{01101100} @tab 0 @tab
+@item 109 @tab 6D @tab @code{01101101} @tab 0 @tab
+@item 110 @tab 6E @tab @code{01101110} @tab 0 @tab
+@item 111 @tab 6F @tab @code{01101111} @tab 0 @tab
+@item 112 @tab 70 @tab @code{01110000} @tab 0 @tab
+@item 113 @tab 71 @tab @code{01110001} @tab 0 @tab
+@item 114 @tab 72 @tab @code{01110010} @tab 0 @tab
+@item 115 @tab 73 @tab @code{01110011} @tab 0 @tab
+@item 116 @tab 74 @tab @code{01110100} @tab 0 @tab
+@item 117 @tab 75 @tab @code{01110101} @tab 0 @tab
+@item 118 @tab 76 @tab @code{01110110} @tab 0 @tab
+@item 119 @tab 77 @tab @code{01110111} @tab 0 @tab
+@item 120 @tab 78 @tab @code{01111000} @tab 0 @tab
+@item 121 @tab 79 @tab @code{01111001} @tab 0 @tab
+@item 122 @tab 7A @tab @code{01111010} @tab 0 @tab
+@item 123 @tab 7B @tab @code{01111011} @tab 0 @tab
+@item 124 @tab 7C @tab @code{01111100} @tab 0 @tab
+@item 125 @tab 7D @tab @code{01111101} @tab 0 @tab
+@item 126 @tab 7E @tab @code{01111110} @tab 0 @tab
+@item 127 @tab 7F @tab @code{01111111} @tab 0 @tab
 @item 128 @tab 80 @tab @code{10000000} @tab 0 @tab @ref{Strings, BIN(len=0)}
 @item 129 @tab 81 @tab @code{10000001} @tab 1 @tab @ref{Strings, BIN(len=1)}
 @item 130 @tab 82 @tab @code{10000010} @tab 2 @tab @ref{Strings, BIN(len=2)}
index abecf2c82e1465f4d7f4dcb692b6006d743ec4418d72923990415f3472cf8fb6..feb97dc476372d43db19229e3000db56a135626104f437f77d80f2c8a32e6697 100644 (file)
@@ -12,6 +12,7 @@ MAP {
             {INT 1234}
             {INT 12345678}
             {INT [expr {1 << 80}]}
+            {INT [expr 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 1]}
         }}
         neg {LIST {
             {INT -1}
@@ -22,6 +23,8 @@ MAP {
             {INT -1234}
             {INT -12345678}
             {INT -[expr {1 << 80}]}
+            {INT [expr {-(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 2)}]}
+            {INT -123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789}
         }}
     }}
     floats {LIST {
index ee0ae7a00fc1fca8c676d82b6799411809621e5e61450f6d90a90cf315ea7109..311e46c48cd78c52c6b53ced31036e0894bfd38fa23b488d95c69a9a4b3c523b 100644 (file)
@@ -36,37 +36,36 @@ proc UUID {v} {
     add $v
 }
 
-proc toBE {l v} {
+proc toBEbin {l v} {
+    set a [list]
     for {set i 0} {$i < $l} {incr i} {
         set b [expr {($l - $i - 1) * 8}]
-        char [expr {($v & (0xFF << $b)) >> $b}]
+        lappend a [binary format c [expr {($v & (0xFF << $b)) >> $b}]]
     }
+    return $a
+}
+
+proc toBE {l v} {
+    foreach c [toBEbin $l $v] { add $c }
 }
 
 proc INT {v} {
-    set neg 0
-    if {$v < 0} {
-        set neg 1
+    if {$v >= 0} {
+        char [expr 0x0C]
+    } {
+        char [expr 0x0D]
         set v [expr {- ($v + 1)}]
     }
-    if {$v < 32} {
-        if {$neg} {
-            char [expr {0x60 | $v}]
-        } {
-            char [expr {0x40 | $v}]
-        }
+    if {$v == 0} {
+        BIN ""
         return
     }
-    if {$neg} { set b [expr 0x30] } { set b [expr 0x20] }
-    set bits 8
     set l 0
     while {1} {
-        if {$v < [expr {1 << $bits}]} { break }
+        if {$v < [expr {1 << (($l+1)*8)}]} { break }
         incr l
-        incr bits 8
     }
-    char [expr {$b | $l}]
-    toBE [expr {$l + 1}] $v
+    BIN [join [toBEbin [expr {$l + 1}] $v] ""]
 }
 
 proc _str {atom v} {