goscript 0.0.26 → 0.0.29

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 (228) hide show
  1. package/README.md +4 -4
  2. package/cmd/goscript/cmd_compile.go +0 -3
  3. package/cmd/goscript/deps.go +11 -0
  4. package/compiler/analysis.go +298 -55
  5. package/compiler/assignment.go +2 -2
  6. package/compiler/builtin_test.go +1 -1
  7. package/compiler/compiler.go +200 -68
  8. package/compiler/compiler_test.go +17 -24
  9. package/compiler/composite-lit.go +32 -8
  10. package/compiler/decl.go +6 -6
  11. package/compiler/expr-call.go +170 -15
  12. package/compiler/expr-selector.go +100 -0
  13. package/compiler/expr.go +1 -1
  14. package/compiler/protobuf.go +557 -0
  15. package/compiler/spec-struct.go +4 -0
  16. package/compiler/spec-value.go +89 -10
  17. package/compiler/spec.go +254 -1
  18. package/compiler/stmt-assign.go +35 -0
  19. package/compiler/type-assert.go +87 -0
  20. package/compiler/type.go +4 -1
  21. package/dist/gs/builtin/builtin.d.ts +20 -1
  22. package/dist/gs/builtin/builtin.js +95 -4
  23. package/dist/gs/builtin/builtin.js.map +1 -1
  24. package/dist/gs/builtin/slice.d.ts +1 -1
  25. package/dist/gs/builtin/slice.js +21 -2
  26. package/dist/gs/builtin/slice.js.map +1 -1
  27. package/dist/gs/errors/errors.d.ts +5 -6
  28. package/dist/gs/errors/errors.js.map +1 -1
  29. package/dist/gs/internal/oserror/errors.d.ts +6 -0
  30. package/dist/gs/internal/oserror/errors.js +7 -0
  31. package/dist/gs/internal/oserror/errors.js.map +1 -0
  32. package/dist/gs/internal/oserror/index.d.ts +1 -0
  33. package/dist/gs/internal/oserror/index.js +2 -0
  34. package/dist/gs/internal/oserror/index.js.map +1 -0
  35. package/dist/gs/io/fs/format.d.ts +3 -0
  36. package/dist/gs/io/fs/format.js +56 -0
  37. package/dist/gs/io/fs/format.js.map +1 -0
  38. package/dist/gs/io/fs/fs.d.ts +79 -0
  39. package/dist/gs/io/fs/fs.js +200 -0
  40. package/dist/gs/io/fs/fs.js.map +1 -0
  41. package/dist/gs/io/fs/glob.d.ts +10 -0
  42. package/dist/gs/io/fs/glob.js +141 -0
  43. package/dist/gs/io/fs/glob.js.map +1 -0
  44. package/dist/gs/io/fs/index.d.ts +8 -0
  45. package/dist/gs/io/fs/index.js +9 -0
  46. package/dist/gs/io/fs/index.js.map +1 -0
  47. package/dist/gs/io/fs/readdir.d.ts +7 -0
  48. package/dist/gs/io/fs/readdir.js +152 -0
  49. package/dist/gs/io/fs/readdir.js.map +1 -0
  50. package/dist/gs/io/fs/readfile.d.ts +6 -0
  51. package/dist/gs/io/fs/readfile.js +118 -0
  52. package/dist/gs/io/fs/readfile.js.map +1 -0
  53. package/dist/gs/io/fs/stat.d.ts +6 -0
  54. package/dist/gs/io/fs/stat.js +87 -0
  55. package/dist/gs/io/fs/stat.js.map +1 -0
  56. package/dist/gs/io/fs/sub.d.ts +6 -0
  57. package/dist/gs/io/fs/sub.js +172 -0
  58. package/dist/gs/io/fs/sub.js.map +1 -0
  59. package/dist/gs/io/fs/walk.d.ts +7 -0
  60. package/dist/gs/io/fs/walk.js +76 -0
  61. package/dist/gs/io/fs/walk.js.map +1 -0
  62. package/dist/gs/io/index.d.ts +1 -0
  63. package/dist/gs/io/index.js +2 -0
  64. package/dist/gs/io/index.js.map +1 -0
  65. package/dist/gs/io/io.d.ts +107 -0
  66. package/dist/gs/io/io.js +385 -0
  67. package/dist/gs/io/io.js.map +1 -0
  68. package/dist/gs/path/index.d.ts +2 -0
  69. package/dist/gs/path/index.js +3 -0
  70. package/dist/gs/path/index.js.map +1 -0
  71. package/dist/gs/path/match.d.ts +6 -0
  72. package/dist/gs/path/match.js +281 -0
  73. package/dist/gs/path/match.js.map +1 -0
  74. package/dist/gs/path/path.d.ts +7 -0
  75. package/dist/gs/path/path.js +256 -0
  76. package/dist/gs/path/path.js.map +1 -0
  77. package/dist/gs/strings/builder.d.ts +18 -0
  78. package/dist/gs/strings/builder.js +205 -0
  79. package/dist/gs/strings/builder.js.map +1 -0
  80. package/dist/gs/strings/clone.d.ts +1 -0
  81. package/dist/gs/strings/clone.js +16 -0
  82. package/dist/gs/strings/clone.js.map +1 -0
  83. package/dist/gs/strings/compare.d.ts +1 -0
  84. package/dist/gs/strings/compare.js +14 -0
  85. package/dist/gs/strings/compare.js.map +1 -0
  86. package/dist/gs/strings/index.d.ts +2 -0
  87. package/dist/gs/strings/index.js +3 -0
  88. package/dist/gs/strings/index.js.map +1 -0
  89. package/dist/gs/strings/iter.d.ts +8 -0
  90. package/dist/gs/strings/iter.js +160 -0
  91. package/dist/gs/strings/iter.js.map +1 -0
  92. package/dist/gs/strings/reader.d.ts +34 -0
  93. package/dist/gs/strings/reader.js +418 -0
  94. package/dist/gs/strings/reader.js.map +1 -0
  95. package/dist/gs/strings/replace.d.ts +106 -0
  96. package/dist/gs/strings/replace.js +1136 -0
  97. package/dist/gs/strings/replace.js.map +1 -0
  98. package/dist/gs/strings/search.d.ts +24 -0
  99. package/dist/gs/strings/search.js +169 -0
  100. package/dist/gs/strings/search.js.map +1 -0
  101. package/dist/gs/strings/strings.d.ts +47 -0
  102. package/dist/gs/strings/strings.js +418 -0
  103. package/dist/gs/strings/strings.js.map +1 -0
  104. package/dist/gs/stringslite/index.d.ts +1 -0
  105. package/dist/gs/stringslite/index.js +2 -0
  106. package/dist/gs/stringslite/index.js.map +1 -0
  107. package/dist/gs/stringslite/strings.d.ts +11 -0
  108. package/dist/gs/stringslite/strings.js +67 -0
  109. package/dist/gs/stringslite/strings.js.map +1 -0
  110. package/dist/gs/sync/index.d.ts +1 -0
  111. package/dist/gs/sync/index.js +2 -0
  112. package/dist/gs/sync/index.js.map +1 -0
  113. package/dist/gs/sync/sync.d.ts +79 -0
  114. package/dist/gs/sync/sync.js +392 -0
  115. package/dist/gs/sync/sync.js.map +1 -0
  116. package/dist/gs/time/time.d.ts +11 -2
  117. package/dist/gs/time/time.js +337 -12
  118. package/dist/gs/time/time.js.map +1 -1
  119. package/dist/gs/unicode/index.d.ts +1 -0
  120. package/dist/gs/unicode/index.js +2 -0
  121. package/dist/gs/unicode/index.js.map +1 -0
  122. package/dist/gs/unicode/unicode.d.ts +105 -0
  123. package/dist/gs/unicode/unicode.js +332 -0
  124. package/dist/gs/unicode/unicode.js.map +1 -0
  125. package/dist/gs/unicode/utf8/index.d.ts +1 -0
  126. package/dist/gs/unicode/utf8/index.js +3 -0
  127. package/dist/gs/unicode/utf8/index.js.map +1 -0
  128. package/dist/gs/unicode/utf8/utf8.d.ts +20 -0
  129. package/dist/gs/unicode/utf8/utf8.js +196 -0
  130. package/dist/gs/unicode/utf8/utf8.js.map +1 -0
  131. package/dist/gs/unsafe/index.d.ts +1 -0
  132. package/dist/gs/unsafe/index.js +2 -0
  133. package/dist/gs/unsafe/index.js.map +1 -0
  134. package/dist/gs/unsafe/unsafe.d.ts +11 -0
  135. package/dist/gs/unsafe/unsafe.js +44 -0
  136. package/dist/gs/unsafe/unsafe.js.map +1 -0
  137. package/go.mod +2 -1
  138. package/go.sum +6 -2
  139. package/gs/README.md +6 -0
  140. package/gs/builtin/builtin.ts +171 -0
  141. package/gs/builtin/channel.ts +683 -0
  142. package/gs/builtin/defer.ts +58 -0
  143. package/gs/builtin/index.ts +1 -0
  144. package/gs/builtin/io.ts +22 -0
  145. package/gs/builtin/map.ts +50 -0
  146. package/gs/builtin/slice.ts +1030 -0
  147. package/gs/builtin/type.ts +1106 -0
  148. package/gs/builtin/varRef.ts +25 -0
  149. package/gs/cmp/godoc.txt +8 -0
  150. package/gs/cmp/index.ts +29 -0
  151. package/gs/context/context.ts +401 -0
  152. package/gs/context/godoc.txt +69 -0
  153. package/gs/context/index.ts +1 -0
  154. package/gs/errors/errors.ts +223 -0
  155. package/gs/errors/godoc.txt +63 -0
  156. package/gs/errors/index.ts +1 -0
  157. package/gs/internal/goarch/godoc.txt +39 -0
  158. package/gs/internal/goarch/index.ts +18 -0
  159. package/gs/internal/oserror/errors.ts +14 -0
  160. package/gs/internal/oserror/index.ts +1 -0
  161. package/gs/io/fs/format.ts +65 -0
  162. package/gs/io/fs/fs.ts +359 -0
  163. package/gs/io/fs/glob.ts +167 -0
  164. package/gs/io/fs/godoc.txt +35 -0
  165. package/gs/io/fs/index.ts +8 -0
  166. package/gs/io/fs/readdir.ts +126 -0
  167. package/gs/io/fs/readfile.ts +77 -0
  168. package/gs/io/fs/stat.ts +38 -0
  169. package/gs/io/fs/sub.ts +208 -0
  170. package/gs/io/fs/walk.ts +89 -0
  171. package/gs/io/godoc.txt +61 -0
  172. package/gs/io/index.ts +1 -0
  173. package/gs/io/io.go +75 -0
  174. package/gs/io/io.ts +546 -0
  175. package/gs/iter/godoc.txt +203 -0
  176. package/gs/iter/index.ts +1 -0
  177. package/gs/iter/iter.ts +117 -0
  178. package/gs/math/bits/index.ts +356 -0
  179. package/gs/math/godoc.txt +76 -0
  180. package/gs/path/index.ts +2 -0
  181. package/gs/path/match.ts +307 -0
  182. package/gs/path/path.ts +301 -0
  183. package/gs/runtime/godoc.txt +331 -0
  184. package/gs/runtime/index.ts +1 -0
  185. package/gs/runtime/runtime.ts +178 -0
  186. package/gs/slices/godoc.txt +44 -0
  187. package/gs/slices/index.ts +1 -0
  188. package/gs/slices/slices.ts +22 -0
  189. package/gs/strings/builder.test.ts +121 -0
  190. package/gs/strings/builder.ts +223 -0
  191. package/gs/strings/clone.test.ts +43 -0
  192. package/gs/strings/clone.ts +17 -0
  193. package/gs/strings/compare.test.ts +84 -0
  194. package/gs/strings/compare.ts +13 -0
  195. package/gs/strings/godoc.txt +66 -0
  196. package/gs/strings/index.ts +2 -0
  197. package/gs/strings/iter.test.ts +343 -0
  198. package/gs/strings/iter.ts +171 -0
  199. package/gs/strings/reader.test.ts +242 -0
  200. package/gs/strings/reader.ts +451 -0
  201. package/gs/strings/replace.test.ts +181 -0
  202. package/gs/strings/replace.ts +1310 -0
  203. package/gs/strings/search.test.ts +214 -0
  204. package/gs/strings/search.ts +213 -0
  205. package/gs/strings/strings.test.ts +477 -0
  206. package/gs/strings/strings.ts +510 -0
  207. package/gs/stringslite/godoc.txt +17 -0
  208. package/gs/stringslite/index.ts +1 -0
  209. package/gs/stringslite/strings.ts +82 -0
  210. package/gs/sync/godoc.txt +21 -0
  211. package/gs/sync/index.ts +1 -0
  212. package/gs/sync/sync.go +64 -0
  213. package/gs/sync/sync.ts +449 -0
  214. package/gs/time/godoc.txt +116 -0
  215. package/gs/time/index.ts +1 -0
  216. package/gs/time/time.ts +585 -0
  217. package/gs/unicode/godoc.txt +52 -0
  218. package/gs/unicode/index.ts +1 -0
  219. package/gs/unicode/unicode.go +38 -0
  220. package/gs/unicode/unicode.ts +418 -0
  221. package/gs/unicode/utf8/godoc.txt +22 -0
  222. package/gs/unicode/utf8/index.ts +2 -0
  223. package/gs/unicode/utf8/utf8.ts +227 -0
  224. package/gs/unsafe/godoc.txt +19 -0
  225. package/gs/unsafe/index.ts +1 -0
  226. package/gs/unsafe/unsafe.test.ts +68 -0
  227. package/gs/unsafe/unsafe.ts +77 -0
  228. package/package.json +4 -3
