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,649 @@
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 is the runtime behind encoding/json in wasm packages: the
10
+ // JSON scanner (adapted from the Go standard library), the encoder state and
11
+ // the decoder state that the per-type codecs generated by the compiler call.
12
+ package jsonrt
13
+
14
+ import (
15
+ "io"
16
+ "strconv"
17
+ )
18
+
19
+ // Valid reports whether data is a valid JSON encoding.
20
+ func Valid(data []byte) bool {
21
+ scan := newScanner()
22
+ return checkValid(data, scan) == nil
23
+ }
24
+
25
+ // checkValid verifies that data is valid JSON-encoded data.
26
+ // scan is passed in for use by checkValid to avoid an allocation.
27
+ // checkValid returns nil or a SyntaxError.
28
+ func checkValid(data []byte, scan *scanner) error {
29
+ scan.reset()
30
+ for _, c := range data {
31
+ scan.bytes++
32
+ if scan.step(scan, c) == scanError {
33
+ return scan.err
34
+ }
35
+ }
36
+ if scan.eof() == scanError {
37
+ return scan.err
38
+ }
39
+ return nil
40
+ }
41
+
42
+ // A SyntaxError is a description of a JSON syntax error.
43
+ // [Unmarshal] will return a SyntaxError if the JSON can't be parsed.
44
+ type SyntaxError struct {
45
+ msg string // description of error
46
+ Offset int64 // error occurred after reading Offset bytes
47
+ }
48
+
49
+ func (e *SyntaxError) Error() string { return e.msg }
50
+
51
+ // A scanner is a JSON scanning state machine.
52
+ // Callers call scan.reset and then pass bytes in one at a time
53
+ // by calling scan.step(&scan, c) for each byte.
54
+ // The return value, referred to as an opcode, tells the
55
+ // caller about significant parsing events like beginning
56
+ // and ending literals, objects, and arrays, so that the
57
+ // caller can follow along if it wishes.
58
+ // The return value scanEnd indicates that a single top-level
59
+ // JSON value has been completed, *before* the byte that
60
+ // just got passed in. (The indication must be delayed in order
61
+ // to recognize the end of numbers: is 123 a whole value or
62
+ // the beginning of 12345e+6?).
63
+ type scanner struct {
64
+ // The step is a func to be called to execute the next transition.
65
+ // Also tried using an integer constant and a single func
66
+ // with a switch, but using the func directly was 10% faster
67
+ // on a 64-bit Mac Mini, and it's nicer to read.
68
+ step func(*scanner, byte) int
69
+
70
+ // Reached end of top-level value.
71
+ endTop bool
72
+
73
+ // Stack of what we're in the middle of - array values, object keys, object values.
74
+ parseState []int
75
+
76
+ // Error that happened, if any.
77
+ err error
78
+
79
+ // total bytes consumed, updated by decoder.Decode (and deliberately
80
+ // not set to zero by scan.reset)
81
+ bytes int64
82
+ }
83
+
84
+ func newScanner() *scanner {
85
+ scan := &scanner{}
86
+ scan.reset()
87
+ return scan
88
+ }
89
+
90
+ // These values are returned by the state transition functions
91
+ // assigned to scanner.state and the method scanner.eof.
92
+ // They give details about the current state of the scan that
93
+ // callers might be interested to know about.
94
+ // It is okay to ignore the return value of any particular
95
+ // call to scanner.state: if one call returns scanError,
96
+ // every subsequent call will return scanError too.
97
+ const (
98
+ // Continue.
99
+ scanContinue = iota // uninteresting byte
100
+ scanBeginLiteral // end implied by next result != scanContinue
101
+ scanBeginObject // begin object
102
+ scanObjectKey // just finished object key (string)
103
+ scanObjectValue // just finished non-last object value
104
+ scanEndObject // end object (implies scanObjectValue if possible)
105
+ scanBeginArray // begin array
106
+ scanArrayValue // just finished array value
107
+ scanEndArray // end array (implies scanArrayValue if possible)
108
+ scanSkipSpace // space byte; can skip; known to be last "continue" result
109
+
110
+ // Stop.
111
+ scanEnd // top-level value ended *before* this byte; known to be first "stop" result
112
+ scanError // hit an error, scanner.err.
113
+ )
114
+
115
+ // These values are stored in the parseState stack.
116
+ // They give the current state of a composite value
117
+ // being scanned. If the parser is inside a nested value
118
+ // the parseState describes the nested state, outermost at entry 0.
119
+ const (
120
+ parseObjectKey = iota // parsing object key (before colon)
121
+ parseObjectValue // parsing object value (after colon)
122
+ parseArrayValue // parsing array value
123
+ )
124
+
125
+ // This limits the max nesting depth to prevent stack overflow.
126
+ // This is permitted by https://tools.ietf.org/html/rfc7159#section-9
127
+ const maxNestingDepth = 10000
128
+
129
+ // reset prepares the scanner for use.
130
+ // It must be called before calling s.step.
131
+ func (s *scanner) reset() {
132
+ s.step = stateBeginValue
133
+ s.parseState = s.parseState[0:0]
134
+ s.err = nil
135
+ s.endTop = false
136
+ }
137
+
138
+ // eof tells the scanner that the end of input has been reached.
139
+ // It returns a scan status just as s.step does.
140
+ func (s *scanner) eof() int {
141
+ if s.err != nil {
142
+ return scanError
143
+ }
144
+ if s.endTop {
145
+ return scanEnd
146
+ }
147
+ s.step(s, ' ')
148
+ if s.endTop {
149
+ return scanEnd
150
+ }
151
+ if s.err == nil {
152
+ s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
153
+ }
154
+ return scanError
155
+ }
156
+
157
+ // pushParseState pushes a new parse state newParseState onto the parse stack.
158
+ // an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned.
159
+ func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
160
+ s.parseState = append(s.parseState, newParseState)
161
+ if len(s.parseState) <= maxNestingDepth {
162
+ return successState
163
+ }
164
+ return s.error(c, "exceeded max depth")
165
+ }
166
+
167
+ // popParseState pops a parse state (already obtained) off the stack
168
+ // and updates s.step accordingly.
169
+ func (s *scanner) popParseState() {
170
+ n := len(s.parseState) - 1
171
+ s.parseState = s.parseState[0:n]
172
+ if n == 0 {
173
+ s.step = stateEndTop
174
+ s.endTop = true
175
+ } else {
176
+ s.step = stateEndValue
177
+ }
178
+ }
179
+
180
+ func isSpace(c byte) bool {
181
+ return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
182
+ }
183
+
184
+ // stateBeginValueOrEmpty is the state after reading `[`.
185
+ func stateBeginValueOrEmpty(s *scanner, c byte) int {
186
+ if isSpace(c) {
187
+ return scanSkipSpace
188
+ }
189
+ if c == ']' {
190
+ return stateEndValue(s, c)
191
+ }
192
+ return stateBeginValue(s, c)
193
+ }
194
+
195
+ // stateBeginValue is the state at the beginning of the input.
196
+ func stateBeginValue(s *scanner, c byte) int {
197
+ if isSpace(c) {
198
+ return scanSkipSpace
199
+ }
200
+ switch c {
201
+ case '{':
202
+ s.step = stateBeginStringOrEmpty
203
+ return s.pushParseState(c, parseObjectKey, scanBeginObject)
204
+ case '[':
205
+ s.step = stateBeginValueOrEmpty
206
+ return s.pushParseState(c, parseArrayValue, scanBeginArray)
207
+ case '"':
208
+ s.step = stateInString
209
+ return scanBeginLiteral
210
+ case '-':
211
+ s.step = stateNeg
212
+ return scanBeginLiteral
213
+ case '0': // beginning of 0.123
214
+ s.step = state0
215
+ return scanBeginLiteral
216
+ case 't': // beginning of true
217
+ s.step = stateT
218
+ return scanBeginLiteral
219
+ case 'f': // beginning of false
220
+ s.step = stateF
221
+ return scanBeginLiteral
222
+ case 'n': // beginning of null
223
+ s.step = stateN
224
+ return scanBeginLiteral
225
+ }
226
+ if '1' <= c && c <= '9' { // beginning of 1234.5
227
+ s.step = state1
228
+ return scanBeginLiteral
229
+ }
230
+ return s.error(c, "looking for beginning of value")
231
+ }
232
+
233
+ // stateBeginStringOrEmpty is the state after reading `{`.
234
+ func stateBeginStringOrEmpty(s *scanner, c byte) int {
235
+ if isSpace(c) {
236
+ return scanSkipSpace
237
+ }
238
+ if c == '}' {
239
+ n := len(s.parseState)
240
+ s.parseState[n-1] = parseObjectValue
241
+ return stateEndValue(s, c)
242
+ }
243
+ return stateBeginString(s, c)
244
+ }
245
+
246
+ // stateBeginString is the state after reading `{"key": value,`.
247
+ func stateBeginString(s *scanner, c byte) int {
248
+ if isSpace(c) {
249
+ return scanSkipSpace
250
+ }
251
+ if c == '"' {
252
+ s.step = stateInString
253
+ return scanBeginLiteral
254
+ }
255
+ return s.error(c, "looking for beginning of object key string")
256
+ }
257
+
258
+ // stateEndValue is the state after completing a value,
259
+ // such as after reading `{}` or `true` or `["x"`.
260
+ func stateEndValue(s *scanner, c byte) int {
261
+ n := len(s.parseState)
262
+ if n == 0 {
263
+ // Completed top-level before the current byte.
264
+ s.step = stateEndTop
265
+ s.endTop = true
266
+ return stateEndTop(s, c)
267
+ }
268
+ if isSpace(c) {
269
+ s.step = stateEndValue
270
+ return scanSkipSpace
271
+ }
272
+ ps := s.parseState[n-1]
273
+ switch ps {
274
+ case parseObjectKey:
275
+ if c == ':' {
276
+ s.parseState[n-1] = parseObjectValue
277
+ s.step = stateBeginValue
278
+ return scanObjectKey
279
+ }
280
+ return s.error(c, "after object key")
281
+ case parseObjectValue:
282
+ if c == ',' {
283
+ s.parseState[n-1] = parseObjectKey
284
+ s.step = stateBeginString
285
+ return scanObjectValue
286
+ }
287
+ if c == '}' {
288
+ s.popParseState()
289
+ return scanEndObject
290
+ }
291
+ return s.error(c, "after object key:value pair")
292
+ case parseArrayValue:
293
+ if c == ',' {
294
+ s.step = stateBeginValue
295
+ return scanArrayValue
296
+ }
297
+ if c == ']' {
298
+ s.popParseState()
299
+ return scanEndArray
300
+ }
301
+ return s.error(c, "after array element")
302
+ }
303
+ return s.error(c, "")
304
+ }
305
+
306
+ // stateEndTop is the state after finishing the top-level value,
307
+ // such as after reading `{}` or `[1,2,3]`.
308
+ // Only space characters should be seen now.
309
+ func stateEndTop(s *scanner, c byte) int {
310
+ if !isSpace(c) {
311
+ // Complain about non-space byte on next call.
312
+ s.error(c, "after top-level value")
313
+ }
314
+ return scanEnd
315
+ }
316
+
317
+ // stateInString is the state after reading `"`.
318
+ func stateInString(s *scanner, c byte) int {
319
+ if c == '"' {
320
+ s.step = stateEndValue
321
+ return scanContinue
322
+ }
323
+ if c == '\\' {
324
+ s.step = stateInStringEsc
325
+ return scanContinue
326
+ }
327
+ if c < 0x20 {
328
+ return s.error(c, "in string literal")
329
+ }
330
+ return scanContinue
331
+ }
332
+
333
+ // stateInStringEsc is the state after reading `"\` during a quoted string.
334
+ func stateInStringEsc(s *scanner, c byte) int {
335
+ switch c {
336
+ case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
337
+ s.step = stateInString
338
+ return scanContinue
339
+ case 'u':
340
+ s.step = stateInStringEscU
341
+ return scanContinue
342
+ }
343
+ return s.error(c, "in string escape code")
344
+ }
345
+
346
+ // stateInStringEscU is the state after reading `"\u` during a quoted string.
347
+ func stateInStringEscU(s *scanner, c byte) int {
348
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
349
+ s.step = stateInStringEscU1
350
+ return scanContinue
351
+ }
352
+ // numbers
353
+ return s.error(c, "in \\u hexadecimal character escape")
354
+ }
355
+
356
+ // stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
357
+ func stateInStringEscU1(s *scanner, c byte) int {
358
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
359
+ s.step = stateInStringEscU12
360
+ return scanContinue
361
+ }
362
+ // numbers
363
+ return s.error(c, "in \\u hexadecimal character escape")
364
+ }
365
+
366
+ // stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
367
+ func stateInStringEscU12(s *scanner, c byte) int {
368
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
369
+ s.step = stateInStringEscU123
370
+ return scanContinue
371
+ }
372
+ // numbers
373
+ return s.error(c, "in \\u hexadecimal character escape")
374
+ }
375
+
376
+ // stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
377
+ func stateInStringEscU123(s *scanner, c byte) int {
378
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
379
+ s.step = stateInString
380
+ return scanContinue
381
+ }
382
+ // numbers
383
+ return s.error(c, "in \\u hexadecimal character escape")
384
+ }
385
+
386
+ // stateNeg is the state after reading `-` during a number.
387
+ func stateNeg(s *scanner, c byte) int {
388
+ if c == '0' {
389
+ s.step = state0
390
+ return scanContinue
391
+ }
392
+ if '1' <= c && c <= '9' {
393
+ s.step = state1
394
+ return scanContinue
395
+ }
396
+ return s.error(c, "in numeric literal")
397
+ }
398
+
399
+ // state1 is the state after reading a non-zero integer during a number,
400
+ // such as after reading `1` or `100` but not `0`.
401
+ func state1(s *scanner, c byte) int {
402
+ if '0' <= c && c <= '9' {
403
+ s.step = state1
404
+ return scanContinue
405
+ }
406
+ return state0(s, c)
407
+ }
408
+
409
+ // state0 is the state after reading `0` during a number.
410
+ func state0(s *scanner, c byte) int {
411
+ if c == '.' {
412
+ s.step = stateDot
413
+ return scanContinue
414
+ }
415
+ if c == 'e' || c == 'E' {
416
+ s.step = stateE
417
+ return scanContinue
418
+ }
419
+ return stateEndValue(s, c)
420
+ }
421
+
422
+ // stateDot is the state after reading the integer and decimal point in a number,
423
+ // such as after reading `1.`.
424
+ func stateDot(s *scanner, c byte) int {
425
+ if '0' <= c && c <= '9' {
426
+ s.step = stateDot0
427
+ return scanContinue
428
+ }
429
+ return s.error(c, "after decimal point in numeric literal")
430
+ }
431
+
432
+ // stateDot0 is the state after reading the integer, decimal point, and subsequent
433
+ // digits of a number, such as after reading `3.14`.
434
+ func stateDot0(s *scanner, c byte) int {
435
+ if '0' <= c && c <= '9' {
436
+ return scanContinue
437
+ }
438
+ if c == 'e' || c == 'E' {
439
+ s.step = stateE
440
+ return scanContinue
441
+ }
442
+ return stateEndValue(s, c)
443
+ }
444
+
445
+ // stateE is the state after reading the mantissa and e in a number,
446
+ // such as after reading `314e` or `0.314e`.
447
+ func stateE(s *scanner, c byte) int {
448
+ if c == '+' || c == '-' {
449
+ s.step = stateESign
450
+ return scanContinue
451
+ }
452
+ return stateESign(s, c)
453
+ }
454
+
455
+ // stateESign is the state after reading the mantissa, e, and sign in a number,
456
+ // such as after reading `314e-` or `0.314e+`.
457
+ func stateESign(s *scanner, c byte) int {
458
+ if '0' <= c && c <= '9' {
459
+ s.step = stateE0
460
+ return scanContinue
461
+ }
462
+ return s.error(c, "in exponent of numeric literal")
463
+ }
464
+
465
+ // stateE0 is the state after reading the mantissa, e, optional sign,
466
+ // and at least one digit of the exponent in a number,
467
+ // such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
468
+ func stateE0(s *scanner, c byte) int {
469
+ if '0' <= c && c <= '9' {
470
+ return scanContinue
471
+ }
472
+ return stateEndValue(s, c)
473
+ }
474
+
475
+ // stateT is the state after reading `t`.
476
+ func stateT(s *scanner, c byte) int {
477
+ if c == 'r' {
478
+ s.step = stateTr
479
+ return scanContinue
480
+ }
481
+ return s.error(c, "in literal true (expecting 'r')")
482
+ }
483
+
484
+ // stateTr is the state after reading `tr`.
485
+ func stateTr(s *scanner, c byte) int {
486
+ if c == 'u' {
487
+ s.step = stateTru
488
+ return scanContinue
489
+ }
490
+ return s.error(c, "in literal true (expecting 'u')")
491
+ }
492
+
493
+ // stateTru is the state after reading `tru`.
494
+ func stateTru(s *scanner, c byte) int {
495
+ if c == 'e' {
496
+ s.step = stateEndValue
497
+ return scanContinue
498
+ }
499
+ return s.error(c, "in literal true (expecting 'e')")
500
+ }
501
+
502
+ // stateF is the state after reading `f`.
503
+ func stateF(s *scanner, c byte) int {
504
+ if c == 'a' {
505
+ s.step = stateFa
506
+ return scanContinue
507
+ }
508
+ return s.error(c, "in literal false (expecting 'a')")
509
+ }
510
+
511
+ // stateFa is the state after reading `fa`.
512
+ func stateFa(s *scanner, c byte) int {
513
+ if c == 'l' {
514
+ s.step = stateFal
515
+ return scanContinue
516
+ }
517
+ return s.error(c, "in literal false (expecting 'l')")
518
+ }
519
+
520
+ // stateFal is the state after reading `fal`.
521
+ func stateFal(s *scanner, c byte) int {
522
+ if c == 's' {
523
+ s.step = stateFals
524
+ return scanContinue
525
+ }
526
+ return s.error(c, "in literal false (expecting 's')")
527
+ }
528
+
529
+ // stateFals is the state after reading `fals`.
530
+ func stateFals(s *scanner, c byte) int {
531
+ if c == 'e' {
532
+ s.step = stateEndValue
533
+ return scanContinue
534
+ }
535
+ return s.error(c, "in literal false (expecting 'e')")
536
+ }
537
+
538
+ // stateN is the state after reading `n`.
539
+ func stateN(s *scanner, c byte) int {
540
+ if c == 'u' {
541
+ s.step = stateNu
542
+ return scanContinue
543
+ }
544
+ return s.error(c, "in literal null (expecting 'u')")
545
+ }
546
+
547
+ // stateNu is the state after reading `nu`.
548
+ func stateNu(s *scanner, c byte) int {
549
+ if c == 'l' {
550
+ s.step = stateNul
551
+ return scanContinue
552
+ }
553
+ return s.error(c, "in literal null (expecting 'l')")
554
+ }
555
+
556
+ // stateNul is the state after reading `nul`.
557
+ func stateNul(s *scanner, c byte) int {
558
+ if c == 'l' {
559
+ s.step = stateEndValue
560
+ return scanContinue
561
+ }
562
+ return s.error(c, "in literal null (expecting 'l')")
563
+ }
564
+
565
+ // stateError is the state after reaching a syntax error,
566
+ // such as after reading `[1}` or `5.1.2`.
567
+ func stateError(s *scanner, c byte) int {
568
+ return scanError
569
+ }
570
+
571
+ // error records an error and switches to the error state.
572
+ func (s *scanner) error(c byte, context string) int {
573
+ s.step = stateError
574
+ s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
575
+ return scanError
576
+ }
577
+
578
+ // quoteChar formats c as a quoted character literal.
579
+ func quoteChar(c byte) string {
580
+ // special cases - different from quoted strings
581
+ if c == '\'' {
582
+ return `'\''`
583
+ }
584
+ if c == '"' {
585
+ return `'"'`
586
+ }
587
+
588
+ // use quoted string with different quotation marks
589
+ s := strconv.Quote(string(c))
590
+ return "'" + s[1:len(s)-1] + "'"
591
+ }
592
+
593
+ // CheckValid returns nil when data is one valid JSON value, else the
594
+ // *SyntaxError describing the first problem.
595
+ func CheckValid(data []byte) error {
596
+ return checkValid(data, newScanner())
597
+ }
598
+
599
+ // ScanNext reads and returns the bytes of the next single JSON value from r,
600
+ // along with the number of leading whitespace bytes that were skipped.
601
+ // If EOF is encountered before any non-whitespace bytes, it returns io.EOF.
602
+ // If the stream ends before the JSON value completes, it returns io.ErrUnexpectedEOF.
603
+ func ScanNext(r *Reader) ([]byte, int64, error) {
604
+ var skipped int64
605
+ var c byte
606
+ for {
607
+ b, err := r.ReadByte()
608
+ if err != nil {
609
+ return nil, skipped, err
610
+ }
611
+ if isSpace(b) {
612
+ skipped++
613
+ continue
614
+ }
615
+ c = b
616
+ break
617
+ }
618
+
619
+ scan := newScanner()
620
+ buf := []byte{c}
621
+ scan.bytes++
622
+ if op := scan.step(scan, c); op == scanError {
623
+ return nil, skipped, scan.err
624
+ }
625
+
626
+ for {
627
+ b, err := r.ReadByte()
628
+ if err == io.EOF {
629
+ op := scan.eof()
630
+ if op == scanEnd {
631
+ return buf, skipped, nil
632
+ }
633
+ return nil, skipped, io.ErrUnexpectedEOF
634
+ }
635
+ if err != nil {
636
+ return nil, skipped, err
637
+ }
638
+ scan.bytes++
639
+ op := scan.step(scan, b)
640
+ if op == scanEnd {
641
+ r.UnreadByte()
642
+ return buf, skipped, nil
643
+ }
644
+ if op == scanError {
645
+ return nil, skipped, scan.err
646
+ }
647
+ buf = append(buf, b)
648
+ }
649
+ }