lib: retire os.assert/abort shims — assert/abort are builtins (#58 respell)
The flat checker scope makes ANY decl named assert/abort anywhere in the combined unit disable the builtin unit-wide (the #45 shadow shape: scope_lookup_prefer's cross-module fallback finds it). lib carried three colliding @symbol("rt_abort") shims (os, time, strconv/stof) plus the os.assert wrapper, so a bare assert(cond) in ANY program importing os mis-bound os.assert and failed arity — a hard blocker for regex fold-5 (regex.ha:660/670 bring builtin-assert mass). Ruled respell-now per the recurrence test (#45 -> #58). Delete the shims and the os.assert wrapper; every bare abort(msg) caller (regex, strings, utf8, hash, getopt, encoding/*, time, stof) now lands on the builtin, and the ~40 os.assert(c, m) sites respell to the builtin assert(c, m) — restoring the exact Hare spelling the lib ports diverged from (e.g. ref/hare/bytes/tokenize.ha:23). os.assert had no Hare counterpart (Hare's assert is a language builtin); rule-9 wrapper removed. temp/dirs/bufio already use the non-colliding rtabort spelling and keep it. Now-dead 'import os;' lines kept (pre-existing precedent: lib/strconv/strconv.ww carries one); a tree-wide dead-import sweep is a separate concern. regex.ww's if+abort workarounds citing #58 stay for the fold-5 owner to fold back into assert. combined.ww regenerated for all five selfhost tools + the smoke fixture via make.
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
// (when no continue exists in the loop).
|
||||
// - Hare `fn foo() T = if (cond) {...} else expr;` expression body
|
||||
// → ww requires a `{}` block body throughout.
|
||||
// - Hare bare `assert(cond)` builtin → `os.assert(cond, msg)`;
|
||||
// - Hare bare `assert(cond)` builtin → `assert(cond, msg)`;
|
||||
// wwstage cgen has no `assert` intercept (deferred fold).
|
||||
// - In-file instances of the above hoist pattern: `i_sz` (line 93)
|
||||
// hoists a per-iteration size cast out of a for-loop comparison
|
||||
@@ -110,7 +110,7 @@ fn leftshift(d: *decimal, k: u32) void = {
|
||||
let SZ_BOUND: size = (len(d.digits): size);
|
||||
let kU64: u64 = (k: u64);
|
||||
let MAXSHIFT_U32: u32 = (maxshift: u32);
|
||||
os.assert(k <= MAXSHIFT_U32, "strconv.leftshift: k > maxshift");
|
||||
assert(k <= MAXSHIFT_U32, "strconv.leftshift: k > maxshift");
|
||||
if (d.nd == (0u64: size)) { return; };
|
||||
let nn: u32 = leftshift_newdigits(d, k);
|
||||
let r: int = (d.nd: int) - 1;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
// (stof.ww hex_to_bits precedent).
|
||||
// - `&&=` → `x = x && y`. `ibool=if(b)1 else 0` expr-body → block.
|
||||
// comma `let a=…, b=…` → split. `if/else` expr-yield → pre-bound
|
||||
// local + block. `assert()` → `os.assert(cond,msg)`.
|
||||
// local + block. `assert()` → `assert(cond,msg)`.
|
||||
// - 2D row-bind `mul=TBL[base]` → direct double-index `TBL[base][0/1]`
|
||||
// (#155 / #156, stof.ww eisel_lemire precedent).
|
||||
// - ibool's u8 result + the u8 BITCOUNT defs cast explicitly to u32/u64
|
||||
@@ -62,7 +62,7 @@ import os;
|
||||
// (u128mul + the r128 struct live in stof.ww, fold-4's first consumer;
|
||||
// reused in-package here.)
|
||||
fn u128rshift(lo: u64, hi: u64, s: u32) u64 = {
|
||||
os.assert(s <= 64u32, "strconv.u128rshift: s > 64");
|
||||
assert(s <= 64u32, "strconv.u128rshift: s > 64");
|
||||
return (hi << (64u64 - (s: u64))) | (lo >> (s: u64));
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ fn pow5fac(v: u64) u32 = {
|
||||
let n_div_5: u64 = 3689348814741910323u64;
|
||||
let count: u32 = 0u32;
|
||||
for (true) {
|
||||
os.assert(value != 0u64, "strconv.pow5fac: value == 0");
|
||||
assert(value != 0u64, "strconv.pow5fac: value == 0");
|
||||
value *= m_inv_5;
|
||||
if (value > n_div_5) { break; };
|
||||
count += 1u32;
|
||||
@@ -92,8 +92,8 @@ fn pow5multiple(v: u64, p: u32) bool = { return pow5fac(v) >= p; };
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:69.
|
||||
fn pow2multiple(v: u64, p: u32) bool = {
|
||||
os.assert(v > 0u64, "strconv.pow2multiple: v == 0");
|
||||
os.assert(p < 64u32, "strconv.pow2multiple: p >= 64");
|
||||
assert(v > 0u64, "strconv.pow2multiple: v == 0");
|
||||
assert(p < 64u32, "strconv.pow2multiple: p >= 64");
|
||||
return (v & ((1u64 << (p: u64)) - 1u64)) == 0u64;
|
||||
};
|
||||
|
||||
@@ -136,7 +136,7 @@ fn mulshiftall64(m: u64, mul0: u64, mul1: u64, j: i32, mm_shift: u32) ryuv = {
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:140.
|
||||
fn log2pow5(e: u32) u32 = {
|
||||
os.assert(e <= 3528u32, "strconv.log2pow5: e > 3528");
|
||||
assert(e <= 3528u32, "strconv.log2pow5: e > 3528");
|
||||
return (e * 1217359u32) >> 19u32;
|
||||
};
|
||||
|
||||
@@ -146,13 +146,13 @@ fn pow5bits(e: u32) u32 = { return ceil_log2pow5(e); };
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:149.
|
||||
fn log10pow2(e: u32) u32 = {
|
||||
os.assert(e <= 1650u32, "strconv.log10pow2: e > 1650");
|
||||
assert(e <= 1650u32, "strconv.log10pow2: e > 1650");
|
||||
return (e * 78913u32) >> 18u32;
|
||||
};
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:154.
|
||||
fn log10pow5(e: u32) u32 = {
|
||||
os.assert(e <= 2620u32, "strconv.log10pow5: e > 2620");
|
||||
assert(e <= 2620u32, "strconv.log10pow5: e > 2620");
|
||||
return (e * 732923u32) >> 20u32;
|
||||
};
|
||||
|
||||
@@ -343,15 +343,15 @@ fn f64todecf64(mantissa: u64, exponent: u32) decf64 = {
|
||||
// u64 siblings at 32-bit width; they reuse the SHARED f64computeinvpow5/
|
||||
// f64computepow5 (and thus the f64 SPLIT2 tables) per ftos_ryu.ha — there
|
||||
// is no separate f32 table. Same scalar-PARAM-mutation → copy-to-local,
|
||||
// comma-split, assert → os.assert, expr-yield → block divergences as the
|
||||
// f64 path above. ====
|
||||
// comma-split, expr-yield → block divergences as the f64 path
|
||||
// above. ====
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:52. Largest p with 5^p | value (32-bit).
|
||||
fn pow5fac32(v: u32) u32 = {
|
||||
let value: u32 = v;
|
||||
let count: u32 = 0u32;
|
||||
for (true) {
|
||||
os.assert(value != 0u32, "strconv.pow5fac32: value == 0");
|
||||
assert(value != 0u32, "strconv.pow5fac32: value == 0");
|
||||
let q: u32 = value / 5u32;
|
||||
let r: u32 = value % 5u32;
|
||||
if (r != 0u32) { break; };
|
||||
@@ -366,8 +366,8 @@ fn pow5multiple32(v: u32, p: u32) bool = { return pow5fac32(v) >= p; };
|
||||
|
||||
// ref/hare/strconv/ftos_ryu.ha:75.
|
||||
fn pow2multiple32(v: u32, p: u32) bool = {
|
||||
os.assert(v > 0u32, "strconv.pow2multiple32: v == 0");
|
||||
os.assert(p < 32u32, "strconv.pow2multiple32: p >= 32");
|
||||
assert(v > 0u32, "strconv.pow2multiple32: v == 0");
|
||||
assert(p < 32u32, "strconv.pow2multiple32: p >= 32");
|
||||
return (v & ((1u32 << p) - 1u32)) == 0u32;
|
||||
};
|
||||
|
||||
@@ -377,14 +377,14 @@ fn pow2multiple32(v: u32, p: u32) bool = {
|
||||
// (lib/types/types.ww — no `export`), so Hare's `types::U32_MAX` can't be
|
||||
// referenced cross-package.
|
||||
fn mulshift32(m: u32, a: u64, s: u32) u32 = {
|
||||
os.assert(s > 32u32, "strconv.mulshift32: s <= 32");
|
||||
assert(s > 32u32, "strconv.mulshift32: s <= 32");
|
||||
let a_lo: u64 = (a: u32): u64;
|
||||
let a_hi: u64 = a >> 32u64;
|
||||
let b0: u64 = (m: u64) * a_lo;
|
||||
let b1: u64 = (m: u64) * a_hi;
|
||||
let sum: u64 = (b0 >> 32u64) + b1;
|
||||
let ss: u64 = sum >> ((s: u64) - 32u64);
|
||||
os.assert(ss <= 4294967295u64, "strconv.mulshift32: ss > U32_MAX");
|
||||
assert(ss <= 4294967295u64, "strconv.mulshift32: ss > U32_MAX");
|
||||
return ss: u32;
|
||||
};
|
||||
|
||||
@@ -533,7 +533,7 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = {
|
||||
|
||||
// ref/hare/strconv/ftos.ha:49. Decimal digit-count of n (n <= 1e17).
|
||||
fn declen(n: u64) uint = {
|
||||
os.assert(n <= 100000000000000000u64, "strconv.declen: n > 1e17");
|
||||
assert(n <= 100000000000000000u64, "strconv.declen: n > 1e17");
|
||||
if (n >= 100000000000000000u64) { return (18u32: uint); };
|
||||
if (n >= 10000000000000000u64) { return (17u32: uint); };
|
||||
if (n >= 1000000000000000u64) { return (16u32: uint); };
|
||||
@@ -621,7 +621,7 @@ fn encode_f_dec(d: *decimal, buf: []u8, out: i32) i32 = {
|
||||
// logic only): no precision zeros, lowercase 'e', no '+'/two-digit pad.
|
||||
fn encode_e_dec(d: *decimal, buf: []u8, out: i32) i32 = {
|
||||
let o: i32 = out;
|
||||
os.assert(d.nd > (0u64: size), "strconv.encode_e_dec: nd == 0");
|
||||
assert(d.nd > (0u64: size), "strconv.encode_e_dec: nd == 0");
|
||||
buf[o] = (d.digits[0] + 48u8): u8;
|
||||
o += 1i32;
|
||||
if ((d.nd: i32) > 1i32) {
|
||||
|
||||
@@ -97,8 +97,6 @@ fn todig(c: u8) u8 = {
|
||||
return 0u8; // unreachable; rt_abort is void-typed (path-cov)
|
||||
};
|
||||
|
||||
@symbol("rt_abort") fn abort(msg: str) void;
|
||||
|
||||
// ref/hare/strconv/stof.ha:25.
|
||||
type fast_parsed_float = struct {
|
||||
mantissa: u64,
|
||||
@@ -280,7 +278,7 @@ fn decimal_parse(d: *decimal, s: str) (void | invalid) = {
|
||||
|
||||
// ref/hare/strconv/stof.ha:173. Count of leading zero bits in n>0.
|
||||
fn leading_zeroes(n: u64) uint = {
|
||||
os.assert(n > 0u64, "strconv.leading_zeroes: n == 0");
|
||||
assert(n > 0u64, "strconv.leading_zeroes: n == 0");
|
||||
let b: u64 = 0u64;
|
||||
if ((n & 0xFFFFFFFF00000000u64) > 0u64) {
|
||||
n >>= 32u64;
|
||||
@@ -599,7 +597,7 @@ export fn stof64(s: str, b: base) (f64 | invalid | overflow) = {
|
||||
} else if (bb == base.HEX_LOWER) {
|
||||
bb = base.HEX;
|
||||
};
|
||||
os.assert(bb == base.DEC || bb == base.HEX,
|
||||
assert(bb == base.DEC || bb == base.HEX,
|
||||
"strconv.stof64: base must be DEC or HEX");
|
||||
|
||||
if (s.len == 0) {
|
||||
@@ -652,7 +650,7 @@ export fn stof32(s: str, b: base) (f32 | invalid | overflow) = {
|
||||
} else if (bb == base.HEX_LOWER) {
|
||||
bb = base.HEX;
|
||||
};
|
||||
os.assert(bb == base.DEC || bb == base.HEX,
|
||||
assert(bb == base.DEC || bb == base.HEX,
|
||||
"strconv.stof32: base must be DEC or HEX");
|
||||
|
||||
if (s.len == 0) {
|
||||
|
||||
Reference in New Issue
Block a user