goscript 0.1.3 → 0.2.0

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 (330) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript/cmd_compile_test.go +105 -6
  8. package/compiler/build-flags.go +9 -10
  9. package/compiler/compile-request.go +12 -9
  10. package/compiler/compliance_test.go +0 -1
  11. package/compiler/config.go +2 -0
  12. package/compiler/gotest/request.go +28 -0
  13. package/compiler/gotest/runner.go +353 -27
  14. package/compiler/gotest/runner_test.go +400 -1
  15. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  16. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  17. package/compiler/lowered-program.go +24 -17
  18. package/compiler/lowering.go +988 -263
  19. package/compiler/lowering_bench_test.go +364 -0
  20. package/compiler/override-facts.go +15 -0
  21. package/compiler/override-parity-verifier.go +450 -0
  22. package/compiler/override-parity.go +122 -0
  23. package/compiler/override-registry_test.go +559 -0
  24. package/compiler/package-graph.go +61 -4
  25. package/compiler/package-graph_test.go +30 -0
  26. package/compiler/protobuf-ts-binding.go +514 -0
  27. package/compiler/protobuf-ts-binding_test.go +172 -0
  28. package/compiler/semantic-model-types.go +17 -4
  29. package/compiler/semantic-model.go +709 -72
  30. package/compiler/semantic-model_test.go +219 -0
  31. package/compiler/service.go +20 -1
  32. package/compiler/skeleton_test.go +1008 -20
  33. package/compiler/typescript-emitter.go +147 -15
  34. package/dist/gs/builtin/builtin.d.ts +2 -2
  35. package/dist/gs/builtin/builtin.js +20 -0
  36. package/dist/gs/builtin/builtin.js.map +1 -1
  37. package/dist/gs/builtin/slice.d.ts +2 -1
  38. package/dist/gs/builtin/slice.js +34 -4
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.d.ts +14 -6
  41. package/dist/gs/builtin/type.js +224 -64
  42. package/dist/gs/builtin/type.js.map +1 -1
  43. package/dist/gs/builtin/varRef.d.ts +11 -0
  44. package/dist/gs/builtin/varRef.js +57 -2
  45. package/dist/gs/builtin/varRef.js.map +1 -1
  46. package/dist/gs/bytes/buffer.gs.js +1 -1
  47. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  48. package/dist/gs/bytes/reader.gs.js +1 -1
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/compress/zlib/index.d.ts +13 -6
  51. package/dist/gs/compress/zlib/index.js +131 -35
  52. package/dist/gs/compress/zlib/index.js.map +1 -1
  53. package/dist/gs/crypto/sha1/index.js +2 -5
  54. package/dist/gs/crypto/sha1/index.js.map +1 -1
  55. package/dist/gs/crypto/sha256/index.js +2 -5
  56. package/dist/gs/crypto/sha256/index.js.map +1 -1
  57. package/dist/gs/crypto/sha512/index.js +2 -5
  58. package/dist/gs/crypto/sha512/index.js.map +1 -1
  59. package/dist/gs/embed/index.d.ts +6 -0
  60. package/dist/gs/embed/index.js +210 -5
  61. package/dist/gs/embed/index.js.map +1 -1
  62. package/dist/gs/encoding/json/index.d.ts +114 -0
  63. package/dist/gs/encoding/json/index.js +544 -36
  64. package/dist/gs/encoding/json/index.js.map +1 -1
  65. package/dist/gs/fmt/fmt.d.ts +3 -3
  66. package/dist/gs/fmt/fmt.js +29 -16
  67. package/dist/gs/fmt/fmt.js.map +1 -1
  68. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  69. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  70. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  71. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  72. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  73. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  74. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  75. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  76. package/dist/gs/go/scanner/index.d.ts +2 -0
  77. package/dist/gs/go/scanner/index.js +29 -5
  78. package/dist/gs/go/scanner/index.js.map +1 -1
  79. package/dist/gs/go/token/index.js +22 -6
  80. package/dist/gs/go/token/index.js.map +1 -1
  81. package/dist/gs/hash/index.d.ts +6 -0
  82. package/dist/gs/hash/index.js +20 -0
  83. package/dist/gs/hash/index.js.map +1 -1
  84. package/dist/gs/internal/goarch/index.d.ts +43 -3
  85. package/dist/gs/internal/goarch/index.js +42 -10
  86. package/dist/gs/internal/goarch/index.js.map +1 -1
  87. package/dist/gs/io/fs/fs.js +26 -14
  88. package/dist/gs/io/fs/fs.js.map +1 -1
  89. package/dist/gs/io/fs/readdir.js +8 -4
  90. package/dist/gs/io/fs/readdir.js.map +1 -1
  91. package/dist/gs/io/fs/sub.js +8 -1
  92. package/dist/gs/io/fs/sub.js.map +1 -1
  93. package/dist/gs/io/io.d.ts +12 -6
  94. package/dist/gs/io/io.js +87 -42
  95. package/dist/gs/io/io.js.map +1 -1
  96. package/dist/gs/math/bits/index.d.ts +31 -5
  97. package/dist/gs/math/bits/index.js +29 -28
  98. package/dist/gs/math/bits/index.js.map +1 -1
  99. package/dist/gs/mime/index.d.ts +16 -0
  100. package/dist/gs/mime/index.js +315 -6
  101. package/dist/gs/mime/index.js.map +1 -1
  102. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  103. package/dist/gs/net/http/httptest/index.js +85 -6
  104. package/dist/gs/net/http/httptest/index.js.map +1 -1
  105. package/dist/gs/net/http/index.d.ts +303 -6
  106. package/dist/gs/net/http/index.js +1615 -58
  107. package/dist/gs/net/http/index.js.map +1 -1
  108. package/dist/gs/os/dir_unix.gs.js +1 -1
  109. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  110. package/dist/gs/os/error.gs.js +1 -1
  111. package/dist/gs/os/error.gs.js.map +1 -1
  112. package/dist/gs/os/exec.gs.d.ts +1 -0
  113. package/dist/gs/os/exec.gs.js +4 -8
  114. package/dist/gs/os/exec.gs.js.map +1 -1
  115. package/dist/gs/os/exec_posix.gs.js +1 -1
  116. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  117. package/dist/gs/os/index.d.ts +1 -1
  118. package/dist/gs/os/index.js +1 -1
  119. package/dist/gs/os/index.js.map +1 -1
  120. package/dist/gs/os/proc.gs.d.ts +4 -0
  121. package/dist/gs/os/proc.gs.js +12 -6
  122. package/dist/gs/os/proc.gs.js.map +1 -1
  123. package/dist/gs/os/root_js.gs.js +1 -1
  124. package/dist/gs/os/root_js.gs.js.map +1 -1
  125. package/dist/gs/os/types.gs.js +1 -1
  126. package/dist/gs/os/types.gs.js.map +1 -1
  127. package/dist/gs/os/types_js.gs.d.ts +6 -2
  128. package/dist/gs/os/types_js.gs.js +170 -9
  129. package/dist/gs/os/types_js.gs.js.map +1 -1
  130. package/dist/gs/os/types_unix.gs.js +1 -1
  131. package/dist/gs/os/types_unix.gs.js.map +1 -1
  132. package/dist/gs/path/path.js +11 -7
  133. package/dist/gs/path/path.js.map +1 -1
  134. package/dist/gs/reflect/index.d.ts +5 -4
  135. package/dist/gs/reflect/index.js +4 -3
  136. package/dist/gs/reflect/index.js.map +1 -1
  137. package/dist/gs/reflect/map.js +15 -0
  138. package/dist/gs/reflect/map.js.map +1 -1
  139. package/dist/gs/reflect/type.d.ts +26 -6
  140. package/dist/gs/reflect/type.js +1498 -279
  141. package/dist/gs/reflect/type.js.map +1 -1
  142. package/dist/gs/reflect/types.d.ts +14 -6
  143. package/dist/gs/reflect/types.js +35 -1
  144. package/dist/gs/reflect/types.js.map +1 -1
  145. package/dist/gs/reflect/value.d.ts +1 -0
  146. package/dist/gs/reflect/value.js +83 -41
  147. package/dist/gs/reflect/value.js.map +1 -1
  148. package/dist/gs/reflect/visiblefields.js +4 -140
  149. package/dist/gs/reflect/visiblefields.js.map +1 -1
  150. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  151. package/dist/gs/runtime/pprof/index.js +50 -30
  152. package/dist/gs/runtime/pprof/index.js.map +1 -1
  153. package/dist/gs/runtime/runtime.js +5 -4
  154. package/dist/gs/runtime/runtime.js.map +1 -1
  155. package/dist/gs/runtime/trace/index.js +5 -19
  156. package/dist/gs/runtime/trace/index.js.map +1 -1
  157. package/dist/gs/strconv/atoi.gs.js +1 -1
  158. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  159. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  160. package/dist/gs/strconv/complex.gs.js +148 -0
  161. package/dist/gs/strconv/complex.gs.js.map +1 -0
  162. package/dist/gs/strconv/index.d.ts +1 -0
  163. package/dist/gs/strconv/index.js +1 -0
  164. package/dist/gs/strconv/index.js.map +1 -1
  165. package/dist/gs/strings/builder.js +1 -1
  166. package/dist/gs/strings/reader.d.ts +1 -1
  167. package/dist/gs/strings/reader.js +11 -7
  168. package/dist/gs/strings/reader.js.map +1 -1
  169. package/dist/gs/strings/replace.js +15 -7
  170. package/dist/gs/strings/replace.js.map +1 -1
  171. package/dist/gs/strings/strings.d.ts +5 -0
  172. package/dist/gs/strings/strings.js +57 -5
  173. package/dist/gs/strings/strings.js.map +1 -1
  174. package/dist/gs/sync/atomic/type.gs.js +9 -9
  175. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  176. package/dist/gs/sync/atomic/value.gs.js +2 -2
  177. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  178. package/dist/gs/sync/sync.d.ts +2 -1
  179. package/dist/gs/sync/sync.js +37 -16
  180. package/dist/gs/sync/sync.js.map +1 -1
  181. package/dist/gs/syscall/env.js +22 -14
  182. package/dist/gs/syscall/env.js.map +1 -1
  183. package/dist/gs/syscall/js/index.js +9 -0
  184. package/dist/gs/syscall/js/index.js.map +1 -1
  185. package/dist/gs/testing/testing.js +59 -15
  186. package/dist/gs/testing/testing.js.map +1 -1
  187. package/dist/gs/time/time.d.ts +24 -1
  188. package/dist/gs/time/time.js +43 -3
  189. package/dist/gs/time/time.js.map +1 -1
  190. package/dist/gs/unique/index.js +7 -1
  191. package/dist/gs/unique/index.js.map +1 -1
  192. package/go.mod +3 -3
  193. package/go.sum +16 -0
  194. package/gs/builtin/builtin.ts +25 -2
  195. package/gs/builtin/runtime-contract.test.ts +260 -18
  196. package/gs/builtin/slice.ts +51 -4
  197. package/gs/builtin/type.ts +310 -63
  198. package/gs/builtin/varRef.ts +85 -2
  199. package/gs/bytes/buffer.gs.ts +1 -1
  200. package/gs/bytes/reader.gs.ts +1 -1
  201. package/gs/compress/zlib/index.test.ts +159 -1
  202. package/gs/compress/zlib/index.ts +164 -37
  203. package/gs/compress/zlib/meta.json +4 -1
  204. package/gs/compress/zlib/parity.json +51 -0
  205. package/gs/crypto/sha1/index.test.ts +19 -2
  206. package/gs/crypto/sha1/index.ts +3 -6
  207. package/gs/crypto/sha256/index.test.ts +14 -2
  208. package/gs/crypto/sha256/index.ts +3 -6
  209. package/gs/crypto/sha512/index.test.ts +17 -2
  210. package/gs/crypto/sha512/index.ts +3 -6
  211. package/gs/embed/index.test.ts +87 -0
  212. package/gs/embed/index.ts +229 -5
  213. package/gs/encoding/json/index.test.ts +360 -6
  214. package/gs/encoding/json/index.ts +679 -38
  215. package/gs/encoding/json/parity.json +81 -0
  216. package/gs/fmt/fmt.test.ts +41 -3
  217. package/gs/fmt/fmt.ts +40 -17
  218. package/gs/fmt/meta.json +6 -1
  219. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  220. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  221. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  222. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  223. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  224. package/gs/github.com/pkg/errors/errors.ts +54 -30
  225. package/gs/go/scanner/index.test.ts +39 -56
  226. package/gs/go/scanner/index.ts +33 -5
  227. package/gs/go/scanner/parity.json +27 -0
  228. package/gs/go/token/index.ts +22 -6
  229. package/gs/hash/index.test.ts +20 -33
  230. package/gs/hash/index.ts +28 -0
  231. package/gs/hash/parity.json +21 -0
  232. package/gs/internal/goarch/index.test.ts +32 -0
  233. package/gs/internal/goarch/index.ts +45 -13
  234. package/gs/internal/goarch/parity.json +144 -0
  235. package/gs/io/fs/fs.ts +26 -14
  236. package/gs/io/fs/readdir.test.ts +38 -0
  237. package/gs/io/fs/readdir.ts +8 -4
  238. package/gs/io/fs/sub.ts +8 -1
  239. package/gs/io/io.test.ts +77 -6
  240. package/gs/io/io.ts +115 -52
  241. package/gs/io/meta.json +7 -1
  242. package/gs/io/parity.json +162 -0
  243. package/gs/math/bits/index.test.ts +14 -1
  244. package/gs/math/bits/index.ts +75 -32
  245. package/gs/math/bits/parity.json +156 -0
  246. package/gs/mime/index.test.ts +90 -0
  247. package/gs/mime/index.ts +369 -6
  248. package/gs/mime/parity.json +36 -0
  249. package/gs/net/http/httptest/index.test.ts +98 -2
  250. package/gs/net/http/httptest/index.ts +101 -6
  251. package/gs/net/http/httptest/parity.json +15 -0
  252. package/gs/net/http/index.test.ts +797 -12
  253. package/gs/net/http/index.ts +1874 -136
  254. package/gs/net/http/meta.json +16 -1
  255. package/gs/net/http/parity.json +193 -0
  256. package/gs/os/dir_unix.gs.ts +1 -1
  257. package/gs/os/error.gs.ts +1 -1
  258. package/gs/os/exec.gs.ts +4 -8
  259. package/gs/os/exec_posix.gs.ts +1 -1
  260. package/gs/os/file_unix_js.test.ts +52 -0
  261. package/gs/os/index.test.ts +9 -0
  262. package/gs/os/index.ts +1 -0
  263. package/gs/os/meta.json +4 -0
  264. package/gs/os/parity.json +9 -0
  265. package/gs/os/proc.gs.ts +18 -5
  266. package/gs/os/proc.test.ts +26 -0
  267. package/gs/os/readdir.test.ts +56 -0
  268. package/gs/os/root_js.gs.ts +1 -1
  269. package/gs/os/types.gs.ts +1 -1
  270. package/gs/os/types_js.gs.ts +170 -9
  271. package/gs/os/types_unix.gs.ts +1 -1
  272. package/gs/path/path.ts +11 -7
  273. package/gs/reflect/deepequal.test.ts +10 -1
  274. package/gs/reflect/field.test.ts +37 -15
  275. package/gs/reflect/function-types.test.ts +518 -22
  276. package/gs/reflect/index.ts +8 -6
  277. package/gs/reflect/map.ts +20 -0
  278. package/gs/reflect/meta.json +6 -4
  279. package/gs/reflect/parity.json +234 -0
  280. package/gs/reflect/sliceat.test.ts +156 -0
  281. package/gs/reflect/structof.test.ts +401 -0
  282. package/gs/reflect/type.ts +1980 -365
  283. package/gs/reflect/typefor.test.ts +540 -10
  284. package/gs/reflect/types.ts +43 -18
  285. package/gs/reflect/value.ts +105 -45
  286. package/gs/reflect/visiblefields.ts +5 -168
  287. package/gs/runtime/parity.json +24 -0
  288. package/gs/runtime/pprof/index.test.ts +29 -7
  289. package/gs/runtime/pprof/index.ts +56 -30
  290. package/gs/runtime/pprof/parity.json +27 -0
  291. package/gs/runtime/runtime.test.ts +3 -1
  292. package/gs/runtime/runtime.ts +4 -3
  293. package/gs/runtime/trace/index.test.ts +5 -3
  294. package/gs/runtime/trace/index.ts +8 -20
  295. package/gs/runtime/trace/parity.json +36 -0
  296. package/gs/strconv/atoi.gs.ts +1 -1
  297. package/gs/strconv/complex.gs.ts +174 -0
  298. package/gs/strconv/complex.test.ts +65 -0
  299. package/gs/strconv/index.ts +1 -0
  300. package/gs/strconv/parity.json +120 -0
  301. package/gs/strings/builder.ts +1 -1
  302. package/gs/strings/meta.json +5 -2
  303. package/gs/strings/parity.json +186 -0
  304. package/gs/strings/reader.test.ts +2 -2
  305. package/gs/strings/reader.ts +11 -7
  306. package/gs/strings/replace.ts +15 -7
  307. package/gs/strings/strings.test.ts +22 -2
  308. package/gs/strings/strings.ts +64 -6
  309. package/gs/sync/atomic/type.gs.ts +9 -9
  310. package/gs/sync/atomic/value.gs.ts +2 -2
  311. package/gs/sync/meta.json +1 -0
  312. package/gs/sync/sync.test.ts +41 -1
  313. package/gs/sync/sync.ts +41 -16
  314. package/gs/syscall/env.ts +29 -14
  315. package/gs/syscall/js/index.test.ts +18 -0
  316. package/gs/syscall/js/index.ts +12 -0
  317. package/gs/testing/testing.test.ts +99 -3
  318. package/gs/testing/testing.ts +95 -24
  319. package/gs/time/parity.json +225 -0
  320. package/gs/time/time.test.ts +20 -2
  321. package/gs/time/time.ts +49 -7
  322. package/gs/unique/index.ts +7 -1
  323. package/package.json +4 -2
  324. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  325. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
  326. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  327. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
  328. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
  329. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  330. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -27,7 +27,7 @@ describe('runtime/trace override', () => {
27
27
  expect(called.value).toBe(true)
28
28
  })
