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:
@@ -167,14 +167,17 @@ wwi_quote(FILE *of, const char *s, u64 n)
|
||||
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);
|
||||
/* #50: the lexer now reads \u/\U, so wide codepoints round-trip as
|
||||
* those escapes (write-twin of lex.c lexunicode). Codepoints <=0xff
|
||||
* keep the \xHH spelling they already round-tripped as. */
|
||||
if (cp > 0xffff) {
|
||||
fprintf(of, "'\\U%08x'", (unsigned)cp);
|
||||
return;
|
||||
}
|
||||
if (cp > 0xff) {
|
||||
fprintf(of, "'\\u%04x'", (unsigned)cp);
|
||||
return;
|
||||
}
|
||||
unsigned char c = (unsigned char)cp;
|
||||
fputc('\'', of);
|
||||
switch (c) {
|
||||
|
||||
Reference in New Issue
Block a user