test: slim uniesc carrier to .wwi roundtrip, value rows now @test-only (#4)
fold-6 carrier-split (drew's ruling): the 6 uniesc value rows (rune/string escape decode) are already covered 1:1 by test/lang/uniesc_test.ww @test rows -- same escape forms, same expected codepoints/bytes, same lexer escape-decode path, and dual-stage via test-lang-byteid (frontend-swap .s byte-id proves wwstage decode transitively, strictly more sensitive than re-running). So drop the duplicate value rows from the C driver; 110_uniesc_run.c slims to just the .wwi roundtrip -- a 2-package sep-build observer that can't be an in-language @test and isn't a reject case (its eventual runww home tracked as #19). The carrier still runs both stages for the roundtrip; no coverage lost, test count unchanged (404).
This commit is contained in:
@@ -1,20 +1,19 @@
|
||||
/*
|
||||
* 110_uniesc_run — \u / \U Unicode escapes, end-to-end through both
|
||||
* the cstage `ww` and the wwstage `ww_ww` drivers (task #50).
|
||||
* 110_uniesc_run — .wwi round-trip carrier for \u / \U Unicode escapes.
|
||||
*
|
||||
* Rune literals carry the raw codepoint; string literals UTF-8-encode
|
||||
* it into 1-4 bytes (ref/hare/hare/lex/lex.ha:347 lex_unicode + the
|
||||
* appendrune in lex_string). \x shares the same codepoint path, so a
|
||||
* >0x7F \x byte now widens to its 2-byte UTF-8 form in strings. Each
|
||||
* fixture returns 42 on a correct decode/encode.
|
||||
* The value-row half (rune/string \u \U \x decode asserts) migrated to the
|
||||
* in-language row-table test/lang/uniesc_test.ww (fold-6, task #4); this
|
||||
* file retains ONLY the .wwi round-trip case, which is a two-package
|
||||
* sep-build observer with no in-language @test home (it asserts the
|
||||
* PRODUCER re-serializes a wide-rune `def` byte-exact, observed across a
|
||||
* package boundary — not expressible as a single-compile @test).
|
||||
*
|
||||
* The dual-driver loop mirrors 640_int_cast_signed: the wwstage arm is
|
||||
* skipped when ww_ww is absent (e.g. a cstage-only build).
|
||||
*
|
||||
* The final per-driver case is a .wwi round-trip: an exported wide-rune
|
||||
* `def` re-serialized by the producer must re-parse byte-exact (the
|
||||
* write-twin of the lexer read-fix — cmd/w6c/wwi.c wwi_rune /
|
||||
* selfhost/cmd/wcc/wwi.ww wwirune emit \u/\U above 0xFF).
|
||||
* An exported wide-rune `def` re-serialized by the producer must re-parse
|
||||
* into the same codepoint (the write-twin of the lexer read-fix —
|
||||
* cmd/w6c/wwi.c wwi_rune / selfhost/cmd/wcc/wwi.ww wwirune emit \u/\U above
|
||||
* 0xFF). Runs through both the cstage `ww` and wwstage `ww_ww` drivers
|
||||
* (task #50); the wwstage arm is skipped when ww_ww is absent (a
|
||||
* cstage-only build), mirroring 640_int_cast_signed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,109 +30,6 @@ runwait(const char *cmd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct row { const char *label; const char *src; int want; };
|
||||
|
||||
static const struct row rows[] = {
|
||||
/* \u (4 hex) rune → U+00E9 codepoint 233. */
|
||||
{ "rune_u_2byte",
|
||||
"fn main() i32 = {\n"
|
||||
" let r: rune = '\\u00e9';\n"
|
||||
" if ((r: u32) == 233u32) { return 42; };\n"
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
/* \U (8 hex) rune → U+1F600 codepoint 128512 (> 0xFFFF, the case
|
||||
* that forced the `0x...: rune` int-cast spelling before #50). */
|
||||
{ "rune_U_emoji",
|
||||
"fn main() i32 = {\n"
|
||||
" let r: rune = '\\U0001F600';\n"
|
||||
" if ((r: u32) == 128512u32) { return 42; };\n"
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
/* \u é string → 2-byte UTF-8 0xC3 0xA9. */
|
||||
{ "str_u_2byte",
|
||||
"package main;\n"
|
||||
"import strings;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let b: []u8 = strings.toutf8(\"\\u00e9\");\n"
|
||||
" if (len(b) != 2) { return 1; };\n"
|
||||
" if (b[0] != 0xc3u8) { return 2; };\n"
|
||||
" if (b[1] != 0xa9u8) { return 3; };\n"
|
||||
" return 42;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
/* \u € string → 3-byte UTF-8 0xE2 0x82 0xAC. */
|
||||
{ "str_u_3byte",
|
||||
"package main;\n"
|
||||
"import strings;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let b: []u8 = strings.toutf8(\"\\u20ac\");\n"
|
||||
" if (len(b) != 3) { return 1; };\n"
|
||||
" if (b[0] != 0xe2u8) { return 2; };\n"
|
||||
" if (b[1] != 0x82u8) { return 3; };\n"
|
||||
" if (b[2] != 0xacu8) { return 4; };\n"
|
||||
" return 42;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
/* \U 😀 string → 4-byte UTF-8 0xF0 0x9F 0x98 0x80. */
|
||||
{ "str_U_4byte",
|
||||
"package main;\n"
|
||||
"import strings;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let b: []u8 = strings.toutf8(\"\\U0001F600\");\n"
|
||||
" if (len(b) != 4) { return 1; };\n"
|
||||
" if (b[0] != 0xf0u8) { return 2; };\n"
|
||||
" if (b[1] != 0x9fu8) { return 3; };\n"
|
||||
" if (b[2] != 0x98u8) { return 4; };\n"
|
||||
" if (b[3] != 0x80u8) { return 5; };\n"
|
||||
" return 42;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
/* \x ≥0x80 now yields a codepoint that UTF-8-encodes (\xe9 →
|
||||
* U+00E9 → 0xC3 0xA9), matching Hare's shared escape path. */
|
||||
{ "str_x_widens",
|
||||
"package main;\n"
|
||||
"import strings;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let b: []u8 = strings.toutf8(\"\\xe9\");\n"
|
||||
" if (len(b) != 2) { return 1; };\n"
|
||||
" if (b[0] != 0xc3u8) { return 2; };\n"
|
||||
" if (b[1] != 0xa9u8) { return 3; };\n"
|
||||
" return 42;\n"
|
||||
"};\n",
|
||||
42 },
|
||||
};
|
||||
|
||||
static int
|
||||
run_driver(const char *driver, const struct row *r, int i)
|
||||
{
|
||||
char src[128], tmpdir[64], outbin[128], rmcmd[160], cmd[1024];
|
||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/wwue_%d_d_%d", getpid(), i);
|
||||
mkdir(tmpdir, 0755);
|
||||
snprintf(src, sizeof src, "%s/wwue_%d_%d.ww", tmpdir, getpid(), i);
|
||||
snprintf(outbin, sizeof outbin, "%s/wwue_%d_%d", tmpdir, getpid(), i);
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "row[%s]: build via %s failed\n",
|
||||
r->label, driver);
|
||||
runwait(rmcmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int got = runwait(outbin);
|
||||
|
||||
runwait(rmcmd);
|
||||
return got;
|
||||
}
|
||||
|
||||
/* run_roundtrip — sep-build a two-package program where the imported
|
||||
* package exports wide-rune defs; the producer must serialize them as
|
||||
* \u/\U so the importer re-parses the same codepoint. Returns the built
|
||||
@@ -219,7 +115,6 @@ main(void)
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
int n = (int)(sizeof rows / sizeof rows[0]);
|
||||
int total = 0, fail = 0;
|
||||
for (int d = 0; drivers[d].name; d++) {
|
||||
if (drivers[d].gated_on_existence
|
||||
@@ -228,17 +123,6 @@ main(void)
|
||||
drivers[d].name, drivers[d].path);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
int got = run_driver(drivers[d].path, &rows[i], i);
|
||||
total++;
|
||||
if (got != rows[i].want) {
|
||||
fprintf(stderr,
|
||||
"uniesc_run[%s][%s]: exit=%d want=%d\n",
|
||||
drivers[d].name, rows[i].label,
|
||||
got, rows[i].want);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
int rt = run_roundtrip(drivers[d].path, d);
|
||||
total++;
|
||||
if (rt != 42) {
|
||||
|
||||
Reference in New Issue
Block a user