gofront 1.7.0 → 1.8.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 (128) hide show
  1. package/README.md +13 -13
  2. package/package.json +8 -37
  3. package/src/backend/js/expressions.js +1341 -148
  4. package/src/backend/js/fmt-runtime.js +573 -0
  5. package/src/backend/js/index.js +375 -57
  6. package/src/backend/js/runtime.js +1460 -133
  7. package/src/backend/js/statements.js +900 -86
  8. package/src/backend/js/stdlib/bits.js +87 -14
  9. package/src/backend/js/stdlib/builder.js +41 -6
  10. package/src/backend/js/stdlib/bytes.js +253 -7
  11. package/src/backend/js/stdlib/errors.js +2 -1
  12. package/src/backend/js/stdlib/fmt.js +349 -10
  13. package/src/backend/js/stdlib/index.js +8 -3
  14. package/src/backend/js/stdlib/json.js +247 -52
  15. package/src/backend/js/stdlib/maps.js +0 -8
  16. package/src/backend/js/stdlib/math.js +17 -1
  17. package/src/backend/js/stdlib/simd.js +10 -0
  18. package/src/backend/js/stdlib/slices.js +36 -6
  19. package/src/backend/js/stdlib/strconv.js +10 -5
  20. package/src/backend/js/stdlib/strings.js +83 -4
  21. package/src/backend/js/stdlib/testing.js +7 -0
  22. package/src/backend/js/stdlib/time.js +79 -55
  23. package/src/backend/js/stdlib/unicode.js +1 -1
  24. package/src/backend/js/stdlib/utf8.js +1 -1
  25. package/src/backend/js/templ.js +38 -76
  26. package/src/backend/js/type-info.js +272 -0
  27. package/src/backend/shared/fmt-types.js +188 -0
  28. package/src/backend/wasm/boundary.js +436 -80
  29. package/src/backend/wasm/emit-builtins.js +303 -13
  30. package/src/backend/wasm/emit-exprs.js +1397 -203
  31. package/src/backend/wasm/emit-maps.js +61 -13
  32. package/src/backend/wasm/emit-stmts.js +1359 -164
  33. package/src/backend/wasm/emit.js +512 -77
  34. package/src/backend/wasm/encode.js +43 -13
  35. package/src/backend/wasm/globals.js +452 -0
  36. package/src/backend/wasm/index.js +194 -2489
  37. package/src/backend/wasm/method-expr.js +381 -0
  38. package/src/backend/wasm/module-emitter.js +2240 -0
  39. package/src/backend/wasm/monomorph.js +62 -4
  40. package/src/backend/wasm/prescan.js +397 -0
  41. package/src/backend/wasm/stdlib/bytes.js +1804 -127
  42. package/src/backend/wasm/stdlib/core.js +1574 -199
  43. package/src/backend/wasm/stdlib/index.js +0 -5
  44. package/src/backend/wasm/stdlib/io.js +1567 -150
  45. package/src/backend/wasm/stdlib/packages.js +2 -0
  46. package/src/backend/wasm/stdlib/simd.js +293 -28
  47. package/src/backend/wasm/stdlib/time.js +1041 -12
  48. package/src/backend/wasm/types.js +200 -15
  49. package/src/backend/wasm/variadic.js +93 -0
  50. package/src/backend/wasm/wat.js +47 -20
  51. package/src/{cli-core.js → cli/cli-core.js} +236 -10
  52. package/src/{test-runner.js → cli/test-runner.js} +332 -39
  53. package/src/{vendor.js → cli/vendor.js} +3 -4
  54. package/src/compiler.js +107 -269
  55. package/src/index.js +15 -169
  56. package/src/{lexer.js → lexer/lexer.js} +102 -55
  57. package/src/{tokens.js → lexer/tokens.js} +1 -0
  58. package/src/link/sourcemap.js +97 -0
  59. package/src/link/stdlib.js +515 -0
  60. package/src/link/wasm.js +294 -0
  61. package/src/lower/bounds.js +394 -0
  62. package/src/lower/boxing.js +1 -1
  63. package/src/lower/captures.js +176 -32
  64. package/src/lower/index.js +26 -18
  65. package/src/lower/json-codecs.js +1398 -0
  66. package/src/lower/ownership.js +22 -1
  67. package/src/lower/range.js +86 -1
  68. package/src/lower/reachability.js +132 -0
  69. package/src/parser/declarations.js +58 -13
  70. package/src/parser/expressions.js +29 -7
  71. package/src/parser/index.js +2 -1
  72. package/src/parser/statements.js +37 -22
  73. package/src/{templ-parser.js → parser/templ.js} +138 -15
  74. package/src/parser/types.js +69 -9
  75. package/src/resolver.js +22 -1
  76. package/src/typechecker/assignability.js +176 -17
  77. package/src/typechecker/const-fold.js +356 -0
  78. package/src/typechecker/constants.js +256 -0
  79. package/src/typechecker/expressions.js +931 -122
  80. package/src/typechecker/index.js +459 -67
  81. package/src/typechecker/init-order.js +330 -0
  82. package/src/typechecker/resolve.js +451 -56
  83. package/src/typechecker/statements.js +90 -9
  84. package/src/typechecker/stdlib/core.js +333 -55
  85. package/src/typechecker/stdlib/excluded.js +898 -0
  86. package/src/typechecker/stdlib/extended.js +322 -26
  87. package/src/typechecker/{stdlib.js → stdlib/index.js} +5 -5
  88. package/src/typechecker/stdlib/simd.js +65 -15
  89. package/src/typechecker/termination.js +1 -1
  90. package/src/typechecker/types.js +149 -25
  91. package/stdlib/bytes/iter.go +192 -0
  92. package/stdlib/bytes/search.go +240 -0
  93. package/stdlib/bytes/split.go +218 -0
  94. package/stdlib/cmp/cmp.go +65 -0
  95. package/stdlib/encoding/json/errors.go +31 -0
  96. package/stdlib/encoding/json/indent.go +71 -0
  97. package/stdlib/encoding/json/number.go +12 -0
  98. package/stdlib/encoding/json/stream.go +173 -0
  99. package/stdlib/errors/overlay.go +12 -0
  100. package/stdlib/hash/hash.go +53 -0
  101. package/stdlib/internal/jsonrt/dec.go +738 -0
  102. package/stdlib/internal/jsonrt/enc.go +366 -0
  103. package/stdlib/internal/jsonrt/indent.go +135 -0
  104. package/stdlib/internal/jsonrt/number.go +27 -0
  105. package/stdlib/internal/jsonrt/reader.go +73 -0
  106. package/stdlib/internal/jsonrt/scanner.go +649 -0
  107. package/stdlib/io/io.go +346 -0
  108. package/stdlib/iter/iter.go +18 -0
  109. package/stdlib/maps/iter.go +65 -0
  110. package/stdlib/math/extra.go +270 -0
  111. package/stdlib/slices/extra.go +73 -0
  112. package/stdlib/slices/iter.go +113 -0
  113. package/stdlib/sort/sort.go +561 -0
  114. package/stdlib/strconv/quote.go +341 -0
  115. package/stdlib/strings/extra.go +35 -0
  116. package/stdlib/strings/iter.go +122 -0
  117. package/stdlib/sync/extra.go +105 -0
  118. package/stdlib/unicode/unicode.go +112 -0
  119. package/stdlib/unicode/utf8/bytes.go +239 -0
  120. package/src/backend/wasm/const-fold.js +0 -205
  121. package/src/backend/wasm/emit-stdlib.js +0 -13
  122. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  123. /package/src/{colors.js → cli/colors.js} +0 -0
  124. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  125. /package/src/{minifier.js → cli/minifier.js} +0 -0
  126. /package/src/{project-config.js → cli/project-config.js} +0 -0
  127. /package/src/{pwa.js → cli/pwa.js} +0 -0
  128. /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
