@lmctl-ai/lmctl 0.2.344 → 0.2.345
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-info.json +1 -1
- package/dist/cli/lmscript.js +2 -2
- package/package.json +1 -1
package/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"sha": "
|
|
1
|
+
{"sha": "3af5bb19239e2cfa7b07fddc5070a24ec5e43391", "dirty": false, "builtAt": "2026-10-19T05:39:55.000Z"}
|
package/dist/cli/lmscript.js
CHANGED
|
@@ -25,12 +25,12 @@ ${i}`,t),this.line=r,this.column=s,this.codeblock=i}static x(e,t,r){throw new n(
|
|
|
25
25
|
`;break;case"r":m+="\r";break;case"t":m+=" ";break;case"u":{let g=r.slice(s,s+4);/^[0-9A-Fa-f]{4}$/.test(g)||i("invalid \\u escape; expected four hexadecimal digits, found "+JSON.stringify(r.slice(s,s+4)),s-2),m+=String.fromCharCode(Number.parseInt(g,16)),s+=4;break}default:i("invalid escape \\"+h+" in a JSON string",s-2)}continue}p===`
|
|
26
26
|
`&&i("unterminated JSON string; a string cannot span lines",d),p<" "&&i("control character "+JSON.stringify(p)+" in a JSON string must be escaped");let f=Kn(p);if(f>=0){let h;try{h=Mo(e[f],"a JSON string",0,0)}catch(g){throw g instanceof ue?mn(t,g.message,s):g}h!==ct&&(m+=h),s++;continue}m+=p,s++}return i("unterminated JSON string; expected a closing quote",d)},c=d=>{a(),s>=r.length&&i("expected a JSON value, found end of body");let m=r[s],p=Kn(m);if(p>=0)return s++,e[p];if((m==="{"||m==="[")&&d>=Pm&&i("nesting deeper than "+Pm+" levels (limit "+Pm+")"),m==="{"){s++;let g={};if(a(),r[s]==="}")return s++,g;for(;;){a(),r[s]!=='"'&&i("expected a quoted object key, found "+o());let _=l();if(a(),r[s]!==":"&&i("expected ':' after the object key, found "+o()),s++,yi(g,_,c(d+1)),a(),r[s]===","){s++;continue}if(r[s]==="}")return s++,g;i("expected ',' or '}' after the object value, found "+o())}}if(m==="["){s++;let g=[];if(a(),r[s]==="]")return s++,g;for(;;){if(g.push(c(d+1)),a(),r[s]===","){s++;continue}if(r[s]==="]")return s++,g;i("expected ',' or ']' after the array element, found "+o())}}if(m==='"')return l();let f=/^(?:true|false|null)/.exec(r.slice(s,s+5));if(f)return s+=f[0].length,f[0]==="true"?!0:f[0]==="false"?!1:null;let h=/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/.exec(r.slice(s,s+400));if(h&&h[0]){let g=s;return s+=h[0].length,/^[0-9A-Za-z_.]/.test(r[s]??"")&&i("invalid JSON number near "+JSON.stringify(h[0]+r[s]),g),Number(h[0])}return i("expected a JSON value (object, array, string, number, true, false or null), found "+o())};a(),s>=r.length&&i("empty _json_ body; expected exactly one JSON value",0);let u=c(0);return a(),s<r.length&&i("expected the end of the body after the JSON value, found "+o()),u}function cL(n,e){let t=[],r=null,s=(a,l)=>(r||(r={parts:[],lineIndex:a,column:l}),r),i=(a,l,c)=>{let u=s(a,l),d=u.parts[u.parts.length-1];d&&"text"in d?d.text+=c:u.parts.push({text:c})},o=()=>{r&&t.push(r),r=null};return n.forEach((a,l)=>{let c="",u=0,d=1,m=-1,p=!1;for(let f of a.pieces){if(typeof f!="string"){if(c==="'")throw new ue("${...} inside single quotes is not supported yet in a _cmd_ body (single quotes are literal); use double quotes",l,d);s(l,d).parts.push({chunk:e[f.chunk],lineIndex:l,column:d}),d+=f.width;continue}for(let h=0;h<f.length;h++,d++){let g=f[h],_=f[h+1];if(c==="'"){if(g==="'"){c="";continue}i(l,d,g);continue}if(c==='"'){if(g==='"'){c="";continue}if(g==="\\"){if(_==='"'||_==="\\"||_==="$"||_==="`"){i(l,d,_),h++,d++;continue}i(l,d,"\\");continue}if(g==="$"||g==="`")throw new ue("shell substitution is not supported; use a ${...} field, or single-quote/escape literal text",l,d);i(l,d,g);continue}if(g===" "||g===" "){o(),m=-1,p=!1;continue}if(g==="'"||g==='"'){s(l,d),g==='"'&&_==='"'&&!r.parts.length&&i(l,d,""),c=g,u=d,g==="'"&&_==="'"&&i(l,d,"");continue}if(g==="\\"){if(_===void 0)throw new ue("dangling backslash at the end of the line; escape a character or quote the text",l,d);i(l,d,_),h++,d++;continue}if("|&<>".includes(g))throw new ue("shell pipe/redirection is not supported; compose commands using stdout/stderr, or quote/escape literal text",l,d);if(g===";")throw new ue("';' is not a command separator in a _cmd_ body (the whole body is one command); quote or escape it for literal text",l,d);if("()*?[]".includes(g)||g==="~"&&!r)throw new ue("shell grouping/expansion is not supported; quote/escape literal text or pass a whole-word list field",l,d);if(g==="$"||g==="`")throw new ue("shell substitution is not supported; use a ${...} field, or quote/escape literal text",l,d);if(g==="{")m<0&&(m=d);else if(g===","&&m>=0)p=!0;else if(g==="}"&&m>=0){if(p)throw new ue("brace expansion is not supported; quote/escape or supply a list",l,m);m=-1}i(l,d,g)}}if(c)throw new ue("unterminated "+(c==="'"?"single":"double")+" quote; close it on the same line",l,u);o()}),t}function uL(n,e){let t=cL(n,e),r=[],s=(i,o,a)=>{if(i===ct)return"?";if(typeof i!="string"&&typeof i!="number")throw new ue("${...} value is "+$l(i)+"; arguments must be strings or numbers (or a whole-word list of them)",o,a);let l=String(i);if(l.includes("\0"))throw new ue("NUL is not allowed in argv",o,a);return l};if(t.forEach((i,o)=>{let a=i.parts.length===1&&"chunk"in i.parts[0]?i.parts[0]:null;if(a&&Array.isArray(a.chunk)){if(o===0&&!a.chunk.length)throw new ue("a program is required; the first-word list is empty",i.lineIndex,i.column);for(let l of a.chunk)r.push(s(l,a.lineIndex,a.column));return}r.push(i.parts.map(l=>"text"in l?l.text:s(l.chunk,l.lineIndex,l.column)).join(""))}),!r.length)throw new ue("a program is required; the _cmd_ body has no words",-1,0);if(!r[0])throw new ue("a non-empty program is required; the first word is empty",t[0].lineIndex,t[0].column);return r}function Ib(n,e){let t=Ul(n,"_graphql_"),r,s=xb(t.text,(o,a)=>{let l=e[o];if(l===ct)return Sb(o);try{return Mo(l,"a _graphql_ body",0,0)}catch(c){if(c instanceof ue)return r??=mn(t,c.message,a),Sb(o);throw c}});if(r)return{text:"",problems:[r]};let i=s.text.endsWith(`
|
|
27
27
|
`)?s.text.slice(0,-1):s.text;return{text:i,problems:wb(i).map(o=>mn(t,o.message.replace(/_lm_field_\d+_/g,"${...}"),s.back(o.offset)))}}function Ab(n,e,t,r){if(n==="graphql")return Ib(e,t).problems;try{return Bm(n,e,t,r),[]}catch(s){if(s instanceof ue)return[s];throw s}}function Bm(n,e,t,r){if(n==="csv")return nL(e,t,{heading:r.heading,delimiter:r.delimiter});if(n==="toml")return oL(e,t);if(n==="props")return aL(e,t);if(n==="json")return lL(e,t);if(n==="cmd")return uL(e,t);if(n==="graphql"){let{text:s,problems:i}=Ib(e,t);if(i.length)throw i[0];return s}throw n==="dsl"?new ue("_dsl_ bodies are compiled by the engine (dsl.ts), not parsed as data",-1,0):new ue("unsupported block marker "+String(n),-1,0)}var Lo,Mm,Pm,ws,Sn,jl,ct,ue,$l,kb,jm,Rb,Kn,mn,rL,Sb,Cb=L(()=>{"use strict";No();Eb();Lo={csv:"_csv_",toml:"_toml_",javaprops:"_props_",graphql:"_graphql_"},Mm=64,Pm=512,ws=class extends Error{offset;constructor(e,t){super(e),this.offset=t}};Sn={csv:"CSV",toml:"TOML",props:"Props",json:"JSON",cmd:"command",graphql:"GraphQL",dsl:"DSL"},jl={csv:{heading:{type:"boolean",default:!0,description:"first data line is the header; false gives a list of lists"},delimiter:{type:"string",default:",",description:"one cell separator character other than a quote or line break"}},toml:{},props:{},json:{},cmd:{},graphql:{},dsl:{schema:{type:"string",default:"",description:"path of the dsl.schema JSON file, a string literal resolved like an import (required)"}}},ct=Symbol("unknown chunk value"),ue=class extends Error{lineIndex;column;constructor(e,t,r){super(e),this.lineIndex=t,this.column=r}},$l=n=>n===null?"null":Array.isArray(n)?"a list":typeof n=="object"?"a map":typeof n=="symbol"?"an unknown value":"a "+typeof n;kb=57344,jm=4096,Rb=n=>String.fromCharCode(kb+n),Kn=n=>{let e=n.charCodeAt(0)-kb;return e>=0&&e<jm?e:-1};mn=(n,e,t)=>{let{lineIndex:r,column:s}=n.at(t);return new ue(e,r,s)};rL=/^[A-Za-z0-9_-]+$/;Sb=n=>"_lm_field_"+n+"_"});function Nb(n,e){return new Error("Invalid template reference "+JSON.stringify(n)+" at offset "+e+"; use a simple name, PROPS.path or ARGV[n]. Assign a temporary variable first and pass it in vars.")}function Po(n){if(typeof n!="string")throw new Error("expand: text must be a string");let e=[],t=0;for(;t<n.length;){let r=n.indexOf("${",t);if(r<0){e.push(n.slice(t));break}if(r>t&&n[r-1]==="$"){e.push(n.slice(t,r-1),"${"),t=r+2;continue}e.push(n.slice(t,r));let s=n.indexOf("}",r+2);if(s<0)throw Nb(n.slice(r+2),r);let i=n.slice(r+2,s),o=mL.exec(i),a=pL.exec(i);if(o)e.push({kind:"property",name:i,key:o[1],offset:r});else if(a&&Number.isSafeInteger(Number(a[1])))e.push({kind:"argument",name:i,index:Number(a[1]),offset:r});else if(dL.test(i)&&i!=="PROPS"&&i!=="ARGV")e.push({kind:"variable",name:i,offset:r});else throw Nb(i,r);t=s+1}return e}function Bl(n,e,t=r=>r!==null&&typeof r=="object"?JSON.stringify(r):String(r)){let r=[],s=new Map;for(let i of Po(n)){if(typeof i=="string"){r.push(i);continue}let o;try{o=e(i)}catch(a){s.set(i.name,a instanceof Error?a.message:String(a));continue}if(o===void 0){s.set(i.name,"not defined");continue}r.push(t(o))}if(s.size)throw new Error("expand: missing references: "+[...s].map(([i,o])=>i+" ("+o+")").join("; "));return r.join("")}var Hm,dL,mL,pL,Wm=L(()=>{Hm="[_a-zA-Z][_a-zA-Z0-9]*",dL=new RegExp("^"+Hm+"$"),mL=new RegExp("^PROPS\\.("+Hm+"(?:\\."+Hm+")*)$"),pL=/^ARGV\[(0|[1-9][0-9]*)\]$/});var Db={};Tn(Db,{CompiledDsl:()=>bi,DSL_MAGIC:()=>Lb,DSL_VERSION:()=>Mb,DslError:()=>qe,MATH_FUNCTIONS:()=>_i,MAX_INT_LITERAL:()=>Xm,OP:()=>F,OPAQUE_MESSAGE:()=>Ts,canonicalSignatures:()=>bL,compileDsl:()=>zm,encodeDsl:()=>Pb,isCompiledDsl:()=>kn,measureStack:()=>Km,parseDslSchema:()=>Vm,signatureText:()=>Ht,typeName:()=>V});import{createHash as fL}from"node:crypto";function V(n){return typeof n=="string"?n:"object"in n?n.object:n.enum}function ke(n,e){return typeof n!=typeof e?!1:typeof n=="string"||typeof e=="string"?n===e:("object"in n?"object:"+n.object:"enum:"+n.enum)==("object"in e?"object:"+e.object:"enum:"+e.enum)}function Vm(n,e){let t=y=>{throw new qe("schema "+e+": "+y,-1,1)},r;try{r=JSON.parse(Buffer.from(n).toString("utf8"))}catch(y){return t("not valid JSON ("+(y instanceof Error?y.message:String(y))+")")}let s=y=>typeof y=="object"&&y!==null&&!Array.isArray(y);if(!s(r))return t("top level must be an object");if(r["dsl.schema"]!==2)return t('"dsl.schema" must be 2; found '+JSON.stringify(r["dsl.schema"]));if(typeof r.name!="string"||!zn.test(r.name))return t('"name" must be an identifier string');for(let y of Object.keys(r))["dsl.schema","name","types","functions","context","enums","conversions"].includes(y)||t("unknown top-level key "+JSON.stringify(y)+" (known: dsl.schema, name, types, functions, context, enums, conversions)");let i=r.types??{},o=r.functions??{},a=r.context??{},l=r.enums??{};if(!s(i))return t('"types" must be an object');if(!s(o))return t('"functions" must be an object');if(!s(a))return t('"context" must be an object');if(!s(l))return t('"enums" must be an object');let c=new Set(Object.keys(i)),u=new Map;for(let[y,b]of Object.entries(l)){(!zn.test(y)||c.has(y)||Ar.includes(y)||y==="void"||y==="self"||Yn.has(y))&&t("enum name "+JSON.stringify(y)+" is not a distinct type name"),(!Array.isArray(b)||b.length===0||b.some(T=>typeof T!="string"||!zn.test(T)))&&t("enum "+y+": values must be a non-empty list of identifier strings");let w=b,k=new Set(w);k.size!==w.length&&t("enum "+y+": duplicate value"),u.set(y,k)}for(let y of c)zn.test(y)||t("type name "+JSON.stringify(y)+" is not an identifier"),(Ar.includes(y)||y==="void")&&t("type "+JSON.stringify(y)+" redefines a primitive");let d=(y,b,w)=>typeof y!="string"?t(b+": type must be a string; found "+JSON.stringify(y)):Ar.includes(y)?y:y==="void"?(w||t(b+": void is only a return type"),"void"):c.has(y)?{object:y}:u.has(y)?{enum:y}:t(b+": type "+JSON.stringify(y)+" is not declared (primitives: int, float, string, bool; types: "+([...c].join(", ")||"none")+")"),m=(y,b,w)=>{if(!s(y))return t(b+": must be an object with params and returns");for(let R of Object.keys(y))["params","returns"].includes(R)||t(b+": unknown key "+JSON.stringify(R)+" (known: params, returns)");if(!Array.isArray(y.params))return t(b+': "params" must be a list of type names');let k=y.params.map((R,C)=>d(R,b+" parameter "+(C+1),!1));k.length>255&&t(b+": at most 255 parameters");let T=y.returns==="self"?w?{object:w}:t(b+': "self" is only valid on methods'):d(y.returns??"void",b+" returns",!0);return{params:k,returns:T}},p=(y,b,w)=>{if(!Array.isArray(y))return t(b+": must be an array of overload signatures");let k=y;if(k.length===0)return t(b+": must contain at least one signature");let T=k.map((R,C)=>m(R,b+" overload "+(C+1),w));for(let R=0;R<T.length;R++)for(let C=R+1;C<T.length;C++)T[R].params.length===T[C].params.length&&T[R].params.every((N,A)=>ke(N,T[C].params[A]))&&t(b+": duplicate overload parameter types");return T},f=new Map;for(let[y,b]of Object.entries(i)){if(!s(b))return t("type "+y+": must be an object with methods");for(let T of Object.keys(b))["methods","operators"].includes(T)||t("type "+y+": unknown key "+JSON.stringify(T)+" (known: methods, operators)");let w=b.methods??{};if(!s(w))return t("type "+y+': "methods" must be an object');let k=new Map;for(let[T,R]of Object.entries(w))zn.test(T)||t("type "+y+": method name "+JSON.stringify(T)+" is not an identifier"),k.set(T,p(R,"method "+y+"."+T,y));f.set(y,k)}let h=new Map;for(let[y,b]of Object.entries(i)){let w=s(b)?b.operators:void 0,k=new Map;if(w!==void 0){s(w)||t("type "+y+': "operators" must be an object');let T=w;for(let[R,C]of Object.entries(T))(!["+","-","*","neg","r+","r-","r*"].includes(R)||typeof C!="string"||!zn.test(C))&&t("type "+y+': invalid operator declaration "'+R+'"'),k.set(R,C)}h.set(y,k)}for(let[y,b]of h)for(let[w,k]of b){let T=f.get(y)?.get(k);T||t("type "+y+': operator "'+w+'" maps to missing method "'+k+'"');let R=w==="neg"?0:1;T.some(C=>C.params.length!==R)&&t("type "+y+': operator "'+w+'" method "'+k+'" must have '+R+" parameter(s)")}let g=new Map;for(let[y,b]of Object.entries(o))zn.test(y)||t("function name "+JSON.stringify(y)+" is not an identifier"),(Object.hasOwn(Es,y)||Hl.has(y))&&t("function name "+JSON.stringify(y)+" is a DSL built-in conversion"),Yn.has(y)&&t("function name "+JSON.stringify(y)+" is a DSL keyword"),g.set(y,p(b,"function "+y));for(let y of u.keys())g.has(y)&&t("enum "+y+" collides with function "+y);let _=new Map;for(let[y,b]of Object.entries(a)){zn.test(y)||t("context name "+JSON.stringify(y)+" is not an identifier"),Yn.has(y)&&t("context name "+JSON.stringify(y)+" is a DSL keyword"),g.has(y)&&t("context variable "+y+" collides with function "+y),u.has(y)&&t("context variable "+y+" collides with enum "+y);let w=d(b,"context "+y,!1);(typeof w=="string"||typeof w=="object"&&"enum"in w)&&t("context "+y+": context variables are host objects; "+V(w)+" is not an object"),_.set(y,V(w))}let v=[];if(r.conversions!==void 0){Array.isArray(r.conversions)||t('"conversions" must be a list');let y=r.conversions;for(let[b,w]of y.entries()){s(w)||t("conversion "+(b+1)+": expected an object with from, to and via"),(typeof w.from!="string"||typeof w.to!="string"||typeof w.via!="string")&&t("conversion "+(b+1)+": expected from, to and via strings");let k=d(w.from,"conversion "+(b+1)+" from",!1),T=d(w.to,"conversion "+(b+1)+" to",!1);(typeof T=="string"||!("object"in T))&&t("conversion "+(b+1)+": to must be an object type");let R=T;ke(k,T)&&t("conversion "+(b+1)+": from and to must differ"),v.some(S=>ke(S.from,k)&&ke(S.to,T))&&t("conversion "+(b+1)+": duplicate conversion pair");let C=w.via,N=C.split(".");(N.length>2||N.some(S=>!zn.test(S)))&&t("conversion "+(b+1)+": via must be a function name or Type.method");let A=N.length===2?N[0]:void 0,E=N.length===2?N[1]:C;N.length===2&&(typeof k!="object"||!("object"in k)||N[0]!==k.object)&&t("conversion "+(b+1)+": via owner must match the source object type");for(let S of Object.keys(w))["from","to","via"].includes(S)||t("conversion "+(b+1)+': unknown key "'+S+'"');v.push({from:k,to:R,via:E,owner:A})}}for(let y of v)v.some(b=>ke(y.to,b.from))&&t("conversion "+V(y.from)+" -> "+V(y.to)+": conversion chains are forbidden");for(let y of v){let b=V(y.to);y.owner?(f.get(y.owner)?.get(y.via)?.filter(k=>k.params.length===0&&ke(k.returns,y.to))??[]).length!==1&&t("conversion "+V(y.from)+" -> "+b+': via method "'+y.via+'" must be a unique zero-argument method returning '+b):(g.get(y.via)?.filter(k=>k.params.length===1&&ke(k.params[0],y.from)&&ke(k.returns,y.to))??[]).length!==1&&t("conversion "+V(y.from)+" -> "+b+': via function "'+y.via+'" must be a unique unary function returning '+b)}return{name:r.name,types:f,functions:g,context:_,enums:u,conversions:v,operators:h,bytes:n}}function yL(n){let e=[];n.forEach((r,s)=>{let i=0;for(;i<r.length;){let o=r[i];if(o===" "||o===" "||o==="\r"){i++;continue}if(o==="#")break;let a=i+1;if(/[A-Za-z_]/.test(o)){let c=i;for(;c<r.length&&/[A-Za-z0-9_]/.test(r[c]);)c++;e.push({kind:"ident",text:r.slice(i,c),lineIndex:s,column:a}),i=c;continue}if(/[0-9]/.test(o)){let c=i;for(;c<r.length&&/[0-9]/.test(r[c]);)c++;let u=!1;if(r[c]==="."&&/[0-9]/.test(r[c+1]??""))for(u=!0,c++;c<r.length&&/[0-9]/.test(r[c]);)c++;if(/[A-Za-z_.]/.test(r[c]??""))throw new qe("malformed number "+JSON.stringify(r.slice(i,c+1))+" (int: digits; float: digits.digits; no exponent, no suffix)",s,a);let d=Number(r.slice(i,c));if(!u&&BigInt(r.slice(i,c))>BigInt(Xm))throw new qe("int literal "+r.slice(i,c)+" exceeds 2^53 ("+Xm+"), the largest integer lmscript represents exactly",s,a);e.push({kind:u?"float":"int",text:r.slice(i,c),value:d,lineIndex:s,column:a}),i=c;continue}if(o==='"'){let c=i+1,u="";for(;c<r.length&&r[c]!=='"';){if(r[c]==="\\"){let d=r[c+1],m={n:`
|
|
28
|
-
`,t:" ",r:"\r",'"':'"',"\\":"\\"};if(!(d in m))throw new qe("unknown escape \\"+(d??"")+' in string (known: \\n \\t \\r \\" \\\\)',s,c+1);u+=m[d],c+=2;continue}u+=r[c++]}if(c>=r.length)throw new qe("unterminated string literal (strings end on their line)",s,a);e.push({kind:"string",text:r.slice(i,c+1),value:u,lineIndex:s,column:a}),i=c+1;continue}let l=hL.find(c=>r.startsWith(c,i));if(!l)throw new qe("unexpected character "+JSON.stringify(o),s,a);e.push({kind:"punct",text:l,lineIndex:s,column:a}),i+=l.length}});let t=n.length-1;return e.push({kind:"eof",text:"end of body",lineIndex:Math.max(0,t),column:(n[t]?.length??0)+1}),e}function Ht(n){return"("+n.params.map(V).join(", ")+") -> "+V(n.returns)}function _L(n,e){let t=[],r=new Map,s=0,i=0,o=(c,u)=>{throw new qe(c,u.lineIndex,u.column)},a=(c,u)=>n[c]?.text===u,l=(c,u,d)=>{let m=n[c];return!m||m.kind!=="ident"?o("expected a type name for "+u,m??n[n.length-1]):Ar.includes(m.text)?m.text:m.text==="void"&&d?"void":e.types.has(m.text)?{object:m.text}:e.enums.has(m.text)?{enum:m.text}:o("unknown type "+JSON.stringify(m.text)+" for "+u+" (known: "+[...Ar,...d?["void"]:[],...e.types.keys(),...e.enums.keys()].join(", ")+")",m)};for(;n[i]?.kind!=="eof";){let c=n[i];if(c.kind==="ident"&&c.text==="fn"){s!==0&&o("nested function definitions are not allowed",c);let u=i++,d=n[i++];if(!d||d.kind!=="ident")return o("expected a function name after 'fn'",d??c);let m=d.text,p=e.functions.has(m)?"host function from the schema":e.context.has(m)?"context variable from the schema":e.types.has(m)||e.enums.has(m)||Ar.includes(m)||m==="void"?"type name":qm.has(m)?"DSL built-in":Yn.has(m)?"DSL keyword":r.has(m)?"another user function":"";p&&o("function '"+m+"' conflicts with "+p+" and cannot be defined",d),a(i++,"(")||o("expected '(' after function name",n[i-1]);let f=[],h=new Set;for(;!a(i,")");){let w=n[i++];if(!w||w.kind!=="ident")return o("expected a parameter name",w??d);(Yn.has(w.text)||e.context.has(w.text)||e.functions.has(w.text)||qm.has(w.text)||e.types.has(w.text)||e.enums.has(w.text)||Ar.includes(w.text)||w.text==="void")&&o("parameter '"+w.text+"' conflicts with a schema name or DSL built-in",w),h.has(w.text)&&o("duplicate parameter '"+w.text+"'",w),h.add(w.text),a(i++,":")||o("expected ':' after parameter name",n[i-1]);let k=l(i++,"parameter '"+w.text+"'",!1);if(f.push({name:w.text,type:k,token:w}),a(i,",")){i++,a(i,")")&&o("expected a parameter after ','",n[i]);continue}a(i,")")||o("expected ',' or ')' after parameter",n[i]??w)}i++,(!a(i++,"-")||!a(i++,">"))&&o("expected '->' and a return type after parameters",n[i-1]??d);let g=l(i++,"function return",!0);a(i++,"{")||o("expected '{' before function body",n[i-1]??d);let _=i,v=1;for(;i<n.length&&v>0;)n[i].kind==="ident"&&n[i].text==="fn"&&o("nested function definitions are not allowed",n[i]),n[i].kind==="punct"&&n[i].text==="{"?v++:n[i].kind==="punct"&&n[i].text==="}"&&v--,i++;v!==0&&o("expected '}' to close function '"+m+"'",n[_-1]);let y=n.slice(_,i-1),b=n[i-1];r.set(m,{name:m,params:f,returns:g,body:[...y,{kind:"eof",text:"end of function",lineIndex:b.lineIndex,column:b.column}],token:n[u]});continue}s>0&&c.kind==="ident"&&c.text==="fn"&&o("nested function definitions are not allowed",c),c.kind==="punct"&&c.text==="{"&&s++,c.kind==="punct"&&c.text==="}"&&s--,t.push(c),i++}t[t.length-1]?.kind!=="eof"&&t.push(n[n.length-1]);for(let c of r.values())for(let u of c.params)r.has(u.name)&&o("parameter '"+u.name+"' conflicts with user function '"+u.name+"'",u.token);return{tokens:t,functions:r}}function Km(n,e){let t=c=>{let u=c.slice(c.indexOf("(")+1,c.lastIndexOf(")"));return{argc:u===""?0:u.split(", ").length,returns:!c.endsWith("-> void")}},r=0,s=0,i=0,o=()=>n[i++],a=()=>{let c=n[i]<<8|n[i+1];return i+=2,c},l=(c,u)=>{if(r+=c,r<0)throw new qe("compiler bug: operand stack underflow at opcode "+u+" (pc "+i+")",-1,1);r>s&&(s=r)};for(;i<n.length;){let c=o();switch(c){case F.PUSH_INT:i+=8,l(1,c);break;case F.PUSH_FLOAT:i+=8,l(1,c);break;case F.PUSH_STR:i+=4,l(1,c);break;case F.PUSH_BOOL:i+=1,l(1,c);break;case F.LOAD_LOCAL:case F.LOAD_CTX:i+=2,l(1,c);break;case F.STORE_LOCAL:i+=2,l(-1,c);break;case F.CALL_FN:{let{argc:u,returns:d}=t(e[a()]);o(),l(-u+(d?1:0),c);break}case F.CALL_METHOD:{let{argc:u,returns:d}=t(e[a()]);o(),l(-u-1+(d?1:0),c);break}case F.EQ:case F.NE:case F.ADD_I:case F.SUB_I:case F.MUL_I:case F.DIV_I:case F.MOD_I:case F.ADD_F:case F.SUB_F:case F.MUL_F:case F.DIV_F:case F.LT_I:case F.LE_I:case F.GT_I:case F.GE_I:case F.LT_F:case F.LE_F:case F.GT_F:case F.GE_F:case F.CONCAT:case F.POP:l(-1,c);break;case F.NOT:case F.NEG_I:case F.NEG_F:case F.I2F:case F.I2S:case F.F2S:case F.B2S:case F.HALT:break;case F.JUMP:i+=4;break;case F.JUMP_IF_FALSE:case F.JUMP_IF_TRUE:i+=4,l(-1,c);break;case F.FOR_RANGE:i+=8,l(-2,c);break;case F.FOR_NEXT:i+=6;break;case F.WHILE_BEGIN:case F.LOOP_BACK:i+=c===F.WHILE_BEGIN?0:4;break;case F.WHILE_TEST:i+=4,l(-1,c);break;case F.MATH:l(1-_i[o()].params.length,c);break;case F.DUP:l(1,c);break;default:throw new qe("compiler bug: unknown opcode "+c+" while measuring the stack",-1,1)}}if(s>65535)throw new qe("the expression nesting needs "+s+" operand slots; the format records at most 65535",-1,1);return s}function Pb(n,e){let t=[],r=p=>{t.push(p&255)},s=p=>{t.push(p>>8&255,p&255)},i=p=>{t.push(p>>>24&255,p>>>16&255,p>>>8&255,p&255)},{consts:o,imports:a,contexts:l,locals:c,code:u,lines:d=[]}=e,m=p=>{let f=o.indexOf(p);if(f<0)throw new qe("compiler bug: section text "+JSON.stringify(p)+" is not a constant",-1,1);return f};for(let p of Buffer.from(Lb,"latin1"))t.push(p);s(Mb);for(let p of fL("sha256").update(n.bytes).digest())t.push(p);i(o.length);for(let p of o){let f=Buffer.from(p,"utf8");r(1),i(f.length);for(let h of f)t.push(h)}s(a.length);for(let p of a)i(m(p));s(l.length);for(let p of l)i(m(p.name)),i(m(p.type));if(c.length>65535)throw new qe("too many local variables (the format holds 65535)",-1,1);s(c.length);for(let p of c)i(m(p.type)),r(p.hidden?1:0);s(Km(u,a)),i(u.length);for(let p of u)t.push(p);i(d.length);for(let p of d)i(p.pc),i(p.line),s(p.column);return Uint8Array.from(t)}function bL(n){let e=Ht,t=[];for(let[r,s]of n.context)t.push("context "+r+": "+s);for(let[r,s]of n.functions)for(let i of s)t.push("fn "+r+e(i));for(let[r,s]of n.types)for(let[i,o]of s)for(let a of o)t.push("method "+r+"."+i+e(a));return t.sort()}function zm(n,e){let t=yL(n);if(t.length===1)throw new qe("the DSL body is empty",-1,1);let r=_L(t,e),s=new Gm(r.tokens,e,r.functions).compile(),i=Pb(e,s);return{bytes:i,consts:[...s.consts],imports:[...s.imports],locals:[...s.locals],nlocals:s.locals.length,maxStack:Km(s.code,s.imports),codeLength:s.code.length,codeOffset:i.length-4-s.lines.length*10-s.code.length}}function kn(n){return typeof n=="object"&&n!==null&&Jm.has(n)}var qe,zn,Ar,Ob,Es,_i,Hl,gL,qm,hL,Xm,Yn,F,Lb,Mb,Do,Gm,Jm,bi,Ts,Ym=L(()=>{"use strict";qe=class extends Error{lineIndex;column;constructor(e,t,r){super(e),this.lineIndex=t,this.column=r}},zn=/^[A-Za-z_][A-Za-z0-9_]*$/,Ar=["int","float","string","bool"],Ob=["int","float"],Es={float:{params:["int"],returns:"float"},str:{params:["int"],returns:"string"}},_i=[{name:"sin",params:["float"],returns:"float"},{name:"cos",params:["float"],returns:"float"},{name:"sqrt",params:["float"],returns:"float"},{name:"abs",params:["float"],returns:"float"},{name:"floor",params:["float"],returns:"float"},{name:"pow",params:["float","float"],returns:"float"},{name:"min",params:["float","float"],returns:"float"},{name:"max",params:["float","float"],returns:"float"},{name:"clamp",params:["float","float","float"],returns:"float"},{name:"lerp",params:["float","float","float"],returns:"float"},{name:"ease",params:["float"],returns:"float"},{name:"ease_in",params:["float"],returns:"float"},{name:"ease_out",params:["float"],returns:"float"},{name:"int",params:["float"],returns:"int"},{name:"abs",params:["int"],returns:"int"},{name:"min",params:["int","int"],returns:"int"},{name:"max",params:["int","int"],returns:"int"},{name:"clamp",params:["int","int","int"],returns:"int"}],Hl=new Set(_i.map(n=>n.name)),gL=[...Object.keys(Es),...Hl].join(", "),qm=new Set([...Object.keys(Es),...Hl]);hL=["==","!=","<=",">=","&&","||","(",")","{","}",";",",",":",".","!","=","<",">","+","-","*","/","%"],Xm=9007199254740992,Yn=new Set(["let","if","else","true","false","for","in","range","fn","return","switch","case","default","while","break","continue"]);F={PUSH_INT:1,PUSH_STR:2,PUSH_BOOL:3,LOAD_LOCAL:4,STORE_LOCAL:5,LOAD_CTX:6,CALL_FN:7,CALL_METHOD:8,EQ:9,NE:10,NOT:11,JUMP:12,JUMP_IF_FALSE:13,JUMP_IF_TRUE:14,DUP:15,POP:16,HALT:17,PUSH_FLOAT:18,ADD_I:19,SUB_I:20,MUL_I:21,DIV_I:22,ADD_F:23,SUB_F:24,MUL_F:25,DIV_F:26,NEG_I:27,NEG_F:28,LT_I:29,LE_I:30,GT_I:31,GE_I:32,LT_F:33,LE_F:34,GT_F:35,GE_F:36,I2F:37,CONCAT:38,I2S:39,F2S:40,B2S:41,MATH:50,MOD_I:51,FOR_RANGE:47,FOR_NEXT:49,WHILE_BEGIN:52,WHILE_TEST:53,LOOP_BACK:54},Lb="DSLB",Mb=5;Do=class{bytes=[];consts=[];imports=[];contexts=[];lines=[];mark(e){let t=e.lineIndex+1,r=this.lines[this.lines.length-1];!r||r.pc!==this.bytes.length?this.lines.push({pc:this.bytes.length,line:t,column:e.column}):(r.line=t,r.column=e.column)}constant(e){let t=this.consts.indexOf(e);return t<0&&(this.consts.push(e),t=this.consts.length-1),t}import(e){let t=this.imports.indexOf(e);if(t<0){if(this.imports.length>=65535)throw new qe("too many distinct callees (the import table holds 65535)",-1,1);this.imports.push(e),t=this.imports.length-1}return t}context(e,t){let r=this.contexts.findIndex(s=>s.name===e);return r<0&&(this.contexts.push({name:e,type:t}),r=this.contexts.length-1),r}u8(e){this.bytes.push(e&255)}u16(e){this.bytes.push(e>>8&255,e&255)}u32(e){this.bytes.push(e>>>24&255,e>>>16&255,e>>>8&255,e&255)}i32(e){this.u32(e)}i64(e){let t=Buffer.alloc(8);t.writeBigInt64BE(BigInt(e));for(let r of t)this.bytes.push(r)}f64(e){let t=Buffer.alloc(8);t.writeDoubleBE(e);for(let r of t)this.bytes.push(r)}jump(e){this.u8(e);let t=this.bytes.length;return this.i32(0),t}patch(e,t=this.bytes.length){let r=t-(e+4);this.bytes[e]=r>>>24&255,this.bytes[e+1]=r>>>16&255,this.bytes[e+2]=r>>>8&255,this.bytes[e+3]=r&255}};Gm=class{pos=0;code=new Do;scopes=[new Map];locals=[];tokens;schema;functions;expansionStack=[];sourceMapped=!1;validating=!1;validatedFunctions=new Set;loopStack=[];constructor(e,t,r=new Map){this.tokens=e,this.schema=t,this.functions=r}compile(){for(let e of this.functions.values())this.validateFunction(e);for(this.code=new Do,this.locals=[],this.scopes=[new Map],this.pos=0,this.expansionStack=[],this.sourceMapped=!1,this.loopStack=[];this.peek().kind!=="eof";)this.statement();this.code.u8(F.HALT);for(let e of this.code.imports)this.code.constant(e);for(let e of this.code.contexts)this.code.constant(e.name),this.code.constant(e.type);for(let e of this.locals)this.code.constant(e.type);return{consts:this.code.consts,imports:this.code.imports,contexts:this.code.contexts,locals:this.locals,code:this.code.bytes,lines:this.sourceMapped?this.code.lines:[]}}validateFunction(e){if(this.validatedFunctions.has(e.name))return;let t={code:this.code,locals:this.locals,scopes:this.scopes,tokens:this.tokens,pos:this.pos,stack:this.expansionStack,expanded:this.sourceMapped,validating:this.validating,loops:this.loopStack};this.code=new Do,this.locals=[],this.scopes=[new Map],this.tokens=e.body,this.pos=0,this.expansionStack=[...t.stack,e.name],this.sourceMapped=!1,this.validating=!0,this.loopStack=[],this.bindParameters(e),this.compileFunctionBody(e),this.code=t.code,this.locals=t.locals,this.scopes=t.scopes,this.tokens=t.tokens,this.pos=t.pos,this.expansionStack=t.stack,this.sourceMapped=t.expanded,this.validating=t.validating,this.loopStack=t.loops,this.validatedFunctions.add(e.name)}bindParameters(e){let t=[];for(let r of e.params){this.locals.length>=65535&&this.fail("too many local variables after inlining function '"+e.name+"' (the format holds 65535)",r.token);let s=this.locals.length;this.locals.push({type:V(r.type),hidden:!1}),this.scopes[0].set(r.name,{type:r.type,slot:s}),t.push(s)}return t}compileFunctionBody(e){let t=!1;for(;this.peek().kind!=="eof";){let r=this.peek();if(r.kind==="ident"&&r.text==="return"){this.code.mark(r),e.returns==="void"&&this.fail("void function '"+e.name+"' has no return value",r),this.next();let s=this.peek(),i=this.expression();ke(i,e.returns)||this.fail("function '"+e.name+"' returns "+V(e.returns)+"; found "+V(i),s),this.expect(";","';' after the return expression"),this.peek().kind!=="eof"&&this.fail("return must be the final top-level statement in function '"+e.name+"'"),t=!0;break}this.statement()}e.returns!=="void"&&!t&&this.fail("function '"+e.name+"' must end with 'return expr;'",e.token)}inlineFunction(e,t,r){if(this.expansionStack.includes(e.name)){let i=[...this.expansionStack.slice(this.expansionStack.indexOf(e.name)),e.name].join(" -> ");this.fail("recursive user functions are not allowed (cycle: "+i+")",t)}let s={tokens:this.tokens,pos:this.pos,scopes:this.scopes,stack:this.expansionStack,loops:this.loopStack};this.tokens=e.body,this.pos=0,this.scopes=[new Map],this.expansionStack=[...s.stack,e.name],this.loopStack=[],e.params.forEach((i,o)=>this.scopes[0].set(i.name,{type:i.type,slot:r[o]})),this.sourceMapped=!0,this.compileFunctionBody(e),this.tokens=s.tokens,this.pos=s.pos,this.scopes=s.scopes,this.expansionStack=s.stack,this.loopStack=s.loops}peek(e=0){return this.tokens[Math.min(this.pos+e,this.tokens.length-1)]}next(){let e=this.peek();return e.kind!=="eof"&&this.pos++,e}fail(e,t=this.peek()){throw new qe(e,t.lineIndex,t.column)}is(e){let t=this.peek();return(t.kind==="punct"||t.kind==="ident")&&t.text===e}expect(e,t="'"+e+"'"){return this.is(e)||this.fail("expected "+t+", found "+this.describe(this.peek())),this.next()}describe(e){return e.kind==="eof"?"end of body":e.kind==="string"?"string "+e.text:"'"+e.text+"'"}lookup(e){for(let t=this.scopes.length-1;t>=0;t--){let r=this.scopes[t].get(e);if(r)return r}}statement(){let e=this.peek();if(this.code.mark(e),e.kind==="ident"&&e.text==="return"&&this.fail("return is allowed only as the final top-level statement of a value-returning function",e),e.kind==="ident"&&e.text==="let"){this.next(),this.letStatement();return}if(e.kind==="ident"&&e.text==="if"){this.next(),this.ifStatement();return}if(e.kind==="ident"&&e.text==="for"){this.next(),this.forStatement();return}if(e.kind==="ident"&&e.text==="while"){this.next(),this.whileStatement();return}if(e.kind==="ident"&&(e.text==="break"||e.text==="continue")){this.loopStack.length||this.fail("'"+e.text+"' is allowed only inside a loop (and cannot cross a function boundary)",e),this.sourceMapped=!0,this.next(),this.expect(";","';' after "+e.text),(e.text==="break"?this.loopStack[this.loopStack.length-1].breaks:this.loopStack[this.loopStack.length-1].continues).push(this.code.jump(F.JUMP));return}if(e.kind==="ident"&&e.text==="switch"){this.next(),this.switchStatement();return}if(e.kind==="ident"&&e.text==="else"&&this.fail("'else' without a preceding if"),e.kind==="ident"&&!Yn.has(e.text)&&this.peek(1).kind==="punct"&&this.peek(1).text==="="){this.assignment();return}e.kind==="punct"&&e.text==="}"&&this.fail("unexpected '}' (no block is open)");let t=this.peek(),r=this.expression();t.kind==="ident"&&this.tokens[this.pos-1].text===")"||this.fail("this expression has no effect; only calls, let, assignment and if are statements",t),r!=="void"&&this.code.u8(F.POP),this.expect(";","';' after the statement")}letStatement(){let e=this.next();(e.kind!=="ident"||Yn.has(e.text))&&this.fail("expected a variable name after let, found "+this.describe(e),e);let t=e.text;this.schema.context.has(t)&&this.fail("'"+t+"' is a context variable from the schema and cannot be redeclared",e),this.schema.functions.has(t)&&this.fail("'"+t+"' is a host function from the schema and cannot be a variable",e),this.functions.has(t)&&this.fail("'"+t+"' is a user function and cannot be a variable",e),Object.hasOwn(Es,t)&&this.fail("'"+t+"' is a DSL built-in and cannot be a variable",e);let r=this.lookup(t);r?.readonly&&this.fail((r.readonlyLabel??"loop counter")+" '"+t+"' is read-only and cannot be redeclared",e),this.scopes[this.scopes.length-1].has(t)&&this.fail("variable '"+t+"' is already declared in this block",e),this.expect("=","'=' after the variable name (the type is inferred from the initializer)");let s=this.expression();s==="void"&&this.fail("cannot store a void result in '"+t+"'",e),this.locals.length>=65535&&this.fail("too many local variables (the format holds 65535)",e);let i=this.locals.length;this.locals.push({type:V(s),hidden:!1}),this.scopes[this.scopes.length-1].set(t,{type:s,slot:i}),this.code.u8(F.STORE_LOCAL),this.code.u16(i),this.expect(";","';' after the declaration")}assignment(){let e=this.next(),t=e.text;this.expect("=");let r=this.lookup(t);r||(this.schema.context.has(t)&&this.fail("'"+t+"' is a context object and cannot be reassigned",e),this.fail("undefined variable '"+t+"' (declare it with let "+t+" = ...;)",e)),r.readonly&&this.fail((r.readonlyLabel??"loop counter")+" '"+t+"' is read-only and cannot be assigned",e);let s=this.peek(),i=this.expression();ke(i,r.type)||this.fail("cannot assign "+V(i)+" to '"+t+"' of type "+V(r.type),s),this.code.u8(F.STORE_LOCAL),this.code.u16(r.slot),this.expect(";","';' after the assignment")}ifStatement(){this.expect("(","'(' after if");let e=this.peek(),t=this.expression();t!=="bool"&&this.fail("if condition must be bool; found "+V(t),e),this.expect(")","')' after the condition");let r=this.code.jump(F.JUMP_IF_FALSE);if(this.block(),this.is("else")){this.next();let s=this.code.jump(F.JUMP);this.code.patch(r),this.is("if")?(this.next(),this.ifStatement()):this.block(),this.code.patch(s)}else this.code.patch(r)}forStatement(){this.expect("(","'(' after for");let e=this.next();(e.kind!=="ident"||Yn.has(e.text))&&this.fail("expected a loop counter name, found "+this.describe(e),e);let t=e.text;if((this.schema.context.has(t)||this.schema.functions.has(t)||this.functions.has(t)||Object.hasOwn(Es,t)||qm.has(t))&&this.fail("loop counter '"+t+"' cannot shadow a schema name or built-in",e),this.lookup(t)?.readonly&&this.fail("loop counter '"+t+"' is read-only and cannot be redeclared",e),this.expect("in","'in' after the loop counter"),!this.is("range")){(this.schema.types.has(t)||this.schema.enums.has(t)||Ar.includes(t)||t==="void")&&this.fail("foreach variable '"+t+"' cannot shadow a schema type name",e),this.foreachStatement(e,t);return}this.next(),this.expect("(","'(' after range");let r=this.peek(),s=this.expression();s!=="int"&&this.fail("range start must be int; found "+V(s),r),this.expect(",","',' between the range start and end");let i=this.peek(),o=this.expression();o!=="int"&&this.fail("range end must be int; found "+V(o),i),this.expect(")","')' after range(start, end); range takes exactly two bounds, with step 1"),this.expect(")","')' after the for header"),this.locals.length>65533&&this.fail("too many local variables (the format holds 65535)",e);let a=this.locals.length,l=a+1;this.locals.push({type:"int",hidden:!0},{type:"int",hidden:!0}),this.scopes.push(new Map([[t,{type:"int",slot:a,readonly:!0}]]));let c={breaks:[],continues:[]};this.loopStack.push(c),this.code.u8(F.FOR_RANGE),this.code.u16(a),this.code.u16(l);let u=this.code.bytes.length;this.code.i32(0);let d=this.code.bytes.length;this.block();for(let p of c.continues)this.code.patch(p,this.code.bytes.length);this.code.mark(e),this.code.u8(F.FOR_NEXT),this.code.u16(l);let m=this.code.bytes.length;this.code.i32(0),this.code.patch(m,d),this.code.patch(u);for(let p of c.breaks)this.code.patch(p);this.loopStack.pop(),this.scopes.pop()}foreachStatement(e,t){this.sourceMapped=!0;let r=this.peek(),s=this.expression();(typeof s!="object"||!("object"in s))&&this.fail("foreach needs a host collection object with len() -> int and at(int) -> T; found "+V(s),r);let i=this.schema.types.get(s.object),o=(i.get("len")??[]).filter(_=>_.params.length===0&&_.returns==="int"),a=(i.get("at")??[]).filter(_=>_.params.length===1&&_.params[0]==="int"&&_.returns!=="void");(o.length!==1||a.length!==1)&&this.fail("foreach collection type "+s.object+" must declare exactly len() -> int and at(int) -> T (T must be a value type)",r);let l=a[0].returns;this.expect(")","')' after the foreach collection"),this.locals.length>65531&&this.fail("too many local variables (the format holds 65535)",e);let c=this.locals.length,u=c+1,d=u+1,m=d+1;this.locals.push({type:V(s),hidden:!1},{type:"int",hidden:!0},{type:"int",hidden:!0},{type:V(l),hidden:!1}),this.scopes.push(new Map([[t,{type:l,slot:m,readonly:!0,readonlyLabel:"foreach variable"}]]));let p={breaks:[],continues:[]};this.loopStack.push(p),this.code.mark(e),this.code.u8(F.STORE_LOCAL),this.code.u16(c),this.code.u8(F.PUSH_INT),this.code.i64(0),this.code.u8(F.LOAD_LOCAL),this.code.u16(c),this.emitSchemaMethod(s.object,"len",o[0]),this.code.u8(F.FOR_RANGE),this.code.u16(u),this.code.u16(d);let f=this.code.bytes.length;this.code.i32(0);let h=this.code.bytes.length;this.code.u8(F.LOAD_LOCAL),this.code.u16(c),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),this.emitSchemaMethod(s.object,"at",a[0]),this.code.u8(F.STORE_LOCAL),this.code.u16(m),this.block();for(let _ of p.continues)this.code.patch(_,this.code.bytes.length);this.code.mark(e),this.code.u8(F.FOR_NEXT),this.code.u16(d);let g=this.code.bytes.length;this.code.i32(0),this.code.patch(g,h),this.code.patch(f);for(let _ of p.breaks)this.code.patch(_);this.loopStack.pop(),this.scopes.pop()}whileStatement(){this.sourceMapped=!0;let e=this.tokens[this.pos-1];this.expect("(","'(' after while");let t=this.code.bytes.length;this.code.u8(F.WHILE_BEGIN);let r=this.peek(),s=this.expression();s!=="bool"&&this.fail("while condition must be bool; found "+V(s),r),this.expect(")","')' after the while condition");let i=this.code.jump(F.WHILE_TEST),o={breaks:[],continues:[]};this.loopStack.push(o),this.block();let a=this.code.bytes.length;for(let c of o.continues)this.code.patch(c,a);this.code.mark(e),this.code.u8(F.LOOP_BACK);let l=this.code.bytes.length;this.code.i32(0),this.code.patch(l,t),this.code.patch(i);for(let c of o.breaks)this.code.patch(c);this.loopStack.pop()}emitSchemaMethod(e,t,r){this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e+"."+t+Ht(r))),this.code.u8(r.params.length)}switchStatement(){this.sourceMapped=!0,this.expect("(","'(' after switch");let e=this.peek(),t=this.expression();t!=="int"&&t!=="string"&&(typeof t!="object"||!("enum"in t))&&this.fail("switch expression must be int, string or enum; found "+V(t),e),this.expect(")","')' after the switch expression"),this.locals.length>=65535&&this.fail("too many local variables (the format holds 65535)",e);let r=this.locals.length;this.locals.push({type:V(t),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(r),this.expect("{","'{' after the switch header");let s=new Set,i=[],o=!1,a=0;for(;!this.is("}");){this.peek().kind==="eof"&&this.fail("expected '}' to close switch, found end of body"),o&&this.fail(this.peek().text==="default"?"switch may contain at most one default":"default must be the last switch arm");let l=this.next();if((l.kind!=="ident"||l.text!=="case"&&l.text!=="default")&&this.fail("expected 'case' or 'default' in switch",l),this.code.mark(l),l.text==="default"){o&&this.fail("switch may contain at most one default",l),o=!0,this.expect(":","':' after default"),this.block(),this.code.mark(l),i.push(this.code.jump(F.JUMP));continue}a++;let c=this.switchConstant(t);s.has(c.key)&&this.fail("duplicate switch case "+c.display,c.token),s.add(c.key),this.expect(":","':' after case value"),this.code.u8(F.LOAD_LOCAL),this.code.u16(r),c.emit(),this.code.u8(F.EQ);let u=this.code.jump(F.JUMP_IF_FALSE);this.block(),this.code.mark(l),i.push(this.code.jump(F.JUMP)),this.code.patch(u)}if(this.next(),a===0&&!o&&this.fail("switch requires at least one case or default arm",e),typeof t=="object"&&"enum"in t&&!o){let l=[...this.schema.enums.get(t.enum)].filter(c=>!s.has("enum:"+t.enum+"."+c));l.length&&this.fail("switch on enum "+t.enum+" is missing case(s): "+l.join(", "),e)}for(let l of i)this.code.patch(l)}switchConstant(e){let r=this.peek();if(e==="int"){let l=1;this.is("-")&&(this.next(),l=-1,r=this.peek());let c=this.next();c.kind!=="int"&&this.fail("int switch cases must be integer literals",c);let u=l*c.value;return{key:"int:"+u,display:String(u),token:r,emit:()=>{this.code.u8(F.PUSH_INT),this.code.i64(u)}}}if(e==="string"){let l=this.next();l.kind!=="string"&&this.fail("string switch cases must be string literals",l);let c=l.value;return{key:"string:"+c,display:JSON.stringify(c),token:l,emit:()=>{this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(c))}}}let s=e.enum,i=this.next();(i.kind!=="ident"||i.text!==s||!this.is("."))&&this.fail("enum switch cases must be constants of type "+s+" (for example "+s+".VALUE)",i),this.next();let o=this.next();(o.kind!=="ident"||!this.schema.enums.get(s).has(o.text))&&this.fail("unknown value "+s+"."+o.text+"; expected one of "+[...this.schema.enums.get(s)].join(", "),o);let a=o.text;return{key:"enum:"+s+"."+a,display:s+"."+a,token:i,emit:()=>{this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(a))}}}block(){for(this.expect("{","'{' (every if/else body is a { } block)"),this.scopes.push(new Map);!this.is("}");)this.peek().kind==="eof"&&this.fail("expected '}' to close the block, found end of body"),this.statement();this.next(),this.scopes.pop()}expression(){return this.or()}or(){let e=this.and();for(;this.is("||");){let t=this.next();e!=="bool"&&this.fail("left side of || must be bool; found "+V(e),t),this.code.u8(F.DUP);let r=this.code.jump(F.JUMP_IF_TRUE);this.code.u8(F.POP);let s=this.peek(),i=this.and();i!=="bool"&&this.fail("right side of || must be bool; found "+V(i),s),this.code.patch(r),e="bool"}return e}and(){let e=this.equality();for(;this.is("&&");){let t=this.next();e!=="bool"&&this.fail("left side of && must be bool; found "+V(e),t),this.code.u8(F.DUP);let r=this.code.jump(F.JUMP_IF_FALSE);this.code.u8(F.POP);let s=this.peek(),i=this.equality();i!=="bool"&&this.fail("right side of && must be bool; found "+V(i),s),this.code.patch(r),e="bool"}return e}equality(){let e=this.peek(),t=this.comparison();for(;this.is("==")||this.is("!=");){let r=this.next();(t==="void"||typeof t=="object"&&"object"in t)&&this.fail("'"+r.text+"' compares primitive or enum values; left side is "+V(t),e);let s=this.peek(),i=this.comparison();ke(t,i)||this.fail("'"+r.text+"' needs both sides of the same type; found "+V(t)+" and "+V(i)+this.widenHint(t,i),s),this.code.u8(r.text==="=="?F.EQ:F.NE),t="bool"}return t}widenHint(e,t){return e==="int"&&t==="float"||e==="float"&&t==="int"?" (no implicit conversion: widen the int with float(i))":""}numeric(e,t,r,s,i,o){return Ob.includes(t)||this.fail("'"+e.text+"' needs int or float operands"+(e.text==="+"?" (or two strings)":"")+"; left side is "+V(t),e),ke(t,r)||this.fail("'"+e.text+"' needs both sides of the same numeric type; found "+V(t)+" and "+V(r)+this.widenHint(t,r)+(e.text==="+"&&r==="string"?" (to concatenate, start with a string and convert with str(x))":""),s),this.code.u8(t==="int"?i:o),t}comparison(){let e=this.additive();for(;this.is("<")||this.is("<=")||this.is(">")||this.is(">=");){let t=this.next(),r=this.peek(),s=this.additive(),i={"<":F.LT_I,"<=":F.LE_I,">":F.GT_I,">=":F.GE_I}[t.text],o={"<":F.LT_F,"<=":F.LE_F,">":F.GT_F,">=":F.GE_F}[t.text];this.numeric(t,e,s,r,i,o),e="bool"}return e}additive(){let e=this.multiplicative();for(;this.is("+")||this.is("-");){let t=this.next(),r=this.peek(),s=this.multiplicative();if(t.text==="+"&&e==="string"){s!=="string"&&this.fail("'+' on a string needs a string on the right; found "+V(s)+(typeof s=="string"&&s!=="void"?" (convert with str(x))":""),r),this.code.u8(F.CONCAT);continue}if(typeof e=="object"&&"object"in e){if(this.schema.operators.get(e.object)?.has(t.text)){e=this.operatorCall(e,t.text,s,t);continue}let i=this.schema.conversions.filter(a=>ke(a.from,e)&&"object"in a.to&&this.schema.operators.get(a.to.object)?.has(t.text));i.length>1&&this.fail("operator "+t.text+" is ambiguous after conversions: "+i.map(a=>V(a.to)).join(", "),t);let o=i[0];if(o){let a=this.locals.length;this.locals.push({type:V(s),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(a),this.emitConversion(o),this.code.u8(F.LOAD_LOCAL),this.code.u16(a),e=this.operatorCall(o.to,t.text,s,t);continue}this.fail("type "+e.object+" does not declare operator "+t.text,t)}if(typeof s=="object"&&"object"in s&&(e==="int"||e==="float")){if(this.schema.operators.get(s.object)?.get("r"+t.text)){e=this.operatorCall(s,"r"+t.text,e,t,!0);continue}let o=this.schema.conversions.filter(a=>ke(a.from,s)&&"object"in a.to&&this.schema.operators.get(a.to.object)?.has("r"+t.text));if(o.length>1&&this.fail("operator r"+t.text+" is ambiguous after conversions",t),o.length===1){e=this.operatorCall(o[0].to,"r"+t.text,e,t,!0,o[0]);continue}}e=this.numeric(t,e,s,r,t.text==="+"?F.ADD_I:F.SUB_I,t.text==="+"?F.ADD_F:F.SUB_F)}return e}multiplicative(){let e=this.unary();for(;this.is("*")||this.is("/")||this.is("%");){let t=this.next(),r=this.peek(),s=this.pos,i=this.unary();if(t.text==="%"&&(e!=="int"||i!=="int")&&this.fail("'%' needs two int operands (the remainder takes the dividend's sign); found "+V(e)+" and "+V(i)+(e==="float"||i==="float"?" (there is no float remainder)":""),e!=="int"?t:r),(t.text==="/"||t.text==="%")&&e==="int"&&r.kind==="int"&&r.value===0&&this.pos===s+1&&this.fail((t.text==="/"?"division":"remainder")+" by the literal zero is always a run-time error; remove it",r),t.text==="*"&&typeof e=="object"&&"object"in e){if(this.schema.operators.get(e.object)?.has("*")){e=this.operatorCall(e,"*",i,t);continue}let o=this.schema.conversions.filter(l=>ke(l.from,e)&&"object"in l.to&&this.schema.operators.get(l.to.object)?.has("*"));o.length>1&&this.fail("operator * is ambiguous after conversions: "+o.map(l=>V(l.to)).join(", "),t);let a=o[0];if(a){let l=this.locals.length;this.locals.push({type:V(i),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(l),this.emitConversion(a),this.code.u8(F.LOAD_LOCAL),this.code.u16(l),e=this.operatorCall(a.to,"*",i,t);continue}this.fail("type "+e.object+" does not declare operator *",t)}if(t.text==="*"&&typeof i=="object"&&"object"in i&&(e==="int"||e==="float")){if(this.schema.operators.get(i.object)?.get("r*")){e=this.operatorCall(i,"r*",e,t,!0);continue}let a=this.schema.conversions.filter(l=>ke(l.from,i)&&"object"in l.to&&this.schema.operators.get(l.to.object)?.has("r*"));if(a.length>1&&this.fail("operator r* is ambiguous after conversions",t),a.length===1){e=this.operatorCall(a[0].to,"r*",e,t,!0,a[0]);continue}}e=this.numeric(t,e,i,r,t.text==="*"?F.MUL_I:t.text==="/"?F.DIV_I:F.MOD_I,t.text==="*"?F.MUL_F:F.DIV_F)}return e}unary(){if(this.is("!")){let e=this.next(),t=this.peek(),r=this.unary();return r!=="bool"&&this.fail("'!' needs a bool; found "+V(r),t),this.code.u8(F.NOT),"bool"}if(this.is("-")){let e=this.next(),t=this.peek();if((t.kind==="int"||t.kind==="float")&&!(this.peek(1).kind==="punct"&&this.peek(1).text===".")){this.next();let s=-t.value;return t.kind==="int"?(this.code.u8(F.PUSH_INT),this.code.i64(s),this.postfix("int")):(this.code.u8(F.PUSH_FLOAT),this.code.f64(s),this.postfix("float"))}let r=this.unary();if(Ob.includes(r))return this.code.u8(r==="int"?F.NEG_I:F.NEG_F),r;if(typeof r=="object"&&"object"in r){if(this.schema.operators.get(r.object)?.has("neg"))return this.operatorCall(r,"neg",void 0,t);let s=this.schema.conversions.filter(i=>ke(i.from,r)&&"object"in i.to&&this.schema.operators.get(i.to.object)?.has("neg"));if(s.length===1)return this.emitConversion(s[0]),this.operatorCall(s[0].to,"neg",void 0,t);s.length>1&&this.fail("unary '-' is ambiguous after conversions: "+s.map(i=>V(i.to)).join(", "),t)}this.fail("unary '-' needs an int, float or operator-enabled object; found "+V(r),t)}return this.postfix(this.primary())}postfix(e){for(;this.is(".");){let t=this.next(),r=this.next();r.kind!=="ident"&&this.fail("expected a method name after '.', found "+this.describe(r),r),(typeof e=="string"||"enum"in e)&&this.fail("'"+r.text+"' is not a method: "+V(e)+" values have no methods",r);let s=this.schema.types.get(e.object),i=s.get(r.text);i||this.fail("type "+e.object+" has no method '"+r.text+"' (methods: "+([...s.keys()].join(", ")||"none")+")",r),this.is("(")||this.fail("method "+e.object+"."+r.text+" must be called",t);let o=this.callArguments(i,"method "+e.object+"."+r.text);this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.object+"."+r.text+Ht(o))),this.code.u8(o.params.length),e=o.returns}return e}callArguments(e,t){let r=this.expect("("),s=[];if(!this.is(")"))do{let a=this.peek();s.push({type:this.expression(),token:a})}while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let i=this.resolve(e,s.map(a=>a.type),t,r,s.map(a=>a.token)),o=i.params.map((a,l)=>ke(a,s[l].type)?void 0:this.conversion(s[l].type,a));if(o.some(Boolean)){let a=[];for(let l=s.length-1;l>=0;l--){let c=this.locals.length;this.locals.push({type:V(s[l].type),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(c),a[l]=c}for(let l=0;l<a.length;l++)this.code.u8(F.LOAD_LOCAL),this.code.u16(a[l]),o[l]&&this.emitConversion(o[l])}return i}conversion(e,t){return this.schema.conversions.find(r=>ke(r.from,e)&&ke(r.to,t))}resolve(e,t,r,s,i){let o=e.filter(c=>c.params.length===t.length),a=o.filter(c=>c.params.every((u,d)=>ke(u,t[d])));if(a.length===1)return a[0];a.length>1&&this.fail(r+" is ambiguous: "+a.map(Ht).join(", "),s);let l=o.filter(c=>c.params.every((u,d)=>ke(u,t[d])||!!this.conversion(t[d],u)));if(l.length===1)return l[0];if(l.length>1&&this.fail(r+" is ambiguous for ("+t.map(V).join(", ")+"): "+l.map(Ht).join(", "),s),o.length===1){let c=o[0];if(c.params.length===t.length){let u=c.params.findIndex((d,m)=>!ke(d,t[m])&&!this.conversion(t[m],d));u>=0&&this.fail(r+" expects "+V(c.params[u])+" for argument "+(u+1)+"; found "+V(t[u]),i?.[u]??s)}this.fail(r+" expects "+c.params.length+" argument(s) ("+c.params.map(V).join(", ")+"); found "+t.length,s)}o.length===0&&e.length===1&&this.fail(r+" expects "+e[0].params.length+" argument(s) ("+e[0].params.map(V).join(", ")+"); found "+t.length,s),this.fail(r+" has no overload for ("+t.map(V).join(", ")+"); candidates: "+(o.length?o.map(Ht).join(", "):e.map(Ht).join(", ")),s)}emitConversion(e){if(e.owner){let t=this.schema.types.get(e.owner)?.get(e.via)?.find(r=>r.params.length===0);t||this.fail("conversion via "+e.via+" is not a zero-argument method on "+e.owner),this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.owner+"."+e.via+Ht(t))),this.code.u8(0)}else{let t=this.schema.functions.get(e.via)?.find(r=>r.params.length===1&&ke(r.params[0],e.from));t||this.fail("conversion via "+e.via+" is not a unary function"),this.code.u8(F.CALL_FN),this.code.u16(this.code.import("fn "+e.via+Ht(t))),this.code.u8(1)}}operatorCall(e,t,r,s,i=!1,o){(typeof e!="object"||!("object"in e))&&this.fail("operator "+t+" needs an object operand",s);let a=this.schema.operators.get(e.object)?.get(t);a||this.fail("type "+e.object+" does not declare operator "+t,s);let l=this.schema.types.get(e.object)?.get(a);l||this.fail("operator "+t+" maps to missing method "+e.object+"."+a,s);let c=this.resolve(l,r===void 0?[]:[r],"operator "+t+" on "+e.object,s);if(i&&r!==void 0){let u=this.locals.length;this.locals.push({type:V(o?.from??e),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(u);let d=this.locals.length;this.locals.push({type:V(r),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(d),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),o&&this.emitConversion(o),this.code.u8(F.LOAD_LOCAL),this.code.u16(d),ke(c.params[0],r)||this.emitConversion(this.conversion(r,c.params[0]))}else if(r!==void 0&&!ke(c.params[0],r)){let u=this.locals.length;this.locals.push({type:V(r),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(u),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),this.emitConversion(this.conversion(r,c.params[0]))}return this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.object+"."+a+Ht(c))),this.code.u8(c.params.length),c.returns}userCall(e,t){if(this.expansionStack.includes(e.name)){let a=[...this.expansionStack.slice(this.expansionStack.indexOf(e.name)),e.name].join(" -> ");this.fail("recursive user functions are not allowed (cycle: "+a+")",t)}let r=this.expect("(","'(' after user function '"+e.name+"'"),s=[];if(!this.is(")"))do{let a=this.peek();s.push({type:this.expression(),token:a})}while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let i={params:e.params.map(a=>a.type),returns:e.returns};if(s.length!==e.params.length&&this.fail("user function "+e.name+" expects "+e.params.length+" argument(s) ("+i.params.map(V).join(", ")+"); found "+s.length,r),s.forEach((a,l)=>{ke(a.type,e.params[l].type)||this.fail("user function "+e.name+" expects "+V(e.params[l].type)+" for argument "+(l+1)+"; found "+V(a.type),a.token)}),this.validating)return this.validateFunction(e),e.returns;let o=e.params.map(a=>{this.locals.length>=65535&&this.fail("too many local variables after inlining function '"+e.name+"' (the format holds 65535)",a.token);let l=this.locals.length;return this.locals.push({type:V(a.type),hidden:!1}),l});for(let a=o.length-1;a>=0;a--)this.code.u8(F.STORE_LOCAL),this.code.u16(o[a]);return this.inlineFunction(e,t,o),this.code.mark(t),e.returns}primary(){let e=this.next();if(e.kind==="int")return this.code.u8(F.PUSH_INT),this.code.i64(e.value),"int";if(e.kind==="float")return this.code.u8(F.PUSH_FLOAT),this.code.f64(e.value),"float";if(e.kind==="string")return this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(e.value)),"string";if(e.kind==="punct"&&e.text==="("){let t=this.expression();return this.expect(")","')' to close the parenthesis"),t}if(e.kind==="ident"){if(e.text==="true"||e.text==="false")return this.code.u8(F.PUSH_BOOL),this.code.u8(e.text==="true"?1:0),"bool";Yn.has(e.text)&&this.fail("'"+e.text+"' is a keyword and cannot be used here",e);let t=this.lookup(e.text);if(t)return this.code.u8(F.LOAD_LOCAL),this.code.u16(t.slot),t.type;let r=this.schema.context.get(e.text);if(r)return this.code.u8(F.LOAD_CTX),this.code.u16(this.code.context(e.text,r)),{object:r};if(this.schema.enums.has(e.text)&&this.is(".")){this.next();let a=this.next(),l=this.schema.enums.get(e.text);return(a.kind!=="ident"||!l.has(a.text))&&this.fail("unknown value "+e.text+"."+a.text+"; expected one of "+[...l].join(", "),a),this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(a.text)),{enum:e.text}}if(e.text==="str"){this.is("(")||this.fail("built-in str must be called: add (int | float | bool)",e);let a=this.next(),l=this.peek();this.is(")")&&this.fail("built-in str expects 1 argument (int, float or bool); found 0",a);let c=this.expression();return this.is(",")&&this.fail("built-in str expects 1 argument (int, float or bool); found more",this.peek()),this.expect(")","')' after the argument"),c==="string"&&this.fail("built-in str expects int, float or bool; found string (already a string)",l),typeof c=="object"&&"enum"in c||(c!=="int"&&c!=="float"&&c!=="bool"&&this.fail("built-in str expects int, float, bool or enum; found "+(c==="void"?"void":"object "+V(c)),l),this.code.u8(c==="int"?F.I2S:c==="float"?F.F2S:F.B2S)),"string"}if(Hl.has(e.text)){let a=_i.filter(u=>u.name===e.text);this.is("(")||this.fail("built-in "+e.text+" must be called",e),this.next();let l=[];if(!this.is(")"))do l.push(this.expression());while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let c=_i.findIndex(u=>u.name===e.text&&u.params.length===l.length&&u.params.every((d,m)=>ke(d,l[m])));return c<0&&this.fail("built-in "+e.text+" expects "+a.map(Ht).join(" or ")+"; found ("+l.map(V).join(", ")+") (no implicit conversion)",e),this.code.u8(F.MATH),this.code.u8(c),_i[c].returns}if(Object.hasOwn(Es,e.text)){let a=Es[e.text];return this.is("(")||this.fail("built-in "+e.text+" must be called: add ("+a.params.map(V).join(", ")+")",e),this.callArguments([a],"built-in "+e.text),this.code.u8(F.I2F),a.returns}let s=this.schema.functions.get(e.text);if(s){this.is("(")||this.fail("host function "+e.text+" must be called: add ("+s[0].params.map(V).join(", ")+")",e);let a=this.callArguments(s,"function "+e.text);return this.code.u8(F.CALL_FN),this.code.u16(this.code.import("fn "+e.text+Ht(a))),this.code.u8(a.params.length),a.returns}let i=this.functions.get(e.text);if(i)return this.is("(")||this.fail("user function "+e.text+" must be called: add ("+i.params.map(a=>V(a.type)).join(", ")+")",e),this.userCall(i,e);let o=[...this.schema.context.keys(),...this.schema.functions.keys()];this.fail("undefined name '"+e.text+"' (locals are declared with let; the schema provides: "+(o.join(", ")||"nothing")+"; built-ins: "+gL+")",e)}return this.fail("expected an expression, found "+this.describe(e),e)}};Jm=new WeakMap,bi=class{schemaName;constructor(e,t){this.schemaName=t,Jm.set(this,e),Object.freeze(this)}toString(){throw new Error(Ts)}toJSON(){throw new Error(Ts)}static bytesOf(e){return Jm.get(e)}},Ts="a compiled _dsl_ value is opaque: it has no text, keys or methods; pass it to savedsl(dsl, path)"});import{AsyncLocalStorage as rv}from"node:async_hooks";import{isDeepStrictEqual as vL}from"node:util";import{spawn as wL,spawnSync as sv}from"node:child_process";import{randomUUID as Sp,createHash as EL}from"node:crypto";import{tmpdir as TL}from"node:os";import*as U from"node:fs";import*as se from"node:path";import*as iv from"node:readline";import{fileURLToPath as kp}from"node:url";import{types as Ie}from"node:util";function SL(n,e){let t=n.file&&n.file!=="<main>"?`${n.file}:${n.line}:${n.column}`:`${n.line}:${n.column}`,r=e;if(n.file&&(!r||r&&n.file!=="<main>"&&n.file!=="<std>"))try{U.existsSync(n.file)&&U.statSync(n.file).isFile()&&(r=U.readFileSync(n.file,"utf-8"))}catch{}if(!r)return`[${n.severity.toUpperCase()} at ${t}] ${n.message}`;let s=r.split(`
|
|
28
|
+
`,t:" ",r:"\r",'"':'"',"\\":"\\"};if(!(d in m))throw new qe("unknown escape \\"+(d??"")+' in string (known: \\n \\t \\r \\" \\\\)',s,c+1);u+=m[d],c+=2;continue}u+=r[c++]}if(c>=r.length)throw new qe("unterminated string literal (strings end on their line)",s,a);e.push({kind:"string",text:r.slice(i,c+1),value:u,lineIndex:s,column:a}),i=c+1;continue}let l=hL.find(c=>r.startsWith(c,i));if(!l)throw new qe("unexpected character "+JSON.stringify(o),s,a);e.push({kind:"punct",text:l,lineIndex:s,column:a}),i+=l.length}});let t=n.length-1;return e.push({kind:"eof",text:"end of body",lineIndex:Math.max(0,t),column:(n[t]?.length??0)+1}),e}function Ht(n){return"("+n.params.map(V).join(", ")+") -> "+V(n.returns)}function _L(n,e){let t=[],r=new Map,s=0,i=0,o=(c,u)=>{throw new qe(c,u.lineIndex,u.column)},a=(c,u)=>n[c]?.text===u,l=(c,u,d)=>{let m=n[c];return!m||m.kind!=="ident"?o("expected a type name for "+u,m??n[n.length-1]):Ar.includes(m.text)?m.text:m.text==="void"&&d?"void":e.types.has(m.text)?{object:m.text}:e.enums.has(m.text)?{enum:m.text}:o("unknown type "+JSON.stringify(m.text)+" for "+u+" (known: "+[...Ar,...d?["void"]:[],...e.types.keys(),...e.enums.keys()].join(", ")+")",m)};for(;n[i]?.kind!=="eof";){let c=n[i];if(c.kind==="ident"&&c.text==="fn"){s!==0&&o("nested function definitions are not allowed",c);let u=i++,d=n[i++];if(!d||d.kind!=="ident")return o("expected a function name after 'fn'",d??c);let m=d.text,p=e.functions.has(m)?"host function from the schema":e.context.has(m)?"context variable from the schema":e.types.has(m)||e.enums.has(m)||Ar.includes(m)||m==="void"?"type name":qm.has(m)?"DSL built-in":Yn.has(m)?"DSL keyword":r.has(m)?"another user function":"";p&&o("function '"+m+"' conflicts with "+p+" and cannot be defined",d),a(i++,"(")||o("expected '(' after function name",n[i-1]);let f=[],h=new Set;for(;!a(i,")");){let w=n[i++];if(!w||w.kind!=="ident")return o("expected a parameter name",w??d);(Yn.has(w.text)||e.context.has(w.text)||e.functions.has(w.text)||qm.has(w.text)||e.types.has(w.text)||e.enums.has(w.text)||Ar.includes(w.text)||w.text==="void")&&o("parameter '"+w.text+"' conflicts with a schema name or DSL built-in",w),h.has(w.text)&&o("duplicate parameter '"+w.text+"'",w),h.add(w.text),a(i++,":")||o("expected ':' after parameter name",n[i-1]);let k=l(i++,"parameter '"+w.text+"'",!1);if(f.push({name:w.text,type:k,token:w}),a(i,",")){i++,a(i,")")&&o("expected a parameter after ','",n[i]);continue}a(i,")")||o("expected ',' or ')' after parameter",n[i]??w)}i++,(!a(i++,"-")||!a(i++,">"))&&o("expected '->' and a return type after parameters",n[i-1]??d);let g=l(i++,"function return",!0);a(i++,"{")||o("expected '{' before function body",n[i-1]??d);let _=i,v=1;for(;i<n.length&&v>0;)n[i].kind==="ident"&&n[i].text==="fn"&&o("nested function definitions are not allowed",n[i]),n[i].kind==="punct"&&n[i].text==="{"?v++:n[i].kind==="punct"&&n[i].text==="}"&&v--,i++;v!==0&&o("expected '}' to close function '"+m+"'",n[_-1]);let y=n.slice(_,i-1),b=n[i-1];r.set(m,{name:m,params:f,returns:g,body:[...y,{kind:"eof",text:"end of function",lineIndex:b.lineIndex,column:b.column}],token:n[u]});continue}s>0&&c.kind==="ident"&&c.text==="fn"&&o("nested function definitions are not allowed",c),c.kind==="punct"&&c.text==="{"&&s++,c.kind==="punct"&&c.text==="}"&&s--,t.push(c),i++}t[t.length-1]?.kind!=="eof"&&t.push(n[n.length-1]);for(let c of r.values())for(let u of c.params)r.has(u.name)&&o("parameter '"+u.name+"' conflicts with user function '"+u.name+"'",u.token);return{tokens:t,functions:r}}function Km(n,e){let t=c=>{let u=c.slice(c.indexOf("(")+1,c.lastIndexOf(")"));return{argc:u===""?0:u.split(", ").length,returns:!c.endsWith("-> void")}},r=0,s=0,i=0,o=()=>n[i++],a=()=>{let c=n[i]<<8|n[i+1];return i+=2,c},l=(c,u)=>{if(r+=c,r<0)throw new qe("compiler bug: operand stack underflow at opcode "+u+" (pc "+i+")",-1,1);r>s&&(s=r)};for(;i<n.length;){let c=o();switch(c){case F.PUSH_INT:i+=8,l(1,c);break;case F.PUSH_FLOAT:i+=8,l(1,c);break;case F.PUSH_STR:i+=4,l(1,c);break;case F.PUSH_BOOL:i+=1,l(1,c);break;case F.LOAD_LOCAL:case F.LOAD_CTX:i+=2,l(1,c);break;case F.STORE_LOCAL:i+=2,l(-1,c);break;case F.CALL_FN:{let{argc:u,returns:d}=t(e[a()]);o(),l(-u+(d?1:0),c);break}case F.CALL_METHOD:{let{argc:u,returns:d}=t(e[a()]);o(),l(-u-1+(d?1:0),c);break}case F.EQ:case F.NE:case F.ADD_I:case F.SUB_I:case F.MUL_I:case F.DIV_I:case F.MOD_I:case F.ADD_F:case F.SUB_F:case F.MUL_F:case F.DIV_F:case F.LT_I:case F.LE_I:case F.GT_I:case F.GE_I:case F.LT_F:case F.LE_F:case F.GT_F:case F.GE_F:case F.CONCAT:case F.POP:l(-1,c);break;case F.NOT:case F.NEG_I:case F.NEG_F:case F.I2F:case F.I2S:case F.F2S:case F.B2S:case F.HALT:break;case F.JUMP:i+=4;break;case F.JUMP_IF_FALSE:case F.JUMP_IF_TRUE:i+=4,l(-1,c);break;case F.FOR_RANGE:i+=8,l(-2,c);break;case F.FOR_NEXT:i+=6;break;case F.WHILE_BEGIN:case F.LOOP_BACK:i+=c===F.WHILE_BEGIN?0:4;break;case F.WHILE_TEST:i+=4,l(-1,c);break;case F.MATH:l(1-_i[o()].params.length,c);break;case F.DUP:l(1,c);break;default:throw new qe("compiler bug: unknown opcode "+c+" while measuring the stack",-1,1)}}if(s>65535)throw new qe("the expression nesting needs "+s+" operand slots; the format records at most 65535",-1,1);return s}function Pb(n,e){let t=[],r=p=>{t.push(p&255)},s=p=>{t.push(p>>8&255,p&255)},i=p=>{t.push(p>>>24&255,p>>>16&255,p>>>8&255,p&255)},{consts:o,imports:a,contexts:l,locals:c,code:u,lines:d=[]}=e,m=p=>{let f=o.indexOf(p);if(f<0)throw new qe("compiler bug: section text "+JSON.stringify(p)+" is not a constant",-1,1);return f};for(let p of Buffer.from(Lb,"latin1"))t.push(p);s(Mb);for(let p of fL("sha256").update(n.bytes).digest())t.push(p);i(o.length);for(let p of o){let f=Buffer.from(p,"utf8");r(1),i(f.length);for(let h of f)t.push(h)}s(a.length);for(let p of a)i(m(p));s(l.length);for(let p of l)i(m(p.name)),i(m(p.type));if(c.length>65535)throw new qe("too many local variables (the format holds 65535)",-1,1);s(c.length);for(let p of c)i(m(p.type)),r(p.hidden?1:0);s(Km(u,a)),i(u.length);for(let p of u)t.push(p);i(d.length);for(let p of d)i(p.pc),i(p.line),s(p.column);return Uint8Array.from(t)}function bL(n){let e=Ht,t=[];for(let[r,s]of n.context)t.push("context "+r+": "+s);for(let[r,s]of n.functions)for(let i of s)t.push("fn "+r+e(i));for(let[r,s]of n.types)for(let[i,o]of s)for(let a of o)t.push("method "+r+"."+i+e(a));return t.sort()}function zm(n,e,t){let r=yL(n);if(r.length===1)throw new qe("the DSL body is empty",-1,1);let s=_L(r,e),i=new Gm(s.tokens,e,s.functions,t).compile(),o=Pb(e,i);return{bytes:o,consts:[...i.consts],imports:[...i.imports],locals:[...i.locals],nlocals:i.locals.length,maxStack:Km(i.code,i.imports),codeLength:i.code.length,codeOffset:o.length-4-i.lines.length*10-i.code.length}}function kn(n){return typeof n=="object"&&n!==null&&Jm.has(n)}var qe,zn,Ar,Ob,Es,_i,Hl,gL,qm,hL,Xm,Yn,F,Lb,Mb,Do,Gm,Jm,bi,Ts,Ym=L(()=>{"use strict";qe=class extends Error{lineIndex;column;constructor(e,t,r){super(e),this.lineIndex=t,this.column=r}},zn=/^[A-Za-z_][A-Za-z0-9_]*$/,Ar=["int","float","string","bool"],Ob=["int","float"],Es={float:{params:["int"],returns:"float"},str:{params:["int"],returns:"string"}},_i=[{name:"sin",params:["float"],returns:"float"},{name:"cos",params:["float"],returns:"float"},{name:"sqrt",params:["float"],returns:"float"},{name:"abs",params:["float"],returns:"float"},{name:"floor",params:["float"],returns:"float"},{name:"pow",params:["float","float"],returns:"float"},{name:"min",params:["float","float"],returns:"float"},{name:"max",params:["float","float"],returns:"float"},{name:"clamp",params:["float","float","float"],returns:"float"},{name:"lerp",params:["float","float","float"],returns:"float"},{name:"ease",params:["float"],returns:"float"},{name:"ease_in",params:["float"],returns:"float"},{name:"ease_out",params:["float"],returns:"float"},{name:"int",params:["float"],returns:"int"},{name:"abs",params:["int"],returns:"int"},{name:"min",params:["int","int"],returns:"int"},{name:"max",params:["int","int"],returns:"int"},{name:"clamp",params:["int","int","int"],returns:"int"}],Hl=new Set(_i.map(n=>n.name)),gL=[...Object.keys(Es),...Hl].join(", "),qm=new Set([...Object.keys(Es),...Hl]);hL=["==","!=","<=",">=","&&","||","(",")","{","}",";",",",":",".","!","=","<",">","+","-","*","/","%"],Xm=9007199254740992,Yn=new Set(["let","if","else","true","false","for","in","range","fn","return","switch","case","default","while","break","continue"]);F={PUSH_INT:1,PUSH_STR:2,PUSH_BOOL:3,LOAD_LOCAL:4,STORE_LOCAL:5,LOAD_CTX:6,CALL_FN:7,CALL_METHOD:8,EQ:9,NE:10,NOT:11,JUMP:12,JUMP_IF_FALSE:13,JUMP_IF_TRUE:14,DUP:15,POP:16,HALT:17,PUSH_FLOAT:18,ADD_I:19,SUB_I:20,MUL_I:21,DIV_I:22,ADD_F:23,SUB_F:24,MUL_F:25,DIV_F:26,NEG_I:27,NEG_F:28,LT_I:29,LE_I:30,GT_I:31,GE_I:32,LT_F:33,LE_F:34,GT_F:35,GE_F:36,I2F:37,CONCAT:38,I2S:39,F2S:40,B2S:41,MATH:50,MOD_I:51,FOR_RANGE:47,FOR_NEXT:49,WHILE_BEGIN:52,WHILE_TEST:53,LOOP_BACK:54},Lb="DSLB",Mb=5;Do=class{bytes=[];consts=[];imports=[];contexts=[];lines=[];mark(e,t){let r=t?.(e.lineIndex,e.column),s=r?.line??e.lineIndex+1,i=r?.column??e.column,o=i>65535?0:i,a=this.lines[this.lines.length-1];!a||a.pc!==this.bytes.length?this.lines.push({pc:this.bytes.length,line:s,column:o}):(a.line=s,a.column=o)}constant(e){let t=this.consts.indexOf(e);return t<0&&(this.consts.push(e),t=this.consts.length-1),t}import(e){let t=this.imports.indexOf(e);if(t<0){if(this.imports.length>=65535)throw new qe("too many distinct callees (the import table holds 65535)",-1,1);this.imports.push(e),t=this.imports.length-1}return t}context(e,t){let r=this.contexts.findIndex(s=>s.name===e);return r<0&&(this.contexts.push({name:e,type:t}),r=this.contexts.length-1),r}u8(e){this.bytes.push(e&255)}u16(e){this.bytes.push(e>>8&255,e&255)}u32(e){this.bytes.push(e>>>24&255,e>>>16&255,e>>>8&255,e&255)}i32(e){this.u32(e)}i64(e){let t=Buffer.alloc(8);t.writeBigInt64BE(BigInt(e));for(let r of t)this.bytes.push(r)}f64(e){let t=Buffer.alloc(8);t.writeDoubleBE(e);for(let r of t)this.bytes.push(r)}jump(e){this.u8(e);let t=this.bytes.length;return this.i32(0),t}patch(e,t=this.bytes.length){let r=t-(e+4);this.bytes[e]=r>>>24&255,this.bytes[e+1]=r>>>16&255,this.bytes[e+2]=r>>>8&255,this.bytes[e+3]=r&255}};Gm=class{pos=0;code=new Do;scopes=[new Map];locals=[];tokens;schema;functions;sourceMapper;expansionStack=[];sourceMapped=!1;validating=!1;validatedFunctions=new Set;loopStack=[];constructor(e,t,r=new Map,s){this.tokens=e,this.schema=t,this.functions=r,this.sourceMapper=s}compile(){for(let e of this.functions.values())this.validateFunction(e);for(this.code=new Do,this.locals=[],this.scopes=[new Map],this.pos=0,this.expansionStack=[],this.sourceMapped=!0,this.loopStack=[];this.peek().kind!=="eof";)this.statement();this.code.u8(F.HALT);for(let e of this.code.imports)this.code.constant(e);for(let e of this.code.contexts)this.code.constant(e.name),this.code.constant(e.type);for(let e of this.locals)this.code.constant(e.type);return{consts:this.code.consts,imports:this.code.imports,contexts:this.code.contexts,locals:this.locals,code:this.code.bytes,lines:this.sourceMapped?this.code.lines:[]}}validateFunction(e){if(this.validatedFunctions.has(e.name))return;let t={code:this.code,locals:this.locals,scopes:this.scopes,tokens:this.tokens,pos:this.pos,stack:this.expansionStack,expanded:this.sourceMapped,validating:this.validating,loops:this.loopStack};this.code=new Do,this.locals=[],this.scopes=[new Map],this.tokens=e.body,this.pos=0,this.expansionStack=[...t.stack,e.name],this.sourceMapped=!1,this.validating=!0,this.loopStack=[],this.bindParameters(e),this.compileFunctionBody(e),this.code=t.code,this.locals=t.locals,this.scopes=t.scopes,this.tokens=t.tokens,this.pos=t.pos,this.expansionStack=t.stack,this.sourceMapped=t.expanded,this.validating=t.validating,this.loopStack=t.loops,this.validatedFunctions.add(e.name)}bindParameters(e){let t=[];for(let r of e.params){this.locals.length>=65535&&this.fail("too many local variables after inlining function '"+e.name+"' (the format holds 65535)",r.token);let s=this.locals.length;this.locals.push({type:V(r.type),hidden:!1}),this.scopes[0].set(r.name,{type:r.type,slot:s}),t.push(s)}return t}compileFunctionBody(e){let t=!1;for(;this.peek().kind!=="eof";){let r=this.peek();if(r.kind==="ident"&&r.text==="return"){this.code.mark(r,this.sourceMapper),e.returns==="void"&&this.fail("void function '"+e.name+"' has no return value",r),this.next();let s=this.peek(),i=this.expression();ke(i,e.returns)||this.fail("function '"+e.name+"' returns "+V(e.returns)+"; found "+V(i),s),this.expect(";","';' after the return expression"),this.peek().kind!=="eof"&&this.fail("return must be the final top-level statement in function '"+e.name+"'"),t=!0;break}this.statement()}e.returns!=="void"&&!t&&this.fail("function '"+e.name+"' must end with 'return expr;'",e.token)}inlineFunction(e,t,r){if(this.expansionStack.includes(e.name)){let i=[...this.expansionStack.slice(this.expansionStack.indexOf(e.name)),e.name].join(" -> ");this.fail("recursive user functions are not allowed (cycle: "+i+")",t)}let s={tokens:this.tokens,pos:this.pos,scopes:this.scopes,stack:this.expansionStack,loops:this.loopStack};this.tokens=e.body,this.pos=0,this.scopes=[new Map],this.expansionStack=[...s.stack,e.name],this.loopStack=[],e.params.forEach((i,o)=>this.scopes[0].set(i.name,{type:i.type,slot:r[o]})),this.sourceMapped=!0,this.compileFunctionBody(e),this.tokens=s.tokens,this.pos=s.pos,this.scopes=s.scopes,this.expansionStack=s.stack,this.loopStack=s.loops}peek(e=0){return this.tokens[Math.min(this.pos+e,this.tokens.length-1)]}next(){let e=this.peek();return e.kind!=="eof"&&this.pos++,e}fail(e,t=this.peek()){throw new qe(e,t.lineIndex,t.column)}is(e){let t=this.peek();return(t.kind==="punct"||t.kind==="ident")&&t.text===e}expect(e,t="'"+e+"'"){return this.is(e)||this.fail("expected "+t+", found "+this.describe(this.peek())),this.next()}describe(e){return e.kind==="eof"?"end of body":e.kind==="string"?"string "+e.text:"'"+e.text+"'"}lookup(e){for(let t=this.scopes.length-1;t>=0;t--){let r=this.scopes[t].get(e);if(r)return r}}statement(){let e=this.peek();if(this.code.mark(e,this.sourceMapper),e.kind==="ident"&&e.text==="return"&&this.fail("return is allowed only as the final top-level statement of a value-returning function",e),e.kind==="ident"&&e.text==="let"){this.next(),this.letStatement();return}if(e.kind==="ident"&&e.text==="if"){this.next(),this.ifStatement();return}if(e.kind==="ident"&&e.text==="for"){this.next(),this.forStatement();return}if(e.kind==="ident"&&e.text==="while"){this.next(),this.whileStatement();return}if(e.kind==="ident"&&(e.text==="break"||e.text==="continue")){this.loopStack.length||this.fail("'"+e.text+"' is allowed only inside a loop (and cannot cross a function boundary)",e),this.sourceMapped=!0,this.next(),this.expect(";","';' after "+e.text),(e.text==="break"?this.loopStack[this.loopStack.length-1].breaks:this.loopStack[this.loopStack.length-1].continues).push(this.code.jump(F.JUMP));return}if(e.kind==="ident"&&e.text==="switch"){this.next(),this.switchStatement();return}if(e.kind==="ident"&&e.text==="else"&&this.fail("'else' without a preceding if"),e.kind==="ident"&&!Yn.has(e.text)&&this.peek(1).kind==="punct"&&this.peek(1).text==="="){this.assignment();return}e.kind==="punct"&&e.text==="}"&&this.fail("unexpected '}' (no block is open)");let t=this.peek(),r=this.expression();t.kind==="ident"&&this.tokens[this.pos-1].text===")"||this.fail("this expression has no effect; only calls, let, assignment and if are statements",t),r!=="void"&&this.code.u8(F.POP),this.expect(";","';' after the statement")}letStatement(){let e=this.next();(e.kind!=="ident"||Yn.has(e.text))&&this.fail("expected a variable name after let, found "+this.describe(e),e);let t=e.text;this.schema.context.has(t)&&this.fail("'"+t+"' is a context variable from the schema and cannot be redeclared",e),this.schema.functions.has(t)&&this.fail("'"+t+"' is a host function from the schema and cannot be a variable",e),this.functions.has(t)&&this.fail("'"+t+"' is a user function and cannot be a variable",e),Object.hasOwn(Es,t)&&this.fail("'"+t+"' is a DSL built-in and cannot be a variable",e);let r=this.lookup(t);r?.readonly&&this.fail((r.readonlyLabel??"loop counter")+" '"+t+"' is read-only and cannot be redeclared",e),this.scopes[this.scopes.length-1].has(t)&&this.fail("variable '"+t+"' is already declared in this block",e),this.expect("=","'=' after the variable name (the type is inferred from the initializer)");let s=this.expression();s==="void"&&this.fail("cannot store a void result in '"+t+"'",e),this.locals.length>=65535&&this.fail("too many local variables (the format holds 65535)",e);let i=this.locals.length;this.locals.push({type:V(s),hidden:!1}),this.scopes[this.scopes.length-1].set(t,{type:s,slot:i}),this.code.u8(F.STORE_LOCAL),this.code.u16(i),this.expect(";","';' after the declaration")}assignment(){let e=this.next(),t=e.text;this.expect("=");let r=this.lookup(t);r||(this.schema.context.has(t)&&this.fail("'"+t+"' is a context object and cannot be reassigned",e),this.fail("undefined variable '"+t+"' (declare it with let "+t+" = ...;)",e)),r.readonly&&this.fail((r.readonlyLabel??"loop counter")+" '"+t+"' is read-only and cannot be assigned",e);let s=this.peek(),i=this.expression();ke(i,r.type)||this.fail("cannot assign "+V(i)+" to '"+t+"' of type "+V(r.type),s),this.code.u8(F.STORE_LOCAL),this.code.u16(r.slot),this.expect(";","';' after the assignment")}ifStatement(){this.expect("(","'(' after if");let e=this.peek(),t=this.expression();t!=="bool"&&this.fail("if condition must be bool; found "+V(t),e),this.expect(")","')' after the condition");let r=this.code.jump(F.JUMP_IF_FALSE);if(this.block(),this.is("else")){this.next();let s=this.code.jump(F.JUMP);this.code.patch(r),this.is("if")?(this.next(),this.ifStatement()):this.block(),this.code.patch(s)}else this.code.patch(r)}forStatement(){this.expect("(","'(' after for");let e=this.next();(e.kind!=="ident"||Yn.has(e.text))&&this.fail("expected a loop counter name, found "+this.describe(e),e);let t=e.text;if((this.schema.context.has(t)||this.schema.functions.has(t)||this.functions.has(t)||Object.hasOwn(Es,t)||qm.has(t))&&this.fail("loop counter '"+t+"' cannot shadow a schema name or built-in",e),this.lookup(t)?.readonly&&this.fail("loop counter '"+t+"' is read-only and cannot be redeclared",e),this.expect("in","'in' after the loop counter"),!this.is("range")){(this.schema.types.has(t)||this.schema.enums.has(t)||Ar.includes(t)||t==="void")&&this.fail("foreach variable '"+t+"' cannot shadow a schema type name",e),this.foreachStatement(e,t);return}this.next(),this.expect("(","'(' after range");let r=this.peek(),s=this.expression();s!=="int"&&this.fail("range start must be int; found "+V(s),r),this.expect(",","',' between the range start and end");let i=this.peek(),o=this.expression();o!=="int"&&this.fail("range end must be int; found "+V(o),i),this.expect(")","')' after range(start, end); range takes exactly two bounds, with step 1"),this.expect(")","')' after the for header"),this.locals.length>65533&&this.fail("too many local variables (the format holds 65535)",e);let a=this.locals.length,l=a+1;this.locals.push({type:"int",hidden:!0},{type:"int",hidden:!0}),this.scopes.push(new Map([[t,{type:"int",slot:a,readonly:!0}]]));let c={breaks:[],continues:[]};this.loopStack.push(c),this.code.u8(F.FOR_RANGE),this.code.u16(a),this.code.u16(l);let u=this.code.bytes.length;this.code.i32(0);let d=this.code.bytes.length;this.block();for(let p of c.continues)this.code.patch(p,this.code.bytes.length);this.code.mark(e,this.sourceMapper),this.code.u8(F.FOR_NEXT),this.code.u16(l);let m=this.code.bytes.length;this.code.i32(0),this.code.patch(m,d),this.code.patch(u);for(let p of c.breaks)this.code.patch(p);this.loopStack.pop(),this.scopes.pop()}foreachStatement(e,t){this.sourceMapped=!0;let r=this.peek(),s=this.expression();(typeof s!="object"||!("object"in s))&&this.fail("foreach needs a host collection object with len() -> int and at(int) -> T; found "+V(s),r);let i=this.schema.types.get(s.object),o=(i.get("len")??[]).filter(_=>_.params.length===0&&_.returns==="int"),a=(i.get("at")??[]).filter(_=>_.params.length===1&&_.params[0]==="int"&&_.returns!=="void");(o.length!==1||a.length!==1)&&this.fail("foreach collection type "+s.object+" must declare exactly len() -> int and at(int) -> T (T must be a value type)",r);let l=a[0].returns;this.expect(")","')' after the foreach collection"),this.locals.length>65531&&this.fail("too many local variables (the format holds 65535)",e);let c=this.locals.length,u=c+1,d=u+1,m=d+1;this.locals.push({type:V(s),hidden:!1},{type:"int",hidden:!0},{type:"int",hidden:!0},{type:V(l),hidden:!1}),this.scopes.push(new Map([[t,{type:l,slot:m,readonly:!0,readonlyLabel:"foreach variable"}]]));let p={breaks:[],continues:[]};this.loopStack.push(p),this.code.mark(e,this.sourceMapper),this.code.u8(F.STORE_LOCAL),this.code.u16(c),this.code.u8(F.PUSH_INT),this.code.i64(0),this.code.u8(F.LOAD_LOCAL),this.code.u16(c),this.emitSchemaMethod(s.object,"len",o[0]),this.code.u8(F.FOR_RANGE),this.code.u16(u),this.code.u16(d);let f=this.code.bytes.length;this.code.i32(0);let h=this.code.bytes.length;this.code.u8(F.LOAD_LOCAL),this.code.u16(c),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),this.emitSchemaMethod(s.object,"at",a[0]),this.code.u8(F.STORE_LOCAL),this.code.u16(m),this.block();for(let _ of p.continues)this.code.patch(_,this.code.bytes.length);this.code.mark(e,this.sourceMapper),this.code.u8(F.FOR_NEXT),this.code.u16(d);let g=this.code.bytes.length;this.code.i32(0),this.code.patch(g,h),this.code.patch(f);for(let _ of p.breaks)this.code.patch(_);this.loopStack.pop(),this.scopes.pop()}whileStatement(){this.sourceMapped=!0;let e=this.tokens[this.pos-1];this.expect("(","'(' after while");let t=this.code.bytes.length;this.code.u8(F.WHILE_BEGIN);let r=this.peek(),s=this.expression();s!=="bool"&&this.fail("while condition must be bool; found "+V(s),r),this.expect(")","')' after the while condition");let i=this.code.jump(F.WHILE_TEST),o={breaks:[],continues:[]};this.loopStack.push(o),this.block();let a=this.code.bytes.length;for(let c of o.continues)this.code.patch(c,a);this.code.mark(e,this.sourceMapper),this.code.u8(F.LOOP_BACK);let l=this.code.bytes.length;this.code.i32(0),this.code.patch(l,t),this.code.patch(i);for(let c of o.breaks)this.code.patch(c);this.loopStack.pop()}emitSchemaMethod(e,t,r){this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e+"."+t+Ht(r))),this.code.u8(r.params.length)}switchStatement(){this.sourceMapped=!0,this.expect("(","'(' after switch");let e=this.peek(),t=this.expression();t!=="int"&&t!=="string"&&(typeof t!="object"||!("enum"in t))&&this.fail("switch expression must be int, string or enum; found "+V(t),e),this.expect(")","')' after the switch expression"),this.locals.length>=65535&&this.fail("too many local variables (the format holds 65535)",e);let r=this.locals.length;this.locals.push({type:V(t),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(r),this.expect("{","'{' after the switch header");let s=new Set,i=[],o=!1,a=0;for(;!this.is("}");){this.peek().kind==="eof"&&this.fail("expected '}' to close switch, found end of body"),o&&this.fail(this.peek().text==="default"?"switch may contain at most one default":"default must be the last switch arm");let l=this.next();if((l.kind!=="ident"||l.text!=="case"&&l.text!=="default")&&this.fail("expected 'case' or 'default' in switch",l),this.code.mark(l,this.sourceMapper),l.text==="default"){o&&this.fail("switch may contain at most one default",l),o=!0,this.expect(":","':' after default"),this.block(),this.code.mark(l,this.sourceMapper),i.push(this.code.jump(F.JUMP));continue}a++;let c=this.switchConstant(t);s.has(c.key)&&this.fail("duplicate switch case "+c.display,c.token),s.add(c.key),this.expect(":","':' after case value"),this.code.u8(F.LOAD_LOCAL),this.code.u16(r),c.emit(),this.code.u8(F.EQ);let u=this.code.jump(F.JUMP_IF_FALSE);this.block(),this.code.mark(l,this.sourceMapper),i.push(this.code.jump(F.JUMP)),this.code.patch(u)}if(this.next(),a===0&&!o&&this.fail("switch requires at least one case or default arm",e),typeof t=="object"&&"enum"in t&&!o){let l=[...this.schema.enums.get(t.enum)].filter(c=>!s.has("enum:"+t.enum+"."+c));l.length&&this.fail("switch on enum "+t.enum+" is missing case(s): "+l.join(", "),e)}for(let l of i)this.code.patch(l)}switchConstant(e){let r=this.peek();if(e==="int"){let l=1;this.is("-")&&(this.next(),l=-1,r=this.peek());let c=this.next();c.kind!=="int"&&this.fail("int switch cases must be integer literals",c);let u=l*c.value;return{key:"int:"+u,display:String(u),token:r,emit:()=>{this.code.u8(F.PUSH_INT),this.code.i64(u)}}}if(e==="string"){let l=this.next();l.kind!=="string"&&this.fail("string switch cases must be string literals",l);let c=l.value;return{key:"string:"+c,display:JSON.stringify(c),token:l,emit:()=>{this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(c))}}}let s=e.enum,i=this.next();(i.kind!=="ident"||i.text!==s||!this.is("."))&&this.fail("enum switch cases must be constants of type "+s+" (for example "+s+".VALUE)",i),this.next();let o=this.next();(o.kind!=="ident"||!this.schema.enums.get(s).has(o.text))&&this.fail("unknown value "+s+"."+o.text+"; expected one of "+[...this.schema.enums.get(s)].join(", "),o);let a=o.text;return{key:"enum:"+s+"."+a,display:s+"."+a,token:i,emit:()=>{this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(a))}}}block(){for(this.expect("{","'{' (every if/else body is a { } block)"),this.scopes.push(new Map);!this.is("}");)this.peek().kind==="eof"&&this.fail("expected '}' to close the block, found end of body"),this.statement();this.next(),this.scopes.pop()}expression(){return this.or()}or(){let e=this.and();for(;this.is("||");){let t=this.next();e!=="bool"&&this.fail("left side of || must be bool; found "+V(e),t),this.code.u8(F.DUP);let r=this.code.jump(F.JUMP_IF_TRUE);this.code.u8(F.POP);let s=this.peek(),i=this.and();i!=="bool"&&this.fail("right side of || must be bool; found "+V(i),s),this.code.patch(r),e="bool"}return e}and(){let e=this.equality();for(;this.is("&&");){let t=this.next();e!=="bool"&&this.fail("left side of && must be bool; found "+V(e),t),this.code.u8(F.DUP);let r=this.code.jump(F.JUMP_IF_FALSE);this.code.u8(F.POP);let s=this.peek(),i=this.equality();i!=="bool"&&this.fail("right side of && must be bool; found "+V(i),s),this.code.patch(r),e="bool"}return e}equality(){let e=this.peek(),t=this.comparison();for(;this.is("==")||this.is("!=");){let r=this.next();(t==="void"||typeof t=="object"&&"object"in t)&&this.fail("'"+r.text+"' compares primitive or enum values; left side is "+V(t),e);let s=this.peek(),i=this.comparison();ke(t,i)||this.fail("'"+r.text+"' needs both sides of the same type; found "+V(t)+" and "+V(i)+this.widenHint(t,i),s),this.code.u8(r.text==="=="?F.EQ:F.NE),t="bool"}return t}widenHint(e,t){return e==="int"&&t==="float"||e==="float"&&t==="int"?" (no implicit conversion: widen the int with float(i))":""}numeric(e,t,r,s,i,o){return Ob.includes(t)||this.fail("'"+e.text+"' needs int or float operands"+(e.text==="+"?" (or two strings)":"")+"; left side is "+V(t),e),ke(t,r)||this.fail("'"+e.text+"' needs both sides of the same numeric type; found "+V(t)+" and "+V(r)+this.widenHint(t,r)+(e.text==="+"&&r==="string"?" (to concatenate, start with a string and convert with str(x))":""),s),this.code.mark(e,this.sourceMapper),this.code.u8(t==="int"?i:o),t}comparison(){let e=this.additive();for(;this.is("<")||this.is("<=")||this.is(">")||this.is(">=");){let t=this.next(),r=this.peek(),s=this.additive(),i={"<":F.LT_I,"<=":F.LE_I,">":F.GT_I,">=":F.GE_I}[t.text],o={"<":F.LT_F,"<=":F.LE_F,">":F.GT_F,">=":F.GE_F}[t.text];this.numeric(t,e,s,r,i,o),e="bool"}return e}additive(){let e=this.multiplicative();for(;this.is("+")||this.is("-");){let t=this.next(),r=this.peek(),s=this.multiplicative();if(t.text==="+"&&e==="string"){s!=="string"&&this.fail("'+' on a string needs a string on the right; found "+V(s)+(typeof s=="string"&&s!=="void"?" (convert with str(x))":""),r),this.code.mark(t,this.sourceMapper),this.code.u8(F.CONCAT);continue}if(typeof e=="object"&&"object"in e){if(this.schema.operators.get(e.object)?.has(t.text)){e=this.operatorCall(e,t.text,s,t);continue}let i=this.schema.conversions.filter(a=>ke(a.from,e)&&"object"in a.to&&this.schema.operators.get(a.to.object)?.has(t.text));i.length>1&&this.fail("operator "+t.text+" is ambiguous after conversions: "+i.map(a=>V(a.to)).join(", "),t);let o=i[0];if(o){let a=this.locals.length;this.locals.push({type:V(s),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(a),this.emitConversion(o,t),this.code.u8(F.LOAD_LOCAL),this.code.u16(a),e=this.operatorCall(o.to,t.text,s,t);continue}this.fail("type "+e.object+" does not declare operator "+t.text,t)}if(typeof s=="object"&&"object"in s&&(e==="int"||e==="float")){if(this.schema.operators.get(s.object)?.get("r"+t.text)){e=this.operatorCall(s,"r"+t.text,e,t,!0);continue}let o=this.schema.conversions.filter(a=>ke(a.from,s)&&"object"in a.to&&this.schema.operators.get(a.to.object)?.has("r"+t.text));if(o.length>1&&this.fail("operator r"+t.text+" is ambiguous after conversions",t),o.length===1){e=this.operatorCall(o[0].to,"r"+t.text,e,t,!0,o[0]);continue}}e=this.numeric(t,e,s,r,t.text==="+"?F.ADD_I:F.SUB_I,t.text==="+"?F.ADD_F:F.SUB_F)}return e}multiplicative(){let e=this.unary();for(;this.is("*")||this.is("/")||this.is("%");){let t=this.next(),r=this.peek(),s=this.pos,i=this.unary();if(t.text==="%"&&(e!=="int"||i!=="int")&&this.fail("'%' needs two int operands (the remainder takes the dividend's sign); found "+V(e)+" and "+V(i)+(e==="float"||i==="float"?" (there is no float remainder)":""),e!=="int"?t:r),(t.text==="/"||t.text==="%")&&e==="int"&&r.kind==="int"&&r.value===0&&this.pos===s+1&&this.fail((t.text==="/"?"division":"remainder")+" by the literal zero is always a run-time error; remove it",r),t.text==="*"&&typeof e=="object"&&"object"in e){if(this.schema.operators.get(e.object)?.has("*")){e=this.operatorCall(e,"*",i,t);continue}let o=this.schema.conversions.filter(l=>ke(l.from,e)&&"object"in l.to&&this.schema.operators.get(l.to.object)?.has("*"));o.length>1&&this.fail("operator * is ambiguous after conversions: "+o.map(l=>V(l.to)).join(", "),t);let a=o[0];if(a){let l=this.locals.length;this.locals.push({type:V(i),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(l),this.emitConversion(a,t),this.code.u8(F.LOAD_LOCAL),this.code.u16(l),e=this.operatorCall(a.to,"*",i,t);continue}this.fail("type "+e.object+" does not declare operator *",t)}if(t.text==="*"&&typeof i=="object"&&"object"in i&&(e==="int"||e==="float")){if(this.schema.operators.get(i.object)?.get("r*")){e=this.operatorCall(i,"r*",e,t,!0);continue}let a=this.schema.conversions.filter(l=>ke(l.from,i)&&"object"in l.to&&this.schema.operators.get(l.to.object)?.has("r*"));if(a.length>1&&this.fail("operator r* is ambiguous after conversions",t),a.length===1){e=this.operatorCall(a[0].to,"r*",e,t,!0,a[0]);continue}}e=this.numeric(t,e,i,r,t.text==="*"?F.MUL_I:t.text==="/"?F.DIV_I:F.MOD_I,t.text==="*"?F.MUL_F:F.DIV_F)}return e}unary(){if(this.is("!")){let e=this.next(),t=this.peek(),r=this.unary();return r!=="bool"&&this.fail("'!' needs a bool; found "+V(r),t),this.code.u8(F.NOT),"bool"}if(this.is("-")){let e=this.next(),t=this.peek();if((t.kind==="int"||t.kind==="float")&&!(this.peek(1).kind==="punct"&&this.peek(1).text===".")){this.next();let s=-t.value;return t.kind==="int"?(this.code.u8(F.PUSH_INT),this.code.i64(s),this.postfix("int")):(this.code.u8(F.PUSH_FLOAT),this.code.f64(s),this.postfix("float"))}let r=this.unary();if(Ob.includes(r))return this.code.mark(e,this.sourceMapper),this.code.u8(r==="int"?F.NEG_I:F.NEG_F),r;if(typeof r=="object"&&"object"in r){if(this.schema.operators.get(r.object)?.has("neg"))return this.operatorCall(r,"neg",void 0,e);let s=this.schema.conversions.filter(i=>ke(i.from,r)&&"object"in i.to&&this.schema.operators.get(i.to.object)?.has("neg"));if(s.length===1)return this.emitConversion(s[0],e),this.operatorCall(s[0].to,"neg",void 0,e);s.length>1&&this.fail("unary '-' is ambiguous after conversions: "+s.map(i=>V(i.to)).join(", "),t)}this.fail("unary '-' needs an int, float or operator-enabled object; found "+V(r),t)}return this.postfix(this.primary())}postfix(e){for(;this.is(".");){let t=this.next(),r=this.next();r.kind!=="ident"&&this.fail("expected a method name after '.', found "+this.describe(r),r),(typeof e=="string"||"enum"in e)&&this.fail("'"+r.text+"' is not a method: "+V(e)+" values have no methods",r);let s=this.schema.types.get(e.object),i=s.get(r.text);i||this.fail("type "+e.object+" has no method '"+r.text+"' (methods: "+([...s.keys()].join(", ")||"none")+")",r),this.is("(")||this.fail("method "+e.object+"."+r.text+" must be called",t);let o=this.callArguments(i,"method "+e.object+"."+r.text);this.code.mark(r,this.sourceMapper),this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.object+"."+r.text+Ht(o))),this.code.u8(o.params.length),e=o.returns}return e}callArguments(e,t){let r=this.expect("("),s=[];if(!this.is(")"))do{let a=this.peek();s.push({type:this.expression(),token:a})}while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let i=this.resolve(e,s.map(a=>a.type),t,r,s.map(a=>a.token)),o=i.params.map((a,l)=>ke(a,s[l].type)?void 0:this.conversion(s[l].type,a));if(o.some(Boolean)){let a=[];for(let l=s.length-1;l>=0;l--){let c=this.locals.length;this.locals.push({type:V(s[l].type),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(c),a[l]=c}for(let l=0;l<a.length;l++)this.code.u8(F.LOAD_LOCAL),this.code.u16(a[l]),o[l]&&this.emitConversion(o[l],s[l].token)}return i}conversion(e,t){return this.schema.conversions.find(r=>ke(r.from,e)&&ke(r.to,t))}resolve(e,t,r,s,i){let o=e.filter(c=>c.params.length===t.length),a=o.filter(c=>c.params.every((u,d)=>ke(u,t[d])));if(a.length===1)return a[0];a.length>1&&this.fail(r+" is ambiguous: "+a.map(Ht).join(", "),s);let l=o.filter(c=>c.params.every((u,d)=>ke(u,t[d])||!!this.conversion(t[d],u)));if(l.length===1)return l[0];if(l.length>1&&this.fail(r+" is ambiguous for ("+t.map(V).join(", ")+"): "+l.map(Ht).join(", "),s),o.length===1){let c=o[0];if(c.params.length===t.length){let u=c.params.findIndex((d,m)=>!ke(d,t[m])&&!this.conversion(t[m],d));u>=0&&this.fail(r+" expects "+V(c.params[u])+" for argument "+(u+1)+"; found "+V(t[u]),i?.[u]??s)}this.fail(r+" expects "+c.params.length+" argument(s) ("+c.params.map(V).join(", ")+"); found "+t.length,s)}o.length===0&&e.length===1&&this.fail(r+" expects "+e[0].params.length+" argument(s) ("+e[0].params.map(V).join(", ")+"); found "+t.length,s),this.fail(r+" has no overload for ("+t.map(V).join(", ")+"); candidates: "+(o.length?o.map(Ht).join(", "):e.map(Ht).join(", ")),s)}emitConversion(e,t){if(this.code.mark(t,this.sourceMapper),e.owner){let r=this.schema.types.get(e.owner)?.get(e.via)?.find(s=>s.params.length===0);r||this.fail("conversion via "+e.via+" is not a zero-argument method on "+e.owner),this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.owner+"."+e.via+Ht(r))),this.code.u8(0)}else{let r=this.schema.functions.get(e.via)?.find(s=>s.params.length===1&&ke(s.params[0],e.from));r||this.fail("conversion via "+e.via+" is not a unary function"),this.code.u8(F.CALL_FN),this.code.u16(this.code.import("fn "+e.via+Ht(r))),this.code.u8(1)}}operatorCall(e,t,r,s,i=!1,o){(typeof e!="object"||!("object"in e))&&this.fail("operator "+t+" needs an object operand",s);let a=this.schema.operators.get(e.object)?.get(t);a||this.fail("type "+e.object+" does not declare operator "+t,s);let l=this.schema.types.get(e.object)?.get(a);l||this.fail("operator "+t+" maps to missing method "+e.object+"."+a,s);let c=this.resolve(l,r===void 0?[]:[r],"operator "+t+" on "+e.object,s);if(i&&r!==void 0){let u=this.locals.length;this.locals.push({type:V(o?.from??e),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(u);let d=this.locals.length;this.locals.push({type:V(r),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(d),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),o&&this.emitConversion(o,s),this.code.u8(F.LOAD_LOCAL),this.code.u16(d),ke(c.params[0],r)||this.emitConversion(this.conversion(r,c.params[0]),s)}else if(r!==void 0&&!ke(c.params[0],r)){let u=this.locals.length;this.locals.push({type:V(r),hidden:!1}),this.code.u8(F.STORE_LOCAL),this.code.u16(u),this.code.u8(F.LOAD_LOCAL),this.code.u16(u),this.emitConversion(this.conversion(r,c.params[0]),s)}return this.code.mark(s,this.sourceMapper),this.code.u8(F.CALL_METHOD),this.code.u16(this.code.import("method "+e.object+"."+a+Ht(c))),this.code.u8(c.params.length),c.returns}userCall(e,t){if(this.expansionStack.includes(e.name)){let a=[...this.expansionStack.slice(this.expansionStack.indexOf(e.name)),e.name].join(" -> ");this.fail("recursive user functions are not allowed (cycle: "+a+")",t)}let r=this.expect("(","'(' after user function '"+e.name+"'"),s=[];if(!this.is(")"))do{let a=this.peek();s.push({type:this.expression(),token:a})}while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let i={params:e.params.map(a=>a.type),returns:e.returns};if(s.length!==e.params.length&&this.fail("user function "+e.name+" expects "+e.params.length+" argument(s) ("+i.params.map(V).join(", ")+"); found "+s.length,r),s.forEach((a,l)=>{ke(a.type,e.params[l].type)||this.fail("user function "+e.name+" expects "+V(e.params[l].type)+" for argument "+(l+1)+"; found "+V(a.type),a.token)}),this.validating)return this.validateFunction(e),e.returns;let o=e.params.map(a=>{this.locals.length>=65535&&this.fail("too many local variables after inlining function '"+e.name+"' (the format holds 65535)",a.token);let l=this.locals.length;return this.locals.push({type:V(a.type),hidden:!1}),l});for(let a=o.length-1;a>=0;a--)this.code.u8(F.STORE_LOCAL),this.code.u16(o[a]);return this.inlineFunction(e,t,o),this.code.mark(t,this.sourceMapper),e.returns}primary(){let e=this.next();if(e.kind==="int")return this.code.u8(F.PUSH_INT),this.code.i64(e.value),"int";if(e.kind==="float")return this.code.u8(F.PUSH_FLOAT),this.code.f64(e.value),"float";if(e.kind==="string")return this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(e.value)),"string";if(e.kind==="punct"&&e.text==="("){let t=this.expression();return this.expect(")","')' to close the parenthesis"),t}if(e.kind==="ident"){if(e.text==="true"||e.text==="false")return this.code.u8(F.PUSH_BOOL),this.code.u8(e.text==="true"?1:0),"bool";Yn.has(e.text)&&this.fail("'"+e.text+"' is a keyword and cannot be used here",e);let t=this.lookup(e.text);if(t)return this.code.mark(e,this.sourceMapper),this.code.u8(F.LOAD_LOCAL),this.code.u16(t.slot),t.type;let r=this.schema.context.get(e.text);if(r)return this.code.mark(e,this.sourceMapper),this.code.u8(F.LOAD_CTX),this.code.u16(this.code.context(e.text,r)),{object:r};if(this.schema.enums.has(e.text)&&this.is(".")){this.next();let a=this.next(),l=this.schema.enums.get(e.text);return(a.kind!=="ident"||!l.has(a.text))&&this.fail("unknown value "+e.text+"."+a.text+"; expected one of "+[...l].join(", "),a),this.code.u8(F.PUSH_STR),this.code.u32(this.code.constant(a.text)),{enum:e.text}}if(e.text==="str"){this.is("(")||this.fail("built-in str must be called: add (int | float | bool)",e);let a=this.next(),l=this.peek();this.is(")")&&this.fail("built-in str expects 1 argument (int, float or bool); found 0",a);let c=this.expression();return this.is(",")&&this.fail("built-in str expects 1 argument (int, float or bool); found more",this.peek()),this.expect(")","')' after the argument"),c==="string"&&this.fail("built-in str expects int, float or bool; found string (already a string)",l),typeof c=="object"&&"enum"in c||(c!=="int"&&c!=="float"&&c!=="bool"&&this.fail("built-in str expects int, float, bool or enum; found "+(c==="void"?"void":"object "+V(c)),l),this.code.u8(c==="int"?F.I2S:c==="float"?F.F2S:F.B2S)),"string"}if(Hl.has(e.text)){let a=_i.filter(u=>u.name===e.text);this.is("(")||this.fail("built-in "+e.text+" must be called",e),this.next();let l=[];if(!this.is(")"))do l.push(this.expression());while(this.is(",")&&this.next());this.expect(")","')' after the arguments");let c=_i.findIndex(u=>u.name===e.text&&u.params.length===l.length&&u.params.every((d,m)=>ke(d,l[m])));return c<0&&this.fail("built-in "+e.text+" expects "+a.map(Ht).join(" or ")+"; found ("+l.map(V).join(", ")+") (no implicit conversion)",e),this.code.mark(e,this.sourceMapper),this.code.u8(F.MATH),this.code.u8(c),_i[c].returns}if(Object.hasOwn(Es,e.text)){let a=Es[e.text];return this.is("(")||this.fail("built-in "+e.text+" must be called: add ("+a.params.map(V).join(", ")+")",e),this.callArguments([a],"built-in "+e.text),this.code.u8(F.I2F),a.returns}let s=this.schema.functions.get(e.text);if(s){this.is("(")||this.fail("host function "+e.text+" must be called: add ("+s[0].params.map(V).join(", ")+")",e);let a=this.callArguments(s,"function "+e.text);return this.code.mark(e,this.sourceMapper),this.code.u8(F.CALL_FN),this.code.u16(this.code.import("fn "+e.text+Ht(a))),this.code.u8(a.params.length),a.returns}let i=this.functions.get(e.text);if(i)return this.is("(")||this.fail("user function "+e.text+" must be called: add ("+i.params.map(a=>V(a.type)).join(", ")+")",e),this.userCall(i,e);let o=[...this.schema.context.keys(),...this.schema.functions.keys()];this.fail("undefined name '"+e.text+"' (locals are declared with let; the schema provides: "+(o.join(", ")||"nothing")+"; built-ins: "+gL+")",e)}return this.fail("expected an expression, found "+this.describe(e),e)}};Jm=new WeakMap,bi=class{schemaName;constructor(e,t){this.schemaName=t,Jm.set(this,e),Object.freeze(this)}toString(){throw new Error(Ts)}toJSON(){throw new Error(Ts)}static bytesOf(e){return Jm.get(e)}},Ts="a compiled _dsl_ value is opaque: it has no text, keys or methods; pass it to savedsl(dsl, path)"});import{AsyncLocalStorage as rv}from"node:async_hooks";import{isDeepStrictEqual as vL}from"node:util";import{spawn as wL,spawnSync as sv}from"node:child_process";import{randomUUID as Sp,createHash as EL}from"node:crypto";import{tmpdir as TL}from"node:os";import*as U from"node:fs";import*as se from"node:path";import*as iv from"node:readline";import{fileURLToPath as kp}from"node:url";import{types as Ie}from"node:util";function SL(n,e){let t=n.file&&n.file!=="<main>"?`${n.file}:${n.line}:${n.column}`:`${n.line}:${n.column}`,r=e;if(n.file&&(!r||r&&n.file!=="<main>"&&n.file!=="<std>"))try{U.existsSync(n.file)&&U.statSync(n.file).isFile()&&(r=U.readFileSync(n.file,"utf-8"))}catch{}if(!r)return`[${n.severity.toUpperCase()} at ${t}] ${n.message}`;let s=r.split(`
|
|
29
29
|
`),i=String(n.line),o=n.line-1,a=s[o]??"",l=" | ",c=` ${i.padStart(4," ")} | `,u=" ".repeat(Math.max(0,n.column-1));return`[${n.severity.toUpperCase()} at ${t}] ${n.message}
|
|
30
30
|
`+l+`
|
|
31
31
|
${c}${a}
|
|
32
32
|
${l}${u}^`}function ov(n,e){if(n.length<2)return n;let t=r=>[...e?.get(r.file??"")??[],r.line,r.column];return n.map((r,s)=>({diagnostic:r,index:s,key:t(r)})).sort((r,s)=>{for(let i=0;i<Math.min(r.key.length,s.key.length);i++)if(r.key[i]!==s.key[i])return r.key[i]-s.key[i];return r.key.length-s.key.length||r.index-s.index}).map(r=>r.diagnostic)}function av(n){let e=0;return n.lines.map(t=>({pieces:t.pieces.map(r=>typeof r=="string"?r:{chunk:e++,width:(r.endOffset??0)-(r.offset??0)})}))}function ip(n,e){let t=jl[n.marker],r={};for(let[s,i]of Object.entries(t))r[s]=i.default;for(let s of n.options)r[s.name]=e(s);return r}function Rp(n,e){let t=n.lines[e.lineIndex];return t?{line:t.line,column:t.column+Math.max(0,e.column-1)}:{line:n.line,column:n.column}}function kL(n){if(typeof n=="string"){let e='"';for(let t of n)if(t==='"')e+='\\"';else if(t==="\\")e+="\\\\";else if(t===`
|
|
33
|
-
`)e+="\\n";else if(t===" ")e+="\\t";else if(t==="\r")e+="\\r";else{if(t<" "||t==="\x7F")throw new Error("${} string contains an unsupported control character (U+"+t.codePointAt(0).toString(16).padStart(4,"0").toUpperCase()+")");e+=t}return e+'"'}if(typeof n=="number"){if(Number.isInteger(n)&&Math.abs(n)<=9007199254740992)return String(n);if(Number.isInteger(n))throw new Error("${} integer "+String(n)+" exceeds the DSL literal range \xB12^53");if(!Number.isFinite(n))throw new Error("${} number "+String(n)+" has no DSL literal");let e=n.toFixed(17).replace(/0+$/,"").replace(/\.$/,".0");if(Math.abs(n)>=1e21||Math.abs(n)<1e-6&&n!==0||Number(e)!==n)throw new Error("${} number "+String(n)+" has no exact float literal (the DSL writes digits.digits without an exponent)");return e.startsWith("-")||/\./.test(e)?e:e+".0"}if(typeof n=="boolean")return n?"true":"false";throw new Error("${} value must be a string, a number or a bool; found "+(n===null?"null":Array.isArray(n)?"list":typeof n=="object"?"map":typeof n))}function lv(n,e,t,r){let s="_dsl_",i=(p,f,h)=>{throw new P(s+": "+p,f,h,e,n.file)},o=n.options.find(p=>p.name==="schema");o||i('schema="FILE" is required: the body is compiled against that dsl.schema JSON',n.line,n.column);let a=o.value.kind==="LiteralExpr"?o.value.value:o.value.kind==="GroupingExpr"&&o.value.expression.kind==="LiteralExpr"?o.value.expression.value:void 0;(typeof a!="string"||a==="")&&i("schema must be a non-empty string literal (the schema is read at check time, so it cannot be computed)",o.line,o.column);let l=[],c=[],u=0;for(let p of n.lines){let f="",h=1,g=[];for(let _ of p.pieces){if(typeof _=="string"){f+=_;for(let y=0;y<_.length;y++)g.push(h+y);h+=_.length;continue}let v;try{v=kL(r[u++])}catch(y){return i(y.message,_.line,_.column)}f+=v;for(let y=0;y<v.length;y++)g.push(h);h+=(_.endOffset??0)-(_.offset??0)}g.push(h),l.push(f),c.push(g)}let d;try{d=Wo(a,n.file,t??process.cwd())}catch(p){return i("cannot resolve schema "+JSON.stringify(a)+": "+(p instanceof Error?p.message:String(p)),o.line,o.column)}let m;try{m=U.readFileSync(d)}catch(p){return i("cannot read schema "+JSON.stringify(a)+" (resolved "+d+"): "+(p.code??String(p)),o.line,o.column)}try{let p=Vm(m,a);return new bi(zm(l,p).bytes,p.name)}catch(p){if(!(p instanceof qe))throw p;if(p.lineIndex<0)return i(p.message,o.line,o.column);let f=c[p.lineIndex]??[1],h=f[Math.min(Math.max(p.column,1),f.length)-1],g=Rp(n,{lineIndex:p.lineIndex,column:h});return i(p.message,g.line,g.column)}}function cv(n){if(n)return n.baseDir??(n.file&&!n.file.startsWith("<")&&!/^https?:/i.test(n.file)?se.dirname(se.resolve(n.file)):void 0)}function Fb(n,e,t,r){if(n.marker==="dsl")return lv(n,"RUNTIME",cv(r),t);let s=jl[n.marker],i="_"+n.marker+"_";for(let o of n.options){let a=s[o.name];if(!a)throw new P(i+": unknown option '"+o.name+"'; "+(Object.keys(s).length?"known options: "+Object.keys(s).join(", "):i+" takes no options"),o.line,o.column,"RUNTIME",o.file);let l=e[o.name],c=l===null?"null":Array.isArray(l)?"list":typeof l;if(c!==a.type)throw new P(i+": option '"+o.name+"' must be a "+a.type+"; found "+c,o.line,o.column,"RUNTIME",o.file)}try{return Bm(n.marker,av(n),t,e)}catch(o){if(!(o instanceof ue))throw o;let a=Rp(n,o);throw new P(Sn[n.marker]+": "+o.message,a.line,a.column,"RUNTIME",n.file)}}function jb(n,e,t=[],r){let s=n instanceof P?n:new P(n instanceof Error?n.message:String(n),1,1,"CHECKER",e);return n instanceof Go&&(t=n.diagnostics,r=n.diagnosticPaths),ov([...t,{severity:"error",message:s.message,line:s.line,column:s.column,file:s.file??e}],r)}function uv(n){if(typeof n!="string"||n.length!==1||/["\r\n]/.test(n))throw new Error("CSV delimiter must be one character other than a quote or newline")}function Ct(n,e){return n&&typeof n=="object"&&tr.has(n)?tr.get(n)(String(e)):n!=null&&Object.hasOwn(n,e)?n[e]:void 0}function pt(n,e,t){String(e)==="__proto__"?Object.defineProperty(n,e,{value:t,writable:!0,enumerable:!0,configurable:!0}):n[e]=t}function xp(n,e,t){if(n==null||n===""||n===!1||Array.isArray(n)&&n.length===0)throw t?.(String(e)),Object.assign(new Wt(1),{resourceFailure:String(e)});return n}function Fo(n,e){if(n==null)return;let t=Array.isArray(e)?e:String(e).replace(/\[(\w+)\]/g,".$1").split(".").filter(Boolean),r=n;for(let s of t){if(r==null||typeof r!="object")return;r=Ct(r,s)}return r}function dv(n){if(typeof n!="string"||!n.trim())throw new Error("http_get() requires a non-empty URL string");let e;try{e=new URL(n)}catch{throw new Error("http_get() requires a valid HTTP(S) URL")}if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username||e.password)throw new Error("http_get() only permits HTTP(S) URLs without embedded credentials");let t=`
|
|
33
|
+
`)e+="\\n";else if(t===" ")e+="\\t";else if(t==="\r")e+="\\r";else{if(t<" "||t==="\x7F")throw new Error("${} string contains an unsupported control character (U+"+t.codePointAt(0).toString(16).padStart(4,"0").toUpperCase()+")");e+=t}return e+'"'}if(typeof n=="number"){if(Number.isInteger(n)&&Math.abs(n)<=9007199254740992)return String(n);if(Number.isInteger(n))throw new Error("${} integer "+String(n)+" exceeds the DSL literal range \xB12^53");if(!Number.isFinite(n))throw new Error("${} number "+String(n)+" has no DSL literal");let e=n.toFixed(17).replace(/0+$/,"").replace(/\.$/,".0");if(Math.abs(n)>=1e21||Math.abs(n)<1e-6&&n!==0||Number(e)!==n)throw new Error("${} number "+String(n)+" has no exact float literal (the DSL writes digits.digits without an exponent)");return e.startsWith("-")||/\./.test(e)?e:e+".0"}if(typeof n=="boolean")return n?"true":"false";throw new Error("${} value must be a string, a number or a bool; found "+(n===null?"null":Array.isArray(n)?"list":typeof n=="object"?"map":typeof n))}function lv(n,e,t,r){let s="_dsl_",i=(p,f,h)=>{throw new P(s+": "+p,f,h,e,n.file)},o=n.options.find(p=>p.name==="schema");o||i('schema="FILE" is required: the body is compiled against that dsl.schema JSON',n.line,n.column);let a=o.value.kind==="LiteralExpr"?o.value.value:o.value.kind==="GroupingExpr"&&o.value.expression.kind==="LiteralExpr"?o.value.expression.value:void 0;(typeof a!="string"||a==="")&&i("schema must be a non-empty string literal (the schema is read at check time, so it cannot be computed)",o.line,o.column);let l=[],c=[],u=0;for(let p of n.lines){let f="",h=1,g=[];for(let _ of p.pieces){if(typeof _=="string"){f+=_;for(let y=0;y<_.length;y++)g.push(h+y);h+=_.length;continue}let v;try{v=kL(r[u++])}catch(y){return i(y.message,_.line,_.column)}f+=v;for(let y=0;y<v.length;y++)g.push(h);h+=(_.endOffset??0)-(_.offset??0)}g.push(h),l.push(f),c.push(g)}let d;try{d=Wo(a,n.file,t??process.cwd())}catch(p){return i("cannot resolve schema "+JSON.stringify(a)+": "+(p instanceof Error?p.message:String(p)),o.line,o.column)}let m;try{m=U.readFileSync(d)}catch(p){return i("cannot read schema "+JSON.stringify(a)+" (resolved "+d+"): "+(p.code??String(p)),o.line,o.column)}try{let p=Vm(m,a),f=(h,g)=>{let _=n.lines[h];if(!_)return;let v=c[h]??[1],y=v[Math.min(Math.max(g,1),v.length)-1]??1;return{line:_.line,column:_.column+Math.max(0,y-1)}};return new bi(zm(l,p,f).bytes,p.name)}catch(p){if(!(p instanceof qe))throw p;if(p.lineIndex<0)return i(p.message,o.line,o.column);let f=c[p.lineIndex]??[1],h=f[Math.min(Math.max(p.column,1),f.length)-1],g=Rp(n,{lineIndex:p.lineIndex,column:h});return i(p.message,g.line,g.column)}}function cv(n){if(n)return n.baseDir??(n.file&&!n.file.startsWith("<")&&!/^https?:/i.test(n.file)?se.dirname(se.resolve(n.file)):void 0)}function Fb(n,e,t,r){if(n.marker==="dsl")return lv(n,"RUNTIME",cv(r),t);let s=jl[n.marker],i="_"+n.marker+"_";for(let o of n.options){let a=s[o.name];if(!a)throw new P(i+": unknown option '"+o.name+"'; "+(Object.keys(s).length?"known options: "+Object.keys(s).join(", "):i+" takes no options"),o.line,o.column,"RUNTIME",o.file);let l=e[o.name],c=l===null?"null":Array.isArray(l)?"list":typeof l;if(c!==a.type)throw new P(i+": option '"+o.name+"' must be a "+a.type+"; found "+c,o.line,o.column,"RUNTIME",o.file)}try{return Bm(n.marker,av(n),t,e)}catch(o){if(!(o instanceof ue))throw o;let a=Rp(n,o);throw new P(Sn[n.marker]+": "+o.message,a.line,a.column,"RUNTIME",n.file)}}function jb(n,e,t=[],r){let s=n instanceof P?n:new P(n instanceof Error?n.message:String(n),1,1,"CHECKER",e);return n instanceof Go&&(t=n.diagnostics,r=n.diagnosticPaths),ov([...t,{severity:"error",message:s.message,line:s.line,column:s.column,file:s.file??e}],r)}function uv(n){if(typeof n!="string"||n.length!==1||/["\r\n]/.test(n))throw new Error("CSV delimiter must be one character other than a quote or newline")}function Ct(n,e){return n&&typeof n=="object"&&tr.has(n)?tr.get(n)(String(e)):n!=null&&Object.hasOwn(n,e)?n[e]:void 0}function pt(n,e,t){String(e)==="__proto__"?Object.defineProperty(n,e,{value:t,writable:!0,enumerable:!0,configurable:!0}):n[e]=t}function xp(n,e,t){if(n==null||n===""||n===!1||Array.isArray(n)&&n.length===0)throw t?.(String(e)),Object.assign(new Wt(1),{resourceFailure:String(e)});return n}function Fo(n,e){if(n==null)return;let t=Array.isArray(e)?e:String(e).replace(/\[(\w+)\]/g,".$1").split(".").filter(Boolean),r=n;for(let s of t){if(r==null||typeof r!="object")return;r=Ct(r,s)}return r}function dv(n){if(typeof n!="string"||!n.trim())throw new Error("http_get() requires a non-empty URL string");let e;try{e=new URL(n)}catch{throw new Error("http_get() requires a valid HTTP(S) URL")}if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username||e.password)throw new Error("http_get() only permits HTTP(S) URLs without embedded credentials");let t=`
|
|
34
34
|
const target = process.argv[1];
|
|
35
35
|
const maxBytes = ${op};
|
|
36
36
|
const controller = new AbortController();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmctl-ai/lmctl",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.345",
|
|
4
4
|
"description": "A provider-agnostic control plane for teams of AI coding agents — across providers, with independent review and durable memory.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://lmctl.com",
|