goscript 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +267 -255
  2. package/cmd/goscript/cmd-test.go +193 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/main.go +1 -0
  5. package/compiler/build-flags.go +38 -0
  6. package/compiler/compile-request.go +2 -0
  7. package/compiler/compliance_test.go +0 -8
  8. package/compiler/gotest/owner.go +24 -0
  9. package/compiler/gotest/package-result.go +67 -0
  10. package/compiler/gotest/request.go +145 -0
  11. package/compiler/gotest/result.go +28 -0
  12. package/compiler/gotest/runner.go +588 -0
  13. package/compiler/gotest/runner_test.go +627 -0
  14. package/compiler/gotest/test.go +9 -0
  15. package/compiler/index.test.ts +1 -1
  16. package/compiler/lowered-program.go +71 -19
  17. package/compiler/lowering.go +5065 -569
  18. package/compiler/override-facts.go +307 -0
  19. package/compiler/override-registry.go +50 -189
  20. package/compiler/override-registry_test.go +47 -0
  21. package/compiler/package-graph.go +50 -27
  22. package/compiler/package-graph_test.go +37 -2
  23. package/compiler/package-test-function.go +9 -0
  24. package/compiler/package-test-graph-package.go +40 -0
  25. package/compiler/package-test-graph-variant.go +105 -0
  26. package/compiler/package-test-graph.go +117 -0
  27. package/compiler/package-test-graph_test.go +144 -0
  28. package/compiler/runtime-contract.go +189 -29
  29. package/compiler/runtime-contract_test.go +44 -30
  30. package/compiler/semantic-model-types.go +9 -6
  31. package/compiler/semantic-model.go +538 -38
  32. package/compiler/semantic-model_test.go +55 -0
  33. package/compiler/service.go +1 -1
  34. package/compiler/skeleton_test.go +679 -49
  35. package/compiler/tsworkspace/owner.go +334 -0
  36. package/compiler/tsworkspace/owner_test.go +93 -0
  37. package/compiler/tsworkspace/result.go +17 -0
  38. package/compiler/typescript-emitter.go +459 -82
  39. package/compiler/wasm/compile.go +1 -1
  40. package/compiler/wasm/compile_test.go +61 -11
  41. package/compiler/wasm_api.go +172 -7
  42. package/dist/gs/builtin/builtin.d.ts +20 -2
  43. package/dist/gs/builtin/builtin.js +194 -6
  44. package/dist/gs/builtin/builtin.js.map +1 -1
  45. package/dist/gs/builtin/channel.d.ts +8 -0
  46. package/dist/gs/builtin/channel.js +12 -0
  47. package/dist/gs/builtin/channel.js.map +1 -1
  48. package/dist/gs/builtin/slice.d.ts +22 -2
  49. package/dist/gs/builtin/slice.js +216 -44
  50. package/dist/gs/builtin/slice.js.map +1 -1
  51. package/dist/gs/builtin/type.d.ts +5 -2
  52. package/dist/gs/builtin/type.js +83 -24
  53. package/dist/gs/builtin/type.js.map +1 -1
  54. package/dist/gs/builtin/varRef.d.ts +5 -0
  55. package/dist/gs/builtin/varRef.js +23 -0
  56. package/dist/gs/builtin/varRef.js.map +1 -1
  57. package/dist/gs/bytes/buffer.gs.js +48 -44
  58. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  59. package/dist/gs/bytes/reader.gs.js +20 -18
  60. package/dist/gs/bytes/reader.gs.js.map +1 -1
  61. package/dist/gs/context/context.d.ts +5 -4
  62. package/dist/gs/context/context.js +10 -10
  63. package/dist/gs/context/context.js.map +1 -1
  64. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  65. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  66. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  67. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  68. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  69. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  70. package/dist/gs/embed/index.d.ts +7 -0
  71. package/dist/gs/embed/index.js +16 -0
  72. package/dist/gs/embed/index.js.map +1 -0
  73. package/dist/gs/encoding/json/index.d.ts +1 -0
  74. package/dist/gs/encoding/json/index.js +18 -0
  75. package/dist/gs/encoding/json/index.js.map +1 -1
  76. package/dist/gs/errors/errors.d.ts +4 -0
  77. package/dist/gs/errors/errors.js +81 -0
  78. package/dist/gs/errors/errors.js.map +1 -1
  79. package/dist/gs/fmt/fmt.d.ts +4 -4
  80. package/dist/gs/fmt/fmt.js +42 -11
  81. package/dist/gs/fmt/fmt.js.map +1 -1
  82. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +35 -0
  83. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +211 -1
  84. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  85. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  86. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
  87. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  88. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
  89. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
  90. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  91. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  92. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
  93. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  94. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  95. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  96. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  97. package/dist/gs/go/scanner/index.d.ts +13 -0
  98. package/dist/gs/go/scanner/index.js +35 -0
  99. package/dist/gs/go/scanner/index.js.map +1 -1
  100. package/dist/gs/go/token/index.d.ts +156 -0
  101. package/dist/gs/go/token/index.js +500 -4
  102. package/dist/gs/go/token/index.js.map +1 -1
  103. package/dist/gs/internal/abi/index.d.ts +4 -0
  104. package/dist/gs/internal/abi/index.js +10 -0
  105. package/dist/gs/internal/abi/index.js.map +1 -1
  106. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  107. package/dist/gs/internal/bytealg/index.js +14 -0
  108. package/dist/gs/internal/bytealg/index.js.map +1 -1
  109. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  110. package/dist/gs/internal/byteorder/index.js +56 -25
  111. package/dist/gs/internal/byteorder/index.js.map +1 -1
  112. package/dist/gs/internal/godebug/index.d.ts +12 -0
  113. package/dist/gs/internal/godebug/index.js +30 -0
  114. package/dist/gs/internal/godebug/index.js.map +1 -0
  115. package/dist/gs/io/fs/index.d.ts +1 -0
  116. package/dist/gs/io/fs/index.js +1 -0
  117. package/dist/gs/io/fs/index.js.map +1 -1
  118. package/dist/gs/io/fs/readlink.d.ts +8 -0
  119. package/dist/gs/io/fs/readlink.js +64 -0
  120. package/dist/gs/io/fs/readlink.js.map +1 -0
  121. package/dist/gs/io/fs/walk.d.ts +3 -3
  122. package/dist/gs/io/fs/walk.js +7 -7
  123. package/dist/gs/io/fs/walk.js.map +1 -1
  124. package/dist/gs/io/io.d.ts +40 -6
  125. package/dist/gs/io/io.js +151 -26
  126. package/dist/gs/io/io.js.map +1 -1
  127. package/dist/gs/maps/iter.d.ts +3 -3
  128. package/dist/gs/maps/iter.js +3 -3
  129. package/dist/gs/maps/iter.js.map +1 -1
  130. package/dist/gs/maps/maps.d.ts +2 -2
  131. package/dist/gs/maps/maps.js +1 -1
  132. package/dist/gs/maps/maps.js.map +1 -1
  133. package/dist/gs/math/bits/index.d.ts +13 -4
  134. package/dist/gs/math/bits/index.js +66 -34
  135. package/dist/gs/math/bits/index.js.map +1 -1
  136. package/dist/gs/math/const.gs.d.ts +5 -5
  137. package/dist/gs/math/const.gs.js +4 -4
  138. package/dist/gs/math/const.gs.js.map +1 -1
  139. package/dist/gs/mime/index.d.ts +1 -0
  140. package/dist/gs/mime/index.js +50 -0
  141. package/dist/gs/mime/index.js.map +1 -0
  142. package/dist/gs/net/http/httptest/index.d.ts +11 -0
  143. package/dist/gs/net/http/httptest/index.js +21 -0
  144. package/dist/gs/net/http/httptest/index.js.map +1 -0
  145. package/dist/gs/net/http/index.d.ts +27 -0
  146. package/dist/gs/net/http/index.js +61 -0
  147. package/dist/gs/net/http/index.js.map +1 -0
  148. package/dist/gs/os/dir_unix.gs.js +2 -2
  149. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  150. package/dist/gs/os/types_js.gs.js.map +1 -1
  151. package/dist/gs/path/filepath/match.js +165 -3
  152. package/dist/gs/path/filepath/match.js.map +1 -1
  153. package/dist/gs/path/filepath/path.d.ts +3 -1
  154. package/dist/gs/path/filepath/path.js +133 -4
  155. package/dist/gs/path/filepath/path.js.map +1 -1
  156. package/dist/gs/path/path.d.ts +4 -1
  157. package/dist/gs/path/path.js +16 -4
  158. package/dist/gs/path/path.js.map +1 -1
  159. package/dist/gs/reflect/index.d.ts +1 -1
  160. package/dist/gs/reflect/index.js +1 -1
  161. package/dist/gs/reflect/index.js.map +1 -1
  162. package/dist/gs/reflect/map.js +3 -0
  163. package/dist/gs/reflect/map.js.map +1 -1
  164. package/dist/gs/reflect/type.d.ts +7 -4
  165. package/dist/gs/reflect/type.js +148 -7
  166. package/dist/gs/reflect/type.js.map +1 -1
  167. package/dist/gs/runtime/debug/index.d.ts +2 -0
  168. package/dist/gs/runtime/debug/index.js +8 -0
  169. package/dist/gs/runtime/debug/index.js.map +1 -0
  170. package/dist/gs/runtime/runtime.d.ts +35 -3
  171. package/dist/gs/runtime/runtime.js +72 -0
  172. package/dist/gs/runtime/runtime.js.map +1 -1
  173. package/dist/gs/slices/slices.d.ts +24 -5
  174. package/dist/gs/slices/slices.js +214 -5
  175. package/dist/gs/slices/slices.js.map +1 -1
  176. package/dist/gs/sort/slice.gs.d.ts +3 -3
  177. package/dist/gs/sort/slice.gs.js +6 -6
  178. package/dist/gs/sort/slice.gs.js.map +1 -1
  179. package/dist/gs/sort/sort.gs.d.ts +4 -4
  180. package/dist/gs/sort/sort.gs.js +11 -8
  181. package/dist/gs/sort/sort.gs.js.map +1 -1
  182. package/dist/gs/strings/builder.d.ts +1 -1
  183. package/dist/gs/strings/builder.js +3 -2
  184. package/dist/gs/strings/builder.js.map +1 -1
  185. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  186. package/dist/gs/sync/atomic/type.gs.js +0 -2
  187. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  188. package/dist/gs/sync/sync.d.ts +2 -0
  189. package/dist/gs/sync/sync.js +27 -0
  190. package/dist/gs/sync/sync.js.map +1 -1
  191. package/dist/gs/syscall/constants.d.ts +36 -24
  192. package/dist/gs/syscall/constants.js +12 -0
  193. package/dist/gs/syscall/constants.js.map +1 -1
  194. package/dist/gs/syscall/errors.d.ts +2 -0
  195. package/dist/gs/syscall/errors.js +8 -0
  196. package/dist/gs/syscall/errors.js.map +1 -1
  197. package/dist/gs/syscall/fs.d.ts +43 -0
  198. package/dist/gs/syscall/fs.js +102 -0
  199. package/dist/gs/syscall/fs.js.map +1 -1
  200. package/dist/gs/syscall/js/index.d.ts +90 -0
  201. package/dist/gs/syscall/js/index.js +375 -0
  202. package/dist/gs/syscall/js/index.js.map +1 -0
  203. package/dist/gs/syscall/types.d.ts +22 -0
  204. package/dist/gs/syscall/types.js +45 -1
  205. package/dist/gs/syscall/types.js.map +1 -1
  206. package/dist/gs/testing/index.d.ts +1 -0
  207. package/dist/gs/testing/index.js +2 -0
  208. package/dist/gs/testing/index.js.map +1 -0
  209. package/dist/gs/testing/testing.d.ts +77 -0
  210. package/dist/gs/testing/testing.js +301 -0
  211. package/dist/gs/testing/testing.js.map +1 -0
  212. package/dist/gs/time/time.d.ts +41 -4
  213. package/dist/gs/time/time.js +205 -36
  214. package/dist/gs/time/time.js.map +1 -1
  215. package/dist/gs/unicode/unicode.d.ts +23 -1
  216. package/dist/gs/unicode/unicode.js +79 -10
  217. package/dist/gs/unicode/unicode.js.map +1 -1
  218. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  219. package/dist/gs/unicode/utf8/utf8.js +24 -11
  220. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  221. package/dist/gs/unique/index.d.ts +11 -0
  222. package/dist/gs/unique/index.js +71 -0
  223. package/dist/gs/unique/index.js.map +1 -0
  224. package/go.sum +9 -0
  225. package/gs/builtin/builtin.ts +239 -8
  226. package/gs/builtin/channel.ts +22 -0
  227. package/gs/builtin/runtime-contract.test.ts +126 -0
  228. package/gs/builtin/slice.ts +259 -50
  229. package/gs/builtin/type.ts +109 -34
  230. package/gs/builtin/varRef.ts +38 -1
  231. package/gs/bytes/buffer.gs.ts +48 -44
  232. package/gs/bytes/meta.json +8 -3
  233. package/gs/bytes/reader.gs.ts +20 -19
  234. package/gs/context/context.test.ts +41 -0
  235. package/gs/context/context.ts +22 -26
  236. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  237. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  238. package/gs/embed/index.ts +20 -0
  239. package/gs/embed/meta.json +5 -0
  240. package/gs/encoding/json/index.test.ts +15 -1
  241. package/gs/encoding/json/index.ts +24 -0
  242. package/gs/errors/errors.test.ts +82 -0
  243. package/gs/errors/errors.ts +104 -0
  244. package/gs/fmt/fmt.ts +56 -16
  245. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +73 -1
  246. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +297 -1
  247. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
  248. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
  249. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
  250. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
  251. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
  252. package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
  253. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  254. package/gs/go/internal/scannerhooks/index.ts +9 -0
  255. package/gs/go/scanner/index.test.ts +22 -0
  256. package/gs/go/scanner/index.ts +47 -0
  257. package/gs/go/token/index.test.ts +47 -1
  258. package/gs/go/token/index.ts +570 -4
  259. package/gs/internal/abi/index.test.ts +18 -0
  260. package/gs/internal/abi/index.ts +14 -0
  261. package/gs/internal/bytealg/index.test.ts +18 -0
  262. package/gs/internal/bytealg/index.ts +16 -0
  263. package/gs/internal/byteorder/index.test.ts +39 -0
  264. package/gs/internal/byteorder/index.ts +100 -27
  265. package/gs/internal/godebug/index.test.ts +16 -0
  266. package/gs/internal/godebug/index.ts +35 -0
  267. package/gs/io/fs/index.ts +1 -0
  268. package/gs/io/fs/meta.json +5 -0
  269. package/gs/io/fs/readlink.test.ts +43 -0
  270. package/gs/io/fs/readlink.ts +77 -0
  271. package/gs/io/fs/walk.test.ts +61 -0
  272. package/gs/io/fs/walk.ts +9 -9
  273. package/gs/io/io.ts +174 -31
  274. package/gs/io/meta.json +10 -2
  275. package/gs/maps/iter.ts +12 -6
  276. package/gs/maps/maps.ts +8 -6
  277. package/gs/math/bits/index.ts +103 -47
  278. package/gs/math/const.gs.test.ts +11 -5
  279. package/gs/math/const.gs.ts +5 -6
  280. package/gs/mime/index.ts +54 -0
  281. package/gs/net/http/httptest/index.ts +25 -0
  282. package/gs/net/http/index.test.ts +20 -0
  283. package/gs/net/http/index.ts +81 -0
  284. package/gs/os/dir_unix.gs.ts +2 -3
  285. package/gs/os/types_js.gs.ts +2 -2
  286. package/gs/path/filepath/match.test.ts +31 -12
  287. package/gs/path/filepath/match.ts +178 -3
  288. package/gs/path/filepath/path.test.ts +25 -0
  289. package/gs/path/filepath/path.ts +159 -5
  290. package/gs/path/path.ts +20 -5
  291. package/gs/reflect/index.ts +1 -0
  292. package/gs/reflect/map.test.ts +19 -0
  293. package/gs/reflect/map.ts +4 -0
  294. package/gs/reflect/type.ts +197 -17
  295. package/gs/runtime/debug/index.test.ts +24 -0
  296. package/gs/runtime/debug/index.ts +8 -0
  297. package/gs/runtime/runtime.test.ts +19 -0
  298. package/gs/runtime/runtime.ts +98 -3
  299. package/gs/slices/slices.test.ts +94 -0
  300. package/gs/slices/slices.ts +245 -5
  301. package/gs/sort/meta.json +7 -0
  302. package/gs/sort/slice.gs.ts +16 -7
  303. package/gs/sort/sort.gs.ts +16 -13
  304. package/gs/strings/builder.ts +4 -3
  305. package/gs/sync/atomic/type.gs.ts +13 -14
  306. package/gs/sync/meta.json +3 -1
  307. package/gs/sync/sync.test.ts +13 -1
  308. package/gs/sync/sync.ts +27 -0
  309. package/gs/syscall/constants.ts +39 -24
  310. package/gs/syscall/errors.ts +10 -0
  311. package/gs/syscall/fs.ts +195 -0
  312. package/gs/syscall/js/index.ts +458 -0
  313. package/gs/syscall/js/meta.json +4 -0
  314. package/gs/syscall/net.test.ts +85 -0
  315. package/gs/syscall/types.ts +56 -0
  316. package/gs/testing/index.ts +1 -0
  317. package/gs/testing/meta.json +5 -0
  318. package/gs/testing/testing.test.ts +90 -0
  319. package/gs/testing/testing.ts +382 -0
  320. package/gs/time/time.test.ts +106 -0
  321. package/gs/time/time.ts +278 -57
  322. package/gs/unicode/unicode.test.ts +25 -0
  323. package/gs/unicode/unicode.ts +119 -9
  324. package/gs/unicode/utf8/utf8.test.ts +13 -0
  325. package/gs/unicode/utf8/utf8.ts +28 -16
  326. package/gs/unique/index.ts +91 -0
  327. package/package.json +2 -1