29
29
 
30
- it('writes deterministic trace bytes', () => {
30
+ it('reports execution tracing as unsupported', () => {
31
31
  const chunks: Uint8Array[] = []
32
32
  const writer = {
33
33
  Write(p: Uint8Array): [number, null] {
@@ -36,10 +36,12 @@ describe('runtime/trace override', () => {
36
36
  },
37
37
  }
38
38
 
39
- expect(Start(writer)).toBeNull()
39
+ expect(Start(writer)?.Error()).toBe(
40
+ 'runtime/trace: execution tracing is unsupported in GoScript',
41
+ )
40
42
  Log(context.Background(), 'category', 'message')
41
43
  Stop()
42
44
 
43
- expect(chunks.reduce((total, chunk) => total + chunk.length, 0)).toBeGreaterThan(0)
45
+ expect(chunks).toHaveLength(0)
44
46
  })
45
47
  })
@@ -6,10 +6,13 @@ import * as io from '@goscript/io/index.js'
6
6
  class traceContextKey {}
7
7
 
8
8
  const traceState = {
9
- activeWriter: null as io.Writer | null,
10
9
  nextTaskID: 0,
11
10
  }
12
11
 
12
+ const unsupportedTraceError = errors.New(
13
+ 'runtime/trace: execution tracing is unsupported in GoScript',
14
+ )
15
+
13
16
  export class Task {
14
17
  public id: number
15
18
 
@@ -41,7 +44,8 @@ export function NewTask(
41
44
  }
42
45
 
43
46
  export function Log(_ctx: context.Context | null, category: string, message: string): void {
44
- writeTrace(`log ${category} ${message}\n`)
47
+ void category
48
+ void message
45
49
  }
46
50
 
47
51
  export function Logf(
@@ -75,23 +79,7 @@ export function Start(w: io.Writer | $.VarRef<io.Writer> | null): $.GoError {
75
79
  if (writer == null) {
76
80
  return errors.New('runtime/trace: nil trace writer')
77
81
  }
78
- if (traceState.activeWriter != null) {
79
- return errors.New('runtime/trace: trace already active')
80
- }
81
- traceState.activeWriter = writer
82
- return writeTrace('goscript trace start\n')
83
- }
84
-
85
- export function Stop(): void {
86
- writeTrace('goscript trace stop\n')
87
- traceState.activeWriter = null
82
+ return unsupportedTraceError
88
83
  }
89
84
 
90
- function writeTrace(text: string): $.GoError {
91
- const writer = traceState.activeWriter
92
- if (writer == null) {
93
- return null
94
- }
95
- const [, err] = writer.Write($.stringToBytes(text))
96
- return err
97
- }
85
+ export function Stop(): void {}
@@ -0,0 +1,36 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "strict": false,
4
+ "symbols": {
5
+ "IsEnabled": {
6
+ "status": "real"
7
+ },
8
+ "Log": {
9
+ "status": "real"
10
+ },
11
+ "Logf": {
12
+ "status": "real"
13
+ },
14
+ "NewTask": {
15
+ "status": "real"
16
+ },
17
+ "Region": {
18
+ "status": "real"
19
+ },
20
+ "Start": {
21
+ "status": "real"
22
+ },
23
+ "StartRegion": {
24
+ "status": "real"
25
+ },
26
+ "Stop": {
27
+ "status": "real"
28
+ },
29
+ "Task": {
30
+ "status": "real"
31
+ },
32
+ "WithRegion": {
33
+ "status": "real"
34
+ }
35
+ }
36
+ }
@@ -68,7 +68,7 @@ export class NumError {
68
68
  new NumError(),
69
69
  [{ name: "Error", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }] }, { name: "Unwrap", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }],
70
70
  NumError,
71
- {"Func": { kind: $.TypeKind.Basic, name: "string" }, "Num": { kind: $.TypeKind.Basic, name: "string" }, "Err": { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] }}
71
+ [{ name: "Func", key: "Func", type: { kind: $.TypeKind.Basic, name: "string" } }, { name: "Num", key: "Num", type: { kind: $.TypeKind.Basic, name: "string" } }, { name: "Err", key: "Err", type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }]
72
72
  );