@@ -0,0 +1,738 @@
1
+ // Copyright 2010 The Go Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ //go:build gofront
6
+
7
+ //gofront:target both
8
+
9
+ package jsonrt
10
+
11
+ import (
12
+ "encoding/base64"
13
+ "errors"
14
+ "fmt"
15
+ "math"
16
+ "strconv"
17
+ "strings"
18
+ "unicode/utf8"
19
+ )
20
+
21
+ // An UnmarshalTypeError describes a JSON value that was not appropriate for
22
+ // a value of a specific Go type.
23
+ type UnmarshalTypeError struct {
24
+ Value string // description of JSON value - "bool", "array", "number -5"
25
+ Type string // type of Go value it could not be assigned to
26
+ Offset int64 // error occurred after reading Offset bytes
27
+ Struct string // name of the struct type containing the field
28
+ Field string // the full path from the root struct to the value
29
+ }
30
+
31
+ func (e *UnmarshalTypeError) Error() string {
32
+ if e.Struct != "" || e.Field != "" {
33
+ return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type
34
+ }
35
+ return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type
36
+ }
37
+
38
+ // An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
39
+ type InvalidUnmarshalError struct {
40
+ Type string // "" for a nil argument
41
+ IsPtr bool
42
+ }
43
+
44
+ func (e *InvalidUnmarshalError) Error() string {
45
+ if e.Type == "" {
46
+ return "json: Unmarshal(nil)"
47
+ }
48
+ if !e.IsPtr {
49
+ return "json: Unmarshal(non-pointer " + e.Type + ")"
50
+ }
51
+ return "json: Unmarshal(nil " + e.Type + ")"
52
+ }
53
+
54
+ var (
55
+ OptEscapeHTML = true
56
+ OptUseNumber bool
57
+ OptDisallowUnknownFields bool
58
+ )
59
+
60
+ // Dec is the state of one Unmarshal call. The input has been checked to be
61
+ // valid JSON, so the readers below do not look for syntax errors.
62
+ type Dec struct {
63
+ data []byte
64
+ pos int
65
+ Err error
66
+ fatal bool
67
+ structs []string
68
+ fields []string
69
+ key string
70
+ UseNumber bool
71
+ DisallowUnknownFields bool
72
+ }
73
+
74
+ // NewDec checks that data is one valid JSON value and returns a decoder
75
+ // positioned at it.
76
+ func NewDec(data []byte) (*Dec, error) {
77
+ if err := CheckValid(data); err != nil {
78
+ return nil, err
79
+ }
80
+ return &Dec{
81
+ data: data,
82
+ UseNumber: OptUseNumber,
83
+ DisallowUnknownFields: OptDisallowUnknownFields,
84
+ }, nil
85
+ }
86
+
87
+ // UnknownField records an error when an unknown struct field is encountered with DisallowUnknownFields.
88
+ func (d *Dec) UnknownField(field string) {
89
+ d.Save(fmt.Errorf("json: unknown field %q", field))
90
+ d.Skip()
91
+ }
92
+
93
+ // InvalidUnmarshal is the error for a Unmarshal target v that is not a pointer
94
+ // to a type the compiler generated a decoder for.
95
+ func InvalidUnmarshal(v any) error {
96
+ if v == nil {
97
+ return &InvalidUnmarshalError{}
98
+ }
99
+ name := fmt.Sprintf("%T", v)
100
+ return &InvalidUnmarshalError{Type: name, IsPtr: strings.HasPrefix(name, "*")}
101
+ }
102
+
103
+ // Done returns the first error found while decoding, if any.
104
+ func (d *Dec) Done() error {
105
+ return d.Err
106
+ }
107
+
108
+ // Fatal records an error from an Unmarshaler; decoding stops at once.
109
+ func (d *Dec) Fatal(err error) {
110
+ d.Err = err
111
+ d.fatal = true
112
+ }
113
+
114
+ // Failed reports whether decoding was stopped by Fatal.
115
+ func (d *Dec) Failed() bool {
116
+ return d.fatal
117
+ }
118
+
119
+ // Enter and Leave track the struct field being decoded for error messages.
120
+ func (d *Dec) Enter(structName, field string) {
121
+ d.structs = append(d.structs, structName)
122
+ d.fields = append(d.fields, field)
123
+ }
124
+
125
+ func (d *Dec) Leave() {
126
+ n := len(d.fields) - 1
127
+ d.structs = d.structs[:n]
128
+ d.fields = d.fields[:n]
129
+ }
130
+
131
+ func (d *Dec) ws() {
132
+ for d.pos < len(d.data) {
133
+ c := d.data[d.pos]
134
+ if c == ' ' || c == '\t' || c == '\n' || c == '\r' {
135
+ d.pos++
136
+ } else {
137
+ return
138
+ }
139
+ }
140
+ }
141
+
142
+ func (d *Dec) peek() byte {
143
+ d.ws()
144
+ if d.pos >= len(d.data) {
145
+ return 0
146
+ }
147
+ return d.data[d.pos]
148
+ }
149
+
150
+ // kind names the JSON value at the current position.
151
+ func (d *Dec) kind() string {
152
+ switch d.peek() {
153
+ case '"':
154
+ return "string"
155
+ case '{':
156
+ return "object"
157
+ case '[':
158
+ return "array"
159
+ case 't', 'f':
160
+ return "bool"
161
+ case 'n':
162
+ return "null"
163
+ }
164
+ return "number"
165
+ }
166
+
167
+ func (d *Dec) typeErr(value, typ string) {
168
+ if d.Err != nil {
169
+ return
170
+ }
171
+ e := &UnmarshalTypeError{Value: value, Type: typ, Offset: int64(d.pos)}
172
+ if len(d.fields) > 0 {
173
+ e.Struct = d.structs[len(d.structs)-1]
174
+ e.Field = strings.Join(d.fields, ".")
175
+ }
176
+ d.Err = e
177
+ }
178
+
179
+ // Mismatch records a type error for the next value, which cannot be stored
180
+ // in a value of type typ, and skips it.
181
+ func (d *Dec) Mismatch(typ string) {
182
+ if d.fatal {
183
+ return
184
+ }
185
+ k := d.kind()
186
+ d.Skip()
187
+ d.typeErr(k, typ)
188
+ }
189
+
190
+ // IsArray reports whether the next value is an array.
191
+ func (d *Dec) IsArray() bool {
192
+ return d.peek() == '['
193
+ }
194
+
195
+ // Bytes decodes a base64 string into a byte slice. ok is false for null and
196
+ // for a value that is not a string (an error is recorded unless it is null).
197
+ func (d *Dec) Bytes(typ string) (v []byte, ok bool) {
198
+ s, ok := d.String(typ)
199
+ if !ok {
200
+ return nil, false
201
+ }
202
+ b, err := base64.StdEncoding.DecodeString(s)
203
+ if err != nil {
204
+ d.Save(err)
205
+ return nil, false
206
+ }
207
+ return b, true
208
+ }
209
+
210
+ // KeyInt parses the current object member name as an integer map key.
211
+ func (d *Dec) KeyInt(bits int, signed bool, typ string) (int64, bool) {
212
+ s := d.key
213
+ if signed {
214
+ n, err := strconv.ParseInt(s, 10, bits)
215
+ if err != nil {
216
+ d.typeErr("number "+s, typ)
217
+ return 0, false
218
+ }
219
+ return n, true
220
+ }
221
+ n, err := strconv.ParseUint(s, 10, bits)
222
+ if err != nil {
223
+ d.typeErr("number "+s, typ)
224
+ return 0, false
225
+ }
226
+ return int64(n), true
227
+ }
228
+
229
+ // Unquote reads the string value of a ,string field and returns a decoder
230
+ // for the JSON text inside it, which must be a literal of the given kind
231
+ // ("string", "bool" or "number"). It returns nil for null, and for a value
232
+ // that does not qualify, after recording Go's error.
233
+ func (d *Dec) Unquote(typ, kind string) *Dec {
234
+ if d.fatal || d.Null() {
235
+ return nil
236
+ }
237
+ if d.peek() != '"' {
238
+ d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into " + typ))
239
+ d.Skip()
240
+ return nil
241
+ }
242
+ s := d.readString()
243
+ b := []byte(s)
244
+ if s == "null" {
245
+ return nil
246
+ }
247
+ ok := len(b) > 0 && CheckValid(b) == nil
248
+ if ok {
249
+ c := b[0]
250
+ switch kind {
251
+ case "string":
252
+ ok = c == '"'
253
+ case "bool":
254
+ ok = c == 't' || c == 'f'
255
+ default:
256
+ ok = c == '-' || (c >= '0' && c <= '9')
257
+ }
258
+ }
259
+ if !ok {
260
+ d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal " + strconv.Quote(s) + " into " + typ))
261
+ return nil
262
+ }
263
+ return &Dec{data: b, structs: d.structs, fields: d.fields}
264
+ }
265
+
266
+ // Merge takes over the first error of a decoder made by Unquote.
267
+ func (d *Dec) Merge(sub *Dec) {
268
+ if d.Err == nil {
269
+ d.Err = sub.Err
270
+ }
271
+ }
272
+
273
+ // Save records a non-fatal error (the first one wins).
274
+ func (d *Dec) Save(err error) {
275
+ if d.Err == nil {
276
+ d.Err = err
277
+ }
278
+ }
279
+
280
+ // Null consumes a null and reports whether there was one.
281
+ func (d *Dec) Null() bool {
282
+ if d.fatal {
283
+ return true
284
+ }
285
+ if d.peek() == 'n' {
286
+ d.pos += 4
287
+ return true
288
+ }
289
+ return false
290
+ }
291
+
292
+ // IsNull reports whether the next value is null, without consuming it.
293
+ func (d *Dec) IsNull() bool {
294
+ return d.peek() == 'n'
295
+ }
296
+
297
+ // Skip consumes the next value.
298
+ func (d *Dec) Skip() {
299
+ switch d.peek() {
300
+ case '"':
301
+ d.skipString()
302
+ case '{', '[':
303
+ d.skipContainer()
304
+ default:
305
+ d.skipScalar()
306
+ }
307
+ }
308
+
309
+ func (d *Dec) skipContainer() {
310
+ depth := 0
311
+ for d.pos < len(d.data) {
312
+ c := d.data[d.pos]
313
+ if c == '"' {
314
+ d.skipString()
315
+ continue
316
+ }
317
+ d.pos++
318
+ if c == '{' || c == '[' {
319
+ depth++
320
+ } else if c == '}' || c == ']' {
321
+ depth--
322
+ if depth == 0 {
323
+ return
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ func (d *Dec) skipScalar() {
330
+ for d.pos < len(d.data) {
331
+ c := d.data[d.pos]
332
+ if c == ',' || c == ']' || c == '}' || c == ' ' || c == '\t' || c == '\n' || c == '\r' {
333
+ return
334
+ }
335
+ d.pos++
336
+ }
337
+ }
338
+
339
+ func (d *Dec) skipString() {
340
+ d.pos++ // opening quote
341
+ for d.pos < len(d.data) {
342
+ c := d.data[d.pos]
343
+ d.pos++
344
+ if c == '\\' {
345
+ d.pos++
346
+ } else if c == '"' {
347
+ return
348
+ }
349
+ }
350
+ }
351
+
352
+ // Raw consumes the next value and returns a copy of its bytes.
353
+ func (d *Dec) Raw() []byte {
354
+ d.ws()
355
+ start := d.pos
356
+ d.Skip()
357
+ out := make([]byte, d.pos-start)
358
+ copy(out, d.data[start:d.pos])
359
+ return out
360
+ }
361
+
362
+ // Offset is the number of input bytes consumed so far.
363
+ func (d *Dec) Offset() int {
364
+ return d.pos
365
+ }
366
+
367
+ func (d *Dec) readNumber() string {
368
+ start := d.pos
369
+ for d.pos < len(d.data) {
370
+ c := d.data[d.pos]
371
+ if c >= '0' && c <= '9' || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E' {
372
+ d.pos++
373
+ } else {
374
+ break
375
+ }
376
+ }
377
+ return string(d.data[start:d.pos])
378
+ }
379
+
380
+ // Number decodes a number or string as a Number. ok is false for null.
381
+ func (d *Dec) Number(typ string) (string, bool) {
382
+ if d.fatal || d.Null() {
383
+ return "", false
384
+ }
385
+ if d.peek() == '"' {
386
+ s, ok := d.String(typ)
387
+ if !ok {
388
+ return "", false
389
+ }
390
+ if !isValidNumber(s) {
391
+ d.Save(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", s))
392
+ return "", false
393
+ }
394
+ return s, true
395
+ }
396
+ if d.kind() == "number" {
397
+ return d.readNumber(), true
398
+ }
399
+ d.Mismatch(typ)
400
+ return "", false
401
+ }
402
+
403
+ // Bool decodes a bool. ok is false for null (leave the target alone) and for
404
+ // a value of another kind (a type error is recorded).
405
+ func (d *Dec) Bool(typ string) (v bool, ok bool) {
406
+ if d.fatal || d.Null() {
407
+ return false, false
408
+ }
409
+ c := d.peek()
410
+ if c == 't' {
411
+ d.pos += 4
412
+ return true, true
413
+ }
414
+ if c == 'f' {
415
+ d.pos += 5
416
+ return false, true
417
+ }
418
+ k := d.kind()
419
+ d.Skip()
420
+ d.typeErr(k, typ)
421
+ return false, false
422
+ }
423
+
424
+ // String decodes a string.
425
+ func (d *Dec) String(typ string) (v string, ok bool) {
426
+ if d.fatal || d.Null() {
427
+ return "", false
428
+ }
429
+ if d.peek() != '"' {
430
+ k := d.kind()
431
+ d.Skip()
432
+ d.typeErr(k, typ)
433
+ return "", false
434
+ }
435
+ return d.readString(), true
436
+ }
437
+
438
+ // Int decodes an integer that must fit in bits bits.
439
+ func (d *Dec) Int(bits int, typ string) (v int64, ok bool) {
440
+ if d.fatal || d.Null() {
441
+ return 0, false
442
+ }
443
+ if d.peek() == '"' || d.peek() == '{' || d.peek() == '[' || d.peek() == 't' || d.peek() == 'f' {
444
+ k := d.kind()
445
+ d.Skip()
446
+ d.typeErr(k, typ)
447
+ return 0, false
448
+ }
449
+ s := d.readNumber()
450
+ n, err := strconv.ParseInt(s, 10, bits)
451
+ if err != nil {
452
+ d.typeErr("number "+s, typ)
453
+ return 0, false
454
+ }
455
+ return n, true
456
+ }
457
+
458
+ // Uint decodes an unsigned integer that must fit in bits bits.
459
+ func (d *Dec) Uint(bits int, typ string) (v uint64, ok bool) {
460
+ if d.fatal || d.Null() {
461
+ return 0, false
462
+ }
463
+ if d.peek() == '"' || d.peek() == '{' || d.peek() == '[' || d.peek() == 't' || d.peek() == 'f' {
464
+ k := d.kind()
465
+ d.Skip()
466
+ d.typeErr(k, typ)
467
+ return 0, false
468
+ }
469
+ s := d.readNumber()
470
+ n, err := strconv.ParseUint(s, 10, bits)
471
+ if err != nil {
472
+ d.typeErr("number "+s, typ)
473
+ return 0, false
474
+ }
475
+ return n, true
476
+ }
477
+
478
+ // Float decodes a floating-point number of the given size.
479
+ func (d *Dec) Float(bits int, typ string) (v float64, ok bool) {
480
+ if d.fatal || d.Null() {
481
+ return 0, false
482
+ }
483
+ if d.peek() == '"' || d.peek() == '{' || d.peek() == '[' || d.peek() == 't' || d.peek() == 'f' {
484
+ k := d.kind()
485
+ d.Skip()
486
+ d.typeErr(k, typ)
487
+ return 0, false
488
+ }
489
+ s := d.readNumber()
490
+ n, err := strconv.ParseFloat(s, bits)
491
+ if bits == 32 {
492
+ // Round to float32 here: the number may be out of float32 range.
493
+ n = float64(float32(n))
494
+ }
495
+ if err != nil || math.IsInf(n, 0) {
496
+ d.typeErr("number "+s, typ)
497
+ return 0, false
498
+ }
499
+ return n, true
500
+ }
501
+
502
+ // ObjBegin consumes the opening brace of an object. When the value is not an
503
+ // object it records a type error, skips the value and returns false.
504
+ func (d *Dec) ObjBegin(typ string) bool {
505
+ if d.fatal {
506
+ return false
507
+ }
508
+ if d.peek() != '{' {
509
+ k := d.kind()
510
+ d.Skip()
511
+ d.typeErr(k, typ)
512
+ return false
513
+ }
514
+ d.pos++
515
+ return true
516
+ }
517
+
518
+ // NextKey moves to the next member of an object; false at the closing brace.
519
+ // The member name is then available from Key.
520
+ func (d *Dec) NextKey() bool {
521
+ if d.fatal {
522
+ return false
523
+ }
524
+ c := d.peek()
525
+ if c == '}' {
526
+ d.pos++
527
+ return false
528
+ }
529
+ if c == ',' {
530
+ d.pos++
531
+ }
532
+ d.ws()
533
+ d.key = d.readString()
534
+ d.ws()
535
+ d.pos++ // the colon
536
+ return true
537
+ }
538
+
539
+ // Key is the name of the member NextKey moved to.
540
+ func (d *Dec) Key() string {
541
+ return d.key
542
+ }
543
+
544
+ // ArrBegin consumes the opening bracket of an array.
545
+ func (d *Dec) ArrBegin(typ string) bool {
546
+ if d.fatal {
547
+ return false
548
+ }
549
+ if d.peek() != '[' {
550
+ k := d.kind()
551
+ d.Skip()
552
+ d.typeErr(k, typ)
553
+ return false
554
+ }
555
+ d.pos++
556
+ return true
557
+ }
558
+
559
+ // NextElem moves to the next element of an array; false at the closing bracket.
560
+ func (d *Dec) NextElem() bool {
561
+ if d.fatal {
562
+ return false
563
+ }
564
+ c := d.peek()
565
+ if c == ']' {
566
+ d.pos++
567
+ return false
568
+ }
569
+ if c == ',' {
570
+ d.pos++
571
+ }
572
+ return true
573
+ }
574
+
575
+ // EqualFold reports whether two member names match ignoring case.
576
+ func EqualFold(a, b string) bool {
577
+ return strings.EqualFold(a, b)
578
+ }
579
+
580
+ // readString consumes the string at the current position.
581
+ func (d *Dec) readString() string {
582
+ d.pos++ // opening quote
583
+ start := d.pos
584
+ plain := true
585
+ for d.pos < len(d.data) {
586
+ c := d.data[d.pos]
587
+ if c == '"' {
588
+ break
589
+ }
590
+ if c == '\\' {
591
+ plain = false
592
+ d.pos++
593
+ } else if c >= utf8.RuneSelf {
594
+ plain = false
595
+ }
596
+ d.pos++
597
+ }
598
+ raw := d.data[start:d.pos]
599
+ d.pos++ // closing quote
600
+ if plain {
601
+ return string(raw)
602
+ }
603
+ return unquote(raw)
604
+ }
605
+
606
+ func getu4(s []byte, i int) rune {
607
+ if i+4 > len(s) {
608
+ return -1
609
+ }
610
+ var r rune
611
+ for j := i; j < i+4; j++ {
612
+ c := s[j]
613
+ switch {
614
+ case '0' <= c && c <= '9':
615
+ c = c - '0'
616
+ case 'a' <= c && c <= 'f':
617
+ c = c - 'a' + 10
618
+ case 'A' <= c && c <= 'F':
619
+ c = c - 'A' + 10
620
+ default:
621
+ return -1
622
+ }
623
+ r = r*16 + rune(c)
624
+ }
625
+ return r
626
+ }
627
+
628
+ // unquoteU decodes the \\u escape whose 'u' is at s[r], with a following
629
+ // \\u surrogate half when there is one. It returns the rune and the index of
630
+ // the first byte after the escape.
631
+ func unquoteU(s []byte, r int) (rune, int) {
632
+ rr := getu4(s, r+1)
633
+ r += 5
634
+ if rr >= 0xD800 && rr < 0xDC00 {
635
+ if r+1 < len(s) && s[r] == '\\' && s[r+1] == 'u' {
636
+ rr1 := getu4(s, r+2)
637
+ if rr1 >= 0xDC00 && rr1 < 0xE000 {
638
+ return 0x10000 + (rr-0xD800)<<10 + (rr1 - 0xDC00), r + 6
639
+ }
640
+ }
641
+ return utf8.RuneError, r
642
+ }
643
+ if rr >= 0xDC00 && rr < 0xE000 {
644
+ return utf8.RuneError, r
645
+ }
646
+ return rr, r
647
+ }
648
+
649
+ // unquote decodes the escapes of a JSON string body and coerces it to
650
+ // well-formed UTF-8.
651
+ func unquote(s []byte) string {
652
+ out := make([]byte, 0, len(s))
653
+ r := 0
654
+ for r < len(s) {
655
+ c := s[r]
656
+ if c == '\\' {
657
+ r++
658
+ switch s[r] {
659
+ case 'b':
660
+ out = append(out, '\b')
661
+ r++
662
+ case 'f':
663
+ out = append(out, '\f')
664
+ r++
665
+ case 'n':
666
+ out = append(out, '\n')
667
+ r++
668
+ case 'r':
669
+ out = append(out, '\r')
670
+ r++
671
+ case 't':
672
+ out = append(out, '\t')
673
+ r++
674
+ case 'u':
675
+ var rr rune
676
+ rr, r = unquoteU(s, r)
677
+ out = utf8.AppendRune(out, rr)
678
+ default:
679
+ out = append(out, s[r])
680
+ r++
681
+ }
682
+ } else if c < utf8.RuneSelf {
683
+ out = append(out, c)
684
+ r++
685
+ } else {
686
+ rr, size := utf8.DecodeRune(s[r:])
687
+ r += size
688
+ out = utf8.AppendRune(out, rr)
689
+ }
690
+ }
691
+ return string(out)
692
+ }
693
+
694
+ // Any decodes the next value into the empty interface: map[string]any,
695
+ // []any, float64, string, bool or nil.
696
+ func (d *Dec) Any() any {
697
+ if d.fatal {
698
+ return nil
699
+ }
700
+ switch d.peek() {
701
+ case '{':
702
+ d.pos++
703
+ m := make(map[string]any)
704
+ for d.NextKey() {
705
+ k := d.key
706
+ m[k] = d.Any()
707
+ }
708
+ return m
709
+ case '[':
710
+ d.pos++
711
+ a := make([]any, 0)
712
+ for d.NextElem() {
713
+ a = append(a, d.Any())
714
+ }
715
+ return a
716
+ case '"':
717
+ return d.readString()
718
+ case 't':
719
+ d.pos += 4
720
+ return true
721
+ case 'f':
722
+ d.pos += 5
723
+ return false
724
+ case 'n':
725
+ d.pos += 4
726
+ return nil
727
+ }
728
+ s := d.readNumber()
729
+ if d.UseNumber {
730
+ return Number(s)
731
+ }
732
+ f, err := strconv.ParseFloat(s, 64)
733
+ if err != nil {
734
+ d.typeErr("number "+s, "float64")
735
+ return nil
736
+ }
737
+ return f
738
+ }