gofront 1.7.0 → 1.9.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 (194) hide show
  1. package/README.md +14 -14
  2. package/package.json +10 -38
  3. package/src/backend/js/expressions.js +2060 -389
  4. package/src/backend/js/index.js +586 -174
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +936 -1644
  7. package/src/backend/js/statements.js +1349 -132
  8. package/src/backend/js/stdlib/index.js +51 -94
  9. package/src/backend/js/templ.js +67 -118
  10. package/src/backend/js/type-info.js +436 -0
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +80 -0
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +753 -872
  15. package/src/backend/wasm/emit-builtins.js +914 -237
  16. package/src/backend/wasm/emit-exprs.js +1456 -195
  17. package/src/backend/wasm/emit-maps.js +78 -380
  18. package/src/backend/wasm/emit-stmts.js +1659 -214
  19. package/src/backend/wasm/emit.js +614 -88
  20. package/src/backend/wasm/encode.js +43 -13
  21. package/src/backend/wasm/globals.js +491 -0
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +406 -3195
  24. package/src/backend/wasm/method-expr.js +392 -0
  25. package/src/backend/wasm/module-emitter.js +1615 -0
  26. package/src/backend/wasm/monomorph.js +164 -9
  27. package/src/backend/wasm/natives.js +596 -0
  28. package/src/backend/wasm/prescan.js +249 -0
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -37
  31. package/src/backend/wasm/stdlib/simd.js +293 -28
  32. package/src/backend/wasm/types.js +260 -27
  33. package/src/backend/wasm/variadic.js +93 -0
  34. package/src/backend/wasm/wat.js +47 -20
  35. package/src/{cli-core.js → cli/cli-core.js} +241 -11
  36. package/src/{test-runner.js → cli/test-runner.js} +188 -122
  37. package/src/{vendor.js → cli/vendor.js} +3 -4
  38. package/src/compiler.js +202 -386
  39. package/src/index.js +15 -169
  40. package/src/{lexer.js → lexer/lexer.js} +203 -62
  41. package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
  42. package/src/{tokens.js → lexer/tokens.js} +2 -0
  43. package/src/link/sourcemap.js +97 -0
  44. package/src/link/stdlib.js +737 -0
  45. package/src/link/type-names.js +148 -0
  46. package/src/link/wasm.js +318 -0
  47. package/src/lower/bounds.js +547 -0
  48. package/src/lower/boxing.js +1 -1
  49. package/src/lower/captures.js +267 -64
  50. package/src/lower/embedding.js +32 -3
  51. package/src/lower/errors-as.js +196 -0
  52. package/src/lower/fmt-formatters.js +905 -0
  53. package/src/lower/functions.js +2 -0
  54. package/src/lower/gen-types.js +274 -0
  55. package/src/lower/index.js +33 -19
  56. package/src/lower/json-codecs.js +1379 -0
  57. package/src/lower/ownership.js +47 -8
  58. package/src/lower/range.js +86 -1
  59. package/src/lower/reachability.js +150 -0
  60. package/src/lower/walk.js +12 -0
  61. package/src/parser/declarations.js +83 -15
  62. package/src/parser/expressions.js +110 -18
  63. package/src/parser/index.js +2 -1
  64. package/src/parser/statements.js +38 -22
  65. package/src/{templ-parser.js → parser/templ.js} +179 -17
  66. package/src/parser/types.js +70 -9
  67. package/src/resolver.js +21 -1
  68. package/src/typechecker/assignability.js +291 -19
  69. package/src/typechecker/const-fold.js +399 -0
  70. package/src/typechecker/constants.js +282 -0
  71. package/src/typechecker/expressions.js +1220 -183
  72. package/src/typechecker/index.js +659 -92
  73. package/src/typechecker/init-order.js +426 -0
  74. package/src/typechecker/operand-text.js +40 -0
  75. package/src/typechecker/resolve.js +613 -62
  76. package/src/typechecker/statements.js +212 -20
  77. package/src/typechecker/stdlib/excluded.js +902 -0
  78. package/src/typechecker/stdlib/index.js +38 -0
  79. package/src/typechecker/stdlib/simd.js +65 -15
  80. package/src/typechecker/termination.js +11 -2
  81. package/src/typechecker/types.js +268 -514
  82. package/stdlib/bytes/buffer.go +479 -0
  83. package/stdlib/bytes/bytes.go +1010 -0
  84. package/stdlib/bytes/reader.go +161 -0
  85. package/stdlib/cmp/cmp.go +65 -0
  86. package/stdlib/context/context.go +115 -0
  87. package/stdlib/crypto/rand/rand.go +34 -0
  88. package/stdlib/crypto/sha256/sha256.go +249 -0
  89. package/stdlib/encoding/base64/base64.go +331 -0
  90. package/stdlib/encoding/binary/binary.go +332 -0
  91. package/stdlib/encoding/hex/hex.go +140 -0
  92. package/stdlib/encoding/json/errors.go +31 -0
  93. package/stdlib/encoding/json/indent.go +71 -0
  94. package/stdlib/encoding/json/json.go +62 -0
  95. package/stdlib/encoding/json/number.go +12 -0
  96. package/stdlib/encoding/json/stream.go +173 -0
  97. package/stdlib/errors/errors.go +174 -0
  98. package/stdlib/fmt/errors.go +110 -0
  99. package/stdlib/fmt/format.go +732 -0
  100. package/stdlib/fmt/print.go +1232 -0
  101. package/stdlib/gom/gom.go +293 -0
  102. package/stdlib/hash/hash.go +53 -0
  103. package/stdlib/html/html.go +251 -0
  104. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  105. package/stdlib/internal/jsonrt/dec.go +871 -0
  106. package/stdlib/internal/jsonrt/enc.go +516 -0
  107. package/stdlib/internal/jsonrt/indent.go +135 -0
  108. package/stdlib/internal/jsonrt/number.go +27 -0
  109. package/stdlib/internal/jsonrt/reader.go +73 -0
  110. package/stdlib/internal/jsonrt/scanner.go +658 -0
  111. package/stdlib/io/io.go +502 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/maps.go +131 -0
  114. package/stdlib/math/bits/bits.go +507 -0
  115. package/stdlib/math/extra.go +272 -0
  116. package/stdlib/math/math.go +439 -0
  117. package/stdlib/math/rand/rand.go +297 -0
  118. package/stdlib/os/os.go +93 -0
  119. package/stdlib/path/filepath/filepath.go +47 -0
  120. package/stdlib/path/path.go +394 -0
  121. package/stdlib/regexp/regexp.go +231 -0
  122. package/stdlib/slices/slices.go +526 -0
  123. package/stdlib/slices/sort.go +209 -0
  124. package/stdlib/slices/zsort_cmp.go +480 -0
  125. package/stdlib/slices/zsort_ordered.go +482 -0
  126. package/stdlib/sort/sort.go +500 -0
  127. package/stdlib/sort/zsort_func.go +480 -0
  128. package/stdlib/sort/zsort_iface.go +480 -0
  129. package/stdlib/strconv/float.go +1699 -0
  130. package/stdlib/strconv/isprint.go +752 -0
  131. package/stdlib/strconv/quote.go +526 -0
  132. package/stdlib/strconv/strconv.go +616 -0
  133. package/stdlib/strings/builder.go +95 -0
  134. package/stdlib/strings/reader.go +163 -0
  135. package/stdlib/strings/replacer.go +102 -0
  136. package/stdlib/strings/strings.go +807 -0
  137. package/stdlib/sync/sync.go +268 -0
  138. package/stdlib/testing/async_js.go +61 -0
  139. package/stdlib/testing/benchmark.go +297 -0
  140. package/stdlib/testing/testing.go +523 -0
  141. package/stdlib/time/duration.go +233 -0
  142. package/stdlib/time/format.go +745 -0
  143. package/stdlib/time/parse.go +790 -0
  144. package/stdlib/time/sleep_js.go +63 -0
  145. package/stdlib/time/time.go +834 -0
  146. package/stdlib/unicode/unicode.go +250 -0
  147. package/stdlib/unicode/utf8/utf8.go +464 -0
  148. package/src/backend/js/stdlib/base64.js +0 -12
  149. package/src/backend/js/stdlib/binary.js +0 -102
  150. package/src/backend/js/stdlib/bits.js +0 -46
  151. package/src/backend/js/stdlib/builder.js +0 -63
  152. package/src/backend/js/stdlib/bytes.js +0 -122
  153. package/src/backend/js/stdlib/errors.js +0 -44
  154. package/src/backend/js/stdlib/fmt.js +0 -178
  155. package/src/backend/js/stdlib/gom.js +0 -155
  156. package/src/backend/js/stdlib/hex.js +0 -17
  157. package/src/backend/js/stdlib/html.js +0 -20
  158. package/src/backend/js/stdlib/io.js +0 -137
  159. package/src/backend/js/stdlib/json.js +0 -972
  160. package/src/backend/js/stdlib/maps.js +0 -45
  161. package/src/backend/js/stdlib/math.js +0 -69
  162. package/src/backend/js/stdlib/os.js +0 -13
  163. package/src/backend/js/stdlib/path.js +0 -48
  164. package/src/backend/js/stdlib/rand.js +0 -32
  165. package/src/backend/js/stdlib/regexp.js +0 -54
  166. package/src/backend/js/stdlib/sha256.js +0 -12
  167. package/src/backend/js/stdlib/shared.js +0 -17
  168. package/src/backend/js/stdlib/simd.js +0 -24
  169. package/src/backend/js/stdlib/slices.js +0 -77
  170. package/src/backend/js/stdlib/sort.js +0 -30
  171. package/src/backend/js/stdlib/strconv.js +0 -74
  172. package/src/backend/js/stdlib/strings.js +0 -222
  173. package/src/backend/js/stdlib/sync.js +0 -13
  174. package/src/backend/js/stdlib/testing.js +0 -34
  175. package/src/backend/js/stdlib/time.js +0 -128
  176. package/src/backend/js/stdlib/unicode.js +0 -25
  177. package/src/backend/js/stdlib/utf8.js +0 -26
  178. package/src/backend/wasm/const-fold.js +0 -205
  179. package/src/backend/wasm/emit-stdlib.js +0 -13
  180. package/src/backend/wasm/stdlib/bytes.js +0 -5039
  181. package/src/backend/wasm/stdlib/core.js +0 -8903
  182. package/src/backend/wasm/stdlib/io.js +0 -2161
  183. package/src/backend/wasm/stdlib/packages.js +0 -2400
  184. package/src/backend/wasm/stdlib/pure.js +0 -720
  185. package/src/backend/wasm/stdlib/time.js +0 -1200
  186. package/src/typechecker/stdlib/core.js +0 -801
  187. package/src/typechecker/stdlib/extended.js +0 -914
  188. package/src/typechecker/stdlib.js +0 -22
  189. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  190. /package/src/{colors.js → cli/colors.js} +0 -0
  191. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  192. /package/src/{minifier.js → cli/minifier.js} +0 -0
  193. /package/src/{project-config.js → cli/project-config.js} +0 -0
  194. /package/src/{pwa.js → cli/pwa.js} +0 -0
