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
@@ -0,0 +1,732 @@
1
+ // Copyright 2009 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 fmt
10
+
11
+ import (
12
+ "strconv"
13
+ "unicode/utf8"
14
+ )
15
+
16
+ const (
17
+ ldigits = "0123456789abcdefx"
18
+ udigits = "0123456789ABCDEFX"
19
+ )
20
+
21
+ const (
22
+ signed = true
23
+ unsigned = false
24
+ )
25
+
26
+ // fmtFlags is the set of flags a verb carries.
27
+ type fmtFlags struct {
28
+ widPresent bool
29
+ precPresent bool
30
+ minus bool
31
+ plus bool
32
+ sharp bool
33
+ space bool
34
+ zero bool
35
+
36
+ // For the formats %+v %#v, we set the plusV/sharpV flags and clear the
37
+ // plus/sharp flags since %+v and %#v are in effect different, flagless
38
+ // formats set at the top level.
39
+ plusV bool
40
+ sharpV bool
41
+ }
42
+
43
+ // fmtState is the part of the printer that lays out one value in a buffer. It
44
+ // holds the flags of fmtFlags directly: an embedded struct would be renamed
45
+ // with its type when the package is linked.
46
+ type fmtState struct {
47
+ // buf is the output buffer: its length is the capacity and n the bytes
48
+ // written, so an append is an indexed store, not a new slice value.
49
+ buf []byte
50
+ n int
51
+
52
+ widPresent bool
53
+ precPresent bool
54
+ minus bool
55
+ plus bool
56
+ sharp bool
57
+ space bool
58
+ zero bool
59
+ plusV bool
60
+ sharpV bool
61
+
62
+ wid int
63
+ prec int
64
+ intbuf []byte
65
+ }
66
+
67
+ // grow makes room for need more bytes.
68
+ func (f *fmtState) grow(need int) {
69
+ size := 2 * len(f.buf)
70
+ if size < f.n+need {
71
+ size = f.n + need
72
+ }
73
+ nb := make([]byte, size)
74
+ copy(nb, f.buf[:f.n])
75
+ f.buf = nb
76
+ }
77
+
78
+ // scratch returns the 68-byte buffer numbers and quotes are built in.
79
+ func (f *fmtState) scratch() []byte {
80
+ if f.intbuf == nil {
81
+ f.intbuf = make([]byte, 68)
82
+ }
83
+ return f.intbuf
84
+ }
85
+
86
+ func (f *fmtState) putByte(c byte) {
87
+ if f.n == len(f.buf) {
88
+ f.grow(1)
89
+ }
90
+ f.buf[f.n] = c
91
+ f.n++
92
+ }
93
+
94
+ func (f *fmtState) putBytes(b []byte) {
95
+ n := len(b)
96
+ if f.n+n > len(f.buf) {
97
+ f.grow(n)
98
+ }
99
+ buf, k := f.buf, f.n
100
+ for i := 0; i < n; i++ {
101
+ buf[k+i] = b[i]
102
+ }
103
+ f.n = k + n
104
+ }
105
+
106
+ // putString appends s. An ASCII string is stored byte by byte; any other goes
107
+ // through the encoder.
108
+ func (f *fmtState) putString(s string) {
109
+ n := len(s)
110
+ if f.n+n > len(f.buf) {
111
+ f.grow(n)
112
+ }
113
+ buf, k := f.buf, f.n
114
+ for _, r := range s {
115
+ if r >= 0x80 {
116
+ f.putBytes([]byte(s))
117
+ return
118
+ }
119
+ buf[k] = byte(r)
120
+ k++
121
+ }
122
+ f.n = k
123
+ }
124
+
125
+ // bytes returns what has been written.
126
+ func (f *fmtState) bytes() []byte {
127
+ return f.buf[:f.n]
128
+ }
129
+
130
+ func (f *fmtState) clearflags() {
131
+ f.restoreFlags(fmtFlags{})
132
+ f.wid = 0
133
+ f.prec = 0
134
+ }
135
+
136
+ // saveFlags returns the flags of the verb being formatted.
137
+ func (f *fmtState) saveFlags() fmtFlags {
138
+ return fmtFlags{f.widPresent, f.precPresent, f.minus, f.plus, f.sharp, f.space, f.zero, f.plusV, f.sharpV}
139
+ }
140
+
141
+ // restoreFlags sets the flags saved by saveFlags.
142
+ func (f *fmtState) restoreFlags(s fmtFlags) {
143
+ f.widPresent = s.widPresent
144
+ f.precPresent = s.precPresent
145
+ f.minus = s.minus
146
+ f.plus = s.plus
147
+ f.sharp = s.sharp
148
+ f.space = s.space
149
+ f.zero = s.zero
150
+ f.plusV = s.plusV
151
+ f.sharpV = s.sharpV
152
+ }
153
+
154
+ // writePadding appends n padding bytes.
155
+ func (f *fmtState) writePadding(n int) {
156
+ if n <= 0 {
157
+ return
158
+ }
159
+ padByte := byte(' ')
160
+ // Zero padding is allowed only to the left.
161
+ if f.zero && !f.minus {
162
+ padByte = byte('0')
163
+ }
164
+ for i := 0; i < n; i++ {
165
+ f.putByte(padByte)
166
+ }
167
+ }
168
+
169
+ // pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
170
+ func (f *fmtState) pad(b []byte) {
171
+ if !f.widPresent || f.wid == 0 {
172
+ f.putBytes(b)
173
+ return
174
+ }
175
+ width := f.wid - utf8.RuneCount(b)
176
+ if !f.minus {
177
+ // left padding
178
+ f.writePadding(width)
179
+ f.putBytes(b)
180
+ } else {
181
+ // right padding
182
+ f.putBytes(b)
183
+ f.writePadding(width)
184
+ }
185
+ }
186
+
187
+ // padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
188
+ func (f *fmtState) padString(s string) {
189
+ if !f.widPresent || f.wid == 0 {
190
+ f.putString(s)
191
+ return
192
+ }
193
+ width := f.wid - utf8.RuneCountInString(s)
194
+ if !f.minus {
195
+ // left padding
196
+ f.writePadding(width)
197
+ f.putString(s)
198
+ } else {
199
+ // right padding
200
+ f.putString(s)
201
+ f.writePadding(width)
202
+ }
203
+ }
204
+
205
+ // fmtBoolean formats a boolean.
206
+ func (f *fmtState) fmtBoolean(v bool) {
207
+ if v {
208
+ f.padString("true")
209
+ } else {
210
+ f.padString("false")
211
+ }
212
+ }
213
+
214
+ // fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
215
+ func (f *fmtState) fmtUnicode(u uint64) {
216
+ buf := f.scratch()[0:]
217
+
218
+ // With default precision set the maximum needed buf length is 18
219
+ // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
220
+ // into the already allocated intbuf with a capacity of 68 bytes.
221
+ prec := 4
222
+ if f.precPresent && f.prec > 4 {
223
+ prec = f.prec
224
+ // Compute space needed for "U+" , number, " '", character, "'".
225
+ width := 2 + prec + 2 + utf8.UTFMax + 1
226
+ if width > len(buf) {
227
+ buf = make([]byte, width)
228
+ }
229
+ }
230
+
231
+ // Format into buf, ending at buf[i]. Building numbers is easier right-to-left.
232
+ i := len(buf)
233
+
234
+ // For %#U we want to add a space and a quoted character at the end of the buffer.
235
+ if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
236
+ i--
237
+ buf[i] = '\''
238
+ i -= utf8.RuneLen(rune(u))
239
+ utf8.EncodeRune(buf[i:], rune(u))
240
+ i--
241
+ buf[i] = '\''
242
+ i--
243
+ buf[i] = ' '
244
+ }
245
+ // Format the Unicode code point u as a hexadecimal number.
246
+ for u >= 16 {
247
+ i--
248
+ buf[i] = udigits[u&0xF]
249
+ prec--
250
+ u >>= 4
251
+ }
252
+ i--
253
+ buf[i] = udigits[u]
254
+ prec--
255
+ // Add zeros in front of the number until requested precision is reached.
256
+ for prec > 0 {
257
+ i--
258
+ buf[i] = '0'
259
+ prec--
260
+ }
261
+ // Add a leading "U+".
262
+ i--
263
+ buf[i] = '+'
264
+ i--
265
+ buf[i] = 'U'
266
+
267
+ oldZero := f.zero
268
+ f.zero = false
269
+ f.pad(buf[i:])
270
+ f.zero = oldZero
271
+ }
272
+
273
+ // fmtInteger formats signed and unsigned integers.
274
+ func (f *fmtState) fmtInteger(u uint64, base int, isSigned bool, verb rune, digits string) {
275
+ negative := isSigned && int64(u) < 0
276
+ if negative {
277
+ u = -u
278
+ }
279
+
280
+ buf := f.scratch()[0:]
281
+ // The already allocated f.intbuf with a capacity of 68 bytes
282
+ // is large enough for integer formatting when no precision or width is set.
283
+ if f.widPresent || f.precPresent {
284
+ // Account 3 extra bytes for possible addition of a sign and "0x".
285
+ width := 3 + f.wid + f.prec // wid and prec are always positive.
286
+ if width > len(buf) {
287
+ // We're going to need a bigger boat.
288
+ buf = make([]byte, width)
289
+ }
290
+ }
291
+
292
+ // Two ways to ask for extra leading zero digits: %.3d or %03d.
293
+ // If both are specified the f.zero flag is ignored and
294
+ // padding with spaces is used instead.
295
+ prec := 0
296
+ if f.precPresent {
297
+ prec = f.prec
298
+ // Precision of 0 and value of 0 means "print nothing" but padding.
299
+ if prec == 0 && u == 0 {
300
+ oldZero := f.zero
301
+ f.zero = false
302
+ f.writePadding(f.wid)
303
+ f.zero = oldZero
304
+ return
305
+ }
306
+ } else if f.zero && !f.minus && f.widPresent { // Zero padding is allowed only to the left.
307
+ prec = f.wid
308
+ if negative || f.plus || f.space {
309
+ prec-- // leave room for sign
310
+ }
311
+ }
312
+
313
+ // Because printing is easier right-to-left: format u into buf, ending at buf[i].
314
+ i := len(buf)
315
+ switch base {
316
+ case 10:
317
+ if u < 1<<31 {
318
+ // Small values divide as int: a 64-bit division is much slower
319
+ // where uint64 is a BigInt.
320
+ n := int(u)
321
+ for n >= 10 {
322
+ i--
323
+ next := n / 10
324
+ buf[i] = byte('0' + n - next*10)
325
+ n = next
326
+ }
327
+ u = uint64(n)
328
+ }
329
+ for u >= 10 {
330
+ i--
331
+ next := u / 10
332
+ buf[i] = byte('0' + u - next*10)
333
+ u = next
334
+ }
335
+ case 16:
336
+ for u >= 16 {
337
+ i--
338
+ buf[i] = digits[u&0xF]
339
+ u >>= 4
340
+ }
341
+ case 8:
342
+ for u >= 8 {
343
+ i--
344
+ buf[i] = byte('0' + u&7)
345
+ u >>= 3
346
+ }
347
+ case 2:
348
+ for u >= 2 {
349
+ i--
350
+ buf[i] = byte('0' + u&1)
351
+ u >>= 1
352
+ }
353
+ default:
354
+ panic("fmt: unknown base; can't happen")
355
+ }
356
+ i--
357
+ buf[i] = digits[u]
358
+ for i > 0 && prec > len(buf)-i {
359
+ i--
360
+ buf[i] = '0'
361
+ }
362
+
363
+ // Various prefixes: 0x, -, etc.
364
+ if f.sharp {
365
+ switch base {
366
+ case 2:
367
+ // Add a leading 0b.
368
+ i--
369
+ buf[i] = 'b'
370
+ i--
371
+ buf[i] = '0'
372
+ case 8:
373
+ if buf[i] != '0' {
374
+ i--
375
+ buf[i] = '0'
376
+ }
377
+ case 16:
378
+ // Add a leading 0x or 0X.
379
+ i--
380
+ buf[i] = digits[16]
381
+ i--
382
+ buf[i] = '0'
383
+ }
384
+ }
385
+ if verb == 'O' {
386
+ i--
387
+ buf[i] = 'o'
388
+ i--
389
+ buf[i] = '0'
390
+ }
391
+
392
+ if negative {
393
+ i--
394
+ buf[i] = '-'
395
+ } else if f.plus {
396
+ i--
397
+ buf[i] = '+'
398
+ } else if f.space {
399
+ i--
400
+ buf[i] = ' '
401
+ }
402
+
403
+ // Left padding with zeros has already been handled like precision earlier
404
+ // or the f.zero flag is ignored due to an explicit precision.
405
+ oldZero := f.zero
406
+ f.zero = false
407
+ f.pad(buf[i:])
408
+ f.zero = oldZero
409
+ }
410
+
411
+ // truncateString truncates the string s to the specified precision, if present.
412
+ func (f *fmtState) truncateString(s string) string {
413
+ if f.precPresent {
414
+ n := f.prec
415
+ for i := range s {
416
+ n--
417
+ if n < 0 {
418
+ return s[:i]
419
+ }
420
+ }
421
+ }
422
+ return s
423
+ }
424
+
425
+ // truncate truncates the byte slice b as a string of the specified precision, if present.
426
+ func (f *fmtState) truncate(b []byte) []byte {
427
+ if f.precPresent {
428
+ n := f.prec
429
+ for i := 0; i < len(b); {
430
+ n--
431
+ if n < 0 {
432
+ return b[:i]
433
+ }
434
+ wid := 1
435
+ if b[i] >= utf8.RuneSelf {
436
+ _, wid = utf8.DecodeRune(b[i:])
437
+ }
438
+ i += wid
439
+ }
440
+ }
441
+ return b
442
+ }
443
+
444
+ // fmtS formats a string.
445
+ func (f *fmtState) fmtS(s string) {
446
+ s = f.truncateString(s)
447
+ f.padString(s)
448
+ }
449
+
450
+ // fmtBs formats the byte slice b as if it was formatted as string with fmtS.
451
+ func (f *fmtState) fmtBs(b []byte) {
452
+ b = f.truncate(b)
453
+ f.pad(b)
454
+ }
455
+
456
+ // fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
457
+ func (f *fmtState) fmtSbx(s string, b []byte, digits string) {
458
+ length := len(b)
459
+ if b == nil {
460
+ // No byte slice present. Assume string s should be encoded.
461
+ length = len(s)
462
+ }
463
+ // Set length to not process more bytes than the precision demands.
464
+ if f.precPresent && f.prec < length {
465
+ length = f.prec
466
+ }
467
+ // Compute width of the encoding taking into account the f.sharp and f.space flag.
468
+ width := 2 * length
469
+ if width > 0 {
470
+ if f.space {
471
+ // Each element encoded by two hexadecimals will get a leading 0x or 0X.
472
+ if f.sharp {
473
+ width *= 2
474
+ }
475
+ // Elements will be separated by a space.
476
+ width += length - 1
477
+ } else if f.sharp {
478
+ // Only a leading 0x or 0X will be added for the whole string.
479
+ width += 2
480
+ }
481
+ } else { // The byte slice or string that should be encoded is empty.
482
+ if f.widPresent {
483
+ f.writePadding(f.wid)
484
+ }
485
+ return
486
+ }
487
+ // Handle padding to the left.
488
+ if f.widPresent && f.wid > width && !f.minus {
489
+ f.writePadding(f.wid - width)
490
+ }
491
+ // Write the encoding directly into the output buffer.
492
+ if f.sharp {
493
+ // Add leading 0x or 0X.
494
+ f.putByte('0')
495
+ f.putByte(digits[16])
496
+ }
497
+ for i := 0; i < length; i++ {
498
+ if f.space && i > 0 {
499
+ // Separate elements with a space.
500
+ f.putByte(' ')
501
+ if f.sharp {
502
+ // Add leading 0x or 0X for each element.
503
+ f.putByte('0')
504
+ f.putByte(digits[16])
505
+ }
506
+ }
507
+ var c byte
508
+ if b != nil {
509
+ c = b[i] // Take a byte from the input byte slice.
510
+ } else {
511
+ c = s[i] // Take a byte from the input string.
512
+ }
513
+ // Encode each byte as two hexadecimal digits.
514
+ f.putByte(digits[c>>4])
515
+ f.putByte(digits[c&0xF])
516
+ }
517
+ // Handle padding to the right.
518
+ if f.widPresent && f.wid > width && f.minus {
519
+ f.writePadding(f.wid - width)
520
+ }
521
+ }
522
+
523
+ // fmtSx formats a string as a hexadecimal encoding of its bytes.
524
+ func (f *fmtState) fmtSx(s, digits string) {
525
+ f.fmtSbx(s, nil, digits)
526
+ }
527
+
528
+ // fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
529
+ func (f *fmtState) fmtBx(b []byte, digits string) {
530
+ f.fmtSbx("", b, digits)
531
+ }
532
+
533
+ // fmtQ formats a string as a double-quoted, escaped Go string constant.
534
+ // If f.sharp is set a raw (backquoted) string may be returned instead
535
+ // if the string does not contain any control characters other than tab.
536
+ func (f *fmtState) fmtQ(s string) {
537
+ s = f.truncateString(s)
538
+ if f.sharp && strconv.CanBackquote(s) {
539
+ f.padString("`" + s + "`")
540
+ return
541
+ }
542
+ if !f.plus && plainQuotable(s) {
543
+ f.padString("\"" + s + "\"")
544
+ return
545
+ }
546
+ buf := f.scratch()[:0]
547
+ if f.plus {
548
+ f.pad(strconv.AppendQuoteToASCII(buf, s))
549
+ } else {
550
+ f.pad(strconv.AppendQuote(buf, s))
551
+ }
552
+ }
553
+
554
+ // plainQuotable reports whether Quote leaves s as it is between the quotes:
555
+ // printable ASCII without a quote or backslash.
556
+ func plainQuotable(s string) bool {
557
+ for i := 0; i < len(s); i++ {
558
+ c := s[i]
559
+ if c < ' ' || c > '~' || c == '"' || c == '\\' {
560
+ return false
561
+ }
562
+ }
563
+ return true
564
+ }
565
+
566
+ // fixedFloat formats f, a finite float64 of at least zero, with prec digits
567
+ // after the point; "" when the host cannot, in which case the caller formats
568
+ // it with strconv.
569
+ //
570
+ //gofront:native strconv.fixed
571
+ func fixedFloat(f float64, prec int) string {
572
+ return ""
573
+ }
574
+
575
+ // fmtFixed is fmtFloat for the plain %f of a float64: it reports false when it
576
+ // wrote nothing.
577
+ func (f *fmtState) fmtFixed(v float64, prec int) bool {
578
+ neg := v < 0 || (v == 0 && 1/v < 0)
579
+ if neg {
580
+ v = -v
581
+ }
582
+ s := fixedFloat(v, prec)
583
+ if s == "" {
584
+ return false
585
+ }
586
+ sign := ""
587
+ if neg {
588
+ sign = "-"
589
+ } else if f.plus {
590
+ sign = "+"
591
+ } else if f.space {
592
+ sign = " "
593
+ }
594
+ if sign == "" {
595
+ f.padString(s)
596
+ } else if f.zero && !f.minus && f.widPresent && f.wid > len(s)+1 {
597
+ // Zero padding goes between the sign and the digits.
598
+ f.putString(sign)
599
+ f.writePadding(f.wid - len(s) - 1)
600
+ f.putString(s)
601
+ } else {
602
+ f.padString(sign + s)
603
+ }
604
+ return true
605
+ }
606
+
607
+ // fmtC formats an integer as a Unicode character.
608
+ // If the character is not valid Unicode, it will print '�'.
609
+ func (f *fmtState) fmtC(c uint64) {
610
+ // Explicitly check whether c exceeds utf8.MaxRune since the conversion
611
+ // of a uint64 to a rune may lose precision that indicates an overflow.
612
+ r := rune(c)
613
+ if c > utf8.MaxRune {
614
+ r = utf8.RuneError
615
+ }
616
+ buf := f.scratch()[:0]
617
+ f.pad(utf8.AppendRune(buf, r))
618
+ }
619
+
620
+ // fmtQc formats an integer as a single-quoted, escaped Go character constant.
621
+ // If the character is not valid Unicode, it will print '�'.
622
+ func (f *fmtState) fmtQc(c uint64) {
623
+ r := rune(c)
624
+ if c > utf8.MaxRune {
625
+ r = utf8.RuneError
626
+ }
627
+ buf := f.scratch()[:0]
628
+ if f.plus {
629
+ f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
630
+ } else {
631
+ f.pad(strconv.AppendQuoteRune(buf, r))
632
+ }
633
+ }
634
+
635
+ // fmtFloat formats floats. The default precision for each verb
636
+ // is specified as last argument in the call to fmt_float.
637
+ func (f *fmtState) fmtFloat(v float64, size int, verb rune, prec int) {
638
+ // Format number, reserving space for leading + sign if needed.
639
+ if f.precPresent {
640
+ prec = f.prec
641
+ }
642
+ if verb == 'f' && size == 64 && !f.sharp && prec >= 0 && prec <= 60 && v-v == 0 && f.fmtFixed(v, prec) {
643
+ return
644
+ }
645
+ num := strconv.AppendFloat(append(f.scratch()[:0], '+'), v, byte(verb), prec, size)
646
+ if num[1] == '-' || num[1] == '+' {
647
+ num = num[1:]
648
+ } else {
649
+ num[0] = '+'
650
+ }
651
+ // f.space means to add a leading space instead of a "+" sign unless f.plus is used.
652
+ if f.space && num[0] == '+' && !f.plus {
653
+ num[0] = ' '
654
+ }
655
+ // Special handling for infinities and NaN,
656
+ // which don't look like a number so shouldn't be padded with zeros.
657
+ if num[1] == 'I' || num[1] == 'N' {
658
+ oldZero := f.zero
659
+ f.zero = false
660
+ if num[1] == 'N' && !f.space && !f.plus {
661
+ num = num[1:]
662
+ }
663
+ f.pad(num)
664
+ f.zero = oldZero
665
+ return
666
+ }
667
+ // The sharp flag forces printing a decimal point but removes
668
+ // trailing zeros for %e, %f with the shortest flag.
669
+ if f.sharp && verb != 'b' {
670
+ digits := 0
671
+ switch verb {
672
+ case 'v', 'g', 'G', 'x':
673
+ digits = prec
674
+ // If no precision is set explicitly use a precision of 6.
675
+ if digits == -1 {
676
+ digits = 6
677
+ }
678
+ }
679
+
680
+ // Buffer pre-allocated with enough room for
681
+ // exponent notations of the form "e+123" or "p-1023".
682
+ tail := make([]byte, 0, 6)
683
+ hasDecimalPoint := false
684
+ sawNonzeroDigit := false
685
+ // Starting from i = 1 to skip sign at num[0].
686
+ for i := 1; i < len(num); i++ {
687
+ c := num[i]
688
+ if c == '.' {
689
+ hasDecimalPoint = true
690
+ } else if c == 'p' || c == 'P' || ((c == 'e' || c == 'E') && verb != 'x' && verb != 'X') {
691
+ tail = append(tail, num[i:]...)
692
+ num = num[:i]
693
+ } else {
694
+ // Count significant digits after the first non-zero digit.
695
+ if c != '0' {
696
+ sawNonzeroDigit = true
697
+ }
698
+ if sawNonzeroDigit {
699
+ digits--
700
+ }
701
+ }
702
+ }
703
+ if !hasDecimalPoint {
704
+ // Leading digit 0 should contribute once to digits.
705
+ if len(num) == 2 && num[1] == '0' {
706
+ digits--
707
+ }
708
+ num = append(num, '.')
709
+ }
710
+ for digits > 0 {
711
+ num = append(num, '0')
712
+ digits--
713
+ }
714
+ num = append(num, tail...)
715
+ }
716
+ // We want a sign if asked for and if the sign is not positive.
717
+ if f.plus || num[0] != '+' {
718
+ // If we're zero padding to the left we want the sign before the leading zeros.
719
+ // Achieve this by writing the sign out and then padding the unsigned number.
720
+ // Zero padding is allowed only to the left.
721
+ if f.zero && !f.minus && f.widPresent && f.wid > len(num) {
722
+ f.putByte(num[0])
723
+ f.writePadding(f.wid - len(num))
724
+ f.putBytes(num[1:])
725
+ return
726
+ }
727
+ f.pad(num)
728
+ return
729
+ }
730
+ // No sign to show and the number is positive; just print the unsigned number.
731
+ f.pad(num[1:])
732
+ }