gofront 1.8.0 → 1.9.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 (178) hide show
  1. package/README.md +3 -3
  2. package/package.json +6 -5
  3. package/src/backend/js/expressions.js +1157 -408
  4. package/src/backend/js/index.js +327 -153
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +559 -2552
  7. package/src/backend/js/statements.js +670 -158
  8. package/src/backend/js/stdlib/index.js +45 -93
  9. package/src/backend/js/templ.js +32 -45
  10. package/src/backend/js/type-info.js +298 -19
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +91 -170
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +490 -965
  15. package/src/backend/wasm/emit-builtins.js +884 -256
  16. package/src/backend/wasm/emit-exprs.js +185 -77
  17. package/src/backend/wasm/emit-maps.js +17 -367
  18. package/src/backend/wasm/emit-shared.js +4 -1
  19. package/src/backend/wasm/emit-stmts.js +524 -240
  20. package/src/backend/wasm/emit.js +176 -38
  21. package/src/backend/wasm/globals.js +48 -8
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +44 -530
  24. package/src/backend/wasm/method-expr.js +12 -1
  25. package/src/backend/wasm/module-emitter.js +299 -770
  26. package/src/backend/wasm/monomorph.js +139 -8
  27. package/src/backend/wasm/natives.js +600 -0
  28. package/src/backend/wasm/prescan.js +5 -153
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -32
  31. package/src/backend/wasm/types.js +97 -20
  32. package/src/backend/wasm/variadic.js +9 -4
  33. package/src/cli/cli-core.js +5 -1
  34. package/src/cli/test-runner.js +115 -342
  35. package/src/compiler.js +113 -130
  36. package/src/lexer/lexer.js +106 -11
  37. package/src/lexer/templ-lexer.js +61 -18
  38. package/src/lexer/tokens.js +1 -0
  39. package/src/link/stdlib.js +355 -132
  40. package/src/link/type-names.js +204 -0
  41. package/src/link/wasm.js +30 -6
  42. package/src/lower/bounds.js +153 -0
  43. package/src/lower/captures.js +92 -33
  44. package/src/lower/embedding.js +62 -5
  45. package/src/lower/errors-as.js +196 -0
  46. package/src/lower/fmt-formatters.js +929 -0
  47. package/src/lower/functions.js +225 -7
  48. package/src/lower/gen-types.js +293 -0
  49. package/src/lower/index.js +14 -2
  50. package/src/lower/json-codecs.js +334 -245
  51. package/src/lower/ownership.js +25 -7
  52. package/src/lower/reachability.js +69 -51
  53. package/src/lower/walk.js +12 -0
  54. package/src/parser/declarations.js +30 -5
  55. package/src/parser/expressions.js +111 -57
  56. package/src/parser/statements.js +108 -0
  57. package/src/parser/templ.js +44 -5
  58. package/src/parser/types.js +12 -0
  59. package/src/resolver.js +1 -2
  60. package/src/typechecker/assignability.js +214 -19
  61. package/src/typechecker/const-fold.js +70 -27
  62. package/src/typechecker/constants.js +156 -8
  63. package/src/typechecker/expressions.js +490 -108
  64. package/src/typechecker/index.js +346 -42
  65. package/src/typechecker/init-order.js +136 -40
  66. package/src/typechecker/operand-text.js +41 -0
  67. package/src/typechecker/resolve.js +490 -65
  68. package/src/typechecker/statements.js +288 -27
  69. package/src/typechecker/stdlib/excluded.js +9 -5
  70. package/src/typechecker/stdlib/index.js +25 -9
  71. package/src/typechecker/termination.js +10 -1
  72. package/src/typechecker/types.js +287 -575
  73. package/stdlib/bytes/buffer.go +479 -0
  74. package/stdlib/bytes/bytes.go +1010 -0
  75. package/stdlib/bytes/reader.go +161 -0
  76. package/stdlib/context/context.go +115 -0
  77. package/stdlib/crypto/rand/rand.go +34 -0
  78. package/stdlib/crypto/sha256/sha256.go +249 -0
  79. package/stdlib/encoding/base64/base64.go +331 -0
  80. package/stdlib/encoding/binary/binary.go +332 -0
  81. package/stdlib/encoding/hex/hex.go +140 -0
  82. package/stdlib/encoding/json/json.go +62 -0
  83. package/stdlib/errors/errors.go +174 -0
  84. package/stdlib/fmt/errors.go +110 -0
  85. package/stdlib/fmt/format.go +732 -0
  86. package/stdlib/fmt/print.go +1232 -0
  87. package/stdlib/gom/gom.go +293 -0
  88. package/stdlib/html/html.go +251 -0
  89. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  90. package/stdlib/internal/jsonrt/dec.go +171 -38
  91. package/stdlib/internal/jsonrt/enc.go +186 -36
  92. package/stdlib/internal/jsonrt/scanner.go +17 -8
  93. package/stdlib/io/io.go +157 -1
  94. package/stdlib/maps/maps.go +131 -0
  95. package/stdlib/math/bits/bits.go +507 -0
  96. package/stdlib/math/extra.go +16 -14
  97. package/stdlib/math/math.go +439 -0
  98. package/stdlib/math/rand/rand.go +297 -0
  99. package/stdlib/os/os.go +93 -0
  100. package/stdlib/path/filepath/filepath.go +47 -0
  101. package/stdlib/path/path.go +394 -0
  102. package/stdlib/regexp/regexp.go +231 -0
  103. package/stdlib/slices/slices.go +526 -0
  104. package/stdlib/slices/sort.go +209 -0
  105. package/stdlib/slices/zsort_cmp.go +480 -0
  106. package/stdlib/slices/zsort_ordered.go +482 -0
  107. package/stdlib/sort/sort.go +391 -452
  108. package/stdlib/sort/zsort_func.go +480 -0
  109. package/stdlib/sort/zsort_iface.go +480 -0
  110. package/stdlib/strconv/float.go +1699 -0
  111. package/stdlib/strconv/isprint.go +752 -0
  112. package/stdlib/strconv/quote.go +235 -50
  113. package/stdlib/strconv/strconv.go +616 -0
  114. package/stdlib/strings/builder.go +95 -0
  115. package/stdlib/strings/reader.go +163 -0
  116. package/stdlib/strings/replacer.go +102 -0
  117. package/stdlib/strings/strings.go +807 -0
  118. package/stdlib/sync/sync.go +268 -0
  119. package/stdlib/testing/async_js.go +61 -0
  120. package/stdlib/testing/benchmark.go +297 -0
  121. package/stdlib/testing/testing.go +523 -0
  122. package/stdlib/time/duration.go +233 -0
  123. package/stdlib/time/format.go +745 -0
  124. package/stdlib/time/parse.go +790 -0
  125. package/stdlib/time/sleep_js.go +63 -0
  126. package/stdlib/time/time.go +834 -0
  127. package/stdlib/unicode/unicode.go +141 -3
  128. package/stdlib/unicode/utf8/utf8.go +464 -0
  129. package/src/backend/js/fmt-runtime.js +0 -573
  130. package/src/backend/js/stdlib/base64.js +0 -12
  131. package/src/backend/js/stdlib/binary.js +0 -102
  132. package/src/backend/js/stdlib/bits.js +0 -119
  133. package/src/backend/js/stdlib/builder.js +0 -98
  134. package/src/backend/js/stdlib/bytes.js +0 -368
  135. package/src/backend/js/stdlib/errors.js +0 -45
  136. package/src/backend/js/stdlib/fmt.js +0 -517
  137. package/src/backend/js/stdlib/gom.js +0 -155
  138. package/src/backend/js/stdlib/hex.js +0 -17
  139. package/src/backend/js/stdlib/html.js +0 -20
  140. package/src/backend/js/stdlib/io.js +0 -137
  141. package/src/backend/js/stdlib/json.js +0 -1167
  142. package/src/backend/js/stdlib/maps.js +0 -37
  143. package/src/backend/js/stdlib/math.js +0 -85
  144. package/src/backend/js/stdlib/os.js +0 -13
  145. package/src/backend/js/stdlib/path.js +0 -48
  146. package/src/backend/js/stdlib/rand.js +0 -32
  147. package/src/backend/js/stdlib/regexp.js +0 -54
  148. package/src/backend/js/stdlib/sha256.js +0 -12
  149. package/src/backend/js/stdlib/shared.js +0 -17
  150. package/src/backend/js/stdlib/simd.js +0 -34
  151. package/src/backend/js/stdlib/slices.js +0 -107
  152. package/src/backend/js/stdlib/sort.js +0 -30
  153. package/src/backend/js/stdlib/strconv.js +0 -79
  154. package/src/backend/js/stdlib/strings.js +0 -301
  155. package/src/backend/js/stdlib/sync.js +0 -13
  156. package/src/backend/js/stdlib/testing.js +0 -41
  157. package/src/backend/js/stdlib/time.js +0 -152
  158. package/src/backend/js/stdlib/unicode.js +0 -25
  159. package/src/backend/js/stdlib/utf8.js +0 -26
  160. package/src/backend/wasm/stdlib/bytes.js +0 -6716
  161. package/src/backend/wasm/stdlib/core.js +0 -10278
  162. package/src/backend/wasm/stdlib/io.js +0 -3578
  163. package/src/backend/wasm/stdlib/packages.js +0 -2402
  164. package/src/backend/wasm/stdlib/pure.js +0 -720
  165. package/src/backend/wasm/stdlib/time.js +0 -2229
  166. package/src/typechecker/stdlib/core.js +0 -1079
  167. package/src/typechecker/stdlib/extended.js +0 -1210
  168. package/stdlib/bytes/iter.go +0 -192
  169. package/stdlib/bytes/search.go +0 -240
  170. package/stdlib/bytes/split.go +0 -218
  171. package/stdlib/errors/overlay.go +0 -12
  172. package/stdlib/maps/iter.go +0 -65
  173. package/stdlib/slices/extra.go +0 -73
  174. package/stdlib/slices/iter.go +0 -113
  175. package/stdlib/strings/extra.go +0 -35
  176. package/stdlib/strings/iter.go +0 -122
  177. package/stdlib/sync/extra.go +0 -105
  178. package/stdlib/unicode/utf8/bytes.go +0 -239