73
73
  }
74
74
 
@@ -0,0 +1,174 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import { FormatFloat } from './ftoa.gs.js'
3
+ import { ParseFloat } from './atof.gs.js'
4
+ import { ErrRange, ErrSyntax, NumError } from './atoi.gs.js'
5
+
6
+ export function FormatComplex(
7
+ c: $.Complex,
8
+ fmt: number,
9
+ prec: number,
10
+ bitSize: number,
11
+ ): string {
12
+ const real = FormatFloat($.real(c), fmt, prec, bitSize / 2)
13
+ const imag = $.imag(c)
14
+ const imagText = FormatFloat(Math.abs(imag), fmt, prec, bitSize / 2)
15
+ const sign = imag < 0 || Object.is(imag, -0) ? '-' : '+'
16
+ return `(${real}${sign}${imagText}i)`
17
+ }
18
+
19
+ export function ParseComplex(
20
+ s: string,
21
+ bitSize: number,
22
+ ): [$.Complex, $.GoError] {
23
+ if (/\s/.test(s)) {
24
+ return [$.complex(0, 0), complexSyntaxError(s)]
25
+ }
26
+ const text = s
27
+ if (text.startsWith('(') !== text.endsWith(')')) {
28
+ return [$.complex(0, 0), complexSyntaxError(s)]
29
+ }
30
+ const inner =
31
+ text.startsWith('(') && text.endsWith(')') ? text.slice(1, -1) : text
32
+ if (inner === '') {
33
+ return [$.complex(0, 0), complexSyntaxError(s)]
34
+ }
35
+ if (!inner.endsWith('i')) {
36
+ const [real, err] = parseComplexFloat(inner, bitSize)
37
+ if (err !== null) {
38
+ return [$.complex(isRangeError(err) ? real : 0, 0), complexError(s, err)]
39
+ }
40
+ return [$.complex(real, 0), null]
41
+ }
42
+
43
+ const body = inner.slice(0, -1)
44
+ if (body === '' || body === '+' || body === '-') {
45
+ return [$.complex(0, 0), complexSyntaxError(s)]
46
+ }
47
+ const [pureImag, pureImagErr] = parseComplexFloat(body, bitSize)
48
+ if (pureImagErr === null) {
49
+ return [$.complex(0, pureImag), null]
50
+ }
51
+ if (isRangeError(pureImagErr)) {
52
+ return [$.complex(0, pureImag), complexRangeError(s)]
53
+ }
54
+
55
+ const split = splitComplexParts(body, bitSize)
56
+ if (split === null) {
57
+ return [$.complex(0, 0), complexSyntaxError(s)]
58
+ }
59
+ const [realText, imagText] = split
60
+ const [real, realErr] = parseComplexFloat(realText, bitSize)
61
+ if (realErr !== null) {
62
+ return [$.complex(isRangeError(realErr) ? real : 0, 0), complexError(s, realErr)]
63
+ }
64
+ const [imag, imagErr] = parseComplexFloat(imagText, bitSize)
65
+ if (imagErr !== null) {
66
+ return [$.complex(real, isRangeError(imagErr) ? imag : 0), complexError(s, imagErr)]
67
+ }
68
+ return [$.complex(real, imag), null]
69
+ }
70
+
71
+ function splitComplexParts(body: string, bitSize: number): [string, string] | null {
72
+ for (let i = body.length - 1; i > 0; i--) {
73
+ const char = body[i]
74
+ if (
75
+ (char === '+' || char === '-') &&
76
+ body[i - 1] !== 'e' &&
77
+ body[i - 1] !== 'E' &&
78
+ body[i - 1] !== 'p' &&
79
+ body[i - 1] !== 'P'
80
+ ) {
81
+ const realText = body.slice(0, i)
82
+ const imagText = body.slice(i)
83
+ if (complexPartsParse(realText, imagText, bitSize)) {
84
+ return [realText, imagText]
85
+ }
86
+ if (char === '+' && body[i + 1] === '-' && complexPartsParse(realText, body.slice(i + 1), bitSize)) {
87
+ return [realText, body.slice(i + 1)]
88
+ }
89
+ }
90
+ }
91
+ return null
92
+ }
93
+
94
+ function complexPartsParse(realText: string, imagText: string, bitSize: number): boolean {
95
+ const [, realErr] = parseComplexFloat(realText, bitSize)
96
+ if (realErr !== null) {
97
+ return false
98
+ }
99
+ const [, imagErr] = parseComplexFloat(imagText, bitSize)
100
+ return imagErr === null
101
+ }
102
+
103
+ function parseComplexFloat(s: string, bitSize: number): [number, $.GoError] {
104
+ if (!isComplexFloatLiteral(s)) {
105
+ return [0, complexSyntaxError(s)]
106
+ }
107
+ if (isHexFloatLiteral(s)) {
108
+ return parseHexFloat(s, bitSize / 2)
109
+ }
110
+ const [value, err] = ParseFloat(s, bitSize / 2)
111
+ if (err !== null) {
112
+ return [value, err]
113
+ }
114
+ if (!Number.isFinite(value) && !/^[+-]?(?:inf(?:inity)?|nan)$/i.test(s)) {
115
+ return [value, new NumError({ Func: 'ParseFloat', Num: s, Err: ErrRange })]
116
+ }
117
+ return [value, null]
118
+ }
119
+
120
+ function isComplexFloatLiteral(s: string): boolean {
121
+ return (
122
+ /^[+-]?(?:(?:inf(?:inity)?)|nan|(?:(?:(?:\d(?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?)|(?:\.(?:\d(?:_?\d)*)))(?:[eE][+-]?\d(?:_?\d)*)?)$/i.test(s) ||
123
+ isHexFloatLiteral(s)
124
+ )
125
+ }
126
+
127
+ function isHexFloatLiteral(s: string): boolean {
128
+ if (!/^[+-]?0[xX]_?(?:(?:[0-9A-Fa-f](?:_?[0-9A-Fa-f])*(?:\.(?:[0-9A-Fa-f](?:_?[0-9A-Fa-f])*)?)?)|(?:\.(?:[0-9A-Fa-f](?:_?[0-9A-Fa-f])*)))[pP][+-]?\d(?:_?\d)*$/.test(s)) {
129
+ return false
130
+ }
131
+ const unsigned = s[0] === '+' || s[0] === '-' ? s.slice(1) : s
132
+ const marker = unsigned.toLowerCase().indexOf('p')
133
+ const digits = unsigned.slice(2, marker).replace('.', '').replace(/_/g, '')
134
+ return /^[0-9A-Fa-f]+$/.test(digits)
135
+ }
136
+
137
+ function parseHexFloat(s: string, bitSize: number): [number, $.GoError] {
138
+ const sign = s.startsWith('-') ? -1 : 1
139
+ const unsigned = s[0] === '+' || s[0] === '-' ? s.slice(1) : s
140
+ const clean = unsigned.replace(/_/g, '').toLowerCase()
141
+ const marker = clean.indexOf('p')
142
+ const mantissa = clean.slice(2, marker)
143
+ const exponent = Number.parseInt(clean.slice(marker + 1), 10)
144
+ const [whole, frac = ''] = mantissa.split('.')
145
+ let value = whole === '' ? 0 : Number.parseInt(whole, 16)
146
+ for (let i = 0; i < frac.length; i++) {
147
+ value += Number.parseInt(frac[i], 16) / 16 ** (i + 1)
148
+ }
149
+ const parsed = sign * value * 2 ** exponent
150
+ if (!Number.isFinite(parsed)) {
151
+ return [parsed, new NumError({ Func: 'ParseFloat', Num: s, Err: ErrRange })]
152
+ }
153
+ const maxFloat32 = 3.4028234663852886e38
154
+ if (bitSize === 32 && Math.abs(parsed) > maxFloat32) {
155
+ return [parsed > 0 ? Infinity : -Infinity, new NumError({ Func: 'ParseFloat', Num: s, Err: ErrRange })]
156
+ }
157
+ return [parsed, null]
158
+ }
159
+
160
+ function complexSyntaxError(s: string): $.GoError {
161
+ return new NumError({ Func: 'ParseComplex', Num: s, Err: ErrSyntax })
162
+ }
163
+
164
+ function complexRangeError(s: string): $.GoError {
165
+ return new NumError({ Func: 'ParseComplex', Num: s, Err: ErrRange })
166
+ }
167
+
168
+ function complexError(s: string, err: $.GoError): $.GoError {
169
+ return isRangeError(err) ? complexRangeError(s) : complexSyntaxError(s)
170
+ }
171
+
172
+ function isRangeError(err: $.GoError): boolean {
173
+ return err !== null && err.Error().includes('value out of range')
174
+ }
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { FormatComplex, ParseComplex } from './complex.gs.js'
6
+
7
+ describe('strconv complex helpers', () => {
8
+ it('formats complex values with Go-style parentheses', () => {
9
+ expect(FormatComplex($.complex(1.5, -2), 'f'.charCodeAt(0), -1, 128)).toBe(
10
+ '(1.5-2i)',
11
+ )
12
+ })
13
+
14
+ it('parses signed complex values', () => {
15
+ const [value, err] = ParseComplex('(1.5-2i)', 128)
16
+
17
+ expect(err).toBeNull()
18
+ expect($.real(value)).toBe(1.5)
19
+ expect($.imag(value)).toBe(-2)
20
+ })
21
+
22
+ it('parses real, imaginary, parenthesized, and signed imaginary forms', () => {
23
+ const cases = [
24
+ ['1', 1, 0],
25
+ ['(1)', 1, 0],
26
+ ['1i', 0, 1],
27
+ ['+1i', 0, 1],
28
+ ['-1i', 0, -1],
29
+ ['(1i)', 0, 1],
30
+ ['1+2i', 1, 2],
31
+ ['1+-2i', 1, -2],
32
+ ['1e+2-3i', 100, -3],
33
+ ['1e-2+3i', 0.01, 3],
34
+ ['0x1p+2+0x1.8p+1i', 4, 3],
35
+ ['0x1p-1-0x1p+1i', 0.5, -2],
36
+ ['0x1.8p+2i', 0, 6],
37
+ ['0x_3p3i', 0, 24],
38
+ ['0x_10.3p-8+0x3p3i', 16.1875 / 256, 24],
39
+ ] as const
40
+
41
+ for (const [input, real, imag] of cases) {
42
+ const [value, err] = ParseComplex(input, 128)
43
+
44
+ expect(err, input).toBeNull()
45
+ expect($.real(value)).toBe(real)
46
+ expect($.imag(value)).toBe(imag)
47
+ }
48
+ })
49
+
50
+ it('rejects whitespace and malformed imaginary forms', () => {
51
+ for (const input of [' 1+2i', '1+2i ', '1 +2i', 'i', '+i', '-i', '1++2i', '1-+2i', '0xp1']) {
52
+ const [, err] = ParseComplex(input, 128)
53
+
54
+ expect(err?.Error(), input).toBe(`strconv.ParseComplex: parsing "${input}": invalid syntax`)
55
+ }
56
+ })
57
+
58
+ it('reports hexadecimal range errors', () => {
59
+ const [value, err] = ParseComplex('0x1p1025', 128)
60
+
61
+ expect($.real(value)).toBe(Infinity)
62
+ expect($.imag(value)).toBe(0)
63
+ expect(err?.Error()).toBe('strconv.ParseComplex: parsing "0x1p1025": value out of range')
64
+ })
65
+ })
@@ -10,6 +10,7 @@ export {
10
10
  ParseUint,
11
11
  } from './atoi.gs.js'
12
12
  export { AppendFloat, FormatFloat } from './ftoa.gs.js'
13
+ export { FormatComplex, ParseComplex } from './complex.gs.js'
13
14
  export {
14
15
  AppendInt,
15
16
  AppendUint,
@@ -0,0 +1,120 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "strict": true,
4
+ "symbols": {
5
+ "AppendBool": {
6
+ "status": "real"
7
+ },
8
+ "AppendFloat": {
9
+ "status": "real"
10
+ },
11
+ "AppendInt": {
12
+ "status": "real"
13
+ },
14
+ "AppendQuote": {
15
+ "status": "real"
16
+ },
17
+ "AppendQuoteRune": {
18
+ "status": "real"
19
+ },
20
+ "AppendQuoteRuneToASCII": {
21
+ "status": "real"
22
+ },
23
+ "AppendQuoteRuneToGraphic": {
24
+ "status": "real"
25
+ },
26
+ "AppendQuoteToASCII": {
27
+ "status": "real"
28
+ },
29
+ "AppendQuoteToGraphic": {
30
+ "status": "real"
31
+ },
32
+ "AppendUint": {
33
+ "status": "real"
34
+ },
35
+ "Atoi": {
36
+ "status": "real"
37
+ },
38
+ "CanBackquote": {
39
+ "status": "real"
40
+ },
41
+ "ErrRange": {
42
+ "status": "real"
43
+ },
44
+ "ErrSyntax": {
45
+ "status": "real"
46
+ },
47
+ "FormatBool": {
48
+ "status": "real"
49
+ },
50
+ "FormatComplex": {
51
+ "status": "real"
52
+ },
53
+ "FormatFloat": {
54
+ "status": "real"
55
+ },
56
+ "FormatInt": {
57
+ "status": "real"
58
+ },
59
+ "FormatUint": {
60
+ "status": "real"
61
+ },
62
+ "IntSize": {
63
+ "status": "real"
64
+ },
65
+ "IsGraphic": {
66
+ "status": "real"
67
+ },
68
+ "IsPrint": {
69
+ "status": "real"
70
+ },
71
+ "Itoa": {
72
+ "status": "real"
73
+ },
74
+ "NumError": {
75
+ "status": "real"
76
+ },
77
+ "ParseBool": {
78
+ "status": "real"
79
+ },
80
+ "ParseComplex": {
81
+ "status": "real"
82
+ },
83
+ "ParseFloat": {
84
+ "status": "real"
85
+ },
86
+ "ParseInt": {
87
+ "status": "real"
88
+ },
89
+ "ParseUint": {
90
+ "status": "real"
91
+ },
92
+ "Quote": {
93
+ "status": "real"
94
+ },
95
+ "QuotedPrefix": {
96
+ "status": "real"
97
+ },
98
+ "QuoteRune": {
99
+ "status": "real"
100
+ },
101
+ "QuoteRuneToASCII": {
102
+ "status": "real"
103
+ },
104
+ "QuoteRuneToGraphic": {
105
+ "status": "real"
106
+ },
107
+ "QuoteToASCII": {
108
+ "status": "real"
109
+ },
110
+ "QuoteToGraphic": {
111
+ "status": "real"
112
+ },
113
+ "Unquote": {
114
+ "status": "real"
115
+ },
116
+ "UnquoteChar": {
117
+ "status": "real"
118
+ }
119
+ }
120
+ }
@@ -231,6 +231,6 @@ export class Builder {
231
231
  },
232
232
  ],
233
233
  Builder,
234
- {},
234
+ [],
235
235
  )