package/gs/io/io.ts CHANGED
@@ -49,6 +49,9 @@ export interface Writer {
49
49
  Write(p: $.Bytes): [number, $.GoError]
50
50
  }
51
51
 
52
+ type ReaderLike = Reader | { Reader: Reader | null } | null
53
+ type WriterLike = Writer | { Writer: Writer | null } | null
54
+
52
55
  // Closer is the interface that wraps the basic Close method
53
56
  export interface Closer {
54
57
  Close(): $.GoError
@@ -68,6 +71,110 @@ export interface ReadSeeker extends Reader, Seeker {}
68
71
  export interface WriteSeeker extends Writer, Seeker {}
69
72
  export interface ReadWriteSeeker extends Reader, Writer, Seeker {}
70
73
 
74
+ class pipeState {
75
+ private chunks: Uint8Array[] = []
76
+ private readOffset = 0
77
+ private readerClosed = false
78
+ private writerClosed = false
79
+ private readerErr: $.GoError = null
80
+ private writerErr: $.GoError = null
81
+
82
+ Read(p: $.Bytes): [number, $.GoError] {
83
+ if (this.readerClosed) {
84
+ return [0, this.readerErr ?? ErrClosedPipe]
85
+ }
86
+ if ($.len(p) === 0) {
87
+ return [0, null]
88
+ }
89
+ if (this.chunks.length === 0) {
90
+ if (this.writerClosed) {
91
+ return [0, this.writerErr ?? EOF]
92
+ }
93
+ return [0, EOF]
94
+ }
95
+
96
+ let copied = 0
97
+ while (copied < $.len(p) && this.chunks.length > 0) {
98
+ const chunk = this.chunks[0]
99
+ const available = chunk.length - this.readOffset
100
+ const want = Math.min($.len(p) - copied, available)
101
+ const target = $.goSlice(p, copied, copied + want)
102
+ $.copy(target, chunk.subarray(this.readOffset, this.readOffset + want))
103
+ copied += want
104
+ this.readOffset += want
105
+ if (this.readOffset === chunk.length) {
106
+ this.chunks.shift()
107
+ this.readOffset = 0
108
+ }
109
+ }
110
+ return [copied, null]
111
+ }
112
+
113
+ Write(p: $.Bytes): [number, $.GoError] {
114
+ if (this.writerClosed || this.readerClosed) {
115
+ return [0, this.readerErr ?? ErrClosedPipe]
116
+ }
117
+ const data = new Uint8Array($.len(p))
118
+ $.copy(data, p)
119
+ this.chunks.push(data)
120
+ return [$.len(p), null]
121
+ }
122
+
123
+ CloseReader(err: $.GoError): $.GoError {
124
+ this.readerClosed = true
125
+ this.readerErr = err
126
+ this.chunks = []
127
+ this.readOffset = 0
128
+ return null
129
+ }
130
+
131
+ CloseWriter(err: $.GoError): $.GoError {
132
+ this.writerClosed = true
133
+ this.writerErr = err
134
+ return null
135
+ }
136
+ }
137
+
138
+ // PipeReader is the read half of a pipe.
139
+ export class PipeReader implements Reader, Closer {
140
+ constructor(private pipe: pipeState) {}
141
+
142
+ Read(data: $.Bytes): [number, $.GoError] {
143
+ return this.pipe.Read(data)
144
+ }
145
+
146
+ Close(): $.GoError {
147
+ return this.CloseWithError(null)
148
+ }
149
+
150
+ CloseWithError(err: $.GoError): $.GoError {
151
+ return this.pipe.CloseReader(err ?? ErrClosedPipe)
152
+ }
153
+ }
154
+
155
+ // PipeWriter is the write half of a pipe.
156
+ export class PipeWriter implements Writer, Closer {
157
+ constructor(private pipe: pipeState) {}
158
+
159
+ Write(data: $.Bytes): [number, $.GoError] {
160
+ return this.pipe.Write(data)
161
+ }
162
+
163
+ Close(): $.GoError {
164
+ return this.CloseWithError(null)
165
+ }
166
+
167
+ CloseWithError(err: $.GoError): $.GoError {
168
+ return this.pipe.CloseWriter(err ?? EOF)
169
+ }
170
+ }
171
+
172
+ // Pipe creates a synchronous in-memory pipe.
173
+ export function Pipe(): [PipeReader, PipeWriter] {
174
+ const pipe = new pipeState()
175
+ return [new PipeReader(pipe), new PipeWriter(pipe)]
176
+ }
177
+
71
178
  // ReaderAt is the interface that wraps the basic ReadAt method
72
179
  export interface ReaderAt {
73
180
  ReadAt(p: $.Bytes, off: number): [number, $.GoError]
@@ -150,18 +257,20 @@ export class LimitedReader implements Reader {
150
257
  }
151
258
 
152
259
  Read(p: $.Bytes): [number, $.GoError] {
153
- if (this.N <= 0) {
154
- return [0, EOF]
155
- }
260
+ return (async (): Promise<[number, $.GoError]> => {
261
+ if (this.N <= 0) {
262
+ return [0, EOF]
263
+ }
156
264
 
157
- let readBuf = p
158
- if ($.len(p) > this.N) {
159
- readBuf = $.goSlice(p, 0, this.N)
160
- }
265
+ let readBuf = p
266
+ if ($.len(p) > this.N) {
267
+ readBuf = $.goSlice(p, 0, this.N)
268
+ }
161
269
 
162
- const [n, err] = this.R.Read(readBuf)
163
- this.N -= n
164
- return [n, err]
270
+ const [n, err] = await (this.R.Read(readBuf) as any)
271
+ this.N -= n
272
+ return [n, err]
273
+ })() as any
165
274
  }
166
275
  }
167
276
 
@@ -308,24 +417,33 @@ export function NewOffsetWriter(w: WriterAt, off: number): OffsetWriter {
308
417
  }
309
418
 
310
419
  // Copy copies from src to dst until either EOF is reached on src or an error occurs
311
- export function Copy(dst: Writer, src: Reader): [number, $.GoError] {
312
- return CopyBuffer(dst, src, null)
420
+ export async function Copy(
421
+ dst: WriterLike,
422
+ src: ReaderLike,
423
+ ): Promise<[number, $.GoError]> {
424
+ return await CopyBuffer(dst, src, null)
313
425
  }
314
426
 
315
427
  // CopyBuffer is identical to Copy except that it stages through the provided buffer
316
- export function CopyBuffer(
317
- dst: Writer,
318
- src: Reader,
428
+ export async function CopyBuffer(
429
+ dst: WriterLike,
430
+ src: ReaderLike,
319
431
  buf: $.Bytes | null,
320
- ): [number, $.GoError] {
432
+ ): Promise<[number, $.GoError]> {
433
+ dst = unwrapWriter(dst)
434
+ src = unwrapReader(src)
435
+ if (dst === null || src === null) {
436
+ return [0, newError('io: copy with nil reader or writer')]
437
+ }
438
+
321
439
  // If src implements WriterTo, use it
322
440
  if ('WriteTo' in src && typeof (src as any).WriteTo === 'function') {
323
- return (src as WriterTo).WriteTo(dst)
441
+ return await ((src as WriterTo).WriteTo(dst) as any)
324
442
  }
325
443
 
326
444
  // If dst implements ReaderFrom, use it
327
445
  if ('ReadFrom' in dst && typeof (dst as any).ReadFrom === 'function') {
328
- return (dst as ReaderFrom).ReadFrom(src)
446
+ return await ((dst as ReaderFrom).ReadFrom(src) as any)
329
447
  }
330
448
 
331
449
  if (buf === null) {
@@ -334,9 +452,9 @@ export function CopyBuffer(
334
452
 
335
453
  let written = 0
336
454
  while (true) {
337
- const [nr, er] = src.Read(buf)
455
+ const [nr, er] = await (src.Read(buf) as any)
338
456
  if (nr > 0) {
339
- const [nw, ew] = dst.Write($.goSlice(buf, 0, nr))
457
+ const [nw, ew] = await (dst.Write($.goSlice(buf, 0, nr)) as any)
340
458
  if (nw < 0 || nr < nw) {
341
459
  if (ew === null) {
342
460
  return [written, ErrShortWrite]
@@ -361,13 +479,33 @@ export function CopyBuffer(
361
479
  return [written, null]
362
480
  }
363
481
 
482
+ function unwrapReader(src: ReaderLike): Reader | null {
483
+ if (src == null) {
484
+ return null
485
+ }
486
+ if ('Read' in src && typeof (src as any).Read === 'function') {
487
+ return src as Reader
488
+ }
489
+ return (src as { Reader: Reader | null }).Reader
490
+ }
491
+
492
+ function unwrapWriter(dst: WriterLike): Writer | null {
493
+ if (dst == null) {
494
+ return null
495
+ }
496
+ if ('Write' in dst && typeof (dst as any).Write === 'function') {
497
+ return dst as Writer
498
+ }
499
+ return (dst as { Writer: Writer | null }).Writer
500
+ }
501
+
364
502
  // CopyN copies n bytes (or until an error) from src to dst
365
- export function CopyN(
503
+ export async function CopyN(
366
504
  dst: Writer,
367
505
  src: Reader,
368
506
  n: number,
369
- ): [number, $.GoError] {
370
- const [written, err] = Copy(dst, LimitReader(src, n))
507
+ ): Promise<[number, $.GoError]> {
508
+ const [written, err] = await Copy(dst, LimitReader(src, n))
371
509
  if (written === n) {
372
510
  return [written, null]
373
511
  }
@@ -379,23 +517,26 @@ export function CopyN(
379
517
  }
380
518
 
381
519
  // ReadAtLeast reads from r into buf until it has read at least min bytes
382
- export function ReadAtLeast(
520
+ export async function ReadAtLeast(
383
521
  r: Reader,
384
522
  buf: $.Bytes,
385
523
  min: number,
386
- ): [number, $.GoError] {
524
+ ): Promise<[number, $.GoError]> {
387
525
  if ($.len(buf) < min) {
388
526
  return [0, ErrShortBuffer]
389
527
  }
390
528
 
391
529
  let n = 0
392
530
  while (n < min) {
393
- const [nn, err] = r.Read($.goSlice(buf, n))
531
+ const [nn, err] = await (r.Read($.goSlice(buf, n)) as any)
394
532
  n += nn
395
533
  if (err !== null) {
396
534
  if (err === EOF && n >= min) {
397
535
  return [n, null]
398
536
  }
537
+ if (err === EOF && n === 0) {
538
+ return [n, EOF]
539
+ }
399
540
  if (err === EOF && n < min) {
400
541
  return [n, ErrUnexpectedEOF]
401
542
  }
@@ -406,20 +547,22 @@ export function ReadAtLeast(
406
547
  }
407
548
 
408
549
  // ReadFull reads exactly len(buf) bytes from r into buf
409
- export function ReadFull(r: Reader, buf: $.Bytes): [number, $.GoError] {
410
- return ReadAtLeast(r, buf, $.len(buf))
550
+ export async function ReadFull(r: Reader, buf: $.Bytes): Promise<[number, $.GoError]> {
551
+ return await ReadAtLeast(r, buf, $.len(buf))
411
552
  }
412
553
 
413
554
  // ReadAll reads from r until an error or EOF and returns the data it read
414
- export function ReadAll(r: Reader): [$.Bytes, $.GoError] {
555
+ export async function ReadAll(r: Reader): Promise<[$.Bytes, $.GoError]> {
415
556
  const chunks: $.Bytes[] = []
416
557
  let totalLength = 0
417
558
  const buf = $.makeSlice<number>(512, undefined, 'byte')
418
559
 
419
560
  while (true) {
420
- const [n, err] = r.Read(buf)
561
+ const [n, err] = await (r.Read(buf) as any)
421
562
  if (n > 0) {
422
- chunks.push($.goSlice(buf, 0, n))
563
+ const chunk = $.makeSlice<number>(n, undefined, 'byte')
564
+ $.copy(chunk, $.goSlice(buf, 0, n))
565
+ chunks.push(chunk)
423
566
  totalLength += n
424
567
  }
425
568
  if (err !== null) {
package/gs/io/meta.json CHANGED
@@ -5,5 +5,13 @@
5
5
  "path",
6
6
  "time",
7
7
  "unicode/utf8"
8
- ]
9
- }
8
+ ],
9
+ "asyncFunctions": {
10
+ "Copy": true,
11
+ "CopyBuffer": true,
12
+ "CopyN": true,
13
+ "ReadAtLeast": true,
14
+ "ReadFull": true,
15
+ "ReadAll": true
16
+ }
17
+ }
package/gs/maps/iter.ts CHANGED
@@ -5,9 +5,11 @@ import * as iter from '@goscript/iter/index.js'
5
5
  // All returns an iterator over key-value pairs from m.
6
6
  // The iteration order is not specified and is not guaranteed
7
7
  // to be the same from one call to the next.
8
- export function All<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq2<K, V> {
8
+ export function All<K extends $.Comparable, V>(
9
+ m: Map<K, V> | null,
10
+ ): iter.Seq2<K, V> {
9
11
  return (_yield: ((p0: K, p1: V) => boolean) | null): void => {
10
- for (const [k, v] of m.entries()) {
12
+ for (const [k, v] of m?.entries() ?? []) {
11
13
  if (!_yield!(k, v)) {
12
14
  return
13
15
  }
@@ -18,9 +20,11 @@ export function All<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq2<K, V> {
18
20
  // Keys returns an iterator over keys in m.
19
21
  // The iteration order is not specified and is not guaranteed
20
22
  // to be the same from one call to the next.
21
- export function Keys<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq<K> {
23
+ export function Keys<K extends $.Comparable, V>(
24
+ m: Map<K, V> | null,
25
+ ): iter.Seq<K> {
22
26
  return (_yield: ((p0: K) => boolean) | null): void => {
23
- for (const [k, _v] of m.entries()) {
27
+ for (const [k, _v] of m?.entries() ?? []) {
24
28
  if (!_yield!(k)) {
25
29
  return
26
30
  }
@@ -31,9 +35,11 @@ export function Keys<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq<K> {
31
35
  // Values returns an iterator over values in m.
32
36
  // The iteration order is not specified and is not guaranteed
33
37
  // to be the same from one call to the next.
34
- export function Values<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq<V> {
38
+ export function Values<K extends $.Comparable, V>(
39
+ m: Map<K, V> | null,
40
+ ): iter.Seq<V> {
35
41
  return (_yield: ((p0: V) => boolean) | null): void => {
36
- for (const [_k, v] of m.entries()) {
42
+ for (const [_k, v] of m?.entries() ?? []) {
37
43
  if (!_yield!(v)) {
38
44
  return
39
45
  }
package/gs/maps/maps.ts CHANGED
@@ -55,12 +55,14 @@ export function clone<K extends $.Comparable, V>(
55
55
 
56
56
  // Clone returns a copy of m. This is a shallow clone:
57
57
  // the new keys and values are set using ordinary assignment.
58
- export function Clone<K extends $.Comparable, V>(m: Map<K, V>): Map<K, V> {
58
+ export function Clone<K extends $.Comparable, V>(
59
+ m: Map<K, V> | null,
60
+ ): Map<K, V> | null {
59
61
  // Preserve nil in case it matters.
60
62
  if (m == null) {
61
- return null as unknown as Map<K, V>
63
+ return null
62
64
  }
63
- return clone(m)!
65
+ return clone(m)
64
66
  }
65
67
 
66
68
  // Copy copies all key/value pairs in src adding them to dst.
@@ -68,10 +70,10 @@ export function Clone<K extends $.Comparable, V>(m: Map<K, V>): Map<K, V> {
68
70
  // the value in dst will be overwritten by the value associated
69
71
  // with the key in src.
70
72
  export function Copy<K extends $.Comparable, V>(
71
- dst: Map<K, V>,
72
- src: Map<K, V>,
73
+ dst: Map<K, V> | null,
74
+ src: Map<K, V> | null,
73
75
  ): void {
74
- for (const [k, v] of src.entries()) {
76
+ for (const [k, v] of src?.entries() ?? []) {
75
77
  $.mapSet(dst, k, v)
76
78
  }
77
79
  }
@@ -4,6 +4,22 @@
4
4
  // UintSize is the size of a uint in bits
5
5
  export const UintSize = 32 // Assuming 32-bit for JavaScript numbers
6
6
 
7
+ type Word64 = number | bigint
8
+
9
+ const uint64Mask = (1n << 64n) - 1n
10
+
11
+ function toUint64(x: Word64): bigint {
12
+ return BigInt(x) & uint64Mask
13
+ }
14
+
15
+ function useBigIntResult(...values: Word64[]): boolean {
16
+ return values.some((value) => typeof value === 'bigint')
17
+ }
18
+
19
+ function word64Result(value: bigint, useBigInt: boolean): Word64 {
20
+ return useBigInt ? value : Number(value)
21
+ }
22
+
7
23
  // --- Leading zeros ---
8
24
  export function LeadingZeros(x: number): number {
9
25
  return Math.clz32(x >>> 0)
@@ -21,8 +37,9 @@ export function LeadingZeros32(x: number): number {
21
37
  return Math.clz32(x >>> 0)
22
38
  }
23
39
 
24
- export function LeadingZeros64(x: bigint): number {
40
+ export function LeadingZeros64(x: Word64): number {
25
41
  // For 64-bit, we need to handle it differently
42
+ x = toUint64(x)
26
43
  if (x === 0n) return 64
27
44
  let count = 0
28
45
  let mask = 1n << 63n
@@ -59,7 +76,8 @@ export function TrailingZeros32(x: number): number {
59
76
  return count
60
77
  }
61
78
 
62
- export function TrailingZeros64(x: bigint): number {
79
+ export function TrailingZeros64(x: Word64): number {
80
+ x = toUint64(x)
63
81
  if (x === 0n) return 64
64
82
  let count = 0
65
83
  while ((x & 1n) === 0n && count < 64) {
@@ -93,7 +111,8 @@ export function OnesCount32(x: number): number {
93
111
  return count
94
112
  }
95
113
 
96
- export function OnesCount64(x: bigint): number {
114
+ export function OnesCount64(x: Word64): number {
115
+ x = toUint64(x)
97
116
  let count = 0
98
117
  while (x > 0n) {
99
118
  count++
@@ -128,12 +147,17 @@ export function RotateLeft32(x: number, k: number): number {
128
147
  return ((x << k) | (x >>> (n - k))) >>> 0
129
148
  }
130
149
 
131
- export function RotateLeft64(x: bigint, k: number): bigint {
150
+ export function RotateLeft64(x: number, k: number): number
151
+ export function RotateLeft64(x: bigint, k: number): bigint
152
+ export function RotateLeft64(x: Word64, k: number): Word64 {
132
153
  const n = 64
133
154
  k = k % n
134
- const mask = (1n << 64n) - 1n
135
- x = x & mask
136
- return ((x << BigInt(k)) | (x >> BigInt(n - k))) & mask
155
+ const useBigInt = useBigIntResult(x)
156
+ const word = toUint64(x)
157
+ return word64Result(
158
+ ((word << BigInt(k)) | (word >> BigInt(n - k))) & uint64Mask,
159
+ useBigInt,
160
+ )
137
161
  }
138
162
 
139
163
  // --- Reverse ---
@@ -168,25 +192,39 @@ export function Reverse32(x: number): number {
168
192
  return x >>> 0
169
193
  }
170
194
 
171
- export function Reverse64(x: bigint): bigint {
195
+ export function Reverse64(x: number): number
196
+ export function Reverse64(x: bigint): bigint
197
+ export function Reverse64(x: Word64): Word64 {
172
198
  // Implement 64-bit reverse using similar bit manipulation
173
- const mask = (1n << 64n) - 1n
174
- x = x & mask
199
+ const useBigInt = useBigIntResult(x)
200
+ let word = toUint64(x)
175
201
 
176
202
  // Swap 32-bit halves
177
- x = ((x & 0xffffffff00000000n) >> 32n) | ((x & 0x00000000ffffffffn) << 32n)
203
+ word =
204
+ ((word & 0xffffffff00000000n) >> 32n) |
205
+ ((word & 0x00000000ffffffffn) << 32n)
178
206
  // Swap 16-bit chunks
179
- x = ((x & 0xffff0000ffff0000n) >> 16n) | ((x & 0x0000ffff0000ffffn) << 16n)
207
+ word =
208
+ ((word & 0xffff0000ffff0000n) >> 16n) |
209
+ ((word & 0x0000ffff0000ffffn) << 16n)
180
210
  // Swap 8-bit chunks
181
- x = ((x & 0xff00ff00ff00ff00n) >> 8n) | ((x & 0x00ff00ff00ff00ffn) << 8n)
211
+ word =
212
+ ((word & 0xff00ff00ff00ff00n) >> 8n) |
213
+ ((word & 0x00ff00ff00ff00ffn) << 8n)
182
214
  // Swap 4-bit chunks
183
- x = ((x & 0xf0f0f0f0f0f0f0f0n) >> 4n) | ((x & 0x0f0f0f0f0f0f0f0fn) << 4n)
215
+ word =
216
+ ((word & 0xf0f0f0f0f0f0f0f0n) >> 4n) |
217
+ ((word & 0x0f0f0f0f0f0f0f0fn) << 4n)
184
218
  // Swap 2-bit chunks
185
- x = ((x & 0xccccccccccccccccn) >> 2n) | ((x & 0x3333333333333333n) << 2n)
219
+ word =
220
+ ((word & 0xccccccccccccccccn) >> 2n) |
221
+ ((word & 0x3333333333333333n) << 2n)
186
222
  // Swap 1-bit chunks
187
- x = ((x & 0xaaaaaaaaaaaaaaaan) >> 1n) | ((x & 0x5555555555555555n) << 1n)
223
+ word =
224
+ ((word & 0xaaaaaaaaaaaaaaaan) >> 1n) |
225
+ ((word & 0x5555555555555555n) << 1n)
188
226
 
189
- return x & mask
227
+ return word64Result(word & uint64Mask, useBigInt)
190
228
  }
191
229
 
192
230
  // --- ReverseBytes ---
@@ -209,20 +247,23 @@ export function ReverseBytes32(x: number): number {
209
247
  )
210
248
  }
211
249
 
212
- export function ReverseBytes64(x: bigint): bigint {
213
- const mask = (1n << 64n) - 1n
214
- x = x & mask
215
-
216
- return (
217
- (((x & 0xffn) << 56n) |
218
- ((x & 0xff00n) << 40n) |
219
- ((x & 0xff0000n) << 24n) |
220
- ((x & 0xff000000n) << 8n) |
221
- ((x & 0xff00000000n) >> 8n) |
222
- ((x & 0xff0000000000n) >> 24n) |
223
- ((x & 0xff000000000000n) >> 40n) |
224
- ((x & 0xff00000000000000n) >> 56n)) &
225
- mask
250
+ export function ReverseBytes64(x: number): number
251
+ export function ReverseBytes64(x: bigint): bigint
252
+ export function ReverseBytes64(x: Word64): Word64 {
253
+ const useBigInt = useBigIntResult(x)
254
+ const word = toUint64(x)
255
+
256
+ return word64Result(
257
+ (((word & 0xffn) << 56n) |
258
+ ((word & 0xff00n) << 40n) |
259
+ ((word & 0xff0000n) << 24n) |
260
+ ((word & 0xff000000n) << 8n) |
261
+ ((word & 0xff00000000n) >> 8n) |
262
+ ((word & 0xff0000000000n) >> 24n) |
263
+ ((word & 0xff000000000000n) >> 40n) |
264
+ ((word & 0xff00000000000000n) >> 56n)) &
265
+ uint64Mask,
266
+ useBigInt,
226
267
  )
227
268
  }
228
269
 
@@ -243,7 +284,7 @@ export function Len32(x: number): number {
243
284
  return 32 - LeadingZeros32(x)
244
285
  }
245
286
 
246
- export function Len64(x: bigint): number {
287
+ export function Len64(x: Word64): number {
247
288
  return 64 - LeadingZeros64(x)
248
289
  }
249
290
 
@@ -260,7 +301,12 @@ export function Mul32(x: number, y: number): [number, number] {
260
301
  return [hi, lo]
261
302
  }
262
303
 
263
- export function Mul64(x: bigint, y: bigint): [bigint, bigint] {
304
+ export function Mul64(x: number, y: number): [number, number]
305
+ export function Mul64(x: bigint, y: bigint): [bigint, bigint]
306
+ export function Mul64(x: Word64, y: Word64): [Word64, Word64] {
307
+ const useBigInt = useBigIntResult(x, y)
308
+ x = toUint64(x)
309
+ y = toUint64(y)
264
310
  const mask32 = 0xffffffffn
265
311
 
266
312
  // Split into 32-bit parts
@@ -279,7 +325,7 @@ export function Mul64(x: bigint, y: bigint): [bigint, bigint] {
279
325
  const lo = p00 + ((p01 + p10) << 32n)
280
326
  const hi = p11 + ((p01 + p10) >> 32n) + (lo < p00 ? 1n : 0n)
281
327
 
282
- return [hi, lo]
328
+ return [word64Result(hi & uint64Mask, useBigInt), word64Result(lo & uint64Mask, useBigInt)]
283
329
  }
284
330
 
285
331
  // --- Division functions ---
@@ -302,7 +348,13 @@ export function Div32(hi: number, lo: number, y: number): [number, number] {
302
348
  return [Number(quotient), Number(remainder)]
303
349
  }
304
350
 
305
- export function Div64(hi: bigint, lo: bigint, y: bigint): [bigint, bigint] {
351
+ export function Div64(hi: number, lo: number, y: number): [number, number]
352
+ export function Div64(hi: bigint, lo: bigint, y: bigint): [bigint, bigint]
353
+ export function Div64(hi: Word64, lo: Word64, y: Word64): [Word64, Word64] {
354
+ const useBigInt = useBigIntResult(hi, lo, y)
355
+ hi = toUint64(hi)
356
+ lo = toUint64(lo)
357
+ y = toUint64(y)
306
358
  if (y === 0n) {
307
359
  throw new Error('division by zero')
308
360
  }
@@ -313,7 +365,7 @@ export function Div64(hi: bigint, lo: bigint, y: bigint): [bigint, bigint] {
313
365
  const quotient = dividend / y
314
366
  const remainder = dividend % y
315
367
 
316
- return [quotient, remainder]
368
+ return [word64Result(quotient, useBigInt), word64Result(remainder, useBigInt)]
317
369
  }
318
370
 
319
371
  // --- Add and Sub with carry ---
@@ -328,12 +380,14 @@ export function Add32(x: number, y: number, carry: number): [number, number] {
328
380
  return [result, carryOut]
329
381
  }
330
382
 
331
- export function Add64(x: bigint, y: bigint, carry: bigint): [bigint, bigint] {
332
- const mask = (1n << 64n) - 1n
333
- const sum = (x & mask) + (y & mask) + (carry & mask)
334
- const result = sum & mask
335
- const carryOut = sum > mask ? 1n : 0n
336
- return [result, carryOut]
383
+ export function Add64(x: number, y: number, carry: number): [number, number]
384
+ export function Add64(x: bigint, y: bigint, carry: bigint): [bigint, bigint]
385
+ export function Add64(x: Word64, y: Word64, carry: Word64): [Word64, Word64] {
386
+ const useBigInt = useBigIntResult(x, y, carry)
387
+ const sum = toUint64(x) + toUint64(y) + toUint64(carry)
388
+ const result = sum & uint64Mask
389
+ const carryOut = sum > uint64Mask ? 1n : 0n
390
+ return [word64Result(result, useBigInt), word64Result(carryOut, useBigInt)]
337
391
  }
338
392
 
339
393
  export function Sub(x: number, y: number, borrow: number): [number, number] {
@@ -347,10 +401,12 @@ export function Sub32(x: number, y: number, borrow: number): [number, number] {
347
401
  return [result, borrowOut]
348
402
  }
349
403
 
350
- export function Sub64(x: bigint, y: bigint, borrow: bigint): [bigint, bigint] {
351
- const mask = (1n << 64n) - 1n
352
- const diff = (x & mask) - (y & mask) - (borrow & mask)
353
- const result = diff & mask
404
+ export function Sub64(x: number, y: number, borrow: number): [number, number]
405
+ export function Sub64(x: bigint, y: bigint, borrow: bigint): [bigint, bigint]
406
+ export function Sub64(x: Word64, y: Word64, borrow: Word64): [Word64, Word64] {
407
+ const useBigInt = useBigIntResult(x, y, borrow)
408
+ const diff = toUint64(x) - toUint64(y) - toUint64(borrow)
409
+ const result = diff & uint64Mask
354
410
  const borrowOut = diff < 0n ? 1n : 0n
355
- return [result, borrowOut]
411
+ return [word64Result(result, useBigInt), word64Result(borrowOut, useBigInt)]
356
412
  }
@@ -69,12 +69,18 @@ describe('Mathematical Constants', () => {
69
69
  expect(MaxUint32).toBe(4294967295)
70
70
  })
71
71
 
72
- it('should have correct bigint limits', () => {
73
- expect(MaxInt).toBe(9223372036854775807n)
74
- expect(MinInt).toBe(-9223372036854775808n)
75
- expect(MaxInt64).toBe(9223372036854775807n)
76
- expect(MinInt64).toBe(-9223372036854775808n)
72
+ it('should have correct wide integer limits', () => {
73
+ expect(MaxInt).toBe(Number(9223372036854775807n))
74
+ expect(MinInt).toBe(Number(-9223372036854775808n))
75
+ expect(MaxInt64).toBe(Number(9223372036854775807n))
76
+ expect(MinInt64).toBe(Number(-9223372036854775808n))
77
77
  expect(MaxUint).toBe(0xffffffffffffffffn)
78
78
  expect(MaxUint64).toBe(0xffffffffffffffffn)
79
79
  })
80
+
81
+ it('should typecheck current number-based uint64 comparisons', () => {
82
+ const counter: number = 0
83
+ const atLimit: boolean = counter === MaxUint64
84
+ expect(atLimit).toBe(false)
85
+ })
80
86
  })