Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 39 additions & 37 deletions bend2/comp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,40 @@ function show_main(book: Bend.Book): Show | null {
return show;
}

const SHOW_ESC: [number, string][] = [[10, "n"], [9, "t"], [13, "r"], [0, "0"]];
const SHOW_HEX = "c < 32 || c == 127 || (c >= 0xD800 && c <= 0xDFFF) || c > 0x10FFFF";
const SHOW_BR: Record<string, string> = { Con: "[]", Nil: "[]", Tuple: "()" };

function show_chr_src(js: boolean): string {
const hex = js ? SHOW_HEX.replaceAll(" == ", " === ") : SHOW_HEX;
return js ? `function show_chr(c, q) {
const k = { ${SHOW_ESC.map(([n, s]) => n + ": \"" + s + "\"").join(", ")}, 92: "\\\\" }[c]
?? (c === q.codePointAt(0) ? q : null);
return k !== null ? "\\\\" + k : ${hex}
? "\\\\u{" + c.toString(16) + "}" : String.fromCodePoint(c);
}` : `static void show_chr(u64 c, char q) {
char b[4];
int k = ${SHOW_ESC.map(([n, s]) => "c == " + n + " ? '" + s + "'").join(" : ")}
: c == 92 || c == (u64)q ? (int)c : 0;
if (k != 0) { printf("\\\\%c", k); }
else if (${hex}) { printf("\\\\u{%llx}", (unsigned long long)c); }
else { fwrite(b, 1, io_utf8(b, c), stdout); }
}`;
}

function show_br_js(): string {
return "{ " + Object.entries(SHOW_BR).map(([k, v]) => k + ": \"" + v + "\"")
.join(", ") + " }[fs[0]] ?? \"{}\"";
}

function show_br_c(): string {
const g: Record<string, string[]> = {};
for (const [k, v] of Object.entries(SHOW_BR)) (g[v] ??= []).push(k);
return Object.entries(g).map(([br, ks], i) => (i ? "else if" : "if")
+ " (" + ks.map((k) => `strcmp(k, "${k}") == 0`).join(" || ")
+ `) { o = '${br[0]}'; z = '${br[1]}'; }`).join("\n ");
}

export function io_run(book: Bend.Book, args: string[] = []): number {
const src = js_lib(book, ["main"], null) + "\n" + RUNTIME_MAIN
+ "\ncli_args = " + JSON.stringify(args) + ";\nreturn io_run("
Expand Down Expand Up @@ -5839,20 +5873,7 @@ ${NATIVE.IO}
// its words.
static void show_val(Env e, u32 d, const Term* w, char chain);

// char_show: an escape, a \u{hex}, else the code point in UTF-8
static void show_chr(u64 c, char q) {
char b[4];
int k = c == 10 ? 'n' : c == 9 ? 't' : c == 13 ? 'r' : c == 0 ? '0'
: c == 92 || c == (u64)q ? (int)c : 0;
if (k != 0) {
printf("\\%c", k);
} else if (c < 32 || c == 127 || (c >= 0xD800 && c <= 0xDFFF)
|| c > 0x10FFFF) {
printf("\\u{%llx}", (unsigned long long)c);
} else {
fwrite(b, 1, io_utf8(b, c), stdout);
}
}
${show_chr_src(false)}

// The shortest text that reads back, as a literal: a point before an e
static void show_f32(u32 x) {
Expand Down Expand Up @@ -5929,13 +5950,7 @@ static void show_val(Env e, u32 d, const Term* w, char chain) {
const char* k = SHOW_NAMES[D[a]];
char o = '{';
char z = '}';
if (strcmp(k, "Con") == 0 || strcmp(k, "Nil") == 0) {
o = '[';
z = ']';
} else if (strcmp(k, "Tuple") == 0) {
o = '(';
z = ')';
}
${show_br_c()}
if (o == '{') {
printf("%s{", k);
} else if (chain != o) {
Expand Down Expand Up @@ -6313,13 +6328,7 @@ function cli(argv) {
// Show
// ====

// char_show: an escape, a \u{hex}, else the code point
function show_chr(c, q) {
const k = { 10: "n", 9: "t", 13: "r", 0: "0", 92: "\\" }[c]
?? (c === q.codePointAt(0) ? q : null);
return k !== null ? "\\" + k : c < 32 || c === 127
? "\\u{" + c.toString(16) + "}" : String.fromCodePoint(c);
}
${show_chr_src(true)}

// A pure main's value, spelled as term_show spells it: d is a node of
// the descriptor D over the names N (see show_main), v the value, chain
Expand All @@ -6330,15 +6339,8 @@ function show_val(D, N, d, v, chain) {
? { $: v ? "True" : "False" } : v);
let a = d + 3;
for (; N[D[a]] !== fs[0]; a += 3 + 2 * D[a + 2]) {}
let o = "{";
let z = "}";
if (fs[0] === "Con" || fs[0] === "Nil") {
o = "[";
z = "]";
} else if (fs[0] === "Tuple") {
o = "(";
z = ")";
}
const br = ${show_br_js()};
const o = br[0], z = br[1];
let s = o === "{" ? fs[0] + "{" : chain === o ? "" : o;
for (const [j, f] of fs.slice(1).entries()) {
if (o === "[" ? j === 0 && chain === o : j > 0) {
Expand Down