Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778// Generates the text emitters of engine/downlevel.zena (between the GENERATED markers) from the templates below,// and engine/downlevel-text.wat, the text itself as a data segment at TEXT_BASE that scripts/build.sh merges// into build/downlevel.wasm. `@` is the name entry passed to the emitter. (Zena strings would add a// `wasm:js-string` import.)import fs from "node:fs";import { TEXT_BASE, TEXT_END, dataModule } from "./layout.mjs";
const TEMPLATES = { litVar: "var", litConst: "const", litModExp: "module.exports", litSemi: ";", litRb: "}", litDestr: "var {", litDestrEnd: "}=this;", // Like litDestrEnd, but closes over a dotted namespace chain's own outer segment (its IIFE's own bound // parameter, `o`) instead of `this` — for a merged *intermediate* segment's exports referenced bare // from a deeper, newly-opened segment's body (namespaceStart's ancestor destructure, engine/downlevel.zena). tDestrEndAs: "}=@;", tItem: "@,", tName: "@", tFn: ";(function(@)", // No longer includes its own leading `{`: namespaceStart emits that separately (`litLb`) so an // ancestor destructure (`destructureAs`, engine/downlevel.zena) can be inserted between the `{` that closes // the *previous* segment's signature and this one's own `var @;(function(@)`. litLb: "{", tDotFn: "var @;(function(@)", tCall: ").call(@||(@={}),@);", tCallX: ").call(@=this.@||(this.@={}),@);", tEiNum: ';var @;this.@=@;this[@]="@";', tEiEval: ';var @;this.@=@;typeof @=="string"||(this[@]="@");', tEiStr: ";var @;this.@=@;", tEnNum: ";this[this[@]]=@;", tEnEval: ';typeof this[@]=="string"||(this[this[@]]=@);', tThisIdx: "this[@]", litAuto0: "=0", tAutoI: "=@+1", tAutoN: "=this[@]+1", litAutoVoid: "=void 0", tAssign: "this.@=@;", tLive: 'Object.defineProperty(this,"@",{get(){return @},set(@$){@=@$},enumerable:true,configurable:true});', // Like tLive, but starts non-enumerable and only becomes enumerable the first time it's actually written // (its own setter flips it with a second, get/set-preserving defineProperty call) -- for an ambient namespace // member that might be written only from outside the namespace body, where downlevel mode can't know statically // whether a write is coming (engine/downlevel.zena's ambientVar). `tsc` only ever creates the member once // something actually assigns it; this matches that without needing to know in advance. tAmbientLive: 'Object.defineProperty(this,"@",{get(){return @},set(@$){@=@$;Object.defineProperty(this,"@",{enumerable:true})},enumerable:false,configurable:true});',};
const WORDS = { Infinity: "wInfinity", NaN: "wNaN", eval: "wEval", arguments: "wArguments" };
// All templates live in one text, each ended by `~`, then the WORDS; an emitter is the offset of its template.let text = "";let fns = "";for (const [name, t] of Object.entries(TEMPLATES)) { const usesName = t.includes("@"); fns += `function ${name}(${usesName ? "o: i32" : ""}): void {\n tpl(${text.length}, ${usesName ? "o" : "0"});\n}\n\n`; text += t + "~";}for (const [word, name] of Object.entries(WORDS)) { fns += `function ${name}(a: i32, b: i32): boolean {\n return isWord(a, b, ${text.length}, ${word.length});\n}\n\n`; text += word;}let out = "// GENERATED by scripts/gen/downlevel-text.mjs from its template table. Do not edit by hand.\n";out += `let TEXT: i32 = ${TEXT_BASE};\n\n`;out += fns;
const file = new URL("../../engine/downlevel.zena", import.meta.url);const src = fs.readFileSync(file, "utf8");const begin = "// BEGIN GENERATED\n";const end = "// END GENERATED\n";const a = src.indexOf(begin);const b = src.indexOf(end);if (a < 0 || b < 0) throw new Error("downlevel.zena: GENERATED markers not found");fs.writeFileSync(file, src.slice(0, a + begin.length) + out + src.slice(b));const wat = new URL("../../engine/downlevel-text.wat", import.meta.url);fs.writeFileSync(wat, dataModule("downlevel-text.mjs", TEXT_BASE, Buffer.from(text, "latin1"), TEXT_END));