236
236
  }
@@ -5,5 +5,8 @@
5
5
  "iter",
6
6
  "unicode",
7
7
  "unicode/utf8"
8
- ]
9
- }
8
+ ],
9
+ "asyncMethods": {
10
+ "Reader.WriteTo": true
11
+ }
12
+ }
@@ -0,0 +1,186 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "strict": true,
4
+ "symbols": {
5
+ "Builder": {
6
+ "status": "real"
7
+ },
8
+ "Clone": {
9
+ "status": "real"
10
+ },
11
+ "Compare": {
12
+ "status": "real"
13
+ },
14
+ "Contains": {
15
+ "status": "real"
16
+ },
17
+ "ContainsAny": {
18
+ "status": "real"
19
+ },
20
+ "ContainsFunc": {
21
+ "status": "real"
22
+ },
23
+ "ContainsRune": {
24
+ "status": "real"
25
+ },
26
+ "Count": {
27
+ "status": "real"
28
+ },
29
+ "Cut": {
30
+ "status": "real"
31
+ },
32
+ "CutPrefix": {
33
+ "status": "real"
34
+ },
35
+ "CutSuffix": {
36
+ "status": "real"
37
+ },
38
+ "EqualFold": {
39
+ "status": "real"
40
+ },
41
+ "Fields": {
42
+ "status": "real"
43
+ },
44
+ "FieldsFunc": {
45
+ "status": "real"
46
+ },
47
+ "FieldsFuncSeq": {
48
+ "status": "real"
49
+ },
50
+ "FieldsSeq": {
51
+ "status": "real"
52
+ },
53
+ "HasPrefix": {
54
+ "status": "real"
55
+ },
56
+ "HasSuffix": {
57
+ "status": "real"
58
+ },
59
+ "Index": {
60
+ "status": "real"
61
+ },
62
+ "IndexAny": {
63
+ "status": "real"
64
+ },
65
+ "IndexByte": {
66
+ "status": "real"
67
+ },
68
+ "IndexFunc": {
69
+ "status": "real"
70
+ },
71
+ "IndexRune": {
72
+ "status": "real"
73
+ },
74
+ "Join": {
75
+ "status": "real"
76
+ },
77
+ "LastIndex": {
78
+ "status": "real"
79
+ },
80
+ "LastIndexAny": {
81
+ "status": "real"
82
+ },
83
+ "LastIndexByte": {
84
+ "status": "real"
85
+ },
86
+ "LastIndexFunc": {
87
+ "status": "real"
88
+ },
89
+ "Lines": {
90
+ "status": "real"
91
+ },
92
+ "Map": {
93
+ "status": "real"
94
+ },
95
+ "NewReader": {
96
+ "status": "real"
97
+ },
98
+ "NewReplacer": {
99
+ "status": "real"
100
+ },
101
+ "Reader": {
102
+ "status": "real"
103
+ },
104
+ "Repeat": {
105
+ "status": "real"
106
+ },
107
+ "Replace": {
108
+ "status": "real"
109
+ },
110
+ "ReplaceAll": {
111
+ "status": "real"
112
+ },
113
+ "Replacer": {
114
+ "status": "real"
115
+ },
116
+ "Split": {
117
+ "status": "real"
118
+ },
119
+ "SplitAfter": {
120
+ "status": "real"
121
+ },
122
+ "SplitAfterN": {
123
+ "status": "real"
124
+ },
125
+ "SplitAfterSeq": {
126
+ "status": "real"
127
+ },
128
+ "SplitN": {
129
+ "status": "real"
130
+ },
131
+ "SplitSeq": {
132
+ "status": "real"
133
+ },
134
+ "Title": {
135
+ "status": "real"
136
+ },
137
+ "ToLower": {
138
+ "status": "real"
139
+ },
140
+ "ToLowerSpecial": {
141
+ "status": "real"
142
+ },
143
+ "ToTitle": {
144
+ "status": "real"
145
+ },
146
+ "ToTitleSpecial": {
147
+ "status": "real"
148
+ },
149
+ "ToUpper": {
150
+ "status": "real"
151
+ },
152
+ "ToUpperSpecial": {
153
+ "status": "real"
154
+ },
155
+ "ToValidUTF8": {
156
+ "status": "real"
157
+ },
158
+ "Trim": {
159
+ "status": "real"
160
+ },
161
+ "TrimFunc": {
162
+ "status": "real"
163
+ },
164
+ "TrimLeft": {
165
+ "status": "real"
166
+ },
167
+ "TrimLeftFunc": {
168
+ "status": "real"
169
+ },
170
+ "TrimPrefix": {
171
+ "status": "real"
172
+ },
173
+ "TrimRight": {
174
+ "status": "real"
175
+ },
176
+ "TrimRightFunc": {
177
+ "status": "real"
178
+ },
179
+ "TrimSpace": {
180
+ "status": "real"
181
+ },
182
+ "TrimSuffix": {
183
+ "status": "real"
184
+ }
185
+ }
186
+ }