summary refs log tree commit diff stats
path: root/tests/stdlib/tnet.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/stdlib/tnet.nim')
0 files changed, 0 insertions, 0 deletions
='#n55'>55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
## Arbitrary precision integers.
## * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
when not defined(js):
  {.fatal: "Module jsbigints is designed to be used with the JavaScript backend.".}

type JsBigIntImpl {.importc: "bigint".} = int # https://github.com/nim-lang/Nim/pull/16606
type JsBigInt* = distinct JsBigIntImpl        ## Arbitrary precision integer for JavaScript target.

func big*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} =
  ## Constructor for `JsBigInt`.
  runnableExamples:
    doAssert big(1234567890) == big"1234567890"
    doAssert 0b1111100111.big == 0o1747.big and 0o1747.big == 999.big

func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} =
  ## Constructor for `JsBigInt`.
  runnableExamples:
    doAssert big"-1" == big"1" - big"2"
    # supports decimal, binary, octal, hex:
    doAssert big"12" == 12.big
    doAssert big"0b101" == 0b101.big
    doAssert big"0o701" == 0o701.big
    doAssert big"0xdeadbeaf" == 0xdeadbeaf.big
    doAssert big"0xffffffffffffffff" == (1.big shl 64.big) - 1.big

func toCstring*(this: JsBigInt; radix: 2..36): cstring {.importjs: "#.toString(#)".} =
  ## 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:
    doAssert big"2147483647".toCstring(2) == "1111111111111111111111111111111".cstring

func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".}
  ## Converts 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`.
  runnableExamples: doAssert $big"1024" == "1024n"
  $toCstring(this) & 'n'

func wrapToInt*(this: JsBigInt; bits: Natural): JsBigInt {.importjs:
  "(() => { const i = #, b = #; return BigInt.asIntN(b, i) })()".} =
  ## 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")

func wrapToUint*(this: JsBigInt; bits: Natural): JsBigInt {.importjs:
  "(() => { const i = #, b = #; return BigInt.asUintN(b, i) })()".} =
  ## 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")

func toNumber*(this: JsBigInt): BiggestInt {.importjs: "Number(#)".} =
  ## Does not do any bounds check and may or may not return an inexact representation.
  runnableExamples:
    doAssert toNumber(big"2147483647") == 2147483647.BiggestInt

func `+`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} =
  runnableExamples:
    doAssert (big"9" + big"1") == big"10"

func `-`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} =
  runnableExamples:
    doAssert (big"9" - big"1") == big"8"

func `*`*(x, y: JsBigInt): JsBigInt {.importjs: "(# $1 #)".} =
  runnableExamples:
    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 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 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 big"2" < big"9"

func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} =
  runnableExamples:
    doAssert big"1" <= big"5"

func `==`*(x, y: JsBigInt): bool {.importjs: "(# == #)".} =
  runnableExamples:
    doAssert big"42" == big"42"

func `**`*(x, y: JsBigInt): JsBigInt {.importjs: "((#) $1 #)".} =
  # (#) needed, refs https://github.com/nim-lang/Nim/pull/16409#issuecomment-760550812
  runnableExamples:
    doAssert big"2" ** big"64" == big"18446744073709551616"
    doAssert big"-2" ** big"3" == big"-8"
    doAssert -big"2" ** big"2" == big"4" # parsed as: (-2n) ** 2n
    doAssert big"0" ** big"0" == big"1" # edge case
    var ok = false
    try: discard big"2" ** big"-1" # raises foreign `RangeError`
    except: ok = true
    doAssert ok
  # pending https://github.com/nim-lang/Nim/pull/15940, simplify to:
  # doAssertRaises: discard big"2" ** big"-1" # raises foreign `RangeError`

func `and`*(x, y: JsBigInt): JsBigInt {.importjs: "(# & #)".} =
  runnableExamples:
    doAssert (big"555" and big"2") == big"2"

func `or`*(x, y: JsBigInt): JsBigInt {.importjs: "(# | #)".} =
  runnableExamples:
    doAssert (big"555" or big"2") == big"555"

func `xor`*(x, y: JsBigInt): JsBigInt {.importjs: "(# ^ #)".} =
  runnableExamples:
    doAssert (big"555" xor big"2") == big"553"

func `shl`*(a, b: JsBigInt): JsBigInt {.importjs: "(# << #)".} =
  runnableExamples:
    doAssert (big"999" shl big"2") == big"3996"

func `shr`*(a, b: JsBigInt): JsBigInt {.importjs: "(# >> #)".} =
  runnableExamples:
    doAssert (big"999" shr big"2") == big"249"

func `-`*(this: JsBigInt): JsBigInt {.importjs: "($1#)".} =
  runnableExamples:
    doAssert -(big"10101010101") == big"-10101010101"

func inc*(this: var JsBigInt) {.importjs: "(++[#][0][0])".} =
  runnableExamples:
    var big1: JsBigInt = big"1"
    inc big1
    doAssert big1 == big"2"

func dec*(this: var JsBigInt) {.importjs: "(--[#][0][0])".} =
  runnableExamples:
    var big1: JsBigInt = big"2"
    dec big1
    doAssert big1 == big"1"

func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} =
  runnableExamples:
    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 = big"1"
    dec big1, big"2"
    doAssert big1 == big"-1"

func `+=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} =
  runnableExamples:
    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 = big"1"
    big1 -= big"2"
    doAssert big1 == big"-1"

func `*=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} =
  runnableExamples:
    var big1: JsBigInt = big"2"
    big1 *= big"4"
    doAssert big1 == big"8"

func `/=`*(x: var JsBigInt; y: JsBigInt) {.importjs: "([#][0][0] $1 #)".} =
  ## Same as `x = x div y`.
  runnableExamples:
    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
  ## **Do NOT use.** https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs

proc low*(_: typedesc[JsBigInt]): JsBigInt {.error:
  "Arbitrary precision integers do not have a known low.".} ## **Do NOT use.**

proc high*(_: typedesc[JsBigInt]): JsBigInt {.error:
  "Arbitrary precision integers do not have a known high.".} ## **Do NOT use.**


runnableExamples:
  block:
    let big1: JsBigInt = big"2147483647"
    let big2: JsBigInt = big"666"
    doAssert JsBigInt isnot int
    doAssert big1 != big2
    doAssert big1 > big2
    doAssert big1 >= big2
    doAssert big2 < big1
    doAssert big2 <= big1
    doAssert not(big1 == big2)
    let z = JsBigInt.default
    doAssert $z == "0n"
  block:
    var a: seq[JsBigInt]
    a.setLen 2
    doAssert a == @[big"0", big"0"]
    doAssert a[^1] == big"0"
    var b: JsBigInt
    doAssert b == big"0"
    doAssert b == JsBigInt.default