@@ -0,0 +1,510 @@
1
+ import * as $ from '@goscript/builtin/builtin.js'
2
+
3
+ // Helper function to convert string to runes (code points)
4
+ function stringToRunes(s: string): number[] {
5
+ const runes: number[] = []
6
+ for (const char of s) {
7
+ runes.push(char.codePointAt(0) || 0)
8
+ }
9
+ return runes
10
+ }
11
+
12
+ // Helper function to convert runes to string
13
+ function runesToString(runes: number[]): string {
14
+ return String.fromCodePoint(...runes)
15
+ }
16
+
17
+ // Count counts the number of non-overlapping instances of substr in s.
18
+ // If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
19
+ export function Count(s: string, substr: string): number {
20
+ if (substr === '') {
21
+ return [...s].length + 1 // Unicode-aware length
22
+ }
23
+
24
+ let count = 0
25
+ let pos = 0
26
+ while (true) {
27
+ const index = s.indexOf(substr, pos)
28
+ if (index === -1) break
29
+ count++
30
+ pos = index + substr.length
31
+ }
32
+ return count
33
+ }
34
+
35
+ // Contains reports whether substr is within s.
36
+ export function Contains(s: string, substr: string): boolean {
37
+ return s.includes(substr)
38
+ }
39
+
40
+ // ContainsAny reports whether any Unicode code points in chars are within s.
41
+ export function ContainsAny(s: string, chars: string): boolean {
42
+ for (const char of chars) {
43
+ if (s.includes(char)) {
44
+ return true
45
+ }
46
+ }
47
+ return false
48
+ }
49
+
50
+ // ContainsRune reports whether the Unicode code point r is within s.
51
+ export function ContainsRune(s: string, r: number): boolean {
52
+ const char = String.fromCodePoint(r)
53
+ return s.includes(char)
54
+ }
55
+
56
+ // ContainsFunc reports whether any Unicode code points r within s satisfy f(r).
57
+ export function ContainsFunc(
58
+ s: string,
59
+ f: ((r: number) => boolean) | null,
60
+ ): boolean {
61
+ if (!f) return false
62
+ for (const char of s) {
63
+ const codePoint = char.codePointAt(0)
64
+ if (codePoint !== undefined && f(codePoint)) {
65
+ return true
66
+ }
67
+ }
68
+ return false
69
+ }
70
+
71
+ // Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
72
+ export function Index(s: string, substr: string): number {
73
+ return s.indexOf(substr)
74
+ }
75
+
76
+ // LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.
77
+ export function LastIndex(s: string, substr: string): number {
78
+ return s.lastIndexOf(substr)
79
+ }
80
+
81
+ // IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
82
+ export function IndexByte(s: string, c: number): number {
83
+ const char = String.fromCharCode(c)
84
+ return s.indexOf(char)
85
+ }
86
+
87
+ // IndexRune returns the index of the first instance of the Unicode code point r, or -1 if rune is not present in s.
88
+ export function IndexRune(s: string, r: number): number {
89
+ const char = String.fromCodePoint(r)
90
+ return s.indexOf(char)
91
+ }
92
+
93
+ // IndexAny returns the index of the first instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s.
94
+ export function IndexAny(s: string, chars: string): number {
95
+ for (let i = 0; i < s.length; i++) {
96
+ if (chars.includes(s[i])) {
97
+ return i
98
+ }
99
+ }
100
+ return -1
101
+ }
102
+
103
+ // LastIndexAny returns the index of the last instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s.
104
+ export function LastIndexAny(s: string, chars: string): number {
105
+ for (let i = s.length - 1; i >= 0; i--) {
106
+ if (chars.includes(s[i])) {
107
+ return i
108
+ }
109
+ }
110
+ return -1
111
+ }
112
+
113
+ // LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
114
+ export function LastIndexByte(s: string, c: number): number {
115
+ const char = String.fromCharCode(c)
116
+ return s.lastIndexOf(char)
117
+ }
118
+
119
+ // IndexFunc returns the index into s of the first Unicode code point satisfying f(c), or -1 if none do.
120
+ export function IndexFunc(
121
+ s: string,
122
+ f: ((r: number) => boolean) | null,
123
+ ): number {
124
+ if (!f) return -1
125
+ let index = 0
126
+ for (const char of s) {
127
+ const codePoint = char.codePointAt(0)
128
+ if (codePoint !== undefined && f(codePoint)) {
129
+ return index
130
+ }
131
+ index += char.length
132
+ }
133
+ return -1
134
+ }
135
+
136
+ // LastIndexFunc returns the index into s of the last Unicode code point satisfying f(c), or -1 if none do.
137
+ export function LastIndexFunc(
138
+ s: string,
139
+ f: ((r: number) => boolean) | null,
140
+ ): number {
141
+ if (!f) return -1
142
+ const chars = [...s]
143
+ for (let i = chars.length - 1; i >= 0; i--) {
144
+ const codePoint = chars[i].codePointAt(0)
145
+ if (codePoint !== undefined && f(codePoint)) {
146
+ // Calculate byte index
147
+ return chars.slice(0, i).join('').length
148
+ }
149
+ }
150
+ return -1
151
+ }
152
+
153
+ // Split slices s into all substrings separated by sep and returns a slice of the substrings between those separators.
154
+ export function Split(s: string, sep: string): $.Slice<string> {
155
+ if (sep === '') {
156
+ // Split into individual characters
157
+ return $.arrayToSlice([...s])
158
+ }
159
+ return $.arrayToSlice(s.split(sep))
160
+ }
161
+
162
+ // SplitN slices s into substrings separated by sep and returns a slice of the substrings between those separators.
163
+ export function SplitN(s: string, sep: string, n: number): $.Slice<string> {
164
+ if (n == 0) {
165
+ return $.arrayToSlice([])
166
+ }
167
+ if (n === 1) {
168
+ return $.arrayToSlice([s])
169
+ }
170
+ if (sep === '') {
171
+ const chars = [...s]
172
+ if (n < 0) {
173
+ return $.arrayToSlice(chars)
174
+ }
175
+ return $.arrayToSlice(chars.slice(0, n))
176
+ }
177
+
178
+ const parts = s.split(sep)
179
+ if (n < 0 || parts.length <= n) {
180
+ return $.arrayToSlice(parts)
181
+ }
182
+
183
+ const result = parts.slice(0, n - 1)
184
+ result.push(parts.slice(n - 1).join(sep))
185
+ return $.arrayToSlice(result)
186
+ }
187
+
188
+ // SplitAfter slices s into all substrings after each instance of sep and returns a slice of those substrings.
189
+ export function SplitAfter(s: string, sep: string): $.Slice<string> {
190
+ return SplitAfterN(s, sep, -1)
191
+ }
192
+
193
+ // SplitAfterN slices s into substrings after each instance of sep and returns a slice of those substrings.
194
+ export function SplitAfterN(
195
+ s: string,
196
+ sep: string,
197
+ n: number,
198
+ ): $.Slice<string> {
199
+ if (n == 0) {
200
+ return $.arrayToSlice([])
201
+ }
202
+ if (sep === '') {
203
+ const chars = [...s]
204
+ if (n < 0) {
205
+ return $.arrayToSlice(chars)
206
+ }
207
+ return $.arrayToSlice(chars.slice(0, n))
208
+ }
209
+
210
+ const parts: string[] = []
211
+ let start = 0
212
+ let count = 0
213
+
214
+ while (n < 0 || count < n - 1) {
215
+ const index = s.indexOf(sep, start)
216
+ if (index === -1) break
217
+ parts.push(s.slice(start, index + sep.length))
218
+ start = index + sep.length
219
+ count++
220
+ }
221
+
222
+ if (start < s.length) {
223
+ parts.push(s.slice(start))
224
+ }
225
+
226
+ return $.arrayToSlice(parts)
227
+ }
228
+
229
+ // Fields splits the string s around each instance of one or more consecutive white space characters.
230
+ export function Fields(s: string): $.Slice<string> {
231
+ return $.arrayToSlice(
232
+ s
233
+ .trim()
234
+ .split(/\s+/)
235
+ .filter((part) => part.length > 0),
236
+ )
237
+ }
238
+
239
+ // FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c) and returns an array of slices of s.
240
+ export function FieldsFunc(
241
+ s: string,
242
+ f: ((r: number) => boolean) | null,
243
+ ): $.Slice<string> {
244
+ if (!f) return $.arrayToSlice([s])
245
+
246
+ const parts: string[] = []
247
+ let start = 0
248
+ let inField = false
249
+
250
+ let index = 0
251
+ for (const char of s) {
252
+ const codePoint = char.codePointAt(0)
253
+ if (codePoint !== undefined && f(codePoint)) {
254
+ if (inField) {
255
+ parts.push(s.slice(start, index))
256
+ inField = false
257
+ }
258
+ } else {
259
+ if (!inField) {
260
+ start = index
261
+ inField = true
262
+ }
263
+ }
264
+ index += char.length
265
+ }
266
+
267
+ if (inField) {
268
+ parts.push(s.slice(start))
269
+ }
270
+
271
+ return $.arrayToSlice(parts)
272
+ }
273
+
274
+ // Join concatenates the elements of elems to create a single string. The separator string sep is placed between elements in the resulting string.
275
+ export function Join(elems: $.Slice<string>, sep: string): string {
276
+ const arr = $.asArray(elems)
277
+ if (!Array.isArray(arr)) {
278
+ return ''
279
+ }
280
+ return arr.join(sep)
281
+ }
282
+
283
+ // HasPrefix tests whether the string s begins with prefix.
284
+ export function HasPrefix(s: string, prefix: string): boolean {
285
+ return s.startsWith(prefix)
286
+ }
287
+
288
+ // HasSuffix tests whether the string s ends with suffix.
289
+ export function HasSuffix(s: string, suffix: string): boolean {
290
+ return s.endsWith(suffix)
291
+ }
292
+
293
+ // Map returns a copy of the string s with all its characters modified according to the mapping function.
294
+ export function Map(
295
+ mapping: ((r: number) => number) | null,
296
+ s: string,
297
+ ): string {
298
+ if (!mapping) return s
299
+
300
+ let result = ''
301
+ for (const char of s) {
302
+ const codePoint = char.codePointAt(0)
303
+ if (codePoint !== undefined) {
304
+ const mapped = mapping(codePoint)
305
+ result += String.fromCodePoint(mapped)
306
+ }
307
+ }
308
+ return result
309
+ }
310
+
311
+ // Repeat returns a new string consisting of count copies of the string s.
312
+ export function Repeat(s: string, count: number): string {
313
+ if (count < 0) {
314
+ $.panic('strings: negative Repeat count')
315
+ }
316
+ return s.repeat(count)
317
+ }
318
+
319
+ // ToUpper returns s with all Unicode letters mapped to their upper case.
320
+ export function ToUpper(s: string): string {
321
+ return s.toUpperCase()
322
+ }
323
+
324
+ // ToLower returns s with all Unicode letters mapped to their lower case.
325
+ export function ToLower(s: string): string {
326
+ return s.toLowerCase()
327
+ }
328
+
329
+ // ToTitle returns a copy of the string s with all Unicode letters mapped to their Unicode title case.
330
+ export function ToTitle(s: string): string {
331
+ // JavaScript doesn't have a direct toTitleCase, so we'll use a simple approximation
332
+ return s
333
+ .split(' ')
334
+ .map((word) =>
335
+ word.length > 0 ?
336
+ word[0].toUpperCase() + word.slice(1).toLowerCase()
337
+ : word,
338
+ )
339
+ .join(' ')
340
+ }
341
+
342
+ // Title returns a copy of the string s with all Unicode letters that begin words mapped to their Unicode title case.
343
+ export function Title(s: string): string {
344
+ return ToTitle(s)
345
+ }
346
+
347
+ // TrimSpace returns a slice of the string s, with all leading and trailing white space removed.
348
+ export function TrimSpace(s: string): string {
349
+ return s.trim()
350
+ }
351
+
352
+ // Trim returns a slice of the string s with all leading and trailing Unicode code points contained in cutset removed.
353
+ export function Trim(s: string, cutset: string): string {
354
+ return TrimFunc(s, (r: number) => cutset.includes(String.fromCodePoint(r)))
355
+ }
356
+
357
+ // TrimLeft returns a slice of the string s with all leading Unicode code points contained in cutset removed.
358
+ export function TrimLeft(s: string, cutset: string): string {
359
+ return TrimLeftFunc(s, (r: number) =>
360
+ cutset.includes(String.fromCodePoint(r)),
361
+ )
362
+ }
363
+
364
+ // TrimRight returns a slice of the string s with all trailing Unicode code points contained in cutset removed.
365
+ export function TrimRight(s: string, cutset: string): string {
366
+ return TrimRightFunc(s, (r: number) =>
367
+ cutset.includes(String.fromCodePoint(r)),
368
+ )
369
+ }
370
+
371
+ // TrimFunc returns a slice of the string s with all leading and trailing Unicode code points c satisfying f(c) removed.
372
+ export function TrimFunc(
373
+ s: string,
374
+ f: ((r: number) => boolean) | null,
375
+ ): string {
376
+ if (!f) return s
377
+ return TrimRightFunc(TrimLeftFunc(s, f), f)
378
+ }
379
+
380
+ // TrimLeftFunc returns a slice of the string s with all leading Unicode code points c satisfying f(c) removed.
381
+ export function TrimLeftFunc(
382
+ s: string,
383
+ f: ((r: number) => boolean) | null,
384
+ ): string {
385
+ if (!f) return s
386
+
387
+ let start = 0
388
+ for (const char of s) {
389
+ const codePoint = char.codePointAt(0)
390
+ if (codePoint === undefined || !f(codePoint)) {
391
+ break
392
+ }
393
+ start += char.length
394
+ }
395
+ return s.slice(start)
396
+ }
397
+
398
+ // TrimRightFunc returns a slice of the string s with all trailing Unicode code points c satisfying f(c) removed.
399
+ export function TrimRightFunc(
400
+ s: string,
401
+ f: ((r: number) => boolean) | null,
402
+ ): string {
403
+ if (!f) return s
404
+
405
+ const chars = [...s]
406
+ let end = chars.length
407
+ for (let i = chars.length - 1; i >= 0; i--) {
408
+ const codePoint = chars[i].codePointAt(0)
409
+ if (codePoint === undefined || !f(codePoint)) {
410
+ break
411
+ }
412
+ end = i
413
+ }
414
+ return chars.slice(0, end).join('')
415
+ }
416
+
417
+ // TrimPrefix returns s without the provided leading prefix string. If s doesn't start with prefix, s is returned unchanged.
418
+ export function TrimPrefix(s: string, prefix: string): string {
419
+ if (s.startsWith(prefix)) {
420
+ return s.slice(prefix.length)
421
+ }
422
+ return s
423
+ }
424
+
425
+ // TrimSuffix returns s without the provided ending suffix string. If s doesn't end with suffix, s is returned unchanged.
426
+ export function TrimSuffix(s: string, suffix: string): string {
427
+ if (s.endsWith(suffix)) {
428
+ return s.slice(0, s.length - suffix.length)
429
+ }
430
+ return s
431
+ }
432
+
433
+ // Replace returns a copy of the string s with the first n non-overlapping instances of old replaced by new.
434
+ export function Replace(
435
+ s: string,
436
+ old: string,
437
+ newStr: string,
438
+ n: number,
439
+ ): string {
440
+ if (n <= 0 || old === '') {
441
+ return s
442
+ }
443
+
444
+ let result = s
445
+ let count = 0
446
+ let pos = 0
447
+
448
+ while (count < n) {
449
+ const index = result.indexOf(old, pos)
450
+ if (index === -1) break
451
+
452
+ result = result.slice(0, index) + newStr + result.slice(index + old.length)
453
+ pos = index + newStr.length
454
+ count++
455
+ }
456
+
457
+ return result
458
+ }
459
+
460
+ // ReplaceAll returns a copy of the string s with all non-overlapping instances of old replaced by new.
461
+ export function ReplaceAll(s: string, old: string, newStr: string): string {
462
+ if (old === '') {
463
+ return s
464
+ }
465
+ return s.split(old).join(newStr)
466
+ }
467
+
468
+ // EqualFold reports whether s and t, interpreted as UTF-8 strings, are equal under Unicode case-folding.
469
+ export function EqualFold(s: string, t: string): boolean {
470
+ return s.toLowerCase() === t.toLowerCase()
471
+ }
472
+
473
+ // Compare returns an integer comparing two strings lexicographically.
474
+ export function Compare(a: string, b: string): number {
475
+ if (a < b) return -1
476
+ if (a > b) return 1
477
+ return 0
478
+ }
479
+
480
+ // Cut slices s around the first instance of sep, returning the text before and after sep.
481
+ export function Cut(s: string, sep: string): [string, string, boolean] {
482
+ const index = s.indexOf(sep)
483
+ if (index === -1) {
484
+ return [s, '', false]
485
+ }
486
+ return [s.slice(0, index), s.slice(index + sep.length), true]
487
+ }
488
+
489
+ // CutPrefix returns s without the provided leading prefix string and reports whether it found the prefix.
490
+ export function CutPrefix(s: string, prefix: string): [string, boolean] {
491
+ if (s.startsWith(prefix)) {
492
+ return [s.slice(prefix.length), true]
493
+ }
494
+ return [s, false]
495
+ }
496
+
497
+ // CutSuffix returns s without the provided ending suffix string and reports whether it found the suffix.
498
+ export function CutSuffix(s: string, suffix: string): [string, boolean] {
499
+ if (s.endsWith(suffix)) {
500
+ return [s.slice(0, s.length - suffix.length), true]
501
+ }
502
+ return [s, false]
503
+ }
504
+
505
+ // Clone returns a fresh copy of s.
506
+ export function Clone(s: string): string {
507
+ // In JavaScript, strings are immutable, so we can just return the string
508
+ // But to match Go semantics, we'll create a new string
509
+ return String(s)
510
+ }
@@ -0,0 +1,17 @@
1
+ package stringslite // import "internal/stringslite"
2
+
3
+ Package stringslite implements a subset of strings, only using packages that may
4
+ be imported by "os".
5
+
6
+ Tests for these functions are in the strings package.
7
+
8
+ func Clone(s string) string
9
+ func Cut(s, sep string) (before, after string, found bool)
10
+ func CutPrefix(s, prefix string) (after string, found bool)
11
+ func CutSuffix(s, suffix string) (before string, found bool)
12
+ func HasPrefix(s, prefix string) bool
13
+ func HasSuffix(s, suffix string) bool
14
+ func Index(s, substr string) int
15
+ func IndexByte(s string, c byte) int
16
+ func TrimPrefix(s, prefix string) string
17
+ func TrimSuffix(s, suffix string) string
@@ -0,0 +1 @@
1
+ export * from './strings'
@@ -0,0 +1,82 @@
1
+ import * as $ from '@goscript/builtin/builtin.js'
2
+
3
+ import * as unsafe from '@goscript/unsafe/index.js'
4
+
5
+ export function HasPrefix(s: string, prefix: string): boolean {
6
+ return (
7
+ $.len(s) >= $.len(prefix) &&
8
+ $.sliceString(s, undefined, $.len(prefix)) == prefix
9
+ )
10
+ }
11
+
12
+ export function HasSuffix(s: string, suffix: string): boolean {
13
+ return (
14
+ $.len(s) >= $.len(suffix) &&
15
+ $.sliceString(s, $.len(s) - $.len(suffix), undefined) == suffix
16
+ )
17
+ }
18
+
19
+ export function IndexByte(s: string, c: number): number {
20
+ const char = String.fromCharCode(c)
21
+ return s.indexOf(char)
22
+ }
23
+
24
+ export function Index(s: string, substr: string): number {
25
+ if (substr === '') {
26
+ return 0
27
+ }
28
+ return s.indexOf(substr)
29
+ }
30
+
31
+ export function Cut(s: string, sep: string): [string, string, boolean] {
32
+ let i = Index(s, sep)
33
+ if (i >= 0) {
34
+ return [
35
+ $.sliceString(s, undefined, i),
36
+ $.sliceString(s, i + $.len(sep), undefined),
37
+ true,
38
+ ]
39
+ }
40
+ return [s, '', false]
41
+ }
42
+
43
+ export function CutPrefix(s: string, prefix: string): [string, boolean] {
44
+ if (!HasPrefix(s, prefix)) {
45
+ return [s, false]
46
+ }
47
+ return [$.sliceString(s, $.len(prefix), undefined), true]
48
+ }
49
+
50
+ export function CutSuffix(s: string, suffix: string): [string, boolean] {
51
+ if (!HasSuffix(s, suffix)) {
52
+ return [s, false]
53
+ }
54
+ return [$.sliceString(s, undefined, $.len(s) - $.len(suffix)), true]
55
+ }
56
+
57
+ export function TrimPrefix(s: string, prefix: string): string {
58
+ if (HasPrefix(s, prefix)) {
59
+ return $.sliceString(s, $.len(prefix), undefined)
60
+ }
61
+ return s
62
+ }
63
+
64
+ export function TrimSuffix(s: string, suffix: string): string {
65
+ if (HasSuffix(s, suffix)) {
66
+ return $.sliceString(s, undefined, $.len(s) - $.len(suffix))
67
+ }
68
+ return s
69
+ }
70
+
71
+ export function Clone(s: string): string {
72
+ if ($.len(s) == 0) {
73
+ return ''
74
+ }
75
+ let b = new Uint8Array($.len(s))
76
+ $.copy(b, s)
77
+ return unsafe.String(b![0], $.len(b))
78
+ }
79
+
80
+ export function CopyBytes(b: Uint8Array, s: string): number {
81
+ return $.copy(b, s)
82
+ }
@@ -0,0 +1,21 @@
1
+ package sync // import "sync"
2
+
3
+ Package sync provides basic synchronization primitives such as mutual exclusion
4
+ locks. Other than the Once and WaitGroup types, most are intended for use by
5
+ low-level library routines. Higher-level synchronization is better done via
6
+ channels and communication.
7
+
8
+ Values containing the types defined in this package should not be copied.
9
+
10
+ func OnceFunc(f func()) func()
11
+ func OnceValue[T any](f func() T) func() T
12
+ func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2)
13
+ type Cond struct{ ... }
14
+ func NewCond(l Locker) *Cond
15
+ type Locker interface{ ... }
16
+ type Map struct{ ... }
17
+ type Mutex struct{ ... }
18
+ type Once struct{ ... }
19
+ type Pool struct{ ... }
20
+ type RWMutex struct{ ... }
21
+ type WaitGroup struct{ ... }
@@ -0,0 +1 @@
1
+ export * from './sync.js'
@@ -0,0 +1,64 @@
1
+ package sync
2
+
3
+ import "github.com/aperturerobotics/goscript/compiler"
4
+
5
+ // Metadata for sync package functions
6
+ // This defines which functions/methods are async for the compiler analysis
7
+
8
+ // Mutex methods
9
+ var (
10
+ MutexLockInfo = compiler.FunctionInfo{IsAsync: true}
11
+ MutexUnlockInfo = compiler.FunctionInfo{IsAsync: false}
12
+ MutexTryLockInfo = compiler.FunctionInfo{IsAsync: false}
13
+ )
14
+
15
+ // RWMutex methods
16
+ var (
17
+ RWMutexLockInfo = compiler.FunctionInfo{IsAsync: true}
18
+ RWMutexUnlockInfo = compiler.FunctionInfo{IsAsync: false}
19
+ RWMutexTryLockInfo = compiler.FunctionInfo{IsAsync: false}
20
+ RWMutexRLockInfo = compiler.FunctionInfo{IsAsync: true}
21
+ RWMutexRUnlockInfo = compiler.FunctionInfo{IsAsync: false}
22
+ RWMutexTryRLockInfo = compiler.FunctionInfo{IsAsync: false}
23
+ )
24
+
25
+ // WaitGroup methods
26
+ var (
27
+ WaitGroupAddInfo = compiler.FunctionInfo{IsAsync: false}
28
+ WaitGroupDoneInfo = compiler.FunctionInfo{IsAsync: false}
29
+ WaitGroupWaitInfo = compiler.FunctionInfo{IsAsync: true}
30
+ )
31
+
32
+ // Once methods
33
+ var OnceDoInfo = compiler.FunctionInfo{IsAsync: true}
34
+
35
+ // Cond methods
36
+ var (
37
+ CondBroadcastInfo = compiler.FunctionInfo{IsAsync: false}
38
+ CondSignalInfo = compiler.FunctionInfo{IsAsync: false}
39
+ CondWaitInfo = compiler.FunctionInfo{IsAsync: true}
40
+ )
41
+
42
+ // Map methods
43
+ var (
44
+ MapDeleteInfo = compiler.FunctionInfo{IsAsync: true}
45
+ MapLoadInfo = compiler.FunctionInfo{IsAsync: true}
46
+ MapLoadAndDeleteInfo = compiler.FunctionInfo{IsAsync: true}
47
+ MapLoadOrStoreInfo = compiler.FunctionInfo{IsAsync: true}
48
+ MapRangeInfo = compiler.FunctionInfo{IsAsync: true}
49
+ MapStoreInfo = compiler.FunctionInfo{IsAsync: true}
50
+ )
51
+
52
+ // Pool methods
53
+ var (
54
+ PoolGetInfo = compiler.FunctionInfo{IsAsync: false}
55
+ PoolPutInfo = compiler.FunctionInfo{IsAsync: false}
56
+ )
57
+
58
+ // Functions
59
+ var (
60
+ OnceFuncInfo = compiler.FunctionInfo{IsAsync: false}
61
+ OnceValueInfo = compiler.FunctionInfo{IsAsync: false}
62
+ OnceValuesInfo = compiler.FunctionInfo{IsAsync: false}
63
+ NewCondInfo = compiler.FunctionInfo{IsAsync: false}
64
+ )