lex,wwi: \u/\U unicode escapes + wide-rune .wwi round-trip, both stages (#50)
Hare-faithful \u (4 hex) / \U (8 hex) escapes; \x/\u/\U share one codepoint path (ref/hare/hare/lex/lex.ha lex_unicode); string literals UTF-8-encode multi-byte codepoints (cstage inline utf8enc, wwstage utf8.encoderune). The .wwi producer rune serializer now emits \u/\U so exported wide-rune defs round-trip (was a fatal >0xFF). Reject >0x10FFFF and surrogates with Hare- verbatim error strings. Closes the int-cast spelling divergence (#48 RUNE_MAX). Both stages byte-identical; 446 tests pass.
This commit is contained in:
@@ -201,14 +201,36 @@ fn wwicheckdecl(c: *checker, d: *syntax.node) i32 = {
|
||||
|
||||
// --- type-expr + const-expr unparser (rob §2.2/§2.4) ------------------
|
||||
|
||||
// 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).
|
||||
// wwihexdigits — emit the low `n` hex digits of `v`, most-significant
|
||||
// first, lowercase. Byte-identical to cstage's fprintf("%0Nx").
|
||||
fn wwihexdigits(fd: i32, v: u64, n: i32) void = {
|
||||
let i: i32 = n - 1;
|
||||
for (i >= 0) {
|
||||
let d: u64 = (v >> ((i: u64) * 4u64)) & 15u64;
|
||||
let c: u8 = 0u8;
|
||||
if (d < 10u64) { c = (d: u8) + 48u8; } else { c = ((d: u8) - 10u8) + 97u8; };
|
||||
wputb(fd, c);
|
||||
i -= 1;
|
||||
};
|
||||
};
|
||||
|
||||
// #50: the lexer now reads \u/\U, so wide codepoints round-trip as those
|
||||
// escapes (write-twin of lex.ww lexunicode). Codepoints <=0xff keep the
|
||||
// \xHH spelling they already round-tripped as.
|
||||
fn wwirune(fd: i32, cp: u64) void = {
|
||||
if (cp > 65535u64) {
|
||||
wputb(fd, '\'');
|
||||
wputs(fd, "\\U");
|
||||
wwihexdigits(fd, cp, 8);
|
||||
wputb(fd, '\'');
|
||||
return;
|
||||
};
|
||||
if (cp > 255u64) {
|
||||
wputs(2, "wwi: rune codepoint exceeds \\xHH (task #50)\n");
|
||||
os.exit(1);
|
||||
wputb(fd, '\'');
|
||||
wputs(fd, "\\u");
|
||||
wwihexdigits(fd, cp, 4);
|
||||
wputb(fd, '\'');
|
||||
return;
|
||||
};
|
||||
let c: u8 = cp: u8;
|
||||
wputb(fd, '\'');
|
||||
|
||||
Reference in New Issue
Block a user