@@ -106,593 +106,178 @@ export const BROWSER_GLOBALS = new Set([
106
106
  // gains support; anything not listed is rejected at import with "not yet available in
107
107
  // wasm packages".
108
108
  export const WASM_SUPPORTED_STDLIB = new Set([
109
- "math",
110
- "math/bits",
111
- "math/rand",
112
- "errors",
113
- "fmt",
114
- "strings",
115
- "bytes",
116
- "strconv",
117
- "unicode",
118
- "unicode/utf8",
119
- "slices",
120
- "maps",
121
- "sort",
122
- "path",
123
- "path/filepath",
124
- "html",
125
- "io",
126
- "time",
127
- "testing",
128
109
  "gofront/shared",
129
110
  "gofront/simd",
130
- "sync",
131
- "crypto/rand",
132
- "crypto/sha256",
133
- "encoding/binary",
134
- "encoding/hex",
135
- "encoding/base64",
136
- "os",
137
- "encoding/json",
138
111
  ]);
139
112
 
140
- export const STDLIB_PACKAGES = new Set([
141
- ...WASM_SUPPORTED_STDLIB,
142
- "gom",
143
- "regexp",
144
- ]);
113
+ export const STDLIB_PACKAGES = WASM_SUPPORTED_STDLIB;
145
114
 
146
115
  // Per-namespace member subset the WASM backend implements. `null` means every
147
116
  // member the checker knows about. Members outside the set are rejected in
148
117
  // wasm/both packages with "'strings.Split' is not yet available in wasm packages".
149
- export const WASM_STDLIB_MEMBERS = new Map([
150
- ["os", new Set(["Stdout", "Stderr", "Stdin", "File"])],
151
- [
152
- "math",
153
- new Set([
154
- "Sqrt",
155
- "Floor",
156
- "Ceil",
157
- "Trunc",
158
- "Abs",
159
- "Min",
160
- "Max",
161
- "Copysign",
162
- "Dim",
163
- "Inf",
164
- "NaN",
165
- "IsNaN",
166
- "IsInf",
167
- "Signbit",
168
- "Sin",
169
- "Cos",
170
- "Tan",
171
- "Asin",
172
- "Acos",
173
- "Atan",
174
- "Atan2",
175
- "Pow",
176
- "Mod",
177
- "Hypot",
178
- "Cbrt",
179
- "Exp",
180
- "Exp2",
181
- "Log",
182
- "Log1p",
183
- "Log2",
184
- "Log10",
185
- "Expm1",
186
- "Round",
187
- "Remainder",
188
- "Float64bits",
189
- "Float64frombits",
190
- "Float32bits",
191
- "Float32frombits",
192
- "Sinh",
193
- "Cosh",
194
- "Tanh",
195
- // constants
196
- "E",
197
- "Pi",
198
- "Phi",
199
- "Sqrt2",
200
- "SqrtE",
201
- "SqrtPi",
202
- "SqrtPhi",
203
- "Ln2",
204
- "Log2E",
205
- "Ln10",
206
- "Log10E",
207
- "MaxFloat32",
208
- "SmallestNonzeroFloat32",
209
- "MaxFloat64",
210
- "SmallestNonzeroFloat64",
211
- "MaxInt",
212
- "MinInt",
213
- "MaxInt8",
214
- "MinInt8",
215
- "MaxInt16",
216
- "MinInt16",
217
- "MaxInt32",
218
- "MinInt32",
219
- "MaxInt64",
220
- "MinInt64",
221
- "MaxUint8",
222
- "MaxUint16",
223
- "MaxUint32",
224
- "MaxUint",
225
- "MaxUint64",
226
- ]),
227
- ],
228
- [
229
- "bits",
230
- new Set([
231
- "Add",
232
- "Add32",
233
- "Add64",
234
- "Sub",
235
- "Sub32",
236
- "Sub64",
237
- "Mul",
238
- "Mul32",
239
- "Mul64",
240
- "Div",
241
- "Div32",
242
- "Div64",
243
- "Rem",
244
- "Rem32",
245
- "Rem64",
246
- "LeadingZeros",
247
- "LeadingZeros8",
248
- "LeadingZeros16",
249
- "LeadingZeros32",
250
- "LeadingZeros64",
251
- "TrailingZeros",
252
- "TrailingZeros8",
253
- "TrailingZeros16",
254
- "TrailingZeros32",
255
- "TrailingZeros64",
256
- "OnesCount",
257
- "OnesCount8",
258
- "OnesCount16",
259
- "OnesCount32",
260
- "OnesCount64",
261
- "RotateLeft",
262
- "RotateLeft8",
263
- "RotateLeft16",
264
- "RotateLeft32",
265
- "RotateLeft64",
266
- "Reverse",
267
- "Reverse8",
268
- "Reverse16",
269
- "Reverse32",
270
- "Reverse64",
271
- "ReverseBytes",
272
- "ReverseBytes16",
273
- "ReverseBytes32",
274
- "ReverseBytes64",
275
- "Len",
276
- "Len8",
277
- "Len16",
278
- "Len32",
279
- "Len64",
280
- "UintSize",
281
- ]),
282
- ],
283
- ["errors", new Set(["New", "Is", "Unwrap", "As", "Join"])],
284
- [
285
- "utf8",
286
- new Set([
287
- "RuneCountInString",
288
- "RuneLen",
289
- "ValidString",
290
- "ValidRune",
291
- "DecodeRuneInString",
292
- "DecodeLastRuneInString",
293
- "FullRuneInString",
294
- "RuneError",
295
- "MaxRune",
296
- "UTFMax",
297
- "RuneSelf",
298
- "EncodeRune",
299
- "AppendRune",
300
- "DecodeRune",
301
- "DecodeLastRune",
302
- "RuneCount",
303
- "FullRune",
304
- "Valid",
305
- "RuneStart",
306
- ]),
307
- ],
308
- [
309
- "sort",
310
- new Set([
311
- "Ints",
312
- "Float64s",
313
- "Strings",
314
- "Slice",
315
- "SliceStable",
316
- "SliceIsSorted",
317
- "Search",
318
- "IntsAreSorted",
319
- "Float64sAreSorted",
320
- "StringsAreSorted",
321
- ]),
322
- ],
323
- [
324
- "fmt",
325
- new Set([
326
- "Sprintf",
327
- "Sprint",
328
- "Sprintln",
329
- "Append",
330
- "Appendf",
331
- "Appendln",
332
- "Errorf",
333
- "Printf",
334
- "Println",
335
- "Print",
336
- "Fprintf",
337
- "Fprintln",
338
- "Fprint",
339
- "Sscan",
340
- "Sscanln",
341
- "Sscanf",
342
- "Stringer",
343
- ]),
344
- ],
345
- [
346
- "strings",
347
- new Set([
348
- "Contains",
349
- "ContainsAny",
350
- "ContainsRune",
351
- "HasPrefix",
352
- "HasSuffix",
353
- "Index",
354
- "IndexAny",
355
- "IndexByte",
356
- "IndexRune",
357
- "LastIndex",
358
- "LastIndexByte",
359
- "Count",
360
- "Repeat",
361
- "Replace",
362
- "ReplaceAll",
363
- "ToUpper",
364
- "ToLower",
365
- "Title",
366
- "ToTitle",
367
- "TrimSpace",
368
- "Trim",
369
- "TrimLeft",
370
- "TrimRight",
371
- "TrimPrefix",
372
- "TrimSuffix",
373
- "EqualFold",
374
- "Split",
375
- "Fields",
376
- "Join",
377
- "Cut",
378
- "CutPrefix",
379
- "CutSuffix",
380
- "SplitN",
381
- "SplitAfter",
382
- "SplitAfterN",
383
- "LastIndexAny",
384
- "Map",
385
- "IndexFunc",
386
- "LastIndexFunc",
387
- "TrimFunc",
388
- "TrimLeftFunc",
389
- "TrimRightFunc",
390
- "FieldsFunc",
391
- "NewReplacer",
392
- "Replacer",
393
- "Builder",
394
- "NewReader",
395
- "Reader",
396
- "ToValidUTF8",
397
- ]),
398
- ],
399
- [
400
- "strconv",
401
- new Set([
402
- "Itoa",
403
- "Atoi",
404
- "FormatInt",
405
- "FormatUint",
406
- "FormatFloat",
407
- "FormatBool",
408
- "ParseInt",
409
- "ParseUint",
410
- "ParseFloat",
411
- "ParseBool",
412
- "Quote",
413
- "Unquote",
414
- "AppendInt",
415
- "AppendUint",
416
- "AppendFloat",
417
- "AppendBool",
418
- "ErrSyntax",
419
- "ErrRange",
420
- "IntSize",
421
- "NumError",
422
- "QuoteRune",
423
- "QuoteToASCII",
424
- "QuoteRuneToASCII",
425
- "AppendQuote",
426
- "AppendQuoteToASCII",
427
- "AppendQuoteRune",
428
- "AppendQuoteRuneToASCII",
429
- "CanBackquote",
430
- "UnquoteChar",
431
- "QuotedPrefix",
432
- "IsPrint",
433
- "IsGraphic",
434
- ]),
435
- ],
436
- [
437
- "slices",
438
- new Set([
439
- "Sort",
440
- "Reverse",
441
- "Contains",
442
- "Index",
443
- "IndexFunc",
444
- "ContainsFunc",
445
- "BinarySearch",
446
- "BinarySearchFunc",
447
- "Equal",
448
- "Clone",
449
- "Compare",
450
- "SortFunc",
451
- "SortStableFunc",
452
- "IsSorted",
453
- "IsSortedFunc",
454
- "Min",
455
- "Max",
456
- "MinFunc",
457
- "MaxFunc",
458
- "Compact",
459
- "CompactFunc",
460
- "Concat",
461
- "Delete",
462
- "DeleteFunc",
463
- "Insert",
464
- "Replace",
465
- "Grow",
466
- "Clip",
467
- ]),
468
- ],
469
- [
470
- "maps",
471
- new Set(["Clone", "Copy", "Equal", "EqualFunc", "Delete", "DeleteFunc"]),
472
- ],
473
- [
474
- "unicode",
475
- new Set([
476
- "IsLetter",
477
- "IsDigit",
478
- "IsSpace",
479
- "IsUpper",
480
- "IsLower",
481
- "IsPunct",
482
- "IsControl",
483
- "IsPrint",
484
- "IsGraphic",
485
- "ToUpper",
486
- "ToLower",
487
- ]),
488
- ],
489
- [
490
- "rand",
491
- new Set([
492
- "Intn",
493
- "Float64",
494
- "Float32",
495
- "Int",
496
- "Int63",
497
- "Int63n",
498
- "Int31",
499
- "Int31n",
500
- "Seed",
501
- "Shuffle",
502
- "Perm",
503
- "Read",
504
- "Reader",
505
- ]),
506
- ],
507
- [
508
- "bytes",
509
- new Set([
510
- "Contains",
511
- "HasPrefix",
512
- "HasSuffix",
513
- "Index",
514
- "Count",
515
- "Repeat",
516
- "Replace",
517
- "ReplaceAll",
518
- "ToUpper",
519
- "ToLower",
520
- "TrimSpace",
521
- "Trim",
522
- "Equal",
523
- "Split",
524
- "Join",
525
- "TrimPrefix",
526
- "TrimSuffix",
527
- "TrimLeft",
528
- "TrimRight",
529
- "TrimFunc",
530
- "IndexByte",
531
- "LastIndex",
532
- "LastIndexByte",
533
- "Fields",
534
- "FieldsFunc",
535
- "Clone",
536
- "Cut",
537
- "ToTitle",
538
- "ContainsAny",
539
- "ContainsRune",
540
- "Map",
541
- "SplitN",
542
- "Buffer",
543
- "NewBuffer",
544
- "NewBufferString",
545
- "NewReader",
546
- "Reader",
547
- "ToValidUTF8",
548
- ]),
549
- ],
550
- [
551
- "path",
552
- new Set([
553
- "Base",
554
- "Dir",
555
- "Ext",
556
- "Join",
557
- "Clean",
558
- "IsAbs",
559
- "Split",
560
- "Match",
561
- "ErrBadPattern",
562
- ]),
563
- ],
564
- [
565
- "filepath",
566
- new Set([
567
- "Base",
568
- "Dir",
569
- "Ext",
570
- "Join",
571
- "Clean",
572
- "IsAbs",
573
- "Split",
574
- "Match",
575
- "ErrBadPattern",
576
- ]),
577
- ],
578
- ["html", new Set(["EscapeString", "UnescapeString"])],
579
- [
580
- "io",
581
- new Set([
582
- "Writer",
583
- "Reader",
584
- "ReadWriter",
585
- "Closer",
586
- "EOF",
587
- "ReadAll",
588
- "Discard",
589
- "WriteString",
590
- "LimitReader",
591
- "Copy",
592
- "CopyN",
593
- ]),
594
- ],
595
- [
596
- "time",
597
- new Set([
598
- "Now",
599
- "Since",
600
- "Parse",
601
- "ParseDuration",
602
- "Unix",
603
- "UnixMicro",
604
- "UnixMilli",
605
- "Date",
606
- "FixedZone",
607
- "Duration",
608
- "Nanosecond",
609
- "Microsecond",
610
- "Millisecond",
611
- "Second",
612
- "Minute",
613
- "Hour",
614
- "RFC3339",
615
- "RFC3339Nano",
616
- "DateOnly",
617
- "TimeOnly",
618
- "DateTime",
619
- "UTC",
620
- "Local",
621
- "January",
622
- "February",
623
- "March",
624
- "April",
625
- "May",
626
- "June",
627
- "July",
628
- "August",
629
- "September",
630
- "October",
631
- "November",
632
- "December",
633
- "Sunday",
634
- "Monday",
635
- "Tuesday",
636
- "Wednesday",
637
- "Thursday",
638
- "Friday",
639
- "Saturday",
640
- "Time",
641
- "Month",
642
- "Weekday",
643
- "Location",
644
- ]),
645
- ],
646
- ["testing", new Set(["T", "B", "M", "TB", "BenchmarkResult"])],
647
- ["sync", new Set(["Mutex", "RWMutex", "Once", "WaitGroup", "Locker"])],
648
- ["sha256", new Set(["Sum256", "New", "Size", "BlockSize"])],
649
- [
650
- "binary",
651
- new Set([
652
- "LittleEndian",
653
- "BigEndian",
654
- "ByteOrder",
655
- "Read",
656
- "Write",
657
- "Size",
658
- "AppendUint16",
659
- "AppendUint32",
660
- "AppendUint64",
661
- ]),
662
- ],
663
- [
664
- "hex",
665
- new Set([
666
- "EncodeToString",
667
- "DecodeString",
668
- "Encode",
669
- "Decode",
670
- "EncodedLen",
671
- "DecodedLen",
672
- "ErrLength",
673
- ]),
674
- ],
675
- [
676
- "base64",
677
- new Set([
678
- "StdEncoding",
679
- "URLEncoding",
680
- "RawStdEncoding",
681
- "RawURLEncoding",
682
- "Encoding",
683
- "NewEncoding",
684
- "StdPadding",
685
- "NoPadding",
686
- ]),
687
- ],
688
- ]);
118
+ export const WASM_STDLIB_MEMBERS = new Map();
689
119
 
690
120
  export const VALID_TARGETS = new Set(["js", "wasm", "both"]);
691
121
 
692
122
  // Backend-provided implementations for body-less Go-source stdlib functions
693
123
  // marked `//gofront:intrinsic <name>`: name -> required signature. New
694
124
  // intrinsics need a plan change.
695
- export const INTRINSICS = new Map([]);
125
+ export const INTRINSICS = new Map([
126
+ // A uniformly distributed float64 in [0, 1) from the host source
127
+ // (`Math.random`); the only entropy math/rand draws.
128
+ ["rand_source", "func() float64"],
129
+ // The host clock in nanoseconds since the Unix epoch, and the offset in
130
+ // seconds east of UTC of the host's time zone at a Unix time (time).
131
+ ["time_now", "func() int64"],
132
+ ["time_zone_offset", "func(int64) int"],
133
+ // time (js only): suspend for a number of nanoseconds; the declaration is
134
+ // `async`.
135
+ ["time_sleep", "func(int64) void"],
136
+ // os: write a string to a file descriptor (0 stdin, 1 stdout, 2 stderr),
137
+ // exit the process, and read and set environment variables.
138
+ ["os_write", "func(int, string) void"],
139
+ ["os_exit", "func(int) void"],
140
+ ["os_getenv", "func(string) string"],
141
+ ["os_setenv", "func(string, string) void"],
142
+ // unicode: the host's answer for runes above ASCII, by class (the
143
+ // constants of stdlib/unicode), and its case mappings.
144
+ ["unicode_is", "func(int32, int) bool"],
145
+ ["unicode_to_upper", "func(int32) int32"],
146
+ ["unicode_to_lower", "func(int32) int32"],
147
+ // crypto/rand: four random bytes from the host's secure source.
148
+ ["crypto_rand_u32", "func() uint32"],
149
+ // testing: a monotonic clock in nanoseconds, and an unanchored regular
150
+ // expression match for -run and -bench patterns.
151
+ ["testing_nanotime", "func() int64"],
152
+ ["testing_match", "func(string, string) bool"],
153
+ // testing (js only): call a test body and return what it returned (a
154
+ // promise for an async body, otherwise nil).
155
+ ["testing_call", "func(any, any) any"],
156
+ // fmt: a stable number for a pointer, function or other reference.
157
+ ["fmt_ptr_id", "func(any) uint64"],
158
+ // math: IEEE-754 bit casts, and the host's `Math.*` (`%` for Mod).
159
+ ["math_float64bits", "func(float64) uint64"],
160
+ ["math_float64frombits", "func(uint64) float64"],
161
+ ["math_float32bits", "func(float32) uint32"],
162
+ ["math_float32frombits", "func(uint32) float32"],
163
+ ...[
164
+ "sin",
165
+ "cos",
166
+ "tan",
167
+ "asin",
168
+ "acos",
169
+ "atan",
170
+ "sinh",
171
+ "cosh",
172
+ "tanh",
173
+ "exp",
174
+ "expm1",
175
+ "log",
176
+ "log1p",
177
+ "log2",
178
+ "log10",
179
+ "cbrt",
180
+ ].map((f) => [`math_${f}`, "func(float64) float64"]),
181
+ ...["atan2", "pow", "hypot", "mod"].map((f) => [
182
+ `math_${f}`,
183
+ "func(float64, float64) float64",
184
+ ]),
185
+ ]);
186
+
187
+ // The fmt functions whose calls the compiler wraps with a generated function
188
+ // (src/lower/fmt-formatters.js); a wrapped call may forward `f()`'s results.
189
+ export const FMT_PRINT_FUNCS = new Set([
190
+ "Sprint",
191
+ "Sprintln",
192
+ "Print",
193
+ "Println",
194
+ "Fprint",
195
+ "Fprintln",
196
+ "Append",
197
+ "Appendln",
198
+ "Sprintf",
199
+ "Printf",
200
+ "Errorf",
201
+ "Fprintf",
202
+ "Appendf",
203
+ ]);
204
+
205
+ // Names a standard-library function may carry in `//gofront:native <name>`:
206
+ // the function keeps its Go body, and a backend registry may replace calls to
207
+ // it with host code (or decline). A closed set; new names need a plan change.
208
+ export const NATIVES = new Set([
209
+ "slices.Contains",
210
+ "slices.Index",
211
+ "slices.Reverse",
212
+ "slices.Clone",
213
+ "bytes.Compare",
214
+ "bytes.Equal",
215
+ "bytes.IndexByte",
216
+ "slices.Sort",
217
+ "sort.Ints",
218
+ "sort.Strings",
219
+ "utf8.RuneCountInString",
220
+ "strings.Index",
221
+ "strings.LastIndex",
222
+ "strings.IndexByte",
223
+ "strings.LastIndexByte",
224
+ "strings.IndexRune",
225
+ "strings.IndexAny",
226
+ "strings.LastIndexAny",
227
+ "strings.Contains",
228
+ "strings.ContainsAny",
229
+ "strings.ContainsRune",
230
+ "strings.HasPrefix",
231
+ "strings.HasSuffix",
232
+ "strings.Count",
233
+ "strings.Repeat",
234
+ "strings.Join",
235
+ "strings.Replace",
236
+ "strings.ReplaceAll",
237
+ "strings.Split",
238
+ "strings.Fields",
239
+ "strings.ToUpper",
240
+ "strings.ToLower",
241
+ "strings.TrimSpace",
242
+ "strings.Trim",
243
+ "strings.TrimLeft",
244
+ "strings.TrimRight",
245
+ "strings.TrimPrefix",
246
+ "strings.TrimSuffix",
247
+ "strconv.shortest",
248
+ "strconv.fixed",
249
+ "strconv.parseDecimal",
250
+ // internal/jsonrt: the encoder's writes into its output buffer.
251
+ "jsonrt.putString",
252
+ "jsonrt.putInt",
253
+ "jsonrt.putUint",
254
+ "jsonrt.putFloat",
255
+ "jsonrt.putQuoted",
256
+ "jsonrt.readStr",
257
+ "jsonrt.readNum",
258
+ "jsonrt.CheckValid",
259
+ "jsonrt.LooksFloat32",
260
+ // math: the functions with a single host expression or instruction.
261
+ "math.IsNaN",
262
+ "math.IsInf",
263
+ "math.Inf",
264
+ "math.NaN",
265
+ "math.Signbit",
266
+ "math.Copysign",
267
+ "math.Abs",
268
+ "math.Max",
269
+ "math.Min",
270
+ "math.Trunc",
271
+ "math.Floor",
272
+ "math.Ceil",
273
+ "math.Round",
274
+ "math.Sqrt",
275
+ // math/bits: one host instruction per width (`Math.clz32`, WASM `clz`,
276
+ // `ctz` and `popcnt`).
277
+ ...["Len", "LeadingZeros", "TrailingZeros", "OnesCount"].flatMap((f) =>
278
+ ["", "8", "16", "32", "64"].map((w) => `bits.${f}${w}`),
279
+ ),
280
+ ]);
696
281
 
697
282
  // ── Static operator sets (module-level for reuse) ────────────
698
283
  export const CMP_OPS = new Set(["==", "!=", "<", ">", "<=", ">="]);
@@ -718,6 +303,9 @@ export const FLOAT64 = { kind: "basic", name: "float64" };
718
303
  export const STRING = { kind: "basic", name: "string" };
719
304
  export const BOOL = { kind: "basic", name: "bool" };
720
305
  export const ANY = { kind: "basic", name: "any" };
306
+ // `any` written in source. Untyped JS interop also yields plain ANY, which stays
307
+ // freely assignable; only a declared `any` needs a type assertion.
308
+ export const DECLARED_ANY = { kind: "basic", name: "any", _declared: true };
721
309
  export const TAINTED_ANY = { kind: "basic", name: "any", _tainted: true };
722
310
  export const VOID = { kind: "basic", name: "void" };
723
311
  export const NIL = { kind: "basic", name: "nil" };
@@ -735,6 +323,9 @@ export const UNTYPED_INT = { kind: "untyped", base: "int" };
735
323
  export const UNTYPED_FLOAT = { kind: "untyped", base: "float64" };
736
324
  export const UNTYPED_STRING = { kind: "untyped", base: "string" };
737
325
  export const UNTYPED_BOOL = { kind: "untyped", base: "bool" };
326
+ // An untyped rune constant is an untyped integer whose default type is
327
+ // `rune`; every `base === "int"` rule applies to it unchanged.
328
+ export const UNTYPED_RUNE = { kind: "untyped", base: "int", rune: true };
738
329
 
739
330
  // ── Complex types ────────────────────────────────────────────
740
331
  export const COMPLEX128 = { kind: "basic", name: "complex128" };
@@ -805,6 +396,33 @@ export const isFloat = makeBasicPredicate(...SIZED_FLOAT_NAMES);
805
396
  export const isString = makeBasicPredicate("string");
806
397
  export const isBool = makeBasicPredicate("bool");
807
398
 
399
+ // True when type t represents an int64 or uint64 (including named types like time.Duration).
400
+ export function is64BitInt(t) {
401
+ if (!t) return false;
402
+ if (t.kind === "untyped") return t.base === "int64" || t.base === "uint64";
403
+ let cur = t;
404
+ while (cur?.kind === "named") cur = cur.underlying;
405
+ return (
406
+ cur?.kind === "basic" && (cur.name === "int64" || cur.name === "uint64")
407
+ );
408
+ }
409
+
410
+ export function is64BitSigned(t) {
411
+ if (!t) return false;
412
+ if (t.kind === "untyped") return t.base === "int64";
413
+ let cur = t;
414
+ while (cur?.kind === "named") cur = cur.underlying;
415
+ return cur?.kind === "basic" && cur.name === "int64";
416
+ }
417
+
418
+ export function is64BitUnsigned(t) {
419
+ if (!t) return false;
420
+ if (t.kind === "untyped") return t.base === "uint64";
421
+ let cur = t;
422
+ while (cur?.kind === "named") cur = cur.underlying;
423
+ return cur?.kind === "basic" && cur.name === "uint64";
424
+ }
425
+
808
426
  // ── TypedArray mappings ──────────────────────────────────────
809
427
  // []float64 deliberately stays a plain Array for JSON / JS-library interop.
810
428
  const TYPED_ARRAY_CONSTRUCTORS = {
@@ -915,7 +533,7 @@ export function defaultType(t) {
915
533
  if (t?.kind !== "untyped") return t;
916
534
  switch (t.base) {
917
535
  case "int":
918
- return INT;
536
+ return t.rune ? RUNE : INT;
919
537
  case "float64":
920
538
  return FLOAT64;
921
539
  case "string":
@@ -936,7 +554,7 @@ export function typeStr(t) {
936
554
  case "basic":
937
555
  return t.name;
938
556
  case "untyped":
939
- return `untyped ${t.base}`;
557
+ return t.rune ? "untyped rune" : `untyped ${t.base}`;
940
558
  case "slice":
941
559
  return `[]${typeStr(t.elem)}`;
942
560
  case "shared":
@@ -979,9 +597,103 @@ export function typeStr(t) {
979
597
  }
980
598
  }
981
599
 
600
+ // The field an embedded type declares is named after the type as written, so
601
+ // an alias (`type A = Base; struct{ A }`) gives the field `A`.
602
+ // Per struct type, the methods promoted into its method set from embedded
603
+ // fields: name -> { depth, viaPtr, source, mType }. `depth` counts embeds
604
+ // from the struct, `viaPtr` is set when an embed on the path is a pointer
605
+ // and `source` is the method as declared. Kept outside the struct object so
606
+ // a copy of the struct (`type S Base`) does not share it.
607
+ export const promotedMethods = new WeakMap();
608
+
609
+ // Two embedded fields at the same, shallowest depth declare method `name`,
610
+ // so it is in neither method set of `struct` and selecting it is an error.
611
+ export function isAmbiguousPromotion(struct, name) {
612
+ return promotedMethods.get(struct)?.get(name)?.ambiguous === true;
613
+ }
614
+
615
+ // The ambiguous method names of `struct` (see isAmbiguousPromotion).
616
+ export function ambiguousPromotions(struct) {
617
+ const names = [];
618
+ for (const [name, p] of promotedMethods.get(struct) ?? [])
619
+ if (p.ambiguous) names.push(name);
620
+ return names;
621
+ }
622
+
623
+ export function embeddedFieldName(f) {
624
+ const ast = f.astType?.kind === "PointerType" ? f.astType.base : f.astType;
625
+ const t = f.type?.kind === "pointer" ? f.type.base : f.type;
626
+ return (ast?.name ?? t?.name ?? "")
627
+ .split(".")
628
+ .pop()
629
+ .replace(/\$\$.*$/, "");
630
+ }
631
+
632
+ // Whether `st` declares `name` itself: a field of that name or an embedded
633
+ // field named after its type.
634
+ function declaresField(st, name) {
635
+ return (st._structFields ?? []).some((f) =>
636
+ f.embedded ? embeddedFieldName(f) === name : f.names?.includes(name),
637
+ );
638
+ }
639
+
640
+ // The shallowest depth at which `struct` promotes a field `name` from its
641
+ // embedded types, and how many promotion paths reach it at that depth:
642
+ // { depth, count }, or null when no embedded type offers one.
643
+ function promotedFieldDepth(struct, name, path = new Set()) {
644
+ if (path.has(struct)) return null;
645
+ path.add(struct);
646
+ let best = null;
647
+ for (const e of struct._embeds ?? []) {
648
+ const inner = e?.kind === "pointer" ? e.base : e;
649
+ const st = inner?.kind === "named" ? inner.underlying : inner;
650
+ if (st?.kind !== "struct" || !st._structFields) continue;
651
+ const sub = declaresField(st, name)
652
+ ? { depth: 0, count: 1 }
653
+ : promotedFieldDepth(st, name, path);
654
+ if (!sub) continue;
655
+ const depth = 1 + sub.depth;
656
+ if (!best || depth < best.depth) best = { depth, count: sub.count };
657
+ else if (depth === best.depth) best.count += sub.count;
658
+ }
659
+ path.delete(struct);
660
+ return best;
661
+ }
662
+
663
+ // Whether selecting `name` on `struct`, whose flattened field map has it, is
664
+ // ambiguous: two promotion paths reach a field of that name at the same
665
+ // shallowest depth, or a field and a method promoted at that depth do. A
666
+ // field declared on the struct itself and a method declared on it always win.
667
+ export function isAmbiguousFieldSelector(struct, name) {
668
+ if (declaresField(struct, name)) return false;
669
+ const promoted = promotedMethods.get(struct)?.get(name);
670
+ if (struct.methods?.has(name) && promoted?.mType !== struct.methods.get(name))
671
+ return false;
672
+ const field = promotedFieldDepth(struct, name);
673
+ if (!field) return false;
674
+ if (!promoted || field.depth < promoted.depth) return field.count > 1;
675
+ return field.depth === promoted.depth || promoted.ambiguous === true;
676
+ }
677
+
678
+ // Whether selecting `name` on `struct`, whose flattened field map has it,
679
+ // reaches a method promoted at a shallower depth than the field (Go's depth
680
+ // rule): the method is selected and the deeper field is shadowed.
681
+ export function isMethodPromotedOverField(struct, name) {
682
+ if (declaresField(struct, name)) return false;
683
+ const promoted = promotedMethods.get(struct)?.get(name);
684
+ if (!promoted?.mType || promoted.ambiguous) return false;
685
+ if (struct.methods?.get(name) !== promoted.mType) return false;
686
+ const field = promotedFieldDepth(struct, name);
687
+ return field !== null && promoted.depth < field.depth;
688
+ }
689
+
690
+ // A function-local type shadowed by another type is renamed `Name__L<n>`.
691
+ export const LOCAL_TYPE_SUFFIX = /__L\d+/;
692
+
982
693
  // Go-source stdlib names are mangled to `Name$$path` (`List$$container$list`);
983
694
  // diagnostics show them qualified, as Go does (`list.List`).
984
695
  export function displayTypeName(name) {
696
+ if (typeof name === "string") name = name.replace(LOCAL_TYPE_SUFFIX, "");
985
697
  const i = typeof name === "string" ? name.indexOf("$$") : -1;
986
698
  if (i < 0) return name;
987
699
  return `${name