mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-31 07:23:06 +08:00
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks. - Preserve compiler import boundaries and protected fixtures while cleaning up lint findings. - Standardize source formatting and validate import, fixture, and embedded-source protections.
375 lines
9.4 KiB
JavaScript
375 lines
9.4 KiB
JavaScript
// Generates ToNumber(string) test cases with Node as the oracle — the
|
|
// scr_string_to_number counterpart of gen-number-cases.mjs (formatting).
|
|
// Each line: <UTF-8 bytes of the input string as hex, "-" when empty>\t
|
|
// <16 hex digits of Number(input)'s bit pattern>
|
|
//
|
|
// node gen-tonumber-cases.mjs cases # curated + 50k seeded cases → stdout
|
|
// node gen-tonumber-cases.mjs fuzz <count> # <count> random cases → stdout
|
|
import { argv, stdout } from "node:process";
|
|
|
|
const f64 = new Float64Array(1);
|
|
const u64 = new BigUint64Array(f64.buffer);
|
|
|
|
function line(s) {
|
|
f64[0] = Number(s);
|
|
const hex = Buffer.from(s, "utf8").toString("hex");
|
|
return `${hex === "" ? "-" : hex}\t${u64[0].toString(16).padStart(16, "0")}\n`;
|
|
}
|
|
|
|
// The complete StrWhiteSpace set: WhiteSpace (TAB VT FF SP NBSP ZWNBSP +
|
|
// the Zs category) and LineTerminator (LF CR LS PS).
|
|
const WS = [
|
|
"\t",
|
|
"\n",
|
|
"\v",
|
|
"\f",
|
|
"\r",
|
|
" ",
|
|
"\u00a0",
|
|
"\u1680",
|
|
"\u2000",
|
|
"\u2001",
|
|
"\u2002",
|
|
"\u2003",
|
|
"\u2004",
|
|
"\u2005",
|
|
"\u2006",
|
|
"\u2007",
|
|
"\u2008",
|
|
"\u2009",
|
|
"\u200a",
|
|
"\u2028",
|
|
"\u2029",
|
|
"\u202f",
|
|
"\u205f",
|
|
"\u3000",
|
|
"\ufeff",
|
|
];
|
|
|
|
function* curated() {
|
|
// Whitespace: empty, each StrWhiteSpaceChar alone, all of them joined,
|
|
// and NON-whitespace lookalikes (ZWSP, ZWNJ, MVS) that must be NaN.
|
|
yield "";
|
|
yield* WS;
|
|
yield WS.join("");
|
|
yield* ["\u200b", "\u200c", "\u200d", "\u180e", "\u0085"];
|
|
// Core decimals, signed and whitespace-decorated.
|
|
const core = [
|
|
"0",
|
|
"-0",
|
|
"+0",
|
|
"1",
|
|
"42",
|
|
"-1",
|
|
"0.5",
|
|
".5",
|
|
"5.",
|
|
"1.",
|
|
"+.5",
|
|
"-.5",
|
|
"0.1",
|
|
"0.2",
|
|
"0.3",
|
|
"123.456",
|
|
"3.141592653589793",
|
|
"1e3",
|
|
"1E3",
|
|
"1e+3",
|
|
"1e-3",
|
|
"5.e3",
|
|
".5e-3",
|
|
"2e308",
|
|
"1e309",
|
|
"-1e309",
|
|
"1e-309",
|
|
"1e-324",
|
|
"5e-324",
|
|
"2.5e-324",
|
|
"2e-324",
|
|
"7.5e-324",
|
|
"1e-400",
|
|
"1e400",
|
|
"9007199254740991",
|
|
"9007199254740992",
|
|
"9007199254740993",
|
|
"9007199254740993.0",
|
|
"9007199254740994",
|
|
"9007199254740995",
|
|
"1.7976931348623157e308",
|
|
"1.7976931348623158e308",
|
|
"1.7976931348623159e308",
|
|
"-1.7976931348623157e308",
|
|
"2.2250738585072014e-308",
|
|
"2.2250738585072011e-308",
|
|
"4.9406564584124654e-324",
|
|
"2.4703282292062327e-324",
|
|
"2.4703282292062328e-324",
|
|
"1.0000000000000002",
|
|
"1.0000000000000001",
|
|
"0.000001",
|
|
"0.0000001",
|
|
"1e21",
|
|
"1e-7",
|
|
"123456789012345678901",
|
|
"Infinity",
|
|
"+Infinity",
|
|
"-Infinity",
|
|
];
|
|
yield* core;
|
|
for (const s of core) {
|
|
yield ` ${s} `;
|
|
yield `\t\n${s}\u00a0\ufeff`;
|
|
yield `\u3000${s}\u2028`;
|
|
}
|
|
// Non-decimal integer literals: every prefix case, digit sweeps, the
|
|
// 2^53 neighborhood (rounding), giant exact-integer inputs (bignum
|
|
// rounding, half-even ties), and overflow past 2^1024 → Infinity.
|
|
const radixes = [
|
|
["0x", "0X"],
|
|
["0o", "0O"],
|
|
["0b", "0B"],
|
|
];
|
|
const digits = {
|
|
"0x": "0123456789abcdefABCDEF",
|
|
"0o": "01234567",
|
|
"0b": "01",
|
|
};
|
|
for (const [lo, up] of radixes) {
|
|
const d = digits[lo];
|
|
yield* [`${lo}0`, `${up}0`, `${lo}1`, `${up}1`, `${lo}${d}`, `${lo}00007`];
|
|
yield ` ${lo}11 `;
|
|
yield* [lo, up, `${lo} 1`, `-${lo}1`, `+${lo}1`, `${lo}1.5`, `${lo}1e2x`];
|
|
}
|
|
yield* [
|
|
"0x1fffffffffffff",
|
|
"0x20000000000000",
|
|
"0x20000000000001",
|
|
"0x20000000000002",
|
|
"0x20000000000003",
|
|
"0x20000000000004",
|
|
"0x3fffffffffffff",
|
|
"0x40000000000001",
|
|
"0x40000000000002",
|
|
"0x7fffffffffffffff",
|
|
"0x8000000000000000",
|
|
"0xffffffffffffffff",
|
|
"0x10000000000000000",
|
|
"0x100000000000000001",
|
|
"0xfffffffffffff800000000000000000000", // half-even tie territory
|
|
"0xfffffffffffffbffffffffffffffffffff",
|
|
"0xfffffffffffffc00000000000000000000",
|
|
"0x" + "f".repeat(100),
|
|
"0x" + "1" + "0".repeat(255), // < 2^1024
|
|
"0x" + "1" + "0".repeat(256), // = 2^1024 → Infinity
|
|
"0x" + "f".repeat(300), // way past → Infinity
|
|
"0b" + "1".repeat(53),
|
|
"0b" + "1".repeat(54),
|
|
"0b" + "1".repeat(55),
|
|
"0b1" + "0".repeat(52) + "1",
|
|
"0b1" + "0".repeat(53) + "1",
|
|
"0b" + "1".repeat(1024),
|
|
"0b1" + "0".repeat(1023),
|
|
"0b1" + "0".repeat(1024),
|
|
"0o" + "7".repeat(400),
|
|
"0o1" + "0".repeat(340),
|
|
"0x0000000000000000000000000000",
|
|
];
|
|
// Long decimal digit strings: exactness and overflow through strtod.
|
|
for (const k of [17, 20, 25, 50, 100, 308, 309, 310, 400, 800]) {
|
|
yield "9".repeat(k);
|
|
yield "1" + "0".repeat(k);
|
|
yield "0." + "0".repeat(k) + "1";
|
|
yield "0." + "1".repeat(k);
|
|
yield "1." + "9".repeat(k) + "e-100";
|
|
}
|
|
// Garbage shapes: every one must be NaN (asserted against Node either
|
|
// way — the oracle decides).
|
|
yield* [
|
|
"12px",
|
|
"px12",
|
|
"1.2.3",
|
|
"1..2",
|
|
"..5",
|
|
"1_000",
|
|
"1,000",
|
|
"+-1",
|
|
"-+1",
|
|
"--1",
|
|
"++1",
|
|
"1 2",
|
|
"+ 1",
|
|
"- 1",
|
|
"NaN",
|
|
"nan",
|
|
"-NaN",
|
|
"infinity",
|
|
"INFINITY",
|
|
"Infinit",
|
|
"Infinityy",
|
|
"+Infinity8",
|
|
"- Infinity",
|
|
"e5",
|
|
".e5",
|
|
"+.",
|
|
"-.",
|
|
".",
|
|
"+",
|
|
"-",
|
|
"0x",
|
|
"0xg",
|
|
"0o8",
|
|
"0b2",
|
|
"1e",
|
|
"1e+",
|
|
"1e-",
|
|
"1e1.5",
|
|
"1e+1e",
|
|
"0x1_0",
|
|
"0b1_0",
|
|
"\u0661\u0662\u0663",
|
|
"12\u0663",
|
|
"1\u200b",
|
|
"\u200b1",
|
|
"1 |