lib/types,wcc/ww: export the limit constants (#48)
lib/types limit consts were bare `def`s, so the .wwi (sep-compile's
interface) correctly omitted them while the flat combined.ww let a
cross-package user (lib/strings splitn → types.I32_MAX) reach the
private def — sep-compile then failed (wwstage `asserttyped: dot
'I32_MAX'`; cstage undefined-ref). Hare exports types::I32_MAX and the
whole limit family (ref/hare/types/limits.ha, arch+x86_64.ha); ww not
exporting them was the divergence.
export the 24 existing limit defs ({I,U}{8,16,32,64}_{MIN,MAX},
INT/UINT/SIZE/UINTPTR_{MIN,MAX}) and the existing RUNE_MIN, and add
exported RUNE_MAX. ww's derived machine-word int/uint/size/uintptr
VALUES are kept verbatim (user-ratified 64-bit-int divergence); fidelity
here is the NAME SET + export-visibility, not the values. RUNE_MAX is
written `0x10ffff: rune` — same codepoint as Hare's '\U0010ffff', forced
because ww's lexer has no \u/\U escape (#50).
Exporting the consts made `w6c -I` walk them and fatal on RUNE_MIN
('\0'): the .wwi const-expr unparser had no N_RUNELIT arm. Add one,
both stages (wwi_rune / wwirune), rendering a \xHH-escaped rune literal
(>0xFF fails loud, #50). Const casts need no arm — the checker folds
them to integer literals before the producer runs. 989_m2wwi_run gains
a types.wwi gate (byte-id + re-parse + asserts export def I32_MAX and
RUNE_MAX reach the interface). byte-id-neutral: a def emits no symbol.
This commit is contained in:
@@ -164,6 +164,31 @@ wwi_quote(FILE *of, const char *s, u64 n)
|
||||
fputc('"', of);
|
||||
}
|
||||
|
||||
static void
|
||||
wwi_rune(FILE *of, u64 cp)
|
||||
{
|
||||
/* The lexer's rune escapes stop at \xHH (no \u/\U — task #50), so a
|
||||
* codepoint above 0xff can't render as a re-parseable rune literal;
|
||||
* fail loud rather than emit a malformed one. No exported def names
|
||||
* such a rune today (RUNE_MAX is written as an int-cast for the same
|
||||
* reason). */
|
||||
if (cp > 0xff)
|
||||
fatal("wwi: rune codepoint U+%llx exceeds \\xHH (task #50)",
|
||||
(unsigned long long)cp);
|
||||
unsigned char c = (unsigned char)cp;
|
||||
fputc('\'', of);
|
||||
switch (c) {
|
||||
case '\'': fputs("\\'", of); break;
|
||||
case '\\': fputs("\\\\", of); break;
|
||||
case '\n': fputs("\\n", of); break;
|
||||
case '\t': fputs("\\t", of); break;
|
||||
default:
|
||||
if (c < 0x20 || c >= 0x7f) fprintf(of, "\\x%02x", c);
|
||||
else fputc(c, of);
|
||||
}
|
||||
fputc('\'', of);
|
||||
}
|
||||
|
||||
static void
|
||||
wwi_param(FILE *of, Node *p)
|
||||
{
|
||||
@@ -296,6 +321,11 @@ wwi_expr(FILE *of, Node *e)
|
||||
case N_FALSE: fputs("false", of); break;
|
||||
case N_NIL: fputs("nil", of); break;
|
||||
case N_STRLIT: wwi_quote(of, e->str, e->strlen); break;
|
||||
/* A bare rune literal in a const-expr (types::RUNE_MIN = '\0'); casts
|
||||
* never reach here — the checker folds a const cast to an integer
|
||||
* literal before the producer runs (RUNE_MAX `0x10ffff: rune` emits
|
||||
* as the plain int 1114111). */
|
||||
case N_RUNELIT: wwi_rune(of, e->uval); break;
|
||||
case N_BIN:
|
||||
wwi_expr(of, e->lhs);
|
||||
fprintf(of, " %s ", tokname(e->op));
|
||||
|
||||
Reference in New Issue
Block a user