@@ -0,0 +1,871 @@
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
+ // Dec is the state of one Unmarshal call. The input has been checked to be
55
+ // valid JSON, so the readers below do not look for syntax errors.
56
+ type Dec struct {
57
+ data []byte
58
+ pos int
59
+ Err error
60
+ fatal bool
61
+ structs []string // stack of struct names, depth entries live
62
+ fields []string // stack of field names, depth entries live
63
+ depth int
64
+ key string
65
+ UseNumber bool
66
+ DisallowUnknownFields bool
67
+ }
68
+
69
+ // NewDec checks that data is one valid JSON value and returns a decoder
70
+ // positioned at it.
71
+ func NewDec(data []byte) (*Dec, error) {
72
+ if err := CheckValid(data); err != nil {
73
+ return nil, err
74
+ }
75
+ return &Dec{data: data}, nil
76
+ }
77
+
78
+ // UnknownField records an error when an unknown struct field is encountered with DisallowUnknownFields.
79
+ func (d *Dec) UnknownField(field string) {
80
+ d.Save(fmt.Errorf("json: unknown field %q", field))
81
+ d.Skip()
82
+ }
83
+
84
+ // InvalidUnmarshal is the error for a Unmarshal target v that is not a pointer
85
+ // to a type the compiler generated a decoder for.
86
+ func InvalidUnmarshal(v any) error {
87
+ if v == nil {
88
+ return &InvalidUnmarshalError{}
89
+ }
90
+ name := fmt.Sprintf("%T", v)
91
+ return &InvalidUnmarshalError{Type: name, IsPtr: strings.HasPrefix(name, "*")}
92
+ }
93
+
94
+ // Done returns the first error found while decoding, if any.
95
+ func (d *Dec) Done() error {
96
+ return d.Err
97
+ }
98
+
99
+ // Fatal records an error from an Unmarshaler; decoding stops at once.
100
+ func (d *Dec) Fatal(err error) {
101
+ d.Err = err
102
+ d.fatal = true
103
+ }
104
+
105
+ // Failed reports whether decoding was stopped by Fatal.
106
+ func (d *Dec) Failed() bool {
107
+ return d.fatal
108
+ }
109
+
110
+ // Enter and Leave track the struct field being decoded for error messages.
111
+ // The stacks keep their entries and move an index, so no slice is resliced
112
+ // or copied per struct.
113
+ func (d *Dec) Enter(structName, field string) {
114
+ if d.depth < len(d.fields) {
115
+ d.structs[d.depth] = structName
116
+ d.fields[d.depth] = field
117
+ } else {
118
+ d.structs = append(d.structs, structName)
119
+ d.fields = append(d.fields, field)
120
+ }
121
+ d.depth++
122
+ }
123
+
124
+ func (d *Dec) Leave() {
125
+ d.depth--
126
+ }
127
+
128
+ func (d *Dec) ws() {
129
+ for d.pos < len(d.data) {
130
+ c := d.data[d.pos]
131
+ if c == ' ' || c == '\t' || c == '\n' || c == '\r' {
132
+ d.pos++
133
+ } else {
134
+ return
135
+ }
136
+ }
137
+ }
138
+
139
+ func (d *Dec) peek() byte {
140
+ d.ws()
141
+ if d.pos >= len(d.data) {
142
+ return 0
143
+ }
144
+ return d.data[d.pos]
145
+ }
146
+
147
+ // kind names the JSON value at the current position.
148
+ func (d *Dec) kind() string {
149
+ switch d.peek() {
150
+ case '"':
151
+ return "string"
152
+ case '{':
153
+ return "object"
154
+ case '[':
155
+ return "array"
156
+ case 't', 'f':
157
+ return "bool"
158
+ case 'n':
159
+ return "null"
160
+ }
161
+ return "number"
162
+ }
163
+
164
+ func (d *Dec) typeErr(value, typ string) {
165
+ if d.Err != nil {
166
+ return
167
+ }
168
+ e := &UnmarshalTypeError{Value: value, Type: typ, Offset: int64(d.pos)}
169
+ if d.depth > 0 {
170
+ e.Struct = d.structs[d.depth-1]
171
+ e.Field = strings.Join(d.fields[:d.depth], ".")
172
+ }
173
+ d.Err = e
174
+ }
175
+
176
+ // Mismatch records a type error for the next value, which cannot be stored
177
+ // in a value of type typ, and skips it.
178
+ func (d *Dec) Mismatch(typ string) {
179
+ if d.fatal {
180
+ return
181
+ }
182
+ k := d.kind()
183
+ d.Skip()
184
+ d.typeErr(k, typ)
185
+ }
186
+
187
+ // IsArray reports whether the next value is an array.
188
+ func (d *Dec) IsArray() bool {
189
+ return d.peek() == '['
190
+ }
191
+
192
+ // Bytes decodes a base64 string into a byte slice. ok is false for null and
193
+ // for a value that is not a string (an error is recorded unless it is null).
194
+ func (d *Dec) Bytes(typ string) (v []byte, ok bool) {
195
+ s, ok := d.String(typ)
196
+ if !ok {
197
+ return nil, false
198
+ }
199
+ b, err := base64.StdEncoding.DecodeString(s)
200
+ if err != nil {
201
+ d.Save(err)
202
+ return nil, false
203
+ }
204
+ return b, true
205
+ }
206
+
207
+ // KeyInt parses the current object member name as an integer map key.
208
+ func (d *Dec) KeyInt(bits int, signed bool, typ string) (int64, bool) {
209
+ s := d.key
210
+ if signed {
211
+ n, err := strconv.ParseInt(s, 10, bits)
212
+ if err != nil {
213
+ d.typeErr("number "+s, typ)
214
+ return 0, false
215
+ }
216
+ return n, true
217
+ }
218
+ n, err := strconv.ParseUint(s, 10, bits)
219
+ if err != nil {
220
+ d.typeErr("number "+s, typ)
221
+ return 0, false
222
+ }
223
+ return int64(n), true
224
+ }
225
+
226
+ // Unquote reads the string value of a ,string field and returns a decoder
227
+ // for the JSON text inside it, which must be a literal of the given kind
228
+ // ("string", "bool" or "number"). It returns nil for null, and for a value
229
+ // that does not qualify, after recording Go's error.
230
+ func (d *Dec) Unquote(typ, kind string) *Dec {
231
+ if d.fatal || d.Null() {
232
+ return nil
233
+ }
234
+ if d.peek() != '"' {
235
+ d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into " + typ))
236
+ d.Skip()
237
+ return nil
238
+ }
239
+ s := readStr(d)
240
+ b := []byte(s)
241
+ if s == "null" {
242
+ return nil
243
+ }
244
+ ok := len(b) > 0 && CheckValid(b) == nil
245
+ // A number that starts like one but is not valid fails like any other
246
+ // malformed number.
247
+ if !ok && kind == "number" && len(b) > 0 && (b[0] == '-' || (b[0] >= '0' && b[0] <= '9')) {
248
+ d.typeErr("number "+s, typ)
249
+ return nil
250
+ }
251
+ if ok {
252
+ c := b[0]
253
+ switch kind {
254
+ case "string":
255
+ ok = c == '"'
256
+ case "bool":
257
+ ok = c == 't' || c == 'f'
258
+ default:
259
+ ok = c == '-' || (c >= '0' && c <= '9')
260
+ }
261
+ }
262
+ if !ok {
263
+ d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal " + strconv.Quote(s) + " into " + typ))
264
+ return nil
265
+ }
266
+ return &Dec{data: b, structs: d.structs, fields: d.fields, depth: d.depth}
267
+ }
268
+
269
+ // Merge takes over the first error of a decoder made by Unquote.
270
+ func (d *Dec) Merge(sub *Dec) {
271
+ if d.Err == nil {
272
+ d.Err = sub.Err
273
+ }
274
+ }
275
+
276
+ // Save records a non-fatal error (the first one wins).
277
+ func (d *Dec) Save(err error) {
278
+ if d.Err == nil {
279
+ d.Err = err
280
+ }
281
+ }
282
+
283
+ // Null consumes a null and reports whether there was one.
284
+ func (d *Dec) Null() bool {
285
+ if d.fatal {
286
+ return true
287
+ }
288
+ if d.peek() == 'n' {
289
+ d.pos += 4
290
+ return true
291
+ }
292
+ return false
293
+ }
294
+
295
+ // IsNull reports whether the next value is null, without consuming it.
296
+ func (d *Dec) IsNull() bool {
297
+ return d.peek() == 'n'
298
+ }
299
+
300
+ // Skip consumes the next value.
301
+ func (d *Dec) Skip() {
302
+ switch d.peek() {
303
+ case '"':
304
+ d.skipString()
305
+ case '{', '[':
306
+ d.skipContainer()
307
+ default:
308
+ d.skipScalar()
309
+ }
310
+ }
311
+
312
+ func (d *Dec) skipContainer() {
313
+ depth := 0
314
+ for d.pos < len(d.data) {
315
+ c := d.data[d.pos]
316
+ if c == '"' {
317
+ d.skipString()
318
+ continue
319
+ }
320
+ d.pos++
321
+ if c == '{' || c == '[' {
322
+ depth++
323
+ } else if c == '}' || c == ']' {
324
+ depth--
325
+ if depth == 0 {
326
+ return
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ func (d *Dec) skipScalar() {
333
+ for d.pos < len(d.data) {
334
+ c := d.data[d.pos]
335
+ if c == ',' || c == ']' || c == '}' || c == ' ' || c == '\t' || c == '\n' || c == '\r' {
336
+ return
337
+ }
338
+ d.pos++
339
+ }
340
+ }
341
+
342
+ func (d *Dec) skipString() {
343
+ d.pos++ // opening quote
344
+ for d.pos < len(d.data) {
345
+ c := d.data[d.pos]
346
+ d.pos++
347
+ if c == '\\' {
348
+ d.pos++
349
+ } else if c == '"' {
350
+ return
351
+ }
352
+ }
353
+ }
354
+
355
+ // Raw consumes the next value and returns a copy of its bytes.
356
+ func (d *Dec) Raw() []byte {
357
+ d.ws()
358
+ start := d.pos
359
+ d.Skip()
360
+ out := make([]byte, d.pos-start)
361
+ copy(out, d.data[start:d.pos])
362
+ return out
363
+ }
364
+
365
+ // Offset is the number of input bytes consumed so far.
366
+ func (d *Dec) Offset() int {
367
+ return d.pos
368
+ }
369
+
370
+ // readNum consumes the number literal at the current position.
371
+ //
372
+ //gofront:native jsonrt.readNum
373
+ func readNum(d *Dec) string {
374
+ start := d.pos
375
+ for d.pos < len(d.data) {
376
+ c := d.data[d.pos]
377
+ if c >= '0' && c <= '9' || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E' {
378
+ d.pos++
379
+ } else {
380
+ break
381
+ }
382
+ }
383
+ return string(d.data[start:d.pos])
384
+ }
385
+
386
+ // Number decodes a number or string as a Number. ok is false for null.
387
+ func (d *Dec) Number(typ string) (string, bool) {
388
+ if d.fatal || d.Null() {
389
+ return "", false
390
+ }
391
+ if d.peek() == '"' {
392
+ start := d.pos
393
+ s, ok := d.String(typ)
394
+ if !ok {
395
+ return "", false
396
+ }
397
+ if !isValidNumber(s) {
398
+ // Go quotes the whole JSON literal and stops decoding.
399
+ d.Fatal(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", string(d.data[start:d.pos])))
400
+ return "", false
401
+ }
402
+ return s, true
403
+ }
404
+ if d.kind() == "number" {
405
+ return readNum(d), true
406
+ }
407
+ d.Mismatch(typ)
408
+ return "", false
409
+ }
410
+
411
+ // Bool decodes a bool. ok is false for null (leave the target alone) and for
412
+ // a value of another kind (a type error is recorded).
413
+ func (d *Dec) Bool(typ string) (v bool, ok bool) {
414
+ if d.fatal || d.Null() {
415
+ return false, false
416
+ }
417
+ c := d.peek()
418
+ if c == 't' {
419
+ d.pos += 4
420
+ return true, true
421
+ }
422
+ if c == 'f' {
423
+ d.pos += 5
424
+ return false, true
425
+ }
426
+ k := d.kind()
427
+ d.Skip()
428
+ d.typeErr(k, typ)
429
+ return false, false
430
+ }
431
+
432
+ // String decodes a string.
433
+ func (d *Dec) String(typ string) (v string, ok bool) {
434
+ if d.fatal || d.Null() {
435
+ return "", false
436
+ }
437
+ if d.peek() != '"' {
438
+ k := d.kind()
439
+ d.Skip()
440
+ d.typeErr(k, typ)
441
+ return "", false
442
+ }
443
+ return readStr(d), true
444
+ }
445
+
446
+ // plainInt consumes a decimal integer of at most 15 digits, with no fraction
447
+ // or exponent, that fits in bits bits (and is not negative unless signed), and
448
+ // returns it. It leaves the input alone and reports false for anything else,
449
+ // which the caller then parses and reports from its text. The value stays in
450
+ // an int, which is a plain number in JavaScript.
451
+ func (d *Dec) plainInt(bits int, signed bool) (int, bool) {
452
+ data := d.data
453
+ end := len(data)
454
+ i := d.pos
455
+ neg := false
456
+ if i < end && data[i] == '-' {
457
+ if !signed {
458
+ return 0, false
459
+ }
460
+ neg = true
461
+ i++
462
+ }
463
+ start := i
464
+ v := 0
465
+ for i < end {
466
+ c := data[i]
467
+ if c < '0' || c > '9' {
468
+ break
469
+ }
470
+ if i-start == 15 {
471
+ return 0, false
472
+ }
473
+ v = v*10 + int(c-'0')
474
+ i++
475
+ }
476
+ if i == start {
477
+ return 0, false
478
+ }
479
+ if i < end {
480
+ if c := data[i]; c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-' {
481
+ return 0, false
482
+ }
483
+ }
484
+ if neg {
485
+ v = -v
486
+ }
487
+ if bits < 53 {
488
+ lim := 1 << (bits - 1)
489
+ if !signed {
490
+ lim = 1 << bits
491
+ if v >= lim {
492
+ return 0, false
493
+ }
494
+ } else if v >= lim || v < -lim {
495
+ return 0, false
496
+ }
497
+ }
498
+ d.pos = i
499
+ return v, true
500
+ }
501
+
502
+ var pow10 = [...]float64{1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15}
503
+
504
+ // plainFloat consumes a decimal number of at most 15 digits with no exponent.
505
+ // Such a number is a mantissa that a float64 holds exactly divided by a power
506
+ // of ten that it holds exactly, so one division rounds it correctly. It
507
+ // leaves the input alone and reports false for anything else.
508
+ func (d *Dec) plainFloat() (float64, bool) {
509
+ data := d.data
510
+ end := len(data)
511
+ i := d.pos
512
+ neg := false
513
+ if i < end && data[i] == '-' {
514
+ neg = true
515
+ i++
516
+ }
517
+ start := i
518
+ digits := 0
519
+ frac := 0
520
+ v := 0
521
+ seenDot := false
522
+ for i < end {
523
+ c := data[i]
524
+ if c == '.' && !seenDot {
525
+ seenDot = true
526
+ i++
527
+ continue
528
+ }
529
+ if c < '0' || c > '9' {
530
+ break
531
+ }
532
+ if digits == 15 {
533
+ return 0, false
534
+ }
535
+ v = v*10 + int(c-'0')
536
+ digits++
537
+ if seenDot {
538
+ frac++
539
+ }
540
+ i++
541
+ }
542
+ if digits == 0 || i-start == 0 {
543
+ return 0, false
544
+ }
545
+ if i < end {
546
+ if c := data[i]; c == 'e' || c == 'E' || c == '+' || c == '-' {
547
+ return 0, false
548
+ }
549
+ }
550
+ f := float64(v) / pow10[frac]
551
+ if neg {
552
+ f = -f
553
+ }
554
+ d.pos = i
555
+ return f, true
556
+ }
557
+
558
+ // Int decodes an integer that must fit in bits bits.
559
+ func (d *Dec) Int(bits int, typ string) (v int64, ok bool) {
560
+ if d.fatal || d.Null() {
561
+ return 0, false
562
+ }
563
+ if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
564
+ k := d.kind()
565
+ d.Skip()
566
+ d.typeErr(k, typ)
567
+ return 0, false
568
+ }
569
+ if n, ok := d.plainInt(bits, true); ok {
570
+ return int64(n), true
571
+ }
572
+ s := readNum(d)
573
+ n, err := strconv.ParseInt(s, 10, bits)
574
+ if err != nil {
575
+ d.typeErr("number "+s, typ)
576
+ return 0, false
577
+ }
578
+ return n, true
579
+ }
580
+
581
+ // Uint decodes an unsigned integer that must fit in bits bits.
582
+ func (d *Dec) Uint(bits int, typ string) (v uint64, ok bool) {
583
+ if d.fatal || d.Null() {
584
+ return 0, false
585
+ }
586
+ if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
587
+ k := d.kind()
588
+ d.Skip()
589
+ d.typeErr(k, typ)
590
+ return 0, false
591
+ }
592
+ if n, ok := d.plainInt(bits, false); ok {
593
+ return uint64(n), true
594
+ }
595
+ s := readNum(d)
596
+ n, err := strconv.ParseUint(s, 10, bits)
597
+ if err != nil {
598
+ d.typeErr("number "+s, typ)
599
+ return 0, false
600
+ }
601
+ return n, true
602
+ }
603
+
604
+ // Float decodes a floating-point number of the given size.
605
+ func (d *Dec) Float(bits int, typ string) (v float64, ok bool) {
606
+ if d.fatal || d.Null() {
607
+ return 0, false
608
+ }
609
+ if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
610
+ k := d.kind()
611
+ d.Skip()
612
+ d.typeErr(k, typ)
613
+ return 0, false
614
+ }
615
+ if bits == 64 {
616
+ if f, ok := d.plainFloat(); ok {
617
+ return f, true
618
+ }
619
+ }
620
+ s := readNum(d)
621
+ n, err := strconv.ParseFloat(s, bits)
622
+ if bits == 32 {
623
+ // Round to float32 here: the number may be out of float32 range.
624
+ n = float64(float32(n))
625
+ }
626
+ if err != nil || math.IsInf(n, 0) {
627
+ d.typeErr("number "+s, typ)
628
+ return 0, false
629
+ }
630
+ return n, true
631
+ }
632
+
633
+ // ObjBegin consumes the opening brace of an object. When the value is not an
634
+ // object it records a type error, skips the value and returns false.
635
+ func (d *Dec) ObjBegin(typ string) bool {
636
+ if d.fatal {
637
+ return false
638
+ }
639
+ if d.peek() != '{' {
640
+ k := d.kind()
641
+ d.Skip()
642
+ d.typeErr(k, typ)
643
+ return false
644
+ }
645
+ d.pos++
646
+ return true
647
+ }
648
+
649
+ // NextKey moves to the next member of an object; false at the closing brace.
650
+ // The member name is then available from Key.
651
+ func (d *Dec) NextKey() bool {
652
+ if d.fatal {
653
+ return false
654
+ }
655
+ c := d.peek()
656
+ if c == '}' {
657
+ d.pos++
658
+ return false
659
+ }
660
+ if c == ',' {
661
+ d.pos++
662
+ }
663
+ d.ws()
664
+ d.key = readStr(d)
665
+ d.ws()
666
+ d.pos++ // the colon
667
+ return true
668
+ }
669
+
670
+ // Key is the name of the member NextKey moved to.
671
+ func (d *Dec) Key() string {
672
+ return d.key
673
+ }
674
+
675
+ // ArrBegin consumes the opening bracket of an array.
676
+ func (d *Dec) ArrBegin(typ string) bool {
677
+ if d.fatal {
678
+ return false
679
+ }
680
+ if d.peek() != '[' {
681
+ k := d.kind()
682
+ d.Skip()
683
+ d.typeErr(k, typ)
684
+ return false
685
+ }
686
+ d.pos++
687
+ return true
688
+ }
689
+
690
+ // NextElem moves to the next element of an array; false at the closing bracket.
691
+ func (d *Dec) NextElem() bool {
692
+ if d.fatal {
693
+ return false
694
+ }
695
+ c := d.peek()
696
+ if c == ']' {
697
+ d.pos++
698
+ return false
699
+ }
700
+ if c == ',' {
701
+ d.pos++
702
+ }
703
+ return true
704
+ }
705
+
706
+ // EqualFold reports whether two member names match ignoring case.
707
+ func EqualFold(a, b string) bool {
708
+ return strings.EqualFold(a, b)
709
+ }
710
+
711
+ // readStr consumes the string at the current position.
712
+ //
713
+ //gofront:native jsonrt.readStr
714
+ func readStr(d *Dec) string {
715
+ d.pos++ // opening quote
716
+ start := d.pos
717
+ plain := true
718
+ for d.pos < len(d.data) {
719
+ c := d.data[d.pos]
720
+ if c == '"' {
721
+ break
722
+ }
723
+ if c == '\\' {
724
+ plain = false
725
+ d.pos++
726
+ } else if c >= utf8.RuneSelf {
727
+ plain = false
728
+ }
729
+ d.pos++
730
+ }
731
+ raw := d.data[start:d.pos]
732
+ d.pos++ // closing quote
733
+ if plain {
734
+ return string(raw)
735
+ }
736
+ return unquote(raw)
737
+ }
738
+
739
+ func getu4(s []byte, i int) rune {
740
+ if i+4 > len(s) {
741
+ return -1
742
+ }
743
+ var r rune
744
+ for j := i; j < i+4; j++ {
745
+ c := s[j]
746
+ switch {
747
+ case '0' <= c && c <= '9':
748
+ c = c - '0'
749
+ case 'a' <= c && c <= 'f':
750
+ c = c - 'a' + 10
751
+ case 'A' <= c && c <= 'F':
752
+ c = c - 'A' + 10
753
+ default:
754
+ return -1
755
+ }
756
+ r = r*16 + rune(c)
757
+ }
758
+ return r
759
+ }
760
+
761
+ // unquoteU decodes the \\u escape whose 'u' is at s[r], with a following
762
+ // \\u surrogate half when there is one. It returns the rune and the index of
763
+ // the first byte after the escape.
764
+ func unquoteU(s []byte, r int) (rune, int) {
765
+ rr := getu4(s, r+1)
766
+ r += 5
767
+ if rr >= 0xD800 && rr < 0xDC00 {
768
+ if r+1 < len(s) && s[r] == '\\' && s[r+1] == 'u' {
769
+ rr1 := getu4(s, r+2)
770
+ if rr1 >= 0xDC00 && rr1 < 0xE000 {
771
+ return 0x10000 + (rr-0xD800)<<10 + (rr1 - 0xDC00), r + 6
772
+ }
773
+ }
774
+ return utf8.RuneError, r
775
+ }
776
+ if rr >= 0xDC00 && rr < 0xE000 {
777
+ return utf8.RuneError, r
778
+ }
779
+ return rr, r
780
+ }
781
+
782
+ // unquote decodes the escapes of a JSON string body and coerces it to
783
+ // well-formed UTF-8.
784
+ func unquote(s []byte) string {
785
+ out := make([]byte, 0, len(s))
786
+ r := 0
787
+ for r < len(s) {
788
+ c := s[r]
789
+ if c == '\\' {
790
+ r++
791
+ switch s[r] {
792
+ case 'b':
793
+ out = append(out, '\b')
794
+ r++
795
+ case 'f':
796
+ out = append(out, '\f')
797
+ r++
798
+ case 'n':
799
+ out = append(out, '\n')
800
+ r++
801
+ case 'r':
802
+ out = append(out, '\r')
803
+ r++
804
+ case 't':
805
+ out = append(out, '\t')
806
+ r++
807
+ case 'u':
808
+ var rr rune
809
+ rr, r = unquoteU(s, r)
810
+ out = utf8.AppendRune(out, rr)
811
+ default:
812
+ out = append(out, s[r])
813
+ r++
814
+ }
815
+ } else if c < utf8.RuneSelf {
816
+ out = append(out, c)
817
+ r++
818
+ } else {
819
+ rr, size := utf8.DecodeRune(s[r:])
820
+ r += size
821
+ out = utf8.AppendRune(out, rr)
822
+ }
823
+ }
824
+ return string(out)
825
+ }
826
+
827
+ // Any decodes the next value into the empty interface: map[string]any,
828
+ // []any, float64, string, bool or nil.
829
+ func (d *Dec) Any() any {
830
+ if d.fatal {
831
+ return nil
832
+ }
833
+ switch d.peek() {
834
+ case '{':
835
+ d.pos++
836
+ m := make(map[string]any)
837
+ for d.NextKey() {
838
+ k := d.key
839
+ m[k] = d.Any()
840
+ }
841
+ return m
842
+ case '[':
843
+ d.pos++
844
+ a := make([]any, 0)
845
+ for d.NextElem() {
846
+ a = append(a, d.Any())
847
+ }
848
+ return a
849
+ case '"':
850
+ return readStr(d)
851
+ case 't':
852
+ d.pos += 4
853
+ return true
854
+ case 'f':
855
+ d.pos += 5
856
+ return false
857
+ case 'n':
858
+ d.pos += 4
859
+ return nil
860
+ }
861
+ s := readNum(d)
862
+ if d.UseNumber {
863
+ return Number(s)
864
+ }
865
+ f, err := strconv.ParseFloat(s, 64)
866
+ if err != nil {
867
+ d.typeErr("number "+s, "float64")
868
+ return nil
869
+ }
870
+ return f
871
+ }