goscript 0.2.6 → 0.2.7
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.
- package/cmd/goscript/cmd-compile.go +7 -0
- package/cmd/goscript/cmd_compile_test.go +83 -0
- package/compiler/compile-request.go +3 -0
- package/compiler/compiler-cache.go +828 -0
- package/compiler/compiler-cache_test.go +705 -0
- package/compiler/config.go +2 -0
- package/compiler/index.test.ts +26 -1
- package/compiler/index.ts +5 -0
- package/compiler/lowered-program.go +31 -20
- package/compiler/lowering.go +349 -93
- package/compiler/lowering_bench_test.go +1 -0
- package/compiler/override-facts.go +309 -8
- package/compiler/override-parity-verifier.go +45 -1
- package/compiler/override-parity-verifier_test.go +100 -0
- package/compiler/override-registry_test.go +1 -0
- package/compiler/package-graph.go +40 -12
- package/compiler/package-graph_test.go +29 -0
- package/compiler/runtime-contract.go +8 -0
- package/compiler/service.go +98 -11
- package/compiler/skeleton_test.go +110 -14
- package/compiler/typescript-emitter.go +120 -23
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +3 -0
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +24 -33
- package/dist/gs/builtin/builtin.js +54 -61
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +1 -0
- package/dist/gs/builtin/hostio.js +1 -1
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/panic.d.ts +18 -0
- package/dist/gs/builtin/panic.js +98 -0
- package/dist/gs/builtin/panic.js.map +1 -0
- package/dist/gs/builtin/slice.d.ts +10 -0
- package/dist/gs/builtin/slice.js +110 -53
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.js +15 -3
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +1 -1
- package/dist/gs/builtin/varRef.js +3 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js +51 -38
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.d.ts +1 -1
- package/dist/gs/bytes/reader.gs.js +6 -7
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/cmp/index.d.ts +1 -1
- package/dist/gs/cmp/index.js +43 -10
- package/dist/gs/cmp/index.js.map +1 -1
- package/dist/gs/context/context.d.ts +2 -2
- package/dist/gs/context/context.js +1 -1
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/embed/index.js +1 -1
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/binary/index.js +201 -8
- package/dist/gs/encoding/binary/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +5 -0
- package/dist/gs/encoding/json/index.js +388 -25
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +17 -24
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js +129 -35
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.js +43 -8
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +2 -2
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/io/fs/format.js +2 -2
- package/dist/gs/io/fs/format.js.map +1 -1
- package/dist/gs/io/fs/fs.d.ts +1 -1
- package/dist/gs/io/fs/fs.js +1 -1
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/io.d.ts +21 -21
- package/dist/gs/io/io.js +49 -50
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.js +26 -8
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/copysign.gs.js +10 -17
- package/dist/gs/math/copysign.gs.js.map +1 -1
- package/dist/gs/math/pow.gs.js +5 -0
- package/dist/gs/math/pow.gs.js.map +1 -1
- package/dist/gs/math/signbit.gs.js +6 -2
- package/dist/gs/math/signbit.gs.js.map +1 -1
- package/dist/gs/mime/index.js +1 -0
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +6 -6
- package/dist/gs/net/http/index.js +507 -43
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/stat.gs.d.ts +2 -2
- package/dist/gs/os/types.gs.d.ts +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +1 -1
- package/dist/gs/os/types_js.gs.js +7 -7
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.d.ts +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/os/zero_copy_posix.gs.d.ts +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +8 -4
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.js +216 -42
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/match.js +6 -3
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +5 -4
- package/dist/gs/reflect/type.js +29 -11
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/slices/slices.js +11 -11
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/strconv/atof.gs.js +156 -43
- package/dist/gs/strconv/atof.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.d.ts +3 -2
- package/dist/gs/strconv/atoi.gs.js +86 -67
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/ftoa.gs.js +73 -3
- package/dist/gs/strconv/ftoa.gs.js.map +1 -1
- package/dist/gs/strconv/itoa.gs.d.ts +4 -4
- package/dist/gs/strconv/itoa.gs.js +5 -4
- package/dist/gs/strconv/itoa.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.d.ts +1 -1
- package/dist/gs/strconv/quote.gs.js +311 -103
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +8 -8
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/strings.js +87 -61
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.d.ts +14 -14
- package/dist/gs/sync/atomic/doc_64.gs.js +10 -10
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +22 -22
- package/dist/gs/sync/atomic/type.gs.js +4 -4
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.js +50 -12
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +6 -6
- package/dist/gs/syscall/fs.js +1 -1
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/time/time.d.ts +18 -18
- package/dist/gs/time/time.js +58 -55
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/tables.d.ts +11 -0
- package/dist/gs/unicode/tables.js +635 -0
- package/dist/gs/unicode/tables.js.map +1 -0
- package/dist/gs/unicode/unicode.d.ts +58 -38
- package/dist/gs/unicode/unicode.js +362 -278
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/go.sum +13 -0
- package/gs/builtin/builtin.ts +83 -93
- package/gs/builtin/hostio.ts +1 -1
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/panic.test.ts +189 -0
- package/gs/builtin/panic.ts +107 -0
- package/gs/builtin/runtime-contract.test.ts +5 -5
- package/gs/builtin/slice.test.ts +23 -0
- package/gs/builtin/slice.ts +133 -95
- package/gs/builtin/type.ts +16 -3
- package/gs/builtin/varRef.ts +4 -2
- package/gs/builtin/wide-int.test.ts +41 -0
- package/gs/bytes/bytes.gs.ts +54 -41
- package/gs/bytes/bytes.test.ts +18 -1
- package/gs/bytes/reader.gs.ts +7 -8
- package/gs/cmp/index.test.ts +55 -0
- package/gs/cmp/index.ts +45 -9
- package/gs/context/context.ts +3 -3
- package/gs/embed/index.ts +2 -2
- package/gs/encoding/binary/index.test.ts +104 -0
- package/gs/encoding/binary/index.ts +259 -11
- package/gs/encoding/json/index.test.ts +107 -0
- package/gs/encoding/json/index.ts +400 -29
- package/gs/errors/errors.test.ts +44 -1
- package/gs/errors/errors.ts +15 -31
- package/gs/fmt/fmt.test.ts +70 -2
- package/gs/fmt/fmt.ts +128 -34
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1 -1
- package/gs/internal/bytealg/index.test.ts +26 -1
- package/gs/internal/bytealg/index.ts +44 -8
- package/gs/internal/byteorder/index.ts +6 -4
- package/gs/io/fs/format.ts +2 -2
- package/gs/io/fs/fs.ts +2 -2
- package/gs/io/fs/stat.test.ts +2 -2
- package/gs/io/fs/sub.test.ts +2 -2
- package/gs/io/fs/walk.test.ts +2 -2
- package/gs/io/io.test.ts +47 -5
- package/gs/io/io.ts +73 -73
- package/gs/io/limit.test.ts +103 -0
- package/gs/math/bits/index.test.ts +128 -0
- package/gs/math/bits/index.ts +26 -8
- package/gs/math/copysign.gs.test.ts +3 -1
- package/gs/math/copysign.gs.ts +10 -22
- package/gs/math/pow.gs.test.ts +4 -5
- package/gs/math/pow.gs.ts +5 -0
- package/gs/math/signbit.gs.test.ts +2 -1
- package/gs/math/signbit.gs.ts +6 -3
- package/gs/mime/index.ts +1 -0
- package/gs/net/http/index.test.ts +683 -2
- package/gs/net/http/index.ts +598 -57
- package/gs/net/http/meta.json +3 -0
- package/gs/os/stat.gs.ts +2 -2
- package/gs/os/types.gs.ts +2 -2
- package/gs/os/types_js.gs.ts +9 -9
- package/gs/os/types_unix.gs.ts +2 -2
- package/gs/os/zero_copy_posix.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +16 -0
- package/gs/path/filepath/match.ts +8 -4
- package/gs/path/filepath/path.test.ts +91 -9
- package/gs/path/filepath/path.ts +223 -49
- package/gs/path/match.test.ts +32 -0
- package/gs/path/match.ts +6 -3
- package/gs/reflect/deepequal.test.ts +1 -1
- package/gs/reflect/field.test.ts +1 -1
- package/gs/reflect/function-types.test.ts +6 -6
- package/gs/reflect/sliceat.test.ts +13 -13
- package/gs/reflect/structof.test.ts +4 -4
- package/gs/reflect/type.ts +34 -14
- package/gs/reflect/typefor.test.ts +5 -5
- package/gs/runtime/pprof/index.test.ts +20 -0
- package/gs/runtime/trace/index.test.ts +3 -0
- package/gs/slices/slices.test.ts +31 -0
- package/gs/slices/slices.ts +11 -11
- package/gs/strconv/append.test.ts +99 -0
- package/gs/strconv/atof.gs.ts +156 -42
- package/gs/strconv/atof.test.ts +45 -0
- package/gs/strconv/atoi.gs.ts +87 -69
- package/gs/strconv/atoi.test.ts +49 -0
- package/gs/strconv/ftoa.gs.ts +85 -10
- package/gs/strconv/ftoa.test.ts +43 -0
- package/gs/strconv/itoa.gs.ts +10 -9
- package/gs/strconv/quote.gs.ts +335 -108
- package/gs/strconv/quote.test.ts +111 -0
- package/gs/strings/reader.test.ts +10 -10
- package/gs/strings/reader.ts +9 -9
- package/gs/strings/strings.test.ts +18 -5
- package/gs/strings/strings.ts +81 -68
- package/gs/sync/atomic/doc_64.gs.ts +24 -24
- package/gs/sync/atomic/doc_64.test.ts +5 -5
- package/gs/sync/atomic/type.gs.ts +28 -28
- package/gs/sync/sync.test.ts +109 -1
- package/gs/sync/sync.ts +46 -12
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/net.test.ts +1 -1
- package/gs/time/parse.test.ts +45 -0
- package/gs/time/time.test.ts +46 -23
- package/gs/time/time.ts +69 -66
- package/gs/unicode/gen.go +198 -0
- package/gs/unicode/tables.ts +646 -0
- package/gs/unicode/unicode.test.ts +69 -0
- package/gs/unicode/unicode.ts +396 -312
- package/package.json +1 -1
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +0 -20
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +0 -134
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +0 -30
- package/gs/github.com/aperturerobotics/util/conc/index.ts +0 -172
- package/gs/github.com/aperturerobotics/util/conc/meta.json +0 -9
package/gs/strconv/ftoa.gs.ts
CHANGED
|
@@ -1,12 +1,85 @@
|
|
|
1
1
|
import * as $ from "@goscript/builtin/index.js";
|
|
2
2
|
|
|
3
|
+
const hexConv = new DataView(new ArrayBuffer(8));
|
|
4
|
+
|
|
5
|
+
// formatHexFloat renders a non-negative finite float in Go's hexadecimal
|
|
6
|
+
// floating-point form: a normalized leading hex digit (1, or 0 for zero), an
|
|
7
|
+
// optional hex fraction, and a binary exponent printed with sign and at least
|
|
8
|
+
// two digits. prec < 0 emits the shortest exact fraction; prec >= 0 emits
|
|
9
|
+
// exactly prec fraction digits with round-half-to-even and carry renormalization.
|
|
10
|
+
// upper selects the 0X/P uppercase form.
|
|
11
|
+
function formatHexFloat(f: number, prec: number, upper: boolean): string {
|
|
12
|
+
hexConv.setFloat64(0, f);
|
|
13
|
+
const hi = hexConv.getUint32(0);
|
|
14
|
+
const lo = hexConv.getUint32(4);
|
|
15
|
+
const biasedExp = (hi >>> 20) & 0x7ff;
|
|
16
|
+
let frac = (BigInt(hi & 0xfffff) << 32n) | BigInt(lo >>> 0);
|
|
17
|
+
|
|
18
|
+
const xPrefix = upper ? "0X" : "0x";
|
|
19
|
+
const pChar = upper ? "P" : "p";
|
|
20
|
+
|
|
21
|
+
const assemble = (intDigit: string, fracHex: string, exp: number): string => {
|
|
22
|
+
if (upper) {
|
|
23
|
+
fracHex = fracHex.toUpperCase();
|
|
24
|
+
}
|
|
25
|
+
const expAbs = Math.abs(exp);
|
|
26
|
+
const expStr = (exp < 0 ? "-" : "+") + String(expAbs).padStart(2, "0");
|
|
27
|
+
const mantissa = fracHex.length > 0 ? intDigit + "." + fracHex : intDigit;
|
|
28
|
+
return xPrefix + mantissa + pChar + expStr;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (biasedExp === 0 && frac === 0n) {
|
|
32
|
+
const fracHex = prec > 0 ? "0".repeat(prec) : "";
|
|
33
|
+
return assemble("0", fracHex, 0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Normalize to a 52-bit fraction with an implicit leading 1.
|
|
37
|
+
let exp: number;
|
|
38
|
+
if (biasedExp === 0) {
|
|
39
|
+
// Subnormal: shift the leading set bit up to bit 52.
|
|
40
|
+
let k = 51;
|
|
41
|
+
while ((frac & (1n << BigInt(k))) === 0n) {
|
|
42
|
+
k--;
|
|
43
|
+
}
|
|
44
|
+
exp = k - 1074;
|
|
45
|
+
frac = (frac << BigInt(52 - k)) & ((1n << 52n) - 1n);
|
|
46
|
+
} else {
|
|
47
|
+
exp = biasedExp - 1023;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let fracHex: string;
|
|
51
|
+
if (prec < 0) {
|
|
52
|
+
fracHex = frac.toString(16).padStart(13, "0").replace(/0+$/, "");
|
|
53
|
+
} else if (prec >= 13) {
|
|
54
|
+
fracHex = frac.toString(16).padStart(13, "0").padEnd(prec, "0");
|
|
55
|
+
} else {
|
|
56
|
+
const keepBits = BigInt(prec * 4);
|
|
57
|
+
const droppedBits = 52n - keepBits;
|
|
58
|
+
let kept = frac >> droppedBits;
|
|
59
|
+
const remainder = frac & ((1n << droppedBits) - 1n);
|
|
60
|
+
const half = 1n << (droppedBits - 1n);
|
|
61
|
+
if (remainder > half || (remainder === half && (kept & 1n) === 1n)) {
|
|
62
|
+
kept += 1n;
|
|
63
|
+
}
|
|
64
|
+
if (kept >= 1n << keepBits) {
|
|
65
|
+
// Carry past the kept digits renormalizes: the integer digit would
|
|
66
|
+
// become 2, so bump the exponent and zero the fraction.
|
|
67
|
+
exp += 1;
|
|
68
|
+
kept = 0n;
|
|
69
|
+
}
|
|
70
|
+
fracHex = prec === 0 ? "" : kept.toString(16).padStart(prec, "0");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return assemble("1", fracHex, exp);
|
|
74
|
+
}
|
|
75
|
+
|
|
3
76
|
// FormatFloat converts the floating-point number f to a string,
|
|
4
77
|
// according to the format fmt and precision prec. It rounds the
|
|
5
78
|
// result assuming that the original was obtained from a floating-point
|
|
6
79
|
// value of bitSize bits (32 for float32, 64 for float64).
|
|
7
80
|
export function FormatFloat(f: number, fmt: number, prec: number, bitSize: number): string {
|
|
8
81
|
const fmtChar = String.fromCharCode(fmt);
|
|
9
|
-
|
|
82
|
+
|
|
10
83
|
// Handle special cases
|
|
11
84
|
if (isNaN(f)) {
|
|
12
85
|
return "NaN";
|
|
@@ -17,12 +90,18 @@ export function FormatFloat(f: number, fmt: number, prec: number, bitSize: numbe
|
|
|
17
90
|
if (f === -Infinity) {
|
|
18
91
|
return "-Inf";
|
|
19
92
|
}
|
|
20
|
-
|
|
93
|
+
|
|
21
94
|
// Convert to appropriate precision for float32
|
|
22
95
|
if (bitSize === 32) {
|
|
23
96
|
f = Math.fround(f);
|
|
24
97
|
}
|
|
25
|
-
|
|
98
|
+
|
|
99
|
+
if (fmtChar === 'x' || fmtChar === 'X') {
|
|
100
|
+
hexConv.setFloat64(0, f);
|
|
101
|
+
const neg = (hexConv.getUint32(0) >>> 31) === 1;
|
|
102
|
+
return (neg ? "-" : "") + formatHexFloat(Math.abs(f), prec, fmtChar === 'X');
|
|
103
|
+
}
|
|
104
|
+
|
|
26
105
|
switch (fmtChar.toLowerCase()) {
|
|
27
106
|
case 'e':
|
|
28
107
|
// Exponential notation
|
|
@@ -30,25 +109,21 @@ export function FormatFloat(f: number, fmt: number, prec: number, bitSize: numbe
|
|
|
30
109
|
return f.toExponential();
|
|
31
110
|
}
|
|
32
111
|
return f.toExponential(prec);
|
|
33
|
-
|
|
112
|
+
|
|
34
113
|
case 'f':
|
|
35
114
|
// Fixed-point notation
|
|
36
115
|
if (prec < 0) {
|
|
37
116
|
return f.toString();
|
|
38
117
|
}
|
|
39
118
|
return f.toFixed(prec);
|
|
40
|
-
|
|
119
|
+
|
|
41
120
|
case 'g':
|
|
42
121
|
// Use the more compact of 'e' or 'f'
|
|
43
122
|
if (prec < 0) {
|
|
44
123
|
return f.toPrecision();
|
|
45
124
|
}
|
|
46
125
|
return f.toPrecision(prec + 1);
|
|
47
|
-
|
|
48
|
-
case 'x':
|
|
49
|
-
// Hexadecimal notation (simplified)
|
|
50
|
-
return f.toString(16);
|
|
51
|
-
|
|
126
|
+
|
|
52
127
|
default:
|
|
53
128
|
// Default to 'g' format
|
|
54
129
|
if (prec < 0) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { FormatFloat } from './ftoa.gs.js'
|
|
4
|
+
|
|
5
|
+
const X = 'x'.charCodeAt(0)
|
|
6
|
+
const XU = 'X'.charCodeAt(0)
|
|
7
|
+
|
|
8
|
+
// Ground truth captured from go1.26.4 strconv.FormatFloat with the 'x' verb.
|
|
9
|
+
describe("strconv.FormatFloat 'x' (Go hex-float syntax)", () => {
|
|
10
|
+
it('emits normalized hex floats with a signed two-digit exponent', () => {
|
|
11
|
+
expect(FormatFloat(100, X, -1, 64)).toBe('0x1.9p+06')
|
|
12
|
+
expect(FormatFloat(1, X, -1, 64)).toBe('0x1p+00')
|
|
13
|
+
expect(FormatFloat(0.5, X, -1, 64)).toBe('0x1p-01')
|
|
14
|
+
expect(FormatFloat(3, X, -1, 64)).toBe('0x1.8p+01')
|
|
15
|
+
expect(FormatFloat(255, X, -1, 64)).toBe('0x1.fep+07')
|
|
16
|
+
expect(FormatFloat(0.1, X, -1, 64)).toBe('0x1.999999999999ap-04')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('handles zero and negative values', () => {
|
|
20
|
+
expect(FormatFloat(0, X, -1, 64)).toBe('0x0p+00')
|
|
21
|
+
expect(FormatFloat(-100, X, -1, 64)).toBe('-0x1.9p+06')
|
|
22
|
+
expect(FormatFloat(-0, X, -1, 64)).toBe('-0x0p+00')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('respects fixed precision with round-half-to-even and carry', () => {
|
|
26
|
+
expect(FormatFloat(100, X, 2, 64)).toBe('0x1.90p+06')
|
|
27
|
+
expect(FormatFloat(100, X, 4, 64)).toBe('0x1.9000p+06')
|
|
28
|
+
expect(FormatFloat(100, X, 13, 64)).toBe('0x1.9000000000000p+06')
|
|
29
|
+
expect(FormatFloat(1.9375, X, 0, 64)).toBe('0x1p+01')
|
|
30
|
+
expect(FormatFloat(1.96875, X, 1, 64)).toBe('0x1.0p+01')
|
|
31
|
+
expect(FormatFloat(255, X, 0, 64)).toBe('0x1p+08')
|
|
32
|
+
expect(FormatFloat(255, X, 1, 64)).toBe('0x1.0p+08')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('formats the smallest subnormal and float32 values', () => {
|
|
36
|
+
expect(FormatFloat(5e-324, X, -1, 64)).toBe('0x1p-1074')
|
|
37
|
+
expect(FormatFloat(100, X, -1, 32)).toBe('0x1.9p+06')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('uses the uppercase 0X/P form for the X verb', () => {
|
|
41
|
+
expect(FormatFloat(100, XU, -1, 64)).toBe('0X1.9P+06')
|
|
42
|
+
})
|
|
43
|
+
})
|
package/gs/strconv/itoa.gs.ts
CHANGED
|
@@ -3,39 +3,40 @@ import * as $ from "@goscript/builtin/index.js";
|
|
|
3
3
|
// FormatUint returns the string representation of i in the given base,
|
|
4
4
|
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
|
|
5
5
|
// for digit values >= 10.
|
|
6
|
-
export function FormatUint(i: number, base: number): string {
|
|
6
|
+
export function FormatUint(i: number | bigint, base: number): string {
|
|
7
7
|
if (base < 2 || base > 36) {
|
|
8
8
|
throw new Error("FormatUint: illegal base");
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
return
|
|
10
|
+
const v = typeof i === "bigint" ? i : BigInt(Math.trunc(i));
|
|
11
|
+
return BigInt.asUintN(64, v).toString(base);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// FormatInt returns the string representation of i in the given base,
|
|
15
15
|
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
|
|
16
16
|
// for digit values >= 10.
|
|
17
|
-
export function FormatInt(i: number, base: number): string {
|
|
17
|
+
export function FormatInt(i: number | bigint, base: number): string {
|
|
18
18
|
if (base < 2 || base > 36) {
|
|
19
19
|
throw new Error("FormatInt: illegal base");
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
const v = typeof i === "bigint" ? i : BigInt(Math.trunc(i));
|
|
22
|
+
return v.toString(base);
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
// Itoa is equivalent to FormatInt(i, 10).
|
|
25
26
|
export function Itoa(i: number): string {
|
|
26
|
-
return FormatInt(i, 10);
|
|
27
|
+
return FormatInt(BigInt(Math.trunc(i)), 10);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// AppendInt appends the string form of the integer i,
|
|
30
31
|
// as generated by FormatInt, to dst and returns the extended buffer.
|
|
31
|
-
export function AppendInt(dst: $.Bytes, i: number, base: number): $.Bytes {
|
|
32
|
+
export function AppendInt(dst: $.Bytes, i: number | bigint, base: number): $.Bytes {
|
|
32
33
|
const str = FormatInt(i, base);
|
|
33
34
|
return $.append(dst, ...$.stringToBytes(str)!);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// AppendUint appends the string form of the unsigned integer i,
|
|
37
38
|
// as generated by FormatUint, to dst and returns the extended buffer.
|
|
38
|
-
export function AppendUint(dst: $.Bytes, i: number, base: number): $.Bytes {
|
|
39
|
+
export function AppendUint(dst: $.Bytes, i: number | bigint, base: number): $.Bytes {
|
|
39
40
|
const str = FormatUint(i, base);
|
|
40
41
|
return $.append(dst, ...$.stringToBytes(str)!);
|
|
41
|
-
}
|
|
42
|
+
}
|