From 45800ea4045d19cdd604cf8a88c6422049b333da Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 20 Dec 2020 03:59:59 -0300 Subject: [PATCH 01/66] Add BigInts --- changelog.md | 5 +- lib/js/jsbigint.nim | 132 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 lib/js/jsbigint.nim diff --git a/changelog.md b/changelog.md index 01eff1cd73ea..4f57d36584c0 100644 --- a/changelog.md +++ b/changelog.md @@ -56,7 +56,7 @@ - `writeStackTrace` is available in JS backend now. - `strscans.scanf` now supports parsing single characters. -- `strscans.scanTuple` added which uses `strscans.scanf` internally, returning a tuple which can be unpacked for easier usage of `scanf`. +- `strscans.scanTuple` added which uses `strscans.scanf` internally, returning a tuple which can be unpacked for easier usage of `scanf`. - Added `setutils.toSet` that can take any iterable and convert it to a built-in set, if the iterable yields a built-in settable type. @@ -66,6 +66,9 @@ - `echo` and `debugEcho` will now raise `IOError` if writing to stdout fails. Previous behavior silently ignored errors. See #16366. Use `-d:nimLegacyEchoNoRaise` for previous behavior. +- Add `jsbigint` module, arbitrary precision integers for JavaScript target. + + ## Language changes - `nimscript` now handles `except Exception as e`. diff --git a/lib/js/jsbigint.nim b/lib/js/jsbigint.nim new file mode 100644 index 000000000000..80b1a49c89a5 --- /dev/null +++ b/lib/js/jsbigint.nim @@ -0,0 +1,132 @@ +## Arbitrary precision integers. +## * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt + +type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. + +func newBigInt*(integer: cint): JsBigInt {.importjs: "BigInt(#)".} + ## Constructor for `JsBigInt`. + +func newBigInt*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} + ## Constructor for `JsBigInt`. + +func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString + +func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$1(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString + +func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString + +func toString*(this: JsBigInt; radix: cint): cstring {.importjs: "#.$1(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString + +func toString*(this: JsBigInt): cstring {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString + +func asIntN*(width: cint; bigInteger: JsBigInt): cint {.importjs: "BigInt.$1(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN + +func asUintN*(width: cint; bigInteger: JsBigInt): cint {.importjs: "BigInt.$1(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN + +func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `/`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `%`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `+=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} + +func `-=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} + +func `*=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} + +func `/=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} + +func `%=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} + +func `++`*(x: JsBigInt): JsBigInt {.importjs: "($1#)".} + +func `--`*(x: JsBigInt): JsBigInt {.importjs: "($1#)".} + +func `>`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} + +func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} + +func `>=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} + +func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} + +func `==`*(x, y: JsBigInt): bool {.importjs: "(# $1= #)".} + +func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} + +func `and`*(x, y: JsBigInt): JsBigInt {.importjs: "(# && #)".} + +func `or`*(x, y: JsBigInt): JsBigInt {.importjs: "(# || #)".} + +func `not`*(x: JsBigInt): JsBigInt {.importjs: "(!#)".} + +func `in`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} + +func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} + +func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} + +func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} + +func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} + +func inc*(a: JsBigInt): JsBigInt {.importjs: "(# += BigInt(1))", discardable.} + +func dec*(a: JsBigInt): JsBigInt {.importjs: "(# -= BigInt(1))", discardable.} + +func inc*(a, b: JsBigInt): JsBigInt {.importjs: "(# += #)", discardable.} + +func dec*(a, b: JsBigInt): JsBigInt {.importjs: "(# -= #)", discardable.} + +func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. + ## https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs + + +runnableExamples: + let big1: JsBigInt = newBigInt(2147483647.cint) + let big2: JsBigInt = newBigInt("666".cstring) + var big3: JsBigInt = newBigInt("2".cstring) + doAssert big1 != big2 + doAssert big1 > big2 + doAssert big1 >= big2 + doAssert big2 < big1 + doAssert big2 <= big1 + doAssert not(big1 == big2) + inc big3 + doAssert big3 == newBigInt(3.cint) + dec big3 + doAssert big3 == newBigInt(2.cint) + inc big3, newBigInt(420.cint) + doAssert big3 == newBigInt(422.cint) + dec big3, newBigInt(420.cint) + doAssert big3 == newBigInt(2.cint) + doAssert (big3 xor big2) == newBigInt(664.cint) + doAssert big1 % big2 == newBigInt("613".cstring) + doAssert -big1 == newBigInt("-2147483647".cstring) + doAssert big1 / big2 == newBigInt("3224449".cstring) + doAssert big1 + big2 == newBigInt("2147484313".cstring) + doAssert big1 - big2 == newBigInt("2147482981".cstring) + doAssert big1 shl big3 == newBigInt("8589934588".cstring) + doAssert big1 shr big3 == newBigInt("536870911".cstring) + doAssert big1 * big2 == newBigInt("1430224108902".cstring) + doAssert big1.toLocaleString("EN".cstring) == "2,147,483,647".cstring + doAssert big1.toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring + doAssert big1.toString() == "2147483647".cstring + doAssert big1.toString(10.cint) == "2147483647".cstring + doAssert big1.toString(2.cint) == "1111111111111111111111111111111".cstring + doAssert big2 ** big3 == newBigInt(443556.cint) + discard newBigInt("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) + discard newBigInt("0".cstring) + discard newBigInt("-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) From 1fd6edcc2f86341217e669b796f36e93dfbd79e1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 02:29:33 -0300 Subject: [PATCH 02/66] Renames tos plurals --- changelog.md | 2 +- lib/js/{jsbigint.nim => jsbigints.nim} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/js/{jsbigint.nim => jsbigints.nim} (100%) diff --git a/changelog.md b/changelog.md index ac6030719e0b..696bedc17541 100644 --- a/changelog.md +++ b/changelog.md @@ -66,7 +66,7 @@ - `echo` and `debugEcho` will now raise `IOError` if writing to stdout fails. Previous behavior silently ignored errors. See #16366. Use `-d:nimLegacyEchoNoRaise` for previous behavior. -- Add `jsbigint` module, arbitrary precision integers for JavaScript target. +- Add `jsbigints` module, arbitrary precision integers for JavaScript target. - Added new operations for singly- and doubly linked lists: `lists.toSinglyLinkedList` and `lists.toDoublyLinkedList` convert from `openArray`s; `lists.copy` implements diff --git a/lib/js/jsbigint.nim b/lib/js/jsbigints.nim similarity index 100% rename from lib/js/jsbigint.nim rename to lib/js/jsbigints.nim From 2492d72f2ce1acdfaadd541cecc75b8ce6473104 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 20:30:02 -0300 Subject: [PATCH 03/66] Bear review --- lib/js/jsbigints.nim | 55 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 80b1a49c89a5..8fdff7e46ef8 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -1,12 +1,11 @@ ## Arbitrary precision integers. ## * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt +when not defined(js) and not defined(nimdoc): + {.fatal: "Module jsbigints is designed to be used with the JavaScript backend.".} type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. -func newBigInt*(integer: cint): JsBigInt {.importjs: "BigInt(#)".} - ## Constructor for `JsBigInt`. - -func newBigInt*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} +func newBigInt*(integer: cstring or SomeInteger): JsBigInt {.importjs: "BigInt(#)".} ## Constructor for `JsBigInt`. func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} @@ -18,16 +17,16 @@ func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$ func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString -func toString*(this: JsBigInt; radix: cint): cstring {.importjs: "#.$1(#)".} +func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func toString*(this: JsBigInt): cstring {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString -func asIntN*(width: cint; bigInteger: JsBigInt): cint {.importjs: "BigInt.$1(#, #)".} +func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN -func asUintN*(width: cint; bigInteger: JsBigInt): cint {.importjs: "BigInt.$1(#, #)".} +func asUintN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} @@ -36,9 +35,11 @@ func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} -func `/`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} +func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} + ## Same as `div` but for `JsBigInt`. -func `%`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} +func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} + ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). func `+=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} @@ -50,9 +51,11 @@ func `/=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} func `%=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} -func `++`*(x: JsBigInt): JsBigInt {.importjs: "($1#)".} +func `inc`*(x: JsBigInt): JsBigInt {.importjs: "(++#)", discardable.} + ## Same as `inc` but for `JsBigInt` (uses JavaScript `++BigInt()`). -func `--`*(x: JsBigInt): JsBigInt {.importjs: "($1#)".} +func `dec`*(x: JsBigInt): JsBigInt {.importjs: "(--#)", discardable.} + ## Same as `dec` but for `JsBigInt` (uses JavaScript `--BigInt()`). func `>`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} @@ -82,10 +85,6 @@ func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} -func inc*(a: JsBigInt): JsBigInt {.importjs: "(# += BigInt(1))", discardable.} - -func dec*(a: JsBigInt): JsBigInt {.importjs: "(# -= BigInt(1))", discardable.} - func inc*(a, b: JsBigInt): JsBigInt {.importjs: "(# += #)", discardable.} func dec*(a, b: JsBigInt): JsBigInt {.importjs: "(# -= #)", discardable.} @@ -95,7 +94,7 @@ func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. runnableExamples: - let big1: JsBigInt = newBigInt(2147483647.cint) + let big1: JsBigInt = newBigInt(2147483647) let big2: JsBigInt = newBigInt("666".cstring) var big3: JsBigInt = newBigInt("2".cstring) doAssert big1 != big2 @@ -105,17 +104,17 @@ runnableExamples: doAssert big2 <= big1 doAssert not(big1 == big2) inc big3 - doAssert big3 == newBigInt(3.cint) + doAssert big3 == newBigInt(3) dec big3 - doAssert big3 == newBigInt(2.cint) - inc big3, newBigInt(420.cint) - doAssert big3 == newBigInt(422.cint) - dec big3, newBigInt(420.cint) - doAssert big3 == newBigInt(2.cint) - doAssert (big3 xor big2) == newBigInt(664.cint) - doAssert big1 % big2 == newBigInt("613".cstring) + doAssert big3 == newBigInt(2) + inc big3, newBigInt(420) + doAssert big3 == newBigInt(422) + dec big3, newBigInt(420) + doAssert big3 == newBigInt(2) + doAssert (big3 xor big2) == newBigInt(664) + doAssert (big1 mod big2) == newBigInt("613".cstring) doAssert -big1 == newBigInt("-2147483647".cstring) - doAssert big1 / big2 == newBigInt("3224449".cstring) + doAssert big1 div big2 == newBigInt("3224449".cstring) doAssert big1 + big2 == newBigInt("2147484313".cstring) doAssert big1 - big2 == newBigInt("2147482981".cstring) doAssert big1 shl big3 == newBigInt("8589934588".cstring) @@ -124,9 +123,9 @@ runnableExamples: doAssert big1.toLocaleString("EN".cstring) == "2,147,483,647".cstring doAssert big1.toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring doAssert big1.toString() == "2147483647".cstring - doAssert big1.toString(10.cint) == "2147483647".cstring - doAssert big1.toString(2.cint) == "1111111111111111111111111111111".cstring - doAssert big2 ** big3 == newBigInt(443556.cint) + doAssert big1.toString(10) == "2147483647".cstring + doAssert big1.toString(2) == "1111111111111111111111111111111".cstring + doAssert big2 ** big3 == newBigInt(443556) discard newBigInt("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) discard newBigInt("0".cstring) discard newBigInt("-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) From ceeecbef015330c58b87cafa20d046b2ebee15c6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 20:34:31 -0300 Subject: [PATCH 04/66] Bear review --- lib/js/jsbigints.nim | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 8fdff7e46ef8..d391e6082dd5 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -49,7 +49,7 @@ func `*=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} func `/=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} -func `%=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `mod=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} func `inc`*(x: JsBigInt): JsBigInt {.importjs: "(++#)", discardable.} ## Same as `inc` but for `JsBigInt` (uses JavaScript `++BigInt()`). @@ -57,15 +57,11 @@ func `inc`*(x: JsBigInt): JsBigInt {.importjs: "(++#)", discardable.} func `dec`*(x: JsBigInt): JsBigInt {.importjs: "(--#)", discardable.} ## Same as `dec` but for `JsBigInt` (uses JavaScript `--BigInt()`). -func `>`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} - func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} -func `>=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} - func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} -func `==`*(x, y: JsBigInt): bool {.importjs: "(# $1= #)".} +func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} From bdc638607f3d6fe1dedd3b423f52a82dee728baa Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 20:41:47 -0300 Subject: [PATCH 05/66] Pear review --- lib/js/jsbigints.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index d391e6082dd5..8259d48ee2d2 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -20,7 +20,7 @@ func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.imp func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString -func toString*(this: JsBigInt): cstring {.importjs: "#.$1()".} +func `$`*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} @@ -118,7 +118,7 @@ runnableExamples: doAssert big1 * big2 == newBigInt("1430224108902".cstring) doAssert big1.toLocaleString("EN".cstring) == "2,147,483,647".cstring doAssert big1.toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring - doAssert big1.toString() == "2147483647".cstring + doAssert $big1 == "2147483647".cstring doAssert big1.toString(10) == "2147483647".cstring doAssert big1.toString(2) == "1111111111111111111111111111111".cstring doAssert big2 ** big3 == newBigInt(443556) From 71a6db563fb556531e8d00cefc7c12a2ec9f3414 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:08:01 -0300 Subject: [PATCH 06/66] Peer review --- lib/js/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 8259d48ee2d2..3560d321506c 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -47,7 +47,7 @@ func `-=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} func `*=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} -func `/=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `div=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# /= #)", discardable.} func `mod=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} From 230f37555390fff37a4ac6d71a676c4bcb85fffb Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:18:53 -0300 Subject: [PATCH 07/66] Peer review --- lib/js/jsbigints.nim | 47 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 3560d321506c..bc0deb9963d8 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -5,7 +5,10 @@ when not defined(js) and not defined(nimdoc): type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. -func newBigInt*(integer: cstring or SomeInteger): JsBigInt {.importjs: "BigInt(#)".} +func newBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} + ## Constructor for `JsBigInt`. + +func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} ## Constructor for `JsBigInt`. func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} @@ -90,9 +93,9 @@ func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. runnableExamples: - let big1: JsBigInt = newBigInt(2147483647) - let big2: JsBigInt = newBigInt("666".cstring) - var big3: JsBigInt = newBigInt("2".cstring) + let big1: JsBigInt = big"2147483647" + let big2: JsBigInt = big"666" + var big3: JsBigInt = big"2" doAssert big1 != big2 doAssert big1 > big2 doAssert big1 >= big2 @@ -100,28 +103,28 @@ runnableExamples: doAssert big2 <= big1 doAssert not(big1 == big2) inc big3 - doAssert big3 == newBigInt(3) + doAssert big3 == big"3" dec big3 - doAssert big3 == newBigInt(2) - inc big3, newBigInt(420) - doAssert big3 == newBigInt(422) - dec big3, newBigInt(420) - doAssert big3 == newBigInt(2) - doAssert (big3 xor big2) == newBigInt(664) - doAssert (big1 mod big2) == newBigInt("613".cstring) - doAssert -big1 == newBigInt("-2147483647".cstring) - doAssert big1 div big2 == newBigInt("3224449".cstring) - doAssert big1 + big2 == newBigInt("2147484313".cstring) - doAssert big1 - big2 == newBigInt("2147482981".cstring) - doAssert big1 shl big3 == newBigInt("8589934588".cstring) - doAssert big1 shr big3 == newBigInt("536870911".cstring) - doAssert big1 * big2 == newBigInt("1430224108902".cstring) + doAssert big3 == big"2" + inc big3, big"420" + doAssert big3 == big"422" + dec big3, big"420" + doAssert big3 == big"2" + doAssert (big3 xor big2) == big"664" + doAssert (big1 mod big2) == big"613" + doAssert -big1 == big"-2147483647" + doAssert big1 div big2 == big"3224449" + doAssert big1 + big2 == big"2147484313" + doAssert big1 - big2 == big"2147482981" + doAssert big1 shl big3 == big"8589934588" + doAssert big1 shr big3 == big"536870911" + doAssert big1 * big2 == big"1430224108902" doAssert big1.toLocaleString("EN".cstring) == "2,147,483,647".cstring doAssert big1.toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring doAssert $big1 == "2147483647".cstring doAssert big1.toString(10) == "2147483647".cstring doAssert big1.toString(2) == "1111111111111111111111111111111".cstring doAssert big2 ** big3 == newBigInt(443556) - discard newBigInt("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) - discard newBigInt("0".cstring) - discard newBigInt("-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999".cstring) + discard big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + discard big"0" + discard big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" From 472546cf5b6ec8c88e9598dfaf335f0795725d14 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:31:44 -0300 Subject: [PATCH 08/66] Improve Stringifications --- lib/js/jsbigints.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index bc0deb9963d8..8d6ef809a67f 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -23,9 +23,11 @@ func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.imp func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString -func `$`*(this: JsBigInt): cstring {.importjs: "#.toString()".} +func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString +func `$`*(this: JsBigInt): string = $toString(this) + func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN From a1d71a9afb2f5194e263c6f91d4f9401f399025a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:33:36 -0300 Subject: [PATCH 09/66] Improve Stringifications --- lib/js/jsbigints.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 8d6ef809a67f..35184fc34b58 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -27,6 +27,7 @@ func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = $toString(this) + ## Return a string representation of `JsBigInt`. func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN From 464f6268d399e09881391c7be90f3b173a729a48 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:36:25 -0300 Subject: [PATCH 10/66] Update changelog.md Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 696bedc17541..c3b59bc87a8d 100644 --- a/changelog.md +++ b/changelog.md @@ -66,7 +66,7 @@ - `echo` and `debugEcho` will now raise `IOError` if writing to stdout fails. Previous behavior silently ignored errors. See #16366. Use `-d:nimLegacyEchoNoRaise` for previous behavior. -- Add `jsbigints` module, arbitrary precision integers for JavaScript target. +- Added `jsbigints` module, arbitrary precision integers for JavaScript target. - Added new operations for singly- and doubly linked lists: `lists.toSinglyLinkedList` and `lists.toDoublyLinkedList` convert from `openArray`s; `lists.copy` implements From 7a8b9f00cb89cc331f395d8bffcbf8ac459fa5c0 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:44:42 -0300 Subject: [PATCH 11/66] RunnableExamplerize --- lib/js/jsbigints.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 35184fc34b58..1a59a9b779c0 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -8,8 +8,10 @@ type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScr func newBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} ## Constructor for `JsBigInt`. -func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} +func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. + runnableExamples: + doAssert big"-1" == big"1" - big"2" func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString From 464c0b1c06c3fa8a97410d1d44325cbb888d66da Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 21:59:15 -0300 Subject: [PATCH 12/66] discard the discardable pragma --- lib/js/jsbigints.nim | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 1a59a9b779c0..69ae051bcabc 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -49,20 +49,20 @@ func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). -func `+=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `+=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} -func `-=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `-=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} -func `*=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `*=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} -func `div=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# /= #)", discardable.} +func `div=`*(x, y: JsBigInt) {.importjs: "(# /= #)".} -func `mod=`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)", discardable.} +func `mod=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} -func `inc`*(x: JsBigInt): JsBigInt {.importjs: "(++#)", discardable.} +func `inc`*(x: JsBigInt) {.importjs: "(++#)".} ## Same as `inc` but for `JsBigInt` (uses JavaScript `++BigInt()`). -func `dec`*(x: JsBigInt): JsBigInt {.importjs: "(--#)", discardable.} +func `dec`*(x: JsBigInt) {.importjs: "(--#)".} ## Same as `dec` but for `JsBigInt` (uses JavaScript `--BigInt()`). func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} @@ -89,9 +89,9 @@ func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} -func inc*(a, b: JsBigInt): JsBigInt {.importjs: "(# += #)", discardable.} +func inc*(a, b: JsBigInt) {.importjs: "(# += #)".} -func dec*(a, b: JsBigInt): JsBigInt {.importjs: "(# -= #)", discardable.} +func dec*(a, b: JsBigInt) {.importjs: "(# -= #)".} func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs @@ -130,6 +130,8 @@ runnableExamples: doAssert big1.toString(10) == "2147483647".cstring doAssert big1.toString(2) == "1111111111111111111111111111111".cstring doAssert big2 ** big3 == newBigInt(443556) + big2 += big2 + big2 -= big2 discard big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" discard big"0" discard big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" From 7309b55b9fe93ce6eee6eb89f6237359247a7ad1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 21 Dec 2020 23:58:07 -0300 Subject: [PATCH 13/66] Several improvements from peer reviews, more docs --- lib/js/jsbigints.nim | 110 ++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 69ae051bcabc..15698de19a90 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -18,9 +18,14 @@ func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString + # TODO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString#Using_options func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString + ## When requesting a language that may not be supported, include a fallback language. Example: + ## + ## .. code-block::nim + ## bigint.toLocaleString(["ban".cstring, "id".cstring]) func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString @@ -44,34 +49,20 @@ func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} - ## Same as `div` but for `JsBigInt`. + ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). -func `+=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} - -func `-=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} - -func `*=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} - -func `div=`*(x, y: JsBigInt) {.importjs: "(# /= #)".} - -func `mod=`*(x, y: JsBigInt) {.importjs: "(# $1 #)".} - -func `inc`*(x: JsBigInt) {.importjs: "(++#)".} - ## Same as `inc` but for `JsBigInt` (uses JavaScript `++BigInt()`). - -func `dec`*(x: JsBigInt) {.importjs: "(--#)".} - ## Same as `dec` but for `JsBigInt` (uses JavaScript `--BigInt()`). - func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} -func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} +func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} = + runnableExamples: + doAssert (big"9" ** big"5") == big"59049" func `and`*(x, y: JsBigInt): JsBigInt {.importjs: "(# && #)".} @@ -81,20 +72,71 @@ func `not`*(x: JsBigInt): JsBigInt {.importjs: "(!#)".} func `in`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} -func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} +func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} = + runnableExamples: + doAssert (big"555" xor big"2") == big"553" -func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} +func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} = + runnableExamples: + doAssert (big"999" shl big"2") == big"3996" -func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} +func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} = + runnableExamples: + doAssert (big"999" shr big"2") == big"249" -func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} +func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = + runnableExamples: + doAssert -(big"10101010101") == big"-10101010101" -func inc*(a, b: JsBigInt) {.importjs: "(# += #)".} +func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. + ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs -func dec*(a, b: JsBigInt) {.importjs: "(# -= #)".} +func inc*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] += #)".} = + runnableExamples: + var big1: JsBigInt = big"1" + let big2: JsBigInt = big"2" + inc big1, big2 + doAssert big1 == big"3" -func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. - ## https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs +func dec*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] -= #)".} = + runnableExamples: + var big1: JsBigInt = big"1" + let big2: JsBigInt = big"2" + dec big1, big2 + doAssert big1 == big"-1" + +func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = + runnableExamples: + var big1: JsBigInt = big"1" + let big2: JsBigInt = big"2" + inc big1, big2 + doAssert big1 == big"3" + +func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = + runnableExamples: + var big1: JsBigInt = big"1" + let big2: JsBigInt = big"2" + dec big1, big2 + doAssert big1 == big"-1" + +func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = + runnableExamples: + var big1: JsBigInt = big"2" + let big2: JsBigInt = big"4" + big1 *= big2 + doAssert big1 == big"8" + +func inc*(x: var JsBigInt) {.importjs: "(++[#][0][0])".} = + runnableExamples: + var big1: JsBigInt = big"1" + inc big1 + doAssert big1 == big"2" + +func dec*(x: var JsBigInt;) {.importjs: "(--[#][0][0])".} = + runnableExamples: + var big1: JsBigInt = big"3" + dec big1 + doAssert big1 == big"2" runnableExamples: @@ -107,13 +149,6 @@ runnableExamples: doAssert big2 < big1 doAssert big2 <= big1 doAssert not(big1 == big2) - inc big3 - doAssert big3 == big"3" - dec big3 - doAssert big3 == big"2" - inc big3, big"420" - doAssert big3 == big"422" - dec big3, big"420" doAssert big3 == big"2" doAssert (big3 xor big2) == big"664" doAssert (big1 mod big2) == big"613" @@ -130,8 +165,7 @@ runnableExamples: doAssert big1.toString(10) == "2147483647".cstring doAssert big1.toString(2) == "1111111111111111111111111111111".cstring doAssert big2 ** big3 == newBigInt(443556) - big2 += big2 - big2 -= big2 - discard big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" - discard big"0" - discard big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + huge.inc + huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + doAssert huge == big"1" From c4ddb1f0868a92d202ce96aaaa66c66370f7c62d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 00:21:04 -0300 Subject: [PATCH 14/66] More doc, more test --- lib/js/jsbigints.nim | 51 +++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 15698de19a90..f038ff750beb 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -16,16 +16,17 @@ func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString -func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$1(#)".} +func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$1(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString # TODO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString#Using_options + runnableExamples: + doAssert big"2147483647".toLocaleString("EN".cstring) == "2,147,483,647".cstring -func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} +func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString - ## When requesting a language that may not be supported, include a fallback language. Example: - ## - ## .. code-block::nim - ## bigint.toLocaleString(["ban".cstring, "id".cstring]) + ## When requesting a language that may not be supported, include a fallback language. + runnableExamples: + doAssert big"2147483647".toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString @@ -33,8 +34,10 @@ func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString -func `$`*(this: JsBigInt): string = $toString(this) +func `$`*(this: JsBigInt): string = ## Return a string representation of `JsBigInt`. + runnableExamples: doAssert $big"1024" == "1024" + $toString(this) func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN @@ -42,23 +45,39 @@ func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #) func asUintN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN -func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} +func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = + runnableExamples: + doAssert (big"9" + big"1") == big"10" -func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} +func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = + runnableExamples: + doAssert (big"9" - big"1") == big"8" -func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} +func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = + runnableExamples: + doAssert (big"42" * big"9") == big"378" -func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} +func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). + runnableExamples: + doAssert (big"512" div big"2") == big"256" -func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} +func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). + runnableExamples: + doAssert (big"4" div big"2") == big"2" -func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} +func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = + runnableExamples: + doAssert big"2" < big"9" -func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} +func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = + runnableExamples: + doAssert big"1" <= big"5" -func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} +func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} = + runnableExamples: + doAssert big"42" <= big"42" func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} = runnableExamples: @@ -159,8 +178,6 @@ runnableExamples: doAssert big1 shl big3 == big"8589934588" doAssert big1 shr big3 == big"536870911" doAssert big1 * big2 == big"1430224108902" - doAssert big1.toLocaleString("EN".cstring) == "2,147,483,647".cstring - doAssert big1.toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring doAssert $big1 == "2147483647".cstring doAssert big1.toString(10) == "2147483647".cstring doAssert big1.toString(2) == "1111111111111111111111111111111".cstring From bd816600fd15b1b72dcff409485afce61ef9384b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 00:29:19 -0300 Subject: [PATCH 15/66] More doc, more test --- lib/js/jsbigints.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index f038ff750beb..c1330bd79047 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -5,8 +5,10 @@ when not defined(js) and not defined(nimdoc): type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. -func newBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} +func newBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. + runnableExamples: + doAssert newBigInt(1234567890) == big"1234567890" func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. @@ -28,8 +30,10 @@ func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.imp runnableExamples: doAssert big"2147483647".toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring -func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} +func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString + runnableExamples: + doAssert big"2147483647".toString(2) == "1111111111111111111111111111111".cstring func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString @@ -180,7 +184,6 @@ runnableExamples: doAssert big1 * big2 == big"1430224108902" doAssert $big1 == "2147483647".cstring doAssert big1.toString(10) == "2147483647".cstring - doAssert big1.toString(2) == "1111111111111111111111111111111".cstring doAssert big2 ** big3 == newBigInt(443556) var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc From cbed4507148b025cc9e4ac9d512c1d536686cfed Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 00:55:00 -0300 Subject: [PATCH 16/66] More doc, more test --- lib/js/jsbigints.nim | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index c1330bd79047..c5be0376cfc6 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -35,7 +35,7 @@ func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} = runnableExamples: doAssert big"2147483647".toString(2) == "1111111111111111111111111111111".cstring -func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} +func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted on $ ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = @@ -43,11 +43,15 @@ func `$`*(this: JsBigInt): string = runnableExamples: doAssert $big"1024" == "1024" $toString(this) -func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} +func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN + runnableExamples: + doAssert asIntN(32, big"2147483647") == 2147483647.int32 -func asUintN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} +func asUintN*(width: int; bigInteger: JsBigInt): uint {.importjs: "BigInt.$1(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN + runnableExamples: + doAssert asUintN(32, big"2147483647") == 2147483647.uint32 func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: @@ -65,11 +69,18 @@ func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). runnableExamples: doAssert (big"512" div big"2") == big"256" + doAssert (big"4" div big"2") == big"2" + doAssert (big"42" div big"10") == big"4" + doAssert (big"420" div big"5") == big"84" + doAssert (big"100" div big"4") == big"25" func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). runnableExamples: - doAssert (big"4" div big"2") == big"2" + doAssert (big"5" mod big"2") == big"1" + doAssert (big"421" mod big"5") == big"1" + doAssert (big"420" mod big"5") == big"0" + doAssert (big"100" mod big"4") == big"0" func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: @@ -81,20 +92,12 @@ func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} = runnableExamples: - doAssert big"42" <= big"42" + doAssert big"42" == big"42" func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} = runnableExamples: doAssert (big"9" ** big"5") == big"59049" -func `and`*(x, y: JsBigInt): JsBigInt {.importjs: "(# && #)".} - -func `or`*(x, y: JsBigInt): JsBigInt {.importjs: "(# || #)".} - -func `not`*(x: JsBigInt): JsBigInt {.importjs: "(!#)".} - -func `in`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} - func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} = runnableExamples: doAssert (big"555" xor big"2") == big"553" @@ -132,14 +135,14 @@ func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = big"1" let big2: JsBigInt = big"2" - inc big1, big2 + big1 += big2 doAssert big1 == big"3" func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = big"1" let big2: JsBigInt = big"2" - dec big1, big2 + big1 -= big2 doAssert big1 == big"-1" func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = @@ -155,7 +158,7 @@ func inc*(x: var JsBigInt) {.importjs: "(++[#][0][0])".} = inc big1 doAssert big1 == big"2" -func dec*(x: var JsBigInt;) {.importjs: "(--[#][0][0])".} = +func dec*(x: var JsBigInt) {.importjs: "(--[#][0][0])".} = runnableExamples: var big1: JsBigInt = big"3" dec big1 From 816d0fe6cfb82ac7607fcdc5238283185c725fb6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 01:16:59 -0300 Subject: [PATCH 17/66] More doc, more test --- lib/js/jsbigints.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index c5be0376cfc6..ecf8e02d165c 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -164,6 +164,18 @@ func dec*(x: var JsBigInt) {.importjs: "(--[#][0][0])".} = dec big1 doAssert big1 == big"2" +func `%=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] %= #)".} = + runnableExamples: + var big1: JsBigInt = big"10" + big1 %= big"2" + doAssert big1 == big"0" + +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = + runnableExamples: + var big1: JsBigInt = big"10" + big1 /= big"2" + doAssert big1 == big"5" + runnableExamples: let big1: JsBigInt = big"2147483647" From 38abc4086a0a8d4505654068d66bd572074a3312 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 01:54:13 -0300 Subject: [PATCH 18/66] Better error message 'Error: usage of low is an {.error.} defined at jsbigints.nim' instead of just 'type mismatch JsBigInt' --- lib/js/jsbigints.nim | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index ecf8e02d165c..65a55dbbb67f 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -114,9 +114,6 @@ func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(big"10101010101") == big"-10101010101" -func `+`*(a: JsBigInt): JsBigInt {.error.} # Can not be used by design. - ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs - func inc*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] += #)".} = runnableExamples: var big1: JsBigInt = big"1" @@ -176,6 +173,13 @@ func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = big1 /= big"2" doAssert big1 == big"5" +func `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. + ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs + +func low*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** + +func high*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** + runnableExamples: let big1: JsBigInt = big"2147483647" From d546f0fe708101ff8618f43edea48493998850b9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 02:23:57 -0300 Subject: [PATCH 19/66] is an overload, rename --- lib/js/jsbigints.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 65a55dbbb67f..ebaa908dd559 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -5,10 +5,10 @@ when not defined(js) and not defined(nimdoc): type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. -func newBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = +func big*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: - doAssert newBigInt(1234567890) == big"1234567890" + doAssert big(1234567890) == big"1234567890" func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. @@ -203,7 +203,7 @@ runnableExamples: doAssert big1 * big2 == big"1430224108902" doAssert $big1 == "2147483647".cstring doAssert big1.toString(10) == "2147483647".cstring - doAssert big2 ** big3 == newBigInt(443556) + doAssert big2 ** big3 == big(443556) var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" From cc70f55746f7a20cf18d2b24e968d1f61e1e5dc3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 02:30:36 -0300 Subject: [PATCH 20/66] proc to scare kids away --- lib/js/jsbigints.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index ebaa908dd559..014ce4778b3f 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -173,12 +173,12 @@ func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = big1 /= big"2" doAssert big1 == big"5" -func `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. +proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs -func low*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** +proc low*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** -func high*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** +proc high*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** runnableExamples: From 27599508e1ebea98c9c9e92c8c8957d148bb6a93 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 03:10:39 -0300 Subject: [PATCH 21/66] moar test moar --- lib/js/jsbigints.nim | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 014ce4778b3f..1ed036def67b 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -208,3 +208,13 @@ runnableExamples: huge.inc huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" doAssert huge == big"1" + var list: seq[JsBigInt] + for i in big"0" .. big"5": + doAssert i is JsBigInt + list.add i + doAssert list == @[big"0", big"1", big"2", big"3", big"4", big"5"] + list = @[] + for i in big"0" ..< big"5": + doAssert i is JsBigInt + list.add i + doAssert list == @[big"0", big"1", big"2", big"3", big"4"] From 0fa9599bb9dd8febd74f7776cc655ae7ab372e9f Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 03:35:07 -0300 Subject: [PATCH 22/66] This useful proc --- lib/js/jsbigints.nim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 1ed036def67b..f3412afeb7fa 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -173,6 +173,15 @@ func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = big1 /= big"2" doAssert big1 == big"5" +proc addInt*(result: var string; integer: JsBigInt) = + ## Converts `integer` to its string representation and appends it to `result`. + runnableExamples: + var a = "12345678" + let b = big"99999999999999999999999999999999999999" + a.addInt b + doAssert a == "1234567899999999999999999999999999999999999999" + result.add integer.toString + proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs From 9719ffad1438f5f87b4024bff280ab59fb17f2d6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 18:26:31 -0300 Subject: [PATCH 23/66] Minor changes --- lib/js/jsbigints.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index f3412afeb7fa..4eaf388777e2 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -162,14 +162,16 @@ func dec*(x: var JsBigInt) {.importjs: "(--[#][0][0])".} = doAssert big1 == big"2" func `%=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] %= #)".} = + ## Same as `x = x mod y`. runnableExamples: var big1: JsBigInt = big"10" big1 %= big"2" doAssert big1 == big"0" func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = + ## Same as `x = x div y`. runnableExamples: - var big1: JsBigInt = big"10" + var big1: JsBigInt = big"11" big1 /= big"2" doAssert big1 == big"5" @@ -185,9 +187,9 @@ proc addInt*(result: var string; integer: JsBigInt) = proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs -proc low*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** +proc low*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** -proc high*(_: JsBigInt): JsBigInt {.error.} ## **Do NOT use.** +proc high*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** runnableExamples: From 79e23c8c1fa26b3d91c0466e1c664c3b41245209 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 18:39:37 -0300 Subject: [PATCH 24/66] Minor changes --- lib/js/jsbigints.nim | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 4eaf388777e2..7bcfc722ebc6 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -43,15 +43,16 @@ func `$`*(this: JsBigInt): string = runnableExamples: doAssert $big"1024" == "1024" $toString(this) -func asIntN*(width: int; bigInteger: JsBigInt): int {.importjs: "BigInt.$1(#, #)".} = +func asIntN*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = + ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert asIntN(32, big"2147483647") == 2147483647.int32 + doAssert asIntN(32, big"2147483647") == big"2147483647" -func asUintN*(width: int; bigInteger: JsBigInt): uint {.importjs: "BigInt.$1(#, #)".} = +func asUintN*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert asUintN(32, big"2147483647") == 2147483647.uint32 + doAssert asUintN(32, big"2147483647") == big"2147483647" func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: From 985d5ced7d3c0fb36b2ba8d7648412307ed1b3ba Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 19:34:43 -0300 Subject: [PATCH 25/66] Update lib/js/jsbigints.nim Co-authored-by: Timothee Cour --- lib/js/jsbigints.nim | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index 7bcfc722ebc6..b6493be473c9 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -69,11 +69,10 @@ func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). runnableExamples: - doAssert (big"512" div big"2") == big"256" - doAssert (big"4" div big"2") == big"2" - doAssert (big"42" div big"10") == big"4" - doAssert (big"420" div big"5") == big"84" - doAssert (big"100" div big"4") == big"25" + doAssert big"13" div big"3" == big"4" + doAssert big"-13" div big"3" == big"-4" + doAssert big"13" div big"-3" == big"-4" + doAssert big"-13" div big"-3" == big"4" func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). From c0cc4190389edae177a88119ef8f04a193595fbc Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 19:36:37 -0300 Subject: [PATCH 26/66] Get int from BigInt --- lib/js/jsbigints.nim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index b6493be473c9..a60030773526 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -54,6 +54,10 @@ func asUintN*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} runnableExamples: doAssert asUintN(32, big"2147483647") == big"2147483647" +func int*(a: JsBigInt): int {.importjs: "Number(#)".} = + runnableExamples: + doAssert int(big"2147483647") == 2147483647 + func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: doAssert (big"9" + big"1") == big"10" From aa0d39a46db6d57049c6b6293d6748da46276cc9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 22 Dec 2020 19:38:24 -0300 Subject: [PATCH 27/66] Update lib/js/jsbigints.nim Co-authored-by: Timothee Cour --- lib/js/jsbigints.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/js/jsbigints.nim b/lib/js/jsbigints.nim index a60030773526..01ea24f602b5 100644 --- a/lib/js/jsbigints.nim +++ b/lib/js/jsbigints.nim @@ -81,10 +81,10 @@ func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). runnableExamples: - doAssert (big"5" mod big"2") == big"1" - doAssert (big"421" mod big"5") == big"1" - doAssert (big"420" mod big"5") == big"0" - doAssert (big"100" mod big"4") == big"0" + doAssert big"13" mod big"3" == big"1" + doAssert big"-13" mod big"3" == big"-1" + doAssert big"13" mod big"-3" == big"1" + doAssert big"-13" mod big"-3" == big"-1" func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: From 3aad4f05b1194455f99c338939f222c85439d1f7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 27 Dec 2020 18:58:02 -0300 Subject: [PATCH 28/66] Bigint moves house --- lib/{js => std}/jsbigints.nim | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{js => std}/jsbigints.nim (100%) diff --git a/lib/js/jsbigints.nim b/lib/std/jsbigints.nim similarity index 100% rename from lib/js/jsbigints.nim rename to lib/std/jsbigints.nim From efb2dc51ea0fd0cc4e05fc7e420f3ffd4c877b0b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 27 Dec 2020 19:56:20 -0300 Subject: [PATCH 29/66] koch bigint --- tools/kochdocs.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 0cfedce473d3..5187bf2e128c 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -15,7 +15,8 @@ const var nimExe*: string -template isJsOnly(file: string): bool = file.isRelativeTo("lib/js") +template isJsOnly(file: string): bool = + file.isRelativeTo("lib/js") or file.extractFilename.startsWith"js" proc exe*(f: string): string = result = addFileExt(f, ExeExt) From 5240526f22af5f9167919502cc21809590eccad1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 27 Dec 2020 21:17:00 -0300 Subject: [PATCH 30/66] move test --- lib/std/jsbigints.nim | 28 --------------------------- tests/stdlib/tjsbigints.nim | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 tests/stdlib/tjsbigints.nim diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 01ea24f602b5..774073218d0c 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -199,37 +199,9 @@ proc high*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** runnableExamples: let big1: JsBigInt = big"2147483647" let big2: JsBigInt = big"666" - var big3: JsBigInt = big"2" doAssert big1 != big2 doAssert big1 > big2 doAssert big1 >= big2 doAssert big2 < big1 doAssert big2 <= big1 doAssert not(big1 == big2) - doAssert big3 == big"2" - doAssert (big3 xor big2) == big"664" - doAssert (big1 mod big2) == big"613" - doAssert -big1 == big"-2147483647" - doAssert big1 div big2 == big"3224449" - doAssert big1 + big2 == big"2147484313" - doAssert big1 - big2 == big"2147482981" - doAssert big1 shl big3 == big"8589934588" - doAssert big1 shr big3 == big"536870911" - doAssert big1 * big2 == big"1430224108902" - doAssert $big1 == "2147483647".cstring - doAssert big1.toString(10) == "2147483647".cstring - doAssert big2 ** big3 == big(443556) - var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" - huge.inc - huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" - doAssert huge == big"1" - var list: seq[JsBigInt] - for i in big"0" .. big"5": - doAssert i is JsBigInt - list.add i - doAssert list == @[big"0", big"1", big"2", big"3", big"4", big"5"] - list = @[] - for i in big"0" ..< big"5": - doAssert i is JsBigInt - list.add i - doAssert list == @[big"0", big"1", big"2", big"3", big"4"] diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim new file mode 100644 index 000000000000..d7b66e144051 --- /dev/null +++ b/tests/stdlib/tjsbigints.nim @@ -0,0 +1,38 @@ +discard """ + targets: "js" +""" + +import std/jsbigints + + +let big1: JsBigInt = big"2147483647" +let big2: JsBigInt = big"666" +var big3: JsBigInt = big"2" + +doAssert big3 == big"2" +doAssert (big3 xor big2) == big"664" +doAssert (big1 mod big2) == big"613" +doAssert -big1 == big"-2147483647" +doAssert big1 div big2 == big"3224449" +doAssert big1 + big2 == big"2147484313" +doAssert big1 - big2 == big"2147482981" +doAssert big1 shl big3 == big"8589934588" +doAssert big1 shr big3 == big"536870911" +doAssert big1 * big2 == big"1430224108902" +doAssert $big1 == "2147483647".cstring +doAssert big1.toString(10) == "2147483647".cstring +doAssert big2 ** big3 == big(443556) +var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +huge.inc +huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +doAssert huge == big"1" +var list: seq[JsBigInt] +for i in big"0" .. big"5": + doAssert i is JsBigInt + list.add i +doAssert list == @[big"0", big"1", big"2", big"3", big"4", big"5"] +list = @[] +for i in big"0" ..< big"5": + doAssert i is JsBigInt + list.add i +doAssert list == @[big"0", big"1", big"2", big"3", big"4"] From 7a940aa7254944254be92abf60e93962571a14e2 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 28 Dec 2020 12:07:15 -0300 Subject: [PATCH 31/66] fixes --- lib/std/jsbigints.nim | 67 +++++++------------------------------ tests/stdlib/tjsbigints.nim | 2 +- 2 files changed, 13 insertions(+), 56 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 774073218d0c..5ea0bb84e25c 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -15,48 +15,33 @@ func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = runnableExamples: doAssert big"-1" == big"1" - big"2" -func toLocaleString*(this: JsBigInt): cstring {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString - -func toLocaleString*(this: JsBigInt; locales: cstring): cstring {.importjs: "#.$1(#)".} = - ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString - # TODO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString#Using_options - runnableExamples: - doAssert big"2147483647".toLocaleString("EN".cstring) == "2,147,483,647".cstring - -func toLocaleString*(this: JsBigInt; locales: openArray[cstring]): cstring {.importjs: "#.$1(#)".} = - ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString - ## When requesting a language that may not be supported, include a fallback language. - runnableExamples: - doAssert big"2147483647".toLocaleString(["EN".cstring, "ES".cstring]) == "2,147,483,647".cstring - -func toString*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} = +func toCstring*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: - doAssert big"2147483647".toString(2) == "1111111111111111111111111111111".cstring + doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring -func toString*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted on $ +func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted on $ ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = ## Return a string representation of `JsBigInt`. runnableExamples: doAssert $big"1024" == "1024" - $toString(this) + $toCstring(this) -func asIntN*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = +func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert asIntN(32, big"2147483647") == big"2147483647" + doAssert toInt(32, big"2147483647") == big"2147483647" -func asUintN*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = +func toUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert asUintN(32, big"2147483647") == big"2147483647" + doAssert toUint(32, big"2147483647") == big"2147483647" -func int*(a: JsBigInt): int {.importjs: "Number(#)".} = +func toInt*(a: JsBigInt): int {.importjs: "Number(#)".} = runnableExamples: - doAssert int(big"2147483647") == 2147483647 + doAssert toInt(big"2147483647") == 2147483647 func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: @@ -118,14 +103,14 @@ func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(big"10101010101") == big"-10101010101" -func inc*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] += #)".} = +func inc*(a: var JsBigInt; b = big"1") {.importjs: "([#][0][0] += #)".} = runnableExamples: var big1: JsBigInt = big"1" let big2: JsBigInt = big"2" inc big1, big2 doAssert big1 == big"3" -func dec*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] -= #)".} = +func dec*(a: var JsBigInt; b = big"1") {.importjs: "([#][0][0] -= #)".} = runnableExamples: var big1: JsBigInt = big"1" let big2: JsBigInt = big"2" @@ -153,25 +138,6 @@ func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = big1 *= big2 doAssert big1 == big"8" -func inc*(x: var JsBigInt) {.importjs: "(++[#][0][0])".} = - runnableExamples: - var big1: JsBigInt = big"1" - inc big1 - doAssert big1 == big"2" - -func dec*(x: var JsBigInt) {.importjs: "(--[#][0][0])".} = - runnableExamples: - var big1: JsBigInt = big"3" - dec big1 - doAssert big1 == big"2" - -func `%=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] %= #)".} = - ## Same as `x = x mod y`. - runnableExamples: - var big1: JsBigInt = big"10" - big1 %= big"2" - doAssert big1 == big"0" - func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = ## Same as `x = x div y`. runnableExamples: @@ -179,15 +145,6 @@ func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = big1 /= big"2" doAssert big1 == big"5" -proc addInt*(result: var string; integer: JsBigInt) = - ## Converts `integer` to its string representation and appends it to `result`. - runnableExamples: - var a = "12345678" - let b = big"99999999999999999999999999999999999999" - a.addInt b - doAssert a == "1234567899999999999999999999999999999999999999" - result.add integer.toString - proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim index d7b66e144051..dad8186ee11c 100644 --- a/tests/stdlib/tjsbigints.nim +++ b/tests/stdlib/tjsbigints.nim @@ -20,7 +20,7 @@ doAssert big1 shl big3 == big"8589934588" doAssert big1 shr big3 == big"536870911" doAssert big1 * big2 == big"1430224108902" doAssert $big1 == "2147483647".cstring -doAssert big1.toString(10) == "2147483647".cstring +doAssert big1.toCstring(10) == "2147483647".cstring doAssert big2 ** big3 == big(443556) var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc From 36b927dc8d365f88e285221d336eb497cc080b00 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 28 Dec 2020 12:22:35 -0300 Subject: [PATCH 32/66] fixes --- lib/std/jsbigints.nim | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 5ea0bb84e25c..2d77f928c2c4 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -15,7 +15,7 @@ func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = runnableExamples: doAssert big"-1" == big"1" - big"2" -func toCstring*(this: JsBigInt; radix: int): cstring {.importjs: "#.$1(#)".} = +func toCstring*(this: JsBigInt; radix: int): cstring {.importjs: "#.toString(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring @@ -28,13 +28,13 @@ func `$`*(this: JsBigInt): string = runnableExamples: doAssert $big"1024" == "1024" $toCstring(this) -func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = +func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: doAssert toInt(32, big"2147483647") == big"2147483647" -func toUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.$1(#, #)".} = +func toUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asUintN(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: doAssert toUint(32, big"2147483647") == big"2147483647" @@ -103,46 +103,41 @@ func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(big"10101010101") == big"-10101010101" -func inc*(a: var JsBigInt; b = big"1") {.importjs: "([#][0][0] += #)".} = +func inc*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] += BigInt(#))".} = runnableExamples: var big1: JsBigInt = big"1" - let big2: JsBigInt = big"2" - inc big1, big2 + inc big1, 2 doAssert big1 == big"3" -func dec*(a: var JsBigInt; b = big"1") {.importjs: "([#][0][0] -= #)".} = +func dec*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] -= BigInt(#))".} = runnableExamples: var big1: JsBigInt = big"1" - let big2: JsBigInt = big"2" - dec big1, big2 + dec big1, 2 doAssert big1 == big"-1" -func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = big"1" - let big2: JsBigInt = big"2" - big1 += big2 + big1 += 2 doAssert big1 == big"3" -func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = big"1" - let big2: JsBigInt = big"2" - big1 -= big2 + big1 -= 2 doAssert big1 == big"-1" -func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = big"2" - let big2: JsBigInt = big"4" - big1 *= big2 + big1 *= 4 doAssert big1 == big"8" -func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = +func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = big"11" - big1 /= big"2" + big1 /= 2 doAssert big1 == big"5" proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. From e450d19b49cef65659fdafadbd9d4c9cc9973871 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 28 Dec 2020 12:33:18 -0300 Subject: [PATCH 33/66] is dangerous --- tools/kochdocs.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 5187bf2e128c..0e5b9a2cb3ed 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -14,9 +14,10 @@ const webUploadOutput = "web/upload" var nimExe*: string +const allowList = ["jsbigints.nim"] # Nim for JavaScript target outside of lib/js/ template isJsOnly(file: string): bool = - file.isRelativeTo("lib/js") or file.extractFilename.startsWith"js" + file.isRelativeTo("lib/js") or file.extractFilename in allowList proc exe*(f: string): string = result = addFileExt(f, ExeExt) From cc256890298eebadcb33c7f64236d26e04f76e18 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 3 Jan 2021 22:23:51 -0300 Subject: [PATCH 34/66] No better naming found, then newJsBigInt is used, later we can add a short alias anyway --- lib/std/jsbigints.nim | 86 +++++++++++++++++++------------------ tests/stdlib/tjsbigints.nim | 42 +++++++++--------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 2d77f928c2c4..79c37c3261bc 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -5,140 +5,142 @@ when not defined(js) and not defined(nimdoc): type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. -func big*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = + + +func newJsBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: - doAssert big(1234567890) == big"1234567890" + doAssert newJsBigInt(1234567890) == newJsBigInt"1234567890" -func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = +func newJsBigInt*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: - doAssert big"-1" == big"1" - big"2" + doAssert newJsBigInt"-1" == newJsBigInt"1" - newJsBigInt"2" func toCstring*(this: JsBigInt; radix: int): cstring {.importjs: "#.toString(#)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: - doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring + doAssert newJsBigInt"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted on $ ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = ## Return a string representation of `JsBigInt`. - runnableExamples: doAssert $big"1024" == "1024" + runnableExamples: doAssert $newJsBigInt"1024" == "1024" $toCstring(this) func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert toInt(32, big"2147483647") == big"2147483647" + doAssert toInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" func toUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asUintN(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert toUint(32, big"2147483647") == big"2147483647" + doAssert toUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" func toInt*(a: JsBigInt): int {.importjs: "Number(#)".} = runnableExamples: - doAssert toInt(big"2147483647") == 2147483647 + doAssert toInt(newJsBigInt"2147483647") == 2147483647 func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (big"9" + big"1") == big"10" + doAssert (newJsBigInt"9" + newJsBigInt"1") == newJsBigInt"10" func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (big"9" - big"1") == big"8" + doAssert (newJsBigInt"9" - newJsBigInt"1") == newJsBigInt"8" func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (big"42" * big"9") == big"378" + doAssert (newJsBigInt"42" * newJsBigInt"9") == newJsBigInt"378" func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). runnableExamples: - doAssert big"13" div big"3" == big"4" - doAssert big"-13" div big"3" == big"-4" - doAssert big"13" div big"-3" == big"-4" - doAssert big"-13" div big"-3" == big"4" + doAssert newJsBigInt"13" div newJsBigInt"3" == newJsBigInt"4" + doAssert newJsBigInt"-13" div newJsBigInt"3" == newJsBigInt"-4" + doAssert newJsBigInt"13" div newJsBigInt"-3" == newJsBigInt"-4" + doAssert newJsBigInt"-13" div newJsBigInt"-3" == newJsBigInt"4" func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). runnableExamples: - doAssert big"13" mod big"3" == big"1" - doAssert big"-13" mod big"3" == big"-1" - doAssert big"13" mod big"-3" == big"1" - doAssert big"-13" mod big"-3" == big"-1" + doAssert newJsBigInt"13" mod newJsBigInt"3" == newJsBigInt"1" + doAssert newJsBigInt"-13" mod newJsBigInt"3" == newJsBigInt"-1" + doAssert newJsBigInt"13" mod newJsBigInt"-3" == newJsBigInt"1" + doAssert newJsBigInt"-13" mod newJsBigInt"-3" == newJsBigInt"-1" func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: - doAssert big"2" < big"9" + doAssert newJsBigInt"2" < newJsBigInt"9" func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: - doAssert big"1" <= big"5" + doAssert newJsBigInt"1" <= newJsBigInt"5" func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} = runnableExamples: - doAssert big"42" == big"42" + doAssert newJsBigInt"42" == newJsBigInt"42" func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} = runnableExamples: - doAssert (big"9" ** big"5") == big"59049" + doAssert (newJsBigInt"9" ** newJsBigInt"5") == newJsBigInt"59049" func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} = runnableExamples: - doAssert (big"555" xor big"2") == big"553" + doAssert (newJsBigInt"555" xor newJsBigInt"2") == newJsBigInt"553" func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} = runnableExamples: - doAssert (big"999" shl big"2") == big"3996" + doAssert (newJsBigInt"999" shl newJsBigInt"2") == newJsBigInt"3996" func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} = runnableExamples: - doAssert (big"999" shr big"2") == big"249" + doAssert (newJsBigInt"999" shr newJsBigInt"2") == newJsBigInt"249" func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: - doAssert -(big"10101010101") == big"-10101010101" + doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" func inc*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] += BigInt(#))".} = runnableExamples: - var big1: JsBigInt = big"1" + var big1: JsBigInt = newJsBigInt"1" inc big1, 2 - doAssert big1 == big"3" + doAssert big1 == newJsBigInt"3" func dec*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] -= BigInt(#))".} = runnableExamples: - var big1: JsBigInt = big"1" + var big1: JsBigInt = newJsBigInt"1" dec big1, 2 - doAssert big1 == big"-1" + doAssert big1 == newJsBigInt"-1" func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: - var big1: JsBigInt = big"1" + var big1: JsBigInt = newJsBigInt"1" big1 += 2 - doAssert big1 == big"3" + doAssert big1 == newJsBigInt"3" func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: - var big1: JsBigInt = big"1" + var big1: JsBigInt = newJsBigInt"1" big1 -= 2 - doAssert big1 == big"-1" + doAssert big1 == newJsBigInt"-1" func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: - var big1: JsBigInt = big"2" + var big1: JsBigInt = newJsBigInt"2" big1 *= 4 - doAssert big1 == big"8" + doAssert big1 == newJsBigInt"8" func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = ## Same as `x = x div y`. runnableExamples: - var big1: JsBigInt = big"11" + var big1: JsBigInt = newJsBigInt"11" big1 /= 2 - doAssert big1 == big"5" + doAssert big1 == newJsBigInt"5" proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs @@ -149,8 +151,8 @@ proc high*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** runnableExamples: - let big1: JsBigInt = big"2147483647" - let big2: JsBigInt = big"666" + let big1: JsBigInt = newJsBigInt"2147483647" + let big2: JsBigInt = newJsBigInt"666" doAssert big1 != big2 doAssert big1 > big2 doAssert big1 >= big2 diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim index dad8186ee11c..4e8aeac896c2 100644 --- a/tests/stdlib/tjsbigints.nim +++ b/tests/stdlib/tjsbigints.nim @@ -5,34 +5,34 @@ discard """ import std/jsbigints -let big1: JsBigInt = big"2147483647" -let big2: JsBigInt = big"666" -var big3: JsBigInt = big"2" +let big1: JsBigInt = newJsBigInt"2147483647" +let big2: JsBigInt = newJsBigInt"666" +var big3: JsBigInt = newJsBigInt"2" -doAssert big3 == big"2" -doAssert (big3 xor big2) == big"664" -doAssert (big1 mod big2) == big"613" -doAssert -big1 == big"-2147483647" -doAssert big1 div big2 == big"3224449" -doAssert big1 + big2 == big"2147484313" -doAssert big1 - big2 == big"2147482981" -doAssert big1 shl big3 == big"8589934588" -doAssert big1 shr big3 == big"536870911" -doAssert big1 * big2 == big"1430224108902" +doAssert big3 == newJsBigInt"2" +doAssert (big3 xor big2) == newJsBigInt"664" +doAssert (big1 mod big2) == newJsBigInt"613" +doAssert -big1 == newJsBigInt"-2147483647" +doAssert big1 div big2 == newJsBigInt"3224449" +doAssert big1 + big2 == newJsBigInt"2147484313" +doAssert big1 - big2 == newJsBigInt"2147482981" +doAssert big1 shl big3 == newJsBigInt"8589934588" +doAssert big1 shr big3 == newJsBigInt"536870911" +doAssert big1 * big2 == newJsBigInt"1430224108902" doAssert $big1 == "2147483647".cstring doAssert big1.toCstring(10) == "2147483647".cstring -doAssert big2 ** big3 == big(443556) -var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +doAssert big2 ** big3 == newJsBigInt(443556) +var huge = newJsBigInt"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc -huge += big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" -doAssert huge == big"1" +huge += newJsBigInt"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +doAssert huge == newJsBigInt"1" var list: seq[JsBigInt] -for i in big"0" .. big"5": +for i in newJsBigInt"0" .. newJsBigInt"5": doAssert i is JsBigInt list.add i -doAssert list == @[big"0", big"1", big"2", big"3", big"4", big"5"] +doAssert list == @[newJsBigInt"0", newJsBigInt"1", newJsBigInt"2", newJsBigInt"3", newJsBigInt"4", newJsBigInt"5"] list = @[] -for i in big"0" ..< big"5": +for i in newJsBigInt"0" ..< newJsBigInt"5": doAssert i is JsBigInt list.add i -doAssert list == @[big"0", big"1", big"2", big"3", big"4"] +doAssert list == @[newJsBigInt"0", newJsBigInt"1", newJsBigInt"2", newJsBigInt"3", newJsBigInt"4"] From 3316879246d14332721b1663275dd5841efe2f01 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 3 Jan 2021 23:55:25 -0300 Subject: [PATCH 35/66] clean out --- lib/std/jsbigints.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 79c37c3261bc..aab55863a035 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -5,8 +5,6 @@ when not defined(js) and not defined(nimdoc): type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. - - func newJsBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: From 4fa4a35e0f4e01380e4edf0510d60acc35e6fa60 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 00:23:08 -0300 Subject: [PATCH 36/66] clean out --- tests/stdlib/tjsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim index 4e8aeac896c2..c204ff4577ac 100644 --- a/tests/stdlib/tjsbigints.nim +++ b/tests/stdlib/tjsbigints.nim @@ -24,7 +24,7 @@ doAssert big1.toCstring(10) == "2147483647".cstring doAssert big2 ** big3 == newJsBigInt(443556) var huge = newJsBigInt"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc -huge += newJsBigInt"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +huge = huge + newJsBigInt"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" doAssert huge == newJsBigInt"1" var list: seq[JsBigInt] for i in newJsBigInt"0" .. newJsBigInt"5": From f56981f7d4c4e59e5fda9825123c082afa69516f Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 09:15:46 -0300 Subject: [PATCH 37/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index aab55863a035..81bb7e5b15e3 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -24,7 +24,7 @@ func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = - ## Return a string representation of `JsBigInt`. + ## Returns a string representation of `JsBigInt`. runnableExamples: doAssert $newJsBigInt"1024" == "1024" $toCstring(this) From 0334d89c832845bb38f5309a843e13b831b942b8 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 09:15:57 -0300 Subject: [PATCH 38/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 81bb7e5b15e3..dc572fa77b29 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -29,7 +29,7 @@ func `$`*(this: JsBigInt): string = $toCstring(this) func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = - ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. + ## Wraps `a` to a signed `JsBigInt` of `bits` bits, i.e. between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: doAssert toInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" From 00c0d6c3d926a152eb0520c42c7f11abf29d0489 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 10:38:14 -0300 Subject: [PATCH 39/66] Addres some comments --- lib/std/jsbigints.nim | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index aab55863a035..323e6600bc45 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -1,6 +1,6 @@ ## Arbitrary precision integers. ## * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt -when not defined(js) and not defined(nimdoc): +when not defined(js): {.fatal: "Module jsbigints is designed to be used with the JavaScript backend.".} type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. @@ -15,7 +15,9 @@ func newJsBigInt*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = runnableExamples: doAssert newJsBigInt"-1" == newJsBigInt"1" - newJsBigInt"2" -func toCstring*(this: JsBigInt; radix: int): cstring {.importjs: "#.toString(#)".} = +func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(#)".} = + ## Convert from `JsBigInt` to `cstring` representation. + ## * `radix` Base to use for representing numeric values. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: doAssert newJsBigInt"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring @@ -28,20 +30,21 @@ func `$`*(this: JsBigInt): string = runnableExamples: doAssert $newJsBigInt"1024" == "1024" $toCstring(this) -func toInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = +func wrapToInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = ## Wrap `a` to a signed `JsBigInt` of `bits` bits, ie between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert toInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" + doAssert wrapToInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" -func toUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asUintN(#, #)".} = +func wrapToUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asUintN(#, #)".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert toUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" + doAssert wrapToUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" -func toInt*(a: JsBigInt): int {.importjs: "Number(#)".} = +func unsafeToNumber*(a: JsBigInt): int {.importjs: "Number(#)".} = + ## Does not do any bounds check and may or may not return an inexact representation. runnableExamples: - doAssert toInt(newJsBigInt"2147483647") == 2147483647 + doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647 func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: From 6d8eba2111a9bb0d65d9de75b2a37b5ea225254b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 11:09:12 -0300 Subject: [PATCH 40/66] https://github.com/nim-lang/Nim/pull/16409#discussion_r551180020 --- lib/std/jsbigints.nim | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index a8b688c309f6..cf9984af071c 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -106,44 +106,45 @@ func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" -func inc*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] += BigInt(#))".} = +func inc*(a: var JsBigInt; b = newJsBigInt"1") {.importjs: "([#][0][0] += [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, 2 doAssert big1 == newJsBigInt"3" -func dec*(a: var JsBigInt; b = 1) {.importjs: "([#][0][0] -= BigInt(#))".} = +func dec*(a: var JsBigInt; b = newJsBigInt"1") {.importjs: "([#][0][0] -= [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, 2 doAssert big1 == newJsBigInt"-1" -func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += 2 doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= 2 doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= 4 doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= [#][0][0])".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" big1 /= 2 doAssert big1 == newJsBigInt"5" -proc `+`*(_: JsBigInt): JsBigInt {.error.} # Can not be used by design. +proc `+`*(_: JsBigInt): JsBigInt {.error: + "See https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs".} # Can not be used by design ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs proc low*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** From 181f037043da46689294d771f579ce4c5c14716d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 11:12:11 -0300 Subject: [PATCH 41/66] https://github.com/nim-lang/Nim/pull/16409#discussion_r551180898 --- lib/std/jsbigints.nim | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index cf9984af071c..f52ff1ce2316 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -106,13 +106,25 @@ func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" -func inc*(a: var JsBigInt; b = newJsBigInt"1") {.importjs: "([#][0][0] += [#][0][0])".} = +func inc*(a: var JsBigInt) {.importjs: "(++[#][0][0])".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"1" + inc big1 + doAssert big1 == newJsBigInt"2" + +func dec*(a: var JsBigInt) {.importjs: "(--[#][0][0])".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"2" + dec big1 + doAssert big1 == newJsBigInt"1" + +func inc*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] += [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, 2 doAssert big1 == newJsBigInt"3" -func dec*(a: var JsBigInt; b = newJsBigInt"1") {.importjs: "([#][0][0] -= [#][0][0])".} = +func dec*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] -= [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, 2 From ee8853a0efbf851c709ad14960cefb8136935530 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 4 Jan 2021 11:22:02 -0300 Subject: [PATCH 42/66] Try to make error messages a little more usable --- lib/std/jsbigints.nim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index f52ff1ce2316..9c24a90530c4 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -22,11 +22,12 @@ func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(# runnableExamples: doAssert newJsBigInt"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring -func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} # asserted on $ +func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} + ## Convert from `JsBigInt` to `cstring` representation. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = - ## Returns a string representation of `JsBigInt`. + ## Returns a `string` representation of `JsBigInt`. runnableExamples: doAssert $newJsBigInt"1024" == "1024" $toCstring(this) @@ -159,9 +160,11 @@ proc `+`*(_: JsBigInt): JsBigInt {.error: "See https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs".} # Can not be used by design ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs -proc low*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** +proc low*(_: typedesc[JsBigInt]): JsBigInt {.error: + "Arbitrary precision integers do not have a known low.".} ## **Do NOT use.** -proc high*(_: typedesc[JsBigInt]): JsBigInt {.error.} ## **Do NOT use.** +proc high*(_: typedesc[JsBigInt]): JsBigInt {.error: + "Arbitrary precision integers do not have a known high.".} ## **Do NOT use.** runnableExamples: From 9c312755f3b12f1d8d25b50b86436e5ad0aa79a2 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 18:21:16 -0300 Subject: [PATCH 43/66] Flip args reversed --- lib/std/jsbigints.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 9c24a90530c4..eda33f74ba95 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -31,13 +31,15 @@ func `$`*(this: JsBigInt): string = runnableExamples: doAssert $newJsBigInt"1024" == "1024" $toCstring(this) -func wrapToInt*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asIntN(#, #)".} = +func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: + "(() => { const i = #, b = #; return BigInt.asIntN(b, i) })()".} = ## Wrap `a` to a signed `JsBigInt` of `bits` bits, for example between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: doAssert wrapToInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" -func wrapToUint*(bits: int; a: JsBigInt): JsBigInt {.importjs: "BigInt.asUintN(#, #)".} = +func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: + "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: doAssert wrapToUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" From 6668104e0c277ade7b510aeaa72dc19a78f66425 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 18:31:05 -0300 Subject: [PATCH 44/66] Fix inc/dec problem --- lib/std/jsbigints.nim | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index eda33f74ba95..c5b00e03b619 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -44,7 +44,7 @@ func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: runnableExamples: doAssert wrapToUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" -func unsafeToNumber*(a: JsBigInt): int {.importjs: "Number(#)".} = +func unsafeToNumber*(this: JsBigInt): int {.importjs: "Number(#)".} = ## Does not do any bounds check and may or may not return an inexact representation. runnableExamples: doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647 @@ -105,29 +105,41 @@ func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} = runnableExamples: doAssert (newJsBigInt"999" shr newJsBigInt"2") == newJsBigInt"249" -func `-`*(a: JsBigInt): JsBigInt {.importjs: "($1#)".} = +func `-`*(this: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" -func inc*(a: var JsBigInt) {.importjs: "(++[#][0][0])".} = +func inc*(this: var JsBigInt) {.importjs: "(++[#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1 doAssert big1 == newJsBigInt"2" -func dec*(a: var JsBigInt) {.importjs: "(--[#][0][0])".} = +func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" dec big1 doAssert big1 == newJsBigInt"1" -func inc*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] += [#][0][0])".} = +func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += [#][0][0])".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"1" + inc big1, newJsBigInt"2" + doAssert big1 == newJsBigInt"3" + +func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= [#][0][0])".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"1" + dec big1, newJsBigInt"2" + doAssert big1 == newJsBigInt"-1" + +func inc*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] += BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, 2 doAssert big1 == newJsBigInt"3" -func dec*(a: var JsBigInt; b: JsBigInt) {.importjs: "([#][0][0] -= [#][0][0])".} = +func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, 2 From ed6cedada6a4cea2b2598e181fe14537b9a60e1d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 18:40:41 -0300 Subject: [PATCH 45/66] simple --- lib/std/jsbigints.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index c5b00e03b619..b4e7912214d4 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -36,13 +36,13 @@ func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: ## Wrap `a` to a signed `JsBigInt` of `bits` bits, for example between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert wrapToInt(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" + doAssert newJsBigInt("2147483647").wrapToInt(32) == newJsBigInt"2147483647" func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} = ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert wrapToUint(32, newJsBigInt"2147483647") == newJsBigInt"2147483647" + doAssert newJsBigInt("2147483647").wrapToUint(32) == newJsBigInt"2147483647" func unsafeToNumber*(this: JsBigInt): int {.importjs: "Number(#)".} = ## Does not do any bounds check and may or may not return an inexact representation. From cbb76a1b006497250ea5fe79e4e228852d89b53c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 18:52:58 -0300 Subject: [PATCH 46/66] simple --- lib/std/jsbigints.nim | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index b4e7912214d4..1a63c96da4d1 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -148,22 +148,47 @@ func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigIn func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" - big1 += 2 + big1 += newJsBigInt"2" doAssert big1 == newJsBigInt"3" func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" - big1 -= 2 + big1 -= newJsBigInt"2" doAssert big1 == newJsBigInt"-1" func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" - big1 *= 4 + big1 *= newJsBigInt"4" doAssert big1 == newJsBigInt"8" func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= [#][0][0])".} = + ## Same as `x = x div y`. + runnableExamples: + var big1: JsBigInt = newJsBigInt"11" + big1 /= newJsBigInt"2" + doAssert big1 == newJsBigInt"5" + +func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"1" + big1 += 2 + doAssert big1 == newJsBigInt"3" + +func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"1" + big1 -= 2 + doAssert big1 == newJsBigInt"-1" + +func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = + runnableExamples: + var big1: JsBigInt = newJsBigInt"2" + big1 *= 4 + doAssert big1 == newJsBigInt"8" + +func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" From 390a5ae0cb39e62762548abbbbd8f7d30f0104ae Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 19:04:52 -0300 Subject: [PATCH 47/66] simple --- lib/std/jsbigints.nim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 1a63c96da4d1..73a7aa69288b 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -121,13 +121,13 @@ func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} = dec big1 doAssert big1 == newJsBigInt"1" -func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += [#][0][0])".} = +func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= [#][0][0])".} = +func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, newJsBigInt"2" @@ -145,25 +145,25 @@ func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigIn dec big1, 2 doAssert big1 == newJsBigInt"-1" -func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = +func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = +func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 [#][0][0])".} = +func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= newJsBigInt"4" doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= [#][0][0])".} = +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" From 03d61c63beaab3bee280e145c70767ccf4f7d277 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 5 Jan 2021 22:58:05 -0300 Subject: [PATCH 48/66] Update lib/std/jsbigints.nim Co-authored-by: Timothee Cour --- lib/std/jsbigints.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 73a7aa69288b..6fec52361147 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -33,16 +33,17 @@ func `$`*(this: JsBigInt): string = func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asIntN(b, i) })()".} = - ## Wrap `a` to a signed `JsBigInt` of `bits` bits, for example between `-2 ^ (bits - 1)` and `2 ^ (bits - 1) - 1`. + ## Wrap `this` to a signed `JsBigInt` of `bits` bits in `-2 ^ (bits - 1)` .. `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert newJsBigInt("2147483647").wrapToInt(32) == newJsBigInt"2147483647" + doAssert (newJsBigInt("3") + newJsBigInt("2") ** newJsBigInt("66")).wrapToInt(13) == newJsBigInt("3") func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} = + ## Wrap `this` to an unsigned `JsBigInt` of `bits` bits in 0 .. `2 ^ bits - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert newJsBigInt("2147483647").wrapToUint(32) == newJsBigInt"2147483647" + doAssert (newJsBigInt("3") + newJsBigInt("2") ** newJsBigInt("66")).wrapToUint(66) == newJsBigInt("3") func unsafeToNumber*(this: JsBigInt): int {.importjs: "Number(#)".} = ## Does not do any bounds check and may or may not return an inexact representation. From 05f3fcb3050ed5cc906da906e491b2de95703eb3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 11:33:26 -0300 Subject: [PATCH 49/66] Use BiggestInt --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 73a7aa69288b..7d518641f6da 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -44,7 +44,7 @@ func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: runnableExamples: doAssert newJsBigInt("2147483647").wrapToUint(32) == newJsBigInt"2147483647" -func unsafeToNumber*(this: JsBigInt): int {.importjs: "Number(#)".} = +func unsafeToNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = ## Does not do any bounds check and may or may not return an inexact representation. runnableExamples: doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647 From a88eac0c9427500e16a40508ab7e3128b98d25db Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 11:36:10 -0300 Subject: [PATCH 50/66] Use BiggestInt --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 7d518641f6da..5d40833c3cee 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -45,7 +45,7 @@ func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: doAssert newJsBigInt("2147483647").wrapToUint(32) == newJsBigInt"2147483647" func unsafeToNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = - ## Does not do any bounds check and may or may not return an inexact representation. + ## **Unsafe**: Does not do any bounds check and may or may not return an inexact representation. runnableExamples: doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647 From 42e77b6ca226b3c0bd24b6166b11f7c06ec9ce97 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 11:36:53 -0300 Subject: [PATCH 51/66] Use BiggestInt --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 5d40833c3cee..649ec1da13c5 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -47,7 +47,7 @@ func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: func unsafeToNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = ## **Unsafe**: Does not do any bounds check and may or may not return an inexact representation. runnableExamples: - doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647 + doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647.BiggestInt func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: From 60f54bf35da70908414b2973e27a6299ec5618ce Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 13:17:16 -0300 Subject: [PATCH 52/66] https://github.com/nim-lang/Nim/pull/16606 --- lib/std/jsbigints.nim | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index ddac38dfae31..b71db26e00f4 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -3,7 +3,8 @@ when not defined(js): {.fatal: "Module jsbigints is designed to be used with the JavaScript backend.".} -type JsBigInt* = ref object of JsRoot ## Arbitrary precision integer for JavaScript target. +type JsBigIntImpl {.importc: "bigint".} = int # https://github.com/nim-lang/Nim/pull/16606 +type JsBigInt* = distinct JsBigIntImpl ## Arbitrary precision integer for JavaScript target. func newJsBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. @@ -110,86 +111,86 @@ func `-`*(this: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" -func inc*(this: var JsBigInt) {.importjs: "(++[#][0][0])".} = +func inc*(this: var JsBigInt) {.importjs: "(++#)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1 doAssert big1 == newJsBigInt"2" -func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} = +func dec*(this: var JsBigInt) {.importjs: "(--#)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" dec big1 doAssert big1 == newJsBigInt"1" -func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} = +func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "(# += #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= #)".} = +func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "(# -= #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func inc*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] += BigInt(#))".} = +func inc*(this: var JsBigInt; amount: Positive) {.importjs: "(# += BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, 2 doAssert big1 == newJsBigInt"3" -func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigInt(#))".} = +func dec*(this: var JsBigInt; amount: Positive) {.importjs: "(# -= BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, 2 doAssert big1 == newJsBigInt"-1" -func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = +func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= newJsBigInt"4" doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# /= #)".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" big1 /= newJsBigInt"2" doAssert big1 == newJsBigInt"5" -func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `+=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += 2 doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `-=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= 2 doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = +func `*=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= 4 doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = +func `/=`*(x: var JsBigInt; y: int) {.importjs: "(# /= BigInt(#))".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" @@ -210,6 +211,7 @@ proc high*(_: typedesc[JsBigInt]): JsBigInt {.error: runnableExamples: let big1: JsBigInt = newJsBigInt"2147483647" let big2: JsBigInt = newJsBigInt"666" + doAssert JsBigInt isnot int doAssert big1 != big2 doAssert big1 > big2 doAssert big1 >= big2 From a6f65f8079e50154bc7b3d00ddd9fdca377ad9f7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 13:36:07 -0300 Subject: [PATCH 53/66] https://github.com/nim-lang/Nim/pull/16606 --- lib/std/jsbigints.nim | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index b71db26e00f4..3942609a704b 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -111,86 +111,86 @@ func `-`*(this: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" -func inc*(this: var JsBigInt) {.importjs: "(++#)".} = +func inc*(this: var JsBigInt) {.importjs: "(++[#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1 doAssert big1 == newJsBigInt"2" -func dec*(this: var JsBigInt) {.importjs: "(--#)".} = +func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" dec big1 doAssert big1 == newJsBigInt"1" -func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "(# += #)".} = +func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "(# -= #)".} = +func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func inc*(this: var JsBigInt; amount: Positive) {.importjs: "(# += BigInt(#))".} = +func inc*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] += BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" inc big1, 2 doAssert big1 == newJsBigInt"3" -func dec*(this: var JsBigInt; amount: Positive) {.importjs: "(# -= BigInt(#))".} = +func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" dec big1, 2 doAssert big1 == newJsBigInt"-1" -func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = +func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += newJsBigInt"2" doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = +func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# $1 #)".} = +func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= newJsBigInt"4" doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "(# /= #)".} = +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" big1 /= newJsBigInt"2" doAssert big1 == newJsBigInt"5" -func `+=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = +func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 += 2 doAssert big1 == newJsBigInt"3" -func `-=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = +func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" big1 -= 2 doAssert big1 == newJsBigInt"-1" -func `*=`*(x: var JsBigInt; y: int) {.importjs: "(# $1 BigInt(#))".} = +func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = runnableExamples: var big1: JsBigInt = newJsBigInt"2" big1 *= 4 doAssert big1 == newJsBigInt"8" -func `/=`*(x: var JsBigInt; y: int) {.importjs: "(# /= BigInt(#))".} = +func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = newJsBigInt"11" From c16c8df6ad36cf5d171330ff7a3849eb6e21ec84 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 16:49:22 -0300 Subject: [PATCH 54/66] Green test --- lib/std/jsbigints.nim | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 3942609a704b..0718c4e26e90 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -135,18 +135,6 @@ func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= #)".} dec big1, newJsBigInt"2" doAssert big1 == newJsBigInt"-1" -func inc*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] += BigInt(#))".} = - runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - inc big1, 2 - doAssert big1 == newJsBigInt"3" - -func dec*(this: var JsBigInt; amount: Positive) {.importjs: "([#][0][0] -= BigInt(#))".} = - runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - dec big1, 2 - doAssert big1 == newJsBigInt"-1" - func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: var big1: JsBigInt = newJsBigInt"1" @@ -172,31 +160,6 @@ func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = big1 /= newJsBigInt"2" doAssert big1 == newJsBigInt"5" -func `+=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = - runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - big1 += 2 - doAssert big1 == newJsBigInt"3" - -func `-=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = - runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - big1 -= 2 - doAssert big1 == newJsBigInt"-1" - -func `*=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] $1 BigInt(#))".} = - runnableExamples: - var big1: JsBigInt = newJsBigInt"2" - big1 *= 4 - doAssert big1 == newJsBigInt"8" - -func `/=`*(x: var JsBigInt; y: int) {.importjs: "([#][0][0] /= BigInt(#))".} = - ## Same as `x = x div y`. - runnableExamples: - var big1: JsBigInt = newJsBigInt"11" - big1 /= 2 - doAssert big1 == newJsBigInt"5" - proc `+`*(_: JsBigInt): JsBigInt {.error: "See https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs".} # Can not be used by design ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs @@ -218,3 +181,5 @@ runnableExamples: doAssert big2 < big1 doAssert big2 <= big1 doAssert not(big1 == big2) + let z = JsBigInt.default + doAssert $z == "0" From 6a53e03f8c8f2d4335dd2a8c6a80de7e0ea7f22c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 7 Jan 2021 20:22:57 -0300 Subject: [PATCH 55/66] Green test --- lib/std/jsbigints.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 0718c4e26e90..e21af5608b59 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -6,6 +6,7 @@ when not defined(js): type JsBigIntImpl {.importc: "bigint".} = int # https://github.com/nim-lang/Nim/pull/16606 type JsBigInt* = distinct JsBigIntImpl ## Arbitrary precision integer for JavaScript target. + func newJsBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: From a7a9dcffd0c3300ef66291e69aec8b131aa3ca7f Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 8 Jan 2021 17:36:50 -0300 Subject: [PATCH 56/66] Fix CI --- tools/kochdocs.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 75bb4443fcb5..7381f008356c 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -14,10 +14,12 @@ const webUploadOutput = "web/upload" var nimExe*: string +const allowList = ["jsbigints.nim"] template isJsOnly(file: string): bool = file.isRelativeTo("lib/js") or - file.isRelativeTo("lib/fusion/js") + file.isRelativeTo("lib/fusion/js") or + file.extractFilename in allowList proc exe*(f: string): string = result = addFileExt(f, ExeExt) From f71ceb3b69528958b0e76bdb155360accbc1ea7d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 8 Jan 2021 20:33:17 -0300 Subject: [PATCH 57/66] Update lib/std/jsbigints.nim Co-authored-by: Timothee Cour --- lib/std/jsbigints.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index e21af5608b59..5d9790addc9f 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -184,3 +184,11 @@ runnableExamples: doAssert not(big1 == big2) let z = JsBigInt.default doAssert $z == "0" + block: + var a: seq[JsBigInt] + a.setLen 2 + doAssert a == @[newJsBigInt"0", newJsBigInt"0"] + doAssert a[^1] == newJsBigInt"0" + var b: JsBigInt + doAssert b == newJsBigInt"0" + doAssert b == JsBigInt.default From d727b797ec59e64539d419c4fd814c5b5ee1a886 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 8 Jan 2021 21:01:54 -0300 Subject: [PATCH 58/66] String representation is now like 999n --- lib/std/jsbigints.nim | 6 +++--- tests/stdlib/tjsbigints.nim | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 5d9790addc9f..565f152782c7 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -30,8 +30,8 @@ func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} func `$`*(this: JsBigInt): string = ## Returns a `string` representation of `JsBigInt`. - runnableExamples: doAssert $newJsBigInt"1024" == "1024" - $toCstring(this) + runnableExamples: doAssert $newJsBigInt"1024" == "1024n" + $toCstring(this) & 'n' func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asIntN(b, i) })()".} = @@ -183,7 +183,7 @@ runnableExamples: doAssert big2 <= big1 doAssert not(big1 == big2) let z = JsBigInt.default - doAssert $z == "0" + doAssert $z == "0n" block: var a: seq[JsBigInt] a.setLen 2 diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim index c204ff4577ac..57350147d6e2 100644 --- a/tests/stdlib/tjsbigints.nim +++ b/tests/stdlib/tjsbigints.nim @@ -19,7 +19,7 @@ doAssert big1 - big2 == newJsBigInt"2147482981" doAssert big1 shl big3 == newJsBigInt"8589934588" doAssert big1 shr big3 == newJsBigInt"536870911" doAssert big1 * big2 == newJsBigInt"1430224108902" -doAssert $big1 == "2147483647".cstring +doAssert $big1 == "2147483647n" doAssert big1.toCstring(10) == "2147483647".cstring doAssert big2 ** big3 == newJsBigInt(443556) var huge = newJsBigInt"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" From a26ca38e08f0b609445b97084ce4d93fa8eee5ab Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 8 Jan 2021 21:12:21 -0300 Subject: [PATCH 59/66] Going big. Is not perfect but it works. --- lib/std/jsbigints.nim | 111 ++++++++++++++++++------------------ tests/stdlib/tjsbigints.nim | 42 +++++++------- 2 files changed, 76 insertions(+), 77 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 565f152782c7..739665b1777c 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -6,23 +6,22 @@ when not defined(js): type JsBigIntImpl {.importc: "bigint".} = int # https://github.com/nim-lang/Nim/pull/16606 type JsBigInt* = distinct JsBigIntImpl ## Arbitrary precision integer for JavaScript target. - -func newJsBigInt*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = +func big*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: - doAssert newJsBigInt(1234567890) == newJsBigInt"1234567890" + doAssert big(1234567890) == big"1234567890" -func newJsBigInt*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = +func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = ## Constructor for `JsBigInt`. runnableExamples: - doAssert newJsBigInt"-1" == newJsBigInt"1" - newJsBigInt"2" + doAssert big"-1" == big"1" - big"2" func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(#)".} = ## Convert from `JsBigInt` to `cstring` representation. ## * `radix` Base to use for representing numeric values. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: - doAssert newJsBigInt"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring + doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} ## Convert from `JsBigInt` to `cstring` representation. @@ -30,7 +29,7 @@ func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} func `$`*(this: JsBigInt): string = ## Returns a `string` representation of `JsBigInt`. - runnableExamples: doAssert $newJsBigInt"1024" == "1024n" + runnableExamples: doAssert $big"1024" == "1024n" $toCstring(this) & 'n' func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: @@ -38,128 +37,128 @@ func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: ## Wrap `this` to a signed `JsBigInt` of `bits` bits in `-2 ^ (bits - 1)` .. `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: - doAssert (newJsBigInt("3") + newJsBigInt("2") ** newJsBigInt("66")).wrapToInt(13) == newJsBigInt("3") + doAssert (big("3") + big("2") ** big("66")).wrapToInt(13) == big("3") func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} = ## Wrap `this` to an unsigned `JsBigInt` of `bits` bits in 0 .. `2 ^ bits - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: - doAssert (newJsBigInt("3") + newJsBigInt("2") ** newJsBigInt("66")).wrapToUint(66) == newJsBigInt("3") + doAssert (big("3") + big("2") ** big("66")).wrapToUint(66) == big("3") func unsafeToNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = ## **Unsafe**: Does not do any bounds check and may or may not return an inexact representation. runnableExamples: - doAssert unsafeToNumber(newJsBigInt"2147483647") == 2147483647.BiggestInt + doAssert unsafeToNumber(big"2147483647") == 2147483647.BiggestInt func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (newJsBigInt"9" + newJsBigInt"1") == newJsBigInt"10" + doAssert (big"9" + big"1") == big"10" func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (newJsBigInt"9" - newJsBigInt"1") == newJsBigInt"8" + doAssert (big"9" - big"1") == big"8" func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: - doAssert (newJsBigInt"42" * newJsBigInt"9") == newJsBigInt"378" + doAssert (big"42" * big"9") == big"378" func `div`*(x, y: JsBigInt): JsBigInt {.importjs: "(# / #)".} = ## Same as `div` but for `JsBigInt`(uses JavaScript `BigInt() / BigInt()`). runnableExamples: - doAssert newJsBigInt"13" div newJsBigInt"3" == newJsBigInt"4" - doAssert newJsBigInt"-13" div newJsBigInt"3" == newJsBigInt"-4" - doAssert newJsBigInt"13" div newJsBigInt"-3" == newJsBigInt"-4" - doAssert newJsBigInt"-13" div newJsBigInt"-3" == newJsBigInt"4" + doAssert big"13" div big"3" == big"4" + doAssert big"-13" div big"3" == big"-4" + doAssert big"13" div big"-3" == big"-4" + doAssert big"-13" div big"-3" == big"4" func `mod`*(x, y: JsBigInt): JsBigInt {.importjs: "(# % #)".} = ## Same as `mod` but for `JsBigInt` (uses JavaScript `BigInt() % BigInt()`). runnableExamples: - doAssert newJsBigInt"13" mod newJsBigInt"3" == newJsBigInt"1" - doAssert newJsBigInt"-13" mod newJsBigInt"3" == newJsBigInt"-1" - doAssert newJsBigInt"13" mod newJsBigInt"-3" == newJsBigInt"1" - doAssert newJsBigInt"-13" mod newJsBigInt"-3" == newJsBigInt"-1" + doAssert big"13" mod big"3" == big"1" + doAssert big"-13" mod big"3" == big"-1" + doAssert big"13" mod big"-3" == big"1" + doAssert big"-13" mod big"-3" == big"-1" func `<`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: - doAssert newJsBigInt"2" < newJsBigInt"9" + doAssert big"2" < big"9" func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: - doAssert newJsBigInt"1" <= newJsBigInt"5" + doAssert big"1" <= big"5" func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} = runnableExamples: - doAssert newJsBigInt"42" == newJsBigInt"42" + doAssert big"42" == big"42" func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} = runnableExamples: - doAssert (newJsBigInt"9" ** newJsBigInt"5") == newJsBigInt"59049" + doAssert (big"9" ** big"5") == big"59049" func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} = runnableExamples: - doAssert (newJsBigInt"555" xor newJsBigInt"2") == newJsBigInt"553" + doAssert (big"555" xor big"2") == big"553" func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} = runnableExamples: - doAssert (newJsBigInt"999" shl newJsBigInt"2") == newJsBigInt"3996" + doAssert (big"999" shl big"2") == big"3996" func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} = runnableExamples: - doAssert (newJsBigInt"999" shr newJsBigInt"2") == newJsBigInt"249" + doAssert (big"999" shr big"2") == big"249" func `-`*(this: JsBigInt): JsBigInt {.importjs: "($1#)".} = runnableExamples: - doAssert -(newJsBigInt"10101010101") == newJsBigInt"-10101010101" + doAssert -(big"10101010101") == big"-10101010101" func inc*(this: var JsBigInt) {.importjs: "(++[#][0][0])".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"1" + var big1: JsBigInt = big"1" inc big1 - doAssert big1 == newJsBigInt"2" + doAssert big1 == big"2" func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"2" + var big1: JsBigInt = big"2" dec big1 - doAssert big1 == newJsBigInt"1" + doAssert big1 == big"1" func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - inc big1, newJsBigInt"2" - doAssert big1 == newJsBigInt"3" + var big1: JsBigInt = big"1" + inc big1, big"2" + doAssert big1 == big"3" func dec*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] -= #)".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - dec big1, newJsBigInt"2" - doAssert big1 == newJsBigInt"-1" + var big1: JsBigInt = big"1" + dec big1, big"2" + doAssert big1 == big"-1" func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - big1 += newJsBigInt"2" - doAssert big1 == newJsBigInt"3" + var big1: JsBigInt = big"1" + big1 += big"2" + doAssert big1 == big"3" func `-=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"1" - big1 -= newJsBigInt"2" - doAssert big1 == newJsBigInt"-1" + var big1: JsBigInt = big"1" + big1 -= big"2" + doAssert big1 == big"-1" func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = runnableExamples: - var big1: JsBigInt = newJsBigInt"2" - big1 *= newJsBigInt"4" - doAssert big1 == newJsBigInt"8" + var big1: JsBigInt = big"2" + big1 *= big"4" + doAssert big1 == big"8" func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = ## Same as `x = x div y`. runnableExamples: - var big1: JsBigInt = newJsBigInt"11" - big1 /= newJsBigInt"2" - doAssert big1 == newJsBigInt"5" + var big1: JsBigInt = big"11" + big1 /= big"2" + doAssert big1 == big"5" proc `+`*(_: JsBigInt): JsBigInt {.error: "See https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs".} # Can not be used by design @@ -173,8 +172,8 @@ proc high*(_: typedesc[JsBigInt]): JsBigInt {.error: runnableExamples: - let big1: JsBigInt = newJsBigInt"2147483647" - let big2: JsBigInt = newJsBigInt"666" + let big1: JsBigInt = big"2147483647" + let big2: JsBigInt = big"666" doAssert JsBigInt isnot int doAssert big1 != big2 doAssert big1 > big2 @@ -187,8 +186,8 @@ runnableExamples: block: var a: seq[JsBigInt] a.setLen 2 - doAssert a == @[newJsBigInt"0", newJsBigInt"0"] - doAssert a[^1] == newJsBigInt"0" + doAssert a == @[big"0", big"0"] + doAssert a[^1] == big"0" var b: JsBigInt - doAssert b == newJsBigInt"0" + doAssert b == big"0" doAssert b == JsBigInt.default diff --git a/tests/stdlib/tjsbigints.nim b/tests/stdlib/tjsbigints.nim index 57350147d6e2..1988f637bd5c 100644 --- a/tests/stdlib/tjsbigints.nim +++ b/tests/stdlib/tjsbigints.nim @@ -5,34 +5,34 @@ discard """ import std/jsbigints -let big1: JsBigInt = newJsBigInt"2147483647" -let big2: JsBigInt = newJsBigInt"666" -var big3: JsBigInt = newJsBigInt"2" +let big1: JsBigInt = big"2147483647" +let big2: JsBigInt = big"666" +var big3: JsBigInt = big"2" -doAssert big3 == newJsBigInt"2" -doAssert (big3 xor big2) == newJsBigInt"664" -doAssert (big1 mod big2) == newJsBigInt"613" -doAssert -big1 == newJsBigInt"-2147483647" -doAssert big1 div big2 == newJsBigInt"3224449" -doAssert big1 + big2 == newJsBigInt"2147484313" -doAssert big1 - big2 == newJsBigInt"2147482981" -doAssert big1 shl big3 == newJsBigInt"8589934588" -doAssert big1 shr big3 == newJsBigInt"536870911" -doAssert big1 * big2 == newJsBigInt"1430224108902" +doAssert big3 == big"2" +doAssert (big3 xor big2) == big"664" +doAssert (big1 mod big2) == big"613" +doAssert -big1 == big"-2147483647" +doAssert big1 div big2 == big"3224449" +doAssert big1 + big2 == big"2147484313" +doAssert big1 - big2 == big"2147482981" +doAssert big1 shl big3 == big"8589934588" +doAssert big1 shr big3 == big"536870911" +doAssert big1 * big2 == big"1430224108902" doAssert $big1 == "2147483647n" doAssert big1.toCstring(10) == "2147483647".cstring -doAssert big2 ** big3 == newJsBigInt(443556) -var huge = newJsBigInt"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +doAssert big2 ** big3 == big(443556) +var huge = big"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" huge.inc -huge = huge + newJsBigInt"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" -doAssert huge == newJsBigInt"1" +huge = huge + big"-999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" +doAssert huge == big"1" var list: seq[JsBigInt] -for i in newJsBigInt"0" .. newJsBigInt"5": +for i in big"0" .. big"5": doAssert i is JsBigInt list.add i -doAssert list == @[newJsBigInt"0", newJsBigInt"1", newJsBigInt"2", newJsBigInt"3", newJsBigInt"4", newJsBigInt"5"] +doAssert list == @[big"0", big"1", big"2", big"3", big"4", big"5"] list = @[] -for i in newJsBigInt"0" ..< newJsBigInt"5": +for i in big"0" ..< big"5": doAssert i is JsBigInt list.add i -doAssert list == @[newJsBigInt"0", newJsBigInt"1", newJsBigInt"2", newJsBigInt"3", newJsBigInt"4"] +doAssert list == @[big"0", big"1", big"2", big"3", big"4"] From af01469e6819409c89404a02ea709b20db8fa0e7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 8 Jan 2021 21:13:25 -0300 Subject: [PATCH 60/66] Going big. Is not perfect but it works. --- lib/std/jsbigints.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 739665b1777c..a0ec04e97b98 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -46,10 +46,10 @@ func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: runnableExamples: doAssert (big("3") + big("2") ** big("66")).wrapToUint(66) == big("3") -func unsafeToNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = - ## **Unsafe**: Does not do any bounds check and may or may not return an inexact representation. +func toNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} = + ## Does not do any bounds check and may or may not return an inexact representation. runnableExamples: - doAssert unsafeToNumber(big"2147483647") == 2147483647.BiggestInt + doAssert toNumber(big"2147483647") == 2147483647.BiggestInt func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} = runnableExamples: From f045b7bc22de7ca4aab758e76f17d29f178882af Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:13:34 -0300 Subject: [PATCH 61/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index a0ec04e97b98..4052e454e2b9 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -17,7 +17,7 @@ func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} = doAssert big"-1" == big"1" - big"2" func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(#)".} = - ## Convert from `JsBigInt` to `cstring` representation. + ## Converts from `JsBigInt` to `cstring` representation. ## * `radix` Base to use for representing numeric values. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString runnableExamples: From 37d6c66114dd167b9e5db13004bbdd1d3d09da8c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:13:42 -0300 Subject: [PATCH 62/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 4052e454e2b9..bf811680f87f 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -24,7 +24,7 @@ func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(# doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} - ## Convert from `JsBigInt` to `cstring` representation. + ## Converts from `JsBigInt` to `cstring` representation. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString func `$`*(this: JsBigInt): string = From 3ed36728b914fa6da7f08cc48159fefcab83e513 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:13:53 -0300 Subject: [PATCH 63/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index bf811680f87f..03a6c9e65850 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -34,7 +34,7 @@ func `$`*(this: JsBigInt): string = func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asIntN(b, i) })()".} = - ## Wrap `this` to a signed `JsBigInt` of `bits` bits in `-2 ^ (bits - 1)` .. `2 ^ (bits - 1) - 1`. + ## Wraps `this` to a signed `JsBigInt` of `bits` bits in `-2 ^ (bits - 1)` .. `2 ^ (bits - 1) - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN runnableExamples: doAssert (big("3") + big("2") ** big("66")).wrapToInt(13) == big("3") From b879961d93be549801aead0b4a2c35d03c7cd97e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:14:03 -0300 Subject: [PATCH 64/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 03a6c9e65850..22205d3faa6f 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -41,7 +41,7 @@ func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs: "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} = - ## Wrap `this` to an unsigned `JsBigInt` of `bits` bits in 0 .. `2 ^ bits - 1`. + ## Wraps `this` to an unsigned `JsBigInt` of `bits` bits in 0 .. `2 ^ bits - 1`. ## https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN runnableExamples: doAssert (big("3") + big("2") ** big("66")).wrapToUint(66) == big("3") From b849823db616df90eeb6084b6f20443d0cf4d381 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:15:19 -0300 Subject: [PATCH 65/66] Update lib/std/jsbigints.nim Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com> --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 22205d3faa6f..136041f7f308 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -153,7 +153,7 @@ func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = big1 *= big"4" doAssert big1 == big"8" -func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] /= #)".} = +func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} = ## Same as `x = x div y`. runnableExamples: var big1: JsBigInt = big"11" From 95033831eac3c90143eec1c6bc198d1c15d137ba Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 9 Jan 2021 13:21:11 -0300 Subject: [PATCH 66/66] https://github.com/nim-lang/Nim/pull/16409#discussion_r554365041 --- lib/std/jsbigints.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsbigints.nim b/lib/std/jsbigints.nim index 136041f7f308..733f3369b85b 100644 --- a/lib/std/jsbigints.nim +++ b/lib/std/jsbigints.nim @@ -87,7 +87,7 @@ func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} = runnableExamples: doAssert big"1" <= big"5" -func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} = +func `==`*(x, y: JsBigInt): bool {.importjs: "(# == #)".} = runnableExamples: doAssert big"42" == big"42"