Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512// Downlevel mode's JSX output, the classic runtime: `factory(tag, props | null, ...children)`, matching// ts.transpileModule with `jsx: "react"`. strip.zena parses the JSX and calls these through the jsx* hooks,// so only build/downlevel.wasm links this file. Every inserted text is free of line breaks; a string that spans// lines in the source closes before each line break and continues after it (`"a"+<LF>" b"`).import { Memory } from 'zena:memory';import { delta } from './lex.zena';import { outReserve, outCommit } from './strip.zena';import { JSX_ENT } from './keywords.zena';
// The factory names: the options' (`pragma`), then the file's `@jsx`/`@jsxFrag` comment pragmas, as bytes.// A comment pragma's length is -1 before one is seen and 0 when the first one seen is not an entity name, which// TypeScript ignores in favor of the option (it never looks at a second one).var pr: FixedArray<i32> = new FixedArray<i32>(128, 0);var prLen: i32 = 0;var factoryAt: i32 = 0;var factoryLen: i32 = 0;var fragAt: i32 = 0;var fragLen: i32 = 0;var cFactoryAt: i32 = 0;var cFactoryLen: i32 = -1;var cFragAt: i32 = 0;var cFragLen: i32 = -1;
// Kept text segments of the JSX text being written: [start, end) pairs.var seg: FixedArray<i32> = new FixedArray<i32>(64, 0);var segN: i32 = 0;
function prPush(c: i32): void { if (prLen == pr.length) { let b = new FixedArray<i32>(pr.length * 2, 0); var i = 0; while (i < prLen) { b[i] = pr[i]; i = i + 1; } pr = b; } pr[prLen] = c; prLen = prLen + 1;}
// The ABI's pragma(): `a` bytes of the factory, then `b` of the fragment factory, at addr. Starts a stream's// factories, so it also forgets the previous stream's comment pragmas.export function pragma(addr: i32, a: i32, b: i32): void { prLen = 0; factoryAt = 0; factoryLen = a; fragAt = a; fragLen = b; var i = 0; while (i < a + b) { prPush(Memory.default.getU8(addr + i)); i = i + 1; } cFactoryLen = -1; cFragLen = -1;}
function inByte(p: i32): i32 { return Memory.default.getU8(p + delta);}
function isLt(c: i32): boolean { return c == 10 || c == 13;}
// ASCII whitespace, as the pragma regex's `\s` sees it.function isSpace(c: i32): boolean { return c == 32 || c == 9 || c == 10 || c == 13 || c == 11 || c == 12;}
function isIdByte(c: i32, start: boolean): boolean { if ((c >= 97 && c <= 122) || (c >= 65 && c <= 90) || c == 95 || c == 36 || c >= 0x80) return true; return !start && c >= 48 && c <= 57;}
// Input [a, b) is an entity name, `a` or `a.b.c`: what TypeScript's parseIsolatedEntityName accepts.function isEntityName(a: i32, b: i32): boolean { var start = true; var q = a; while (q < b) { let c = inByte(q); if (c == 46) { if (start) return false; start = true; } else { if (!isIdByte(c, start)) return false; start = false; } q = q + 1; } return !start;}
// Input [a, b) is `word`, ignoring ASCII case: 1 for `jsx`, 2 for `jsxfrag`, else 0.function pragmaKind(a: i32, b: i32): i32 { let n = b - a; if (n != 3 && n != 7) return 0; if ((inByte(a) | 32) != 106 || (inByte(a + 1) | 32) != 115 || (inByte(a + 2) | 32) != 120) return 0; if (n == 3) return 1; if ((inByte(a + 3) | 32) != 102 || (inByte(a + 4) | 32) != 114 || (inByte(a + 5) | 32) != 97 || (inByte(a + 6) | 32) != 103) return 0; return 2;}
// TypeScript's processCommentPragmas over the leading comments [0, end) of the file: in each block comment,// `/@(\S+)(\s+(?:\S.*)?)?$/gm`, where the factory is the first word after the name.export function pragmas(end: i32): void { var p = 0; if (end >= 2 && inByte(0) == 35 && inByte(1) == 33) { while (p < end && !isLt(inByte(p))) p = p + 1; } while (p + 1 < end) { let c = inByte(p); if (c == 47 && inByte(p + 1) == 42) { var q = p + 2; while (q + 1 < end && !(inByte(q) == 42 && inByte(q + 1) == 47)) q = q + 1; q = q + 2; if (q > end) q = end; commentPragmas(p, q); p = q; } else if (c == 47 && inByte(p + 1) == 47) { while (p < end && !isLt(inByte(p))) p = p + 1; } else { p = p + 1; } }}
function commentPragmas(a: i32, b: i32): void { var p = a; while (p < b) { if (inByte(p) != 64) { p = p + 1; continue; } var q = p + 1; while (q < b && !isSpace(inByte(q))) q = q + 1; if (q == p + 1) { p = p + 1; continue; } let kind = pragmaKind(p + 1, q); var r = q; while (r < b && isSpace(inByte(r))) r = r + 1; let arg = r; while (r < b && !isSpace(inByte(r))) r = r + 1; if (arg < r) { if (kind == 1 && cFactoryLen < 0) { cFactoryAt = prLen; cFactoryLen = savePragma(arg, r); } else if (kind == 2 && cFragLen < 0) { cFragAt = prLen; cFragLen = savePragma(arg, r); } } while (r < b && !isLt(inByte(r))) r = r + 1; p = r; }}
// Copies input [a, b) after the stored names and returns its length, or 0 when it is not an entity name.function savePragma(a: i32, b: i32): i32 { if (!isEntityName(a, b)) return 0; var q = a; while (q < b) { prPush(inByte(q)); q = q + 1; } return b - a;}
// ---------------------------------------------------------------------------// Output.
function put(c: i32): void { Memory.default.setU8(outReserve(1), c); outCommit(1);}
function putIn(a: i32, b: i32): void { var q = a; while (q < b) { put(inByte(q)); q = q + 1; }}
function putPr(at: i32, n: i32): void { var i = 0; while (i < n) { put(pr[at + i]); i = i + 1; }}
// The line terminators of input [a, b), and nothing else: what keeps the source's lines.function lines(a: i32, b: i32): void { var q = a; while (q < b) { let c = inByte(q); if (isLt(c)) { put(c); } else if (c == 0xe2 && q + 2 < b && inByte(q + 1) == 0x80 && (inByte(q + 2) | 1) == 0xa9) { putIn(q, q + 3); q = q + 2; } q = q + 1; }}
function putNull(): void { put(110); put(117); put(108); put(108);}
// `factory(`, then for a fragment `fragmentFactory,null`.export function open(frag: boolean): void { if (cFactoryLen > 0) putPr(cFactoryAt, cFactoryLen); else putPr(factoryAt, factoryLen); put(40); if (!frag) return; if (cFragLen > 0) putPr(cFragAt, cFragLen); else putPr(fragAt, fragLen); put(44); putNull();}
// Input [a, b), a tag or attribute name, as a string.export function quoted(a: i32, b: i32): void { put(34); putIn(a, b); put(34);}
// `ns:name` as one string; any line terminators between the two parts follow it.export function ns(a1: i32, b1: i32, a2: i32, b2: i32): void { put(34); putIn(a1, b1); put(58); putIn(a2, b2); put(34); lines(b1, a2);}
// strip.zena's JX_* pieces.export function piece(k: i32): void { if (k == 0) { put(44); } else if (k == 1) { put(44); put(123); } else if (k == 2) { put(125); } else if (k == 3) { put(44); putNull(); } else if (k == 4) { put(41); } else if (k == 5) { put(58); } else if (k == 6) { put(58); put(116); put(114); put(117); put(101); } else if (k == 7) { put(44); put(40); } else if (k == 8) { put(40); } else { put(59); }}
// ---------------------------------------------------------------------------// Strings.
// The code point of the UTF-8 sequence at input q, and its length (1 to 4) in seqN.var seqN: i32 = 1;function codePointAt(q: i32): i32 { let c = inByte(q); if (c < 0x80) { seqN = 1; return c; } if (c < 0xe0) { seqN = 2; return ((c & 0x1f) << 6) | (inByte(q + 1) & 0x3f); } if (c < 0xf0) { seqN = 3; return ((c & 0x0f) << 12) | ((inByte(q + 1) & 0x3f) << 6) | (inByte(q + 2) & 0x3f); } seqN = 4; return ((c & 0x07) << 18) | ((inByte(q + 1) & 0x3f) << 12) | ((inByte(q + 2) & 0x3f) << 6) | (inByte(q + 3) & 0x3f);}
// TypeScript's isLineBreak and isWhiteSpaceSingleLine.function isLineBreak(cp: i32): boolean { return cp == 10 || cp == 13 || cp == 0x2028 || cp == 0x2029;}
function isSingleLineSpace(cp: i32): boolean { if (cp == 32 || cp == 9 || cp == 11 || cp == 12) return true; if (cp < 0x85) return false; return cp == 0x85 || cp == 0xa0 || cp == 0x1680 || (cp >= 0x2000 && cp <= 0x200b) || cp == 0x202f || cp == 0x205f || cp == 0x3000 || cp == 0xfeff;}
function hexDigit(d: i32): i32 { if (d < 10) return 48 + d; return 87 + d;}
// `\u{X}`.function putCodePoint(cp: i32): void { put(92); put(117); put(123); var shift = 20; while (shift > 0 && ((cp >> shift) & 15) == 0) shift = shift - 4; while (shift >= 0) { put(hexDigit((cp >> shift) & 15)); shift = shift - 4; } put(125);}
// TypeScript's entities table (engine/jsx-entities.wat): the code point of input [a, b), or -1.function entityCodePoint(a: i32, b: i32): i32 { var r = JSX_ENT; while (true) { let n = Memory.default.getU8(r); if (n == 0) return -1; if (n == b - a) { var i = 0; while (i < n && Memory.default.getU8(r + 1 + i) == inByte(a + i)) i = i + 1; if (i == n) { let v = r + 1 + n; return Memory.default.getU8(v) | (Memory.default.getU8(v + 1) << 8) | (Memory.default.getU8(v + 2) << 16); } } r = r + n + 4; }}
function isWordByte(c: i32): boolean { return (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 48 && c <= 57) || c == 95;}
// TypeScript's decodeEntities at the `&` at input q, before e: `{`, `{` or `&name;`. Writes the code// point and returns the end, or returns q when there is none.function entity(q: i32, e: i32): i32 { var r = q + 1; if (r < e && inByte(r) == 35) { r = r + 1; var hex = false; if (r < e && inByte(r) == 120) { hex = true; r = r + 1; } let d0 = r; var v = 0; while (r < e) { let c = inByte(r); var d = -1; if (c >= 48 && c <= 57) d = c - 48; else if (hex && (c | 32) >= 97 && (c | 32) <= 102) d = (c | 32) - 87; if (d < 0) break; if (v < 0x1000000) { if (hex) v = v * 16 + d; else v = v * 10 + d; } r = r + 1; } if (r == d0 || r >= e || inByte(r) != 59) return q; putCodePoint(v); return r + 1; } let w = r; while (r < e && isWordByte(inByte(r))) r = r + 1; if (r == w || r >= e || inByte(r) != 59) return q; let cp = entityCodePoint(w, r); if (cp < 0) return q; putCodePoint(cp); return r + 1;}
// The body of a string with value input [a, b) (entities decoded), escaped for double quotes. With `split`, a line// terminator (CRLF as one) becomes its escape, then `"+`, the terminator itself, and `"`.function strBody(a: i32, b: i32, split: boolean): void { var q = a; while (q < b) { let c = inByte(q); if (c == 38) { let r = entity(q, b); if (r > q) { q = r; continue; } } if (c == 34 || c == 92) { put(92); put(c); q = q + 1; continue; } var n = 0; if (split && isLt(c)) n = 1; if (n == 1 && c == 13 && q + 1 < b && inByte(q + 1) == 10) n = 2; if (split && c == 0xe2 && q + 2 < b && inByte(q + 1) == 0x80 && (inByte(q + 2) | 1) == 0xa9) n = 3; if (n == 0) { put(c); q = q + 1; continue; } if (c == 10) { put(92); put(110); } else if (c == 13) { put(92); put(114); if (n == 2) { put(92); put(110); } } else { putCodePoint(codePointAt(q)); } put(34); put(43); putIn(q, q + n); put(34); q = q + n; }}
// An attribute string, input [a, b) including its quotes: no escapes in the source, entities decoded.export function str(a: i32, b: i32): void { put(34); strBody(a + 1, b - 1, true); put(34);}
function addSeg(a: i32, b: i32): void { if (segN * 2 + 2 > seg.length) { let next = new FixedArray<i32>(seg.length * 2, 0); var i = 0; while (i < segN * 2) { next[i] = seg[i]; i = i + 1; } seg = next; } seg[segN * 2] = a; seg[segN * 2 + 1] = b; segN = segN + 1;}
// A JSX text child, input [a, b), as `,"..."`, or nothing when it is only whitespace across lines. TypeScript's// fixupWhitespaceAndDecodeEntities: each line is trimmed (except the start of the first and the end of the// last), whitespace-only lines are dropped, and the rest are joined by one space.export function text(a: i32, b: i32): void { segN = 0; var first = a; var lastEnd = -1; var q = a; while (q < b) { let cp = codePointAt(q); let n = seqN; if (isLineBreak(cp)) { if (first >= 0 && lastEnd >= 0) addSeg(first, lastEnd); first = -1; } else if (!isSingleLineSpace(cp)) { lastEnd = q + n; if (first < 0) first = q; } q = q + n; } if (first >= 0) addSeg(first, b); if (segN == 0) { lines(a, b); return; } var p = a; var i = 0; while (i < segN) { let s = seg[i * 2]; if (i == 0) { lines(p, s); put(44); put(34); } else { put(34); put(43); lines(p, s); put(34); put(32); } p = seg[i * 2 + 1]; strBody(s, p, false); i = i + 1; } put(34); lines(p, b);}