rip-lang 3.8.8 → 3.8.10
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/CHANGELOG.md +21 -0
- package/README.md +7 -7
- package/docs/dist/rip-ui.min.js +77 -79
- package/docs/dist/rip-ui.min.js.br +0 -0
- package/docs/dist/rip.browser.js +44 -76
- package/docs/dist/rip.browser.min.js +78 -80
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/docs/dist/ui.js +9 -3
- package/docs/dist/ui.min.js +2 -2
- package/docs/dist/ui.min.js.br +0 -0
- package/package.json +1 -1
- package/src/compiler.js +43 -72
- package/src/grammar/grammar.rip +5 -5
- package/src/parser-rd.js +4 -4
- package/src/parser.js +4 -4
|
Binary file
|
package/docs/dist/ui.js
CHANGED
|
@@ -586,7 +586,7 @@ export const createRouter = (function(components, opts = {}) {
|
|
|
586
586
|
tree = buildRoutes(components, root);
|
|
587
587
|
navCallbacks = new Set();
|
|
588
588
|
components.watch(function(event, path) {
|
|
589
|
-
if (!
|
|
589
|
+
if (!path.startsWith(root + '/')) return;
|
|
590
590
|
return (tree = buildRoutes(components, root));
|
|
591
591
|
});
|
|
592
592
|
resolve = function(url) {
|
|
@@ -845,7 +845,13 @@ export const createRenderer = (function(opts = {}) {
|
|
|
845
845
|
}
|
|
846
846
|
}
|
|
847
847
|
};
|
|
848
|
-
return (
|
|
848
|
+
return (() => { if (!handled) {
|
|
849
|
+
pre = document.createElement('pre');
|
|
850
|
+
pre.style.cssText = 'color:red;padding:1em';
|
|
851
|
+
pre.textContent = err.stack || err.message;
|
|
852
|
+
container.innerHTML = '';
|
|
853
|
+
return container.appendChild(pre);
|
|
854
|
+
} })();
|
|
849
855
|
} })();
|
|
850
856
|
};
|
|
851
857
|
renderer = {start: (function() {
|
|
@@ -890,7 +896,7 @@ export const launch = (async function(appBase = '', opts = {}) {
|
|
|
890
896
|
} else {
|
|
891
897
|
bundleUrl = `${appBase}/bundle`;
|
|
892
898
|
res = await fetch(bundleUrl);
|
|
893
|
-
if (!
|
|
899
|
+
if (!res.ok) {
|
|
894
900
|
throw new Error(`launch: ${bundleUrl} (${res.status})`);
|
|
895
901
|
};
|
|
896
902
|
bundle = await res.json();
|
package/docs/dist/ui.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,c=y+c}i=new Blob([c],{type:"application/javascript"}),d=URL.createObjectURL(i);try{g=await import(d)}finally{URL.revokeObjectURL(d)}if(e){m=B(g);for(let h in m){let v=m[h];e.classes[h]=v}}if(o&&t)o.setCompiled(t,g);return g};me=function(n,r,o,t,e=""){let i,u,a;return a=1000,u=30000,i=function(){let f;return f=new EventSource(t),f.addEventListener("connected",function(){return a=1000,console.log("[Rip] Hot reload connected")}),f.addEventListener("changed",async function(m){let c,g,p,x,y;({paths:p}=JSON.parse(m.data));for(let d of p)n.del(d);if(r.rebuild(),c=r.current,y=p.filter(function(d){return d===c.route?.file||c.layouts?.includes(d)}),y.length>0){x=await Promise.allSettled(y.map(async function(d){let h,v;return v=await fetch(e+"/"+d),h=await v.text(),n.write(d,h)})),g=x.filter(function(d){return d.status==="rejected"});for(let d of g)console.error("[Rip] Hot reload fetch error:",d.reason);return o.remount()}}),f.onerror=function(){return f.close(),console.log(`[Rip] Hot reload reconnecting in ${a/1000}s...`),setTimeout(i,a),a=Math.min(a*2,u)}},i()};var ke=function(n={}){return oe(n)},Te=function(n){return n?.[W]?n[W]:n},Ae=function(n){return n?.[G]===!0},Ue=function(n,r={}){let o,t,e,i,u;if(o=C(r.initial||null),e=C(!1),t=C(null),i=async function(){let a;return e.value=!0,t.value=null,(async()=>{try{return a=await n(),o.value=a}catch(f){return t.value=f}finally{e.value=!1}})()},u={data:void 0,loading:void 0,error:void 0,refetch:i},Object.defineProperty(u,"data",{get:function(){return o.value}}),Object.defineProperty(u,"loading",{get:function(){return e.value}}),Object.defineProperty(u,"error",{get:function(){return t.value}}),!r.lazy)i();return u},$e=function(n,r){let o,t;return o=H(r),t=C(!!o()),M(function(){let e;if(o())return e=setTimeout(function(){return t.value=!0},n),function(){return clearTimeout(e)};else return t.value=!1}),typeof r!=="function"?I(t,r):t},We=function(n,r){let o,t;return o=H(r),t=C(o()),M(function(){let e,i;return i=o(),e=setTimeout(function(){return t.value=i},n),function(){return clearTimeout(e)}}),typeof r!=="function"?I(t,r):t},qe=function(n,r){let o,t,e;return o=H(r),e=C(o()),t=0,M(function(){let i,u,a,f;if(f=o(),i=Date.now(),u=n-(i-t),u<=0)return e.value=f,t=i;else return a=setTimeout(function(){return e.value=o(),t=Date.now()},u),function(){return clearTimeout(a)}}),typeof r!=="function"?I(e,r):e},De=function(n,r){let o,t;return o=H(r),t=C(!!o()),M(function(){let e;if(o())return t.value=!0;else return e=setTimeout(function(){return t.value=!1},n),function(){return clearTimeout(e)}}),typeof r!=="function"?I(t,r):t},Oe=function(){let n,r,o,t;return r=new Map,t=[],n=new Map,o=function(e,i){for(let u of t)u(e,i)},{read:function(e){return r.get(e)},write:function(e,i){let u;return u=!r.has(e),r.set(e,i),n.delete(e),o(u?"create":"change",e)},del:function(e){return r.delete(e),n.delete(e),o("delete",e)},exists:function(e){return r.has(e)},size:function(){return r.size},list:function(e=""){let i,u,a;a=[],i=e?e+"/":"";for(let[f]of r)if(f.startsWith(i)){if(u=f.slice(i.length),u.includes("/"))continue;a.push(f)}return a},listAll:function(e=""){let i,u;u=[],i=e?e+"/":"";for(let[a]of r)if(a.startsWith(i))u.push(a);return u},load:function(e){for(let i in e){let u=e[i];r.set(i,u)}},watch:function(e){return t.push(e),function(){return t.splice(t.indexOf(e),1)}},getCompiled:function(e){return n.get(e)},setCompiled:function(e,i){return n.set(e,i)}}},Le=function(n,r={}){let o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,S,s,P,b,w;if(S=r.root||"components",c=r.base||"",g=r.hash||!1,y=r.onError||null,P=function(l){return c&&l.startsWith(c)?l.slice(c.length)||"/":l},m=function(l){return c?c+l:l},h=function(){let l;if(g){if(l=location.hash.slice(1),!l)return"/";return l[0]==="/"?l:"/"+l}else return location.pathname+location.search+location.hash},w=function(l){return g?l==="/"?location.pathname:"#"+l.slice(1):m(l)},u=C(P(g?h():location.pathname)),i=C({}),f=C(null),t=C([]),a=C({}),o=C(""),e=$e(100,C(!1)),b=F(n,S),p=new Set,n.watch(function(l,R){if(!R.startsWith(S+"/"))return;return b=F(n,S)}),v=function(l){let R,_,E,A,k;if(A=l.split("?")[0].split("#")[0],_=P(A),_=_[0]==="/"?_:"/"+_,E=l.split("?")[1]?.split("#")[0]||"",R=l.includes("#")?l.split("#")[1]:"",k=we(_,b.routes),k){de(function(){return u.value=_,i.value=k.params,f.value=k.route,t.value=ve(k.route.file,S,b.layouts),a.value=Object.fromEntries(new URLSearchParams(E)),o.value=R});for(let T of p)T(s.current);return!0}if(y)y({status:404,path:_});return!1},d=function(){return v(h())},typeof window<"u")window.addEventListener("popstate",d);if(x=function(l){let R,_,E;if(l.button!==0||l.metaKey||l.ctrlKey||l.shiftKey||l.altKey)return;_=l.target;while(_&&_.tagName!=="A")_=_.parentElement;if(!_?.href)return;if(E=new URL(_.href,location.origin),E.origin!==location.origin)return;if(_.target==="_blank"||_.hasAttribute("data-external"))return;return l.preventDefault(),R=g&&E.hash?E.hash.slice(1)||"/":E.pathname+E.search+E.hash,s.push(R)},typeof document<"u")document.addEventListener("click",x);return s={push:function(l){return v(l)?history.pushState(null,"",w(u.read())):void 0},replace:function(l){return v(l)?history.replaceState(null,"",w(u.read())):void 0},back:function(){return history.back()},forward:function(){return history.forward()},current:void 0,path:void 0,params:void 0,route:void 0,layouts:void 0,query:void 0,hash:void 0,navigating:void 0,onNavigate:function(l){return p.add(l),function(){return p.delete(l)}},rebuild:function(){return b=F(n,S)},routes:void 0,init:function(){return v(h()),s},destroy:function(){if(typeof window<"u")window.removeEventListener("popstate",d);if(typeof document<"u")document.removeEventListener("click",x);return p.clear()}},Object.defineProperty(s,"current",{get:function(){return{path:u.value,params:i.value,route:f.value,layouts:t.value,query:a.value,hash:o.value}}}),Object.defineProperty(s,"path",{get:function(){return u.value}}),Object.defineProperty(s,"params",{get:function(){return i.value}}),Object.defineProperty(s,"route",{get:function(){return f.value}}),Object.defineProperty(s,"layouts",{get:function(){return t.value}}),Object.defineProperty(s,"query",{get:function(){return a.value}}),Object.defineProperty(s,"hash",{get:function(){return o.value}}),Object.defineProperty(s,"navigating",{get:function(){return e.value},set:function(l){return e.value=l}}),Object.defineProperty(s,"routes",{get:function(){return b.routes}}),s},Me=function(n={}){let r,o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,S,s,P,b;if({router:s,app:r,components:i,resolver:S,compile:t,target:P,onError:h}=n,u=typeof P==="string"?document.querySelector(P):P||document.getElementById("app"),!u)u=document.createElement("div"),u.id="app",document.body.appendChild(u);return u.style.opacity="0",a=null,m=null,f=[],p=[],y=u,g=0,c=null,e=new Map,x=n.cacheSize||10,o=function(){let w,l;if(a&&m){if(a.beforeUnmount)a.beforeUnmount();if(e.set(m,a),e.size>x){if(l=e.keys().next().value,w=e.get(l),w.unmounted)w.unmounted();e.delete(l)}return a=null,m=null}},b=function(){o();for(let w=p.length-1;w>=0;w--){let l=p[w];if(l.beforeUnmount)l.beforeUnmount();if(l.unmounted)l.unmounted();l._root?.remove()}return p=[],y=u},i.watch(function(w,l){let R;if(e.has(l)){if(R=e.get(l),R.unmounted)R.unmounted();return e.delete(l)}}),d=async function(w){let l,R,_,E,A,k,T,q,ue,V,D,ae,L,le,K,z,Ce,X,j,fe,Q,U;if({route:j,params:z,layouts:q,query:X}=w,!j)return;if(j.file===m)return;return E=++g,s.navigating=!0,(async()=>{try{if(Q=i.read(j.file),!Q){if(h)h({status:404,message:`File not found: ${j.file}`});s.navigating=!1;return}if(ae=await J(Q,t,i,j.file,S),E!==g){s.navigating=!1;return}if(l=ee(ae),!l){if(h)h({status:500,message:`No component found in ${j.file}`});s.navigating=!1;return}if(D=!pe(q,f),le=a?._root,D)b();else o();if(L=D?u:y,D&&q.length>0){u.innerHTML="",L=u;for(let $ of q){if(V=i.read($),!V)continue;if(ue=await J(V,t,i,$,S),E!==g){s.navigating=!1;return}if(R=ee(ue),!R)continue;if(k=new R({app:r,params:z,router:s}),k.beforeMount)k.beforeMount();U=document.createElement("div"),U.setAttribute("data-layout",$),L.appendChild(U),k.mount(U),p.push(k),fe=U.querySelector("#content")||U,L=fe}f=[...q],y=L}else if(D)u.innerHTML="",f=[],y=u;if(_=e.get(j.file),_)e.delete(j.file),L.appendChild(_._root),a=_,m=j.file;else{if(K=document.createElement("div"),K.setAttribute("data-component",j.file),L.appendChild(K),T=new l({app:r,params:z,query:X,router:s}),T.beforeMount)T.beforeMount();if(T.mount(K),a=T,m=j.file,T.load)await T.load(z,X)}return le?.remove(),s.navigating=!1,u.style.opacity==="0"?document.fonts.ready.then(function(){return requestAnimationFrame(function(){return u.style.transition="opacity 150ms ease-in",u.style.opacity="1"})}):void 0}catch($){if(s.navigating=!1,u.style.opacity="1",console.error(`Renderer: error mounting ${j.file}:`,$),h)h({status:500,message:$.message,error:$});A=!1;for(let Y=p.length-1;Y>=0;Y--){let ce=p[Y];if(ce.onError)try{ce.onError($),A=!0;break}catch(Re){console.error("Renderer: error boundary failed:",Re)}}return!A?u.appendChild(Ce):void 0}})()},v={start:function(){return c=M(function(){let w;return w=s.current,w.route?d(w):void 0}),s.init(),v},stop:function(){if(b(),c)c(),c=null;return u.innerHTML=""},remount:function(){let w;return w=s.current,w.route?d(w):void 0},cache:e},v},Ne=async function(n="",r={}){let o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,S,s,P;if(n=n.replace(/\/+$/,""),P=r.target||"#app",c=r.compile||null,x=r.persist||!1,p=r.hash||!1,!c)c=globalThis?.compileToJS||null;if(typeof document<"u"&&!document.querySelector(P))g=document.createElement("div"),g.id=P.replace(/^#/,""),document.body.prepend(g);if(r.bundle)a=r.bundle;else{if(f=`${n}/bundle`,d=await fetch(f),!d.ok)throw Error(`launch: ${f} (${d.status})`);a=await d.json()}if(i=ke({components:{},routes:{},data:{}}),a.data)i.data=a.data;if(a.routes)i.routes=a.routes;if(x&&typeof sessionStorage<"u"){e=`__rip_${n}`,t=x==="local"?localStorage:sessionStorage;try{if(S=t.getItem(e),S){s=JSON.parse(S);for(let b in s){let w=s[b];i.data[b]=w}}}catch{}o=function(){return(()=>{try{return t.setItem(e,JSON.stringify(Te(i.data)))}catch{return null}})()},M(function(){let b;return ne.value,b=setTimeout(o,2000),function(){return clearTimeout(b)}}),window.addEventListener("beforeunload",o)}if(u=Oe(),a.components)u.load(a.components);if(m=`__rip_${n.replace(/\//g,"_")||"app"}`,h={map:he(u),classes:{},key:m},typeof globalThis<"u")globalThis[m]=h.classes;if(i.data.title&&typeof document<"u")document.title=i.data.title;if(v=Le(u,{root:"components",base:n,hash:p,onError:function(b){return console.error(`[Rip] Error ${b.status}: ${b.message||b.path}`)}}),y=Me({router:v,app:i,components:u,resolver:h,compile:c,target:P,onError:function(b){return console.error(`[Rip] ${b.message}`,b.error)}}),y.start(),a.data?.watch)me(u,v,y,`${n}/watch`,n);if(typeof window<"u")window.app=i,window.__RIP__={app:i,components:u,router:v,renderer:y,cache:y.cache,version:"0.3.0"};return{app:i,components:u,router:v,renderer:y}};export{qe as throttle,ke as stash,je as setContext,Te as raw,Ne as launch,Ae as isStash,De as hold,Pe as hasContext,Ee as getContext,$e as delay,We as debounce,Le as createRouter,Ue as createResource,Me as createRenderer,Oe as createComponents};
|
|
1
|
+
var de,ne,W,O,V,pe,M,S,B,H,I,re,he,me,J,G,ye,ge,ve,ee,te,Re,we,oe,Pe,N,ie,be,_e,ke,xe,Ce,ue,Se;({__state:S,__effect:M,__batch:pe}=globalThis.__rip);({setContext:ke,getContext:Re,hasContext:Pe}=globalThis.__ripComponent||{});V=Symbol("stash");O=Symbol("signals");W=Symbol("raw");ne=new WeakMap;B=0;re=S(0);oe=function(n,r){let o;if(!n[O])Object.defineProperty(n,O,{value:new Map,enumerable:!1});if(o=n[O].get(r),!o)o=S(n[r]),n[O].set(r,o);return o};N=function(n){return oe(n,Symbol.for("keys"))};Se=function(n){let r;if(!(n!=null&&typeof n==="object"))return n;if(n[V])return n;if(n instanceof Date||n instanceof RegExp||n instanceof Map||n instanceof Set||n instanceof Promise)return n;if(r=ne.get(n),r)return r;return ie(n)};ie=function(n){let r,o;return o=null,r={get:function(t,e){let i,u;if(e===V)return!0;if(e===W)return t;if(typeof e==="symbol")return Reflect.get(t,e);if(e==="length"&&Array.isArray(t))return N(t).value,t.length;if(e==="get")return function(a){return xe(o,a)};if(e==="set")return function(a,f){return Ce(o,a,f)};if(i=oe(t,e),u=i.value,u!=null&&typeof u==="object")return Se(u);return u},set:function(t,e,i){let u,a;if(u=t[e],a=i?.[W]?i[W]:i,a===u)return!0;if(t[e]=a,t[O]?.has(e))t[O].get(e).value=a;if(u===void 0&&a!==void 0)N(t).value=++B;return re.value++,!0},deleteProperty:function(t,e){let i;if(delete t[e],i=t[O]?.get(e),i)i.value=void 0;return N(t).value=++B,!0},ownKeys:function(t){return N(t).value,Reflect.ownKeys(t)}},o=new Proxy(n,r),ne.set(n,o),o};de=/([./][^./\[\s]+|\[[-+]?\d+\]|\[(?:"[^"]+"|'[^']+')\])/;ue=function(n){let r,o,t,e,i;t=("."+n).split(de),t.shift(),i=[],o=0;while(o<t.length){if(e=t[o],r=e[0],r==="."||r==="/")i.push(e.slice(1));else if(r==="[")if(e[1]==='"'||e[1]==="'")i.push(e.slice(2,-2));else i.push(+e.slice(1,-1));o+=2}return i};xe=function(n,r){let o,t;t=ue(r),o=n;for(let e of t){if(o==null)return;o=o[e]}return o};Ce=function(n,r,o){let t,e;e=ue(r),t=n;for(let i=0;i<e.length;i++){let u=e[i];if(i===e.length-1)t[u]=o;else{if(t[u]==null)t[u]={};t=t[u]}}return o};I=function(n){return typeof n==="function"?n:function(){return n.value}};H=function(n,r){let o;return o={read:function(){return n.read()}},Object.defineProperty(o,"value",{get:function(){return n.value},set:function(t){return r.value=t}}),o};ve=function(n){let r;if(r=n.replace(/\.rip$/,""),r=r.replace(/\[\.\.\.(\w+)\]/g,"*$1"),r=r.replace(/\[(\w+)\]/g,":$1"),r==="index")return"/";return r=r.replace(/\/index$/,""),"/"+r};_e=function(n){let r,o;return r=[],o=n.replace(/\*(\w+)/g,function(t,e){return r.push(e),"(.+)"}).replace(/:(\w+)/g,function(t,e){return r.push(e),"([^/]+)"}),{regex:new RegExp("^"+o+"$"),names:r}};be=function(n,r){let o,t;for(let e of r)if(o=n.match(e.regex.regex),o){t={};for(let i=0;i<e.regex.names.length;i++){let u=e.regex.names[i];t[u]=decodeURIComponent(o[i+1])}return{route:e,params:t}}return null};J=function(n,r="components"){let o,t,e,i,u,a,f,m;f=[],e=new Map,o=n.listAll(r);for(let c of o){if(a=c.slice(r.length+1),!a.endsWith(".rip"))continue;if(i=a.split("/").pop(),i==="_layout.rip"){t=a==="_layout.rip"?"":a.slice(0,-12),e.set(t,c);continue}if(i.startsWith("_"))continue;m=ve(a),u=_e(m),f.push({pattern:m,regex:u,file:c,rel:a})}return f.sort(function(c,g){let p,x,y,d;if(x=(c.pattern.match(/:/g)||[]).length,d=(g.pattern.match(/:/g)||[]).length,p=c.pattern.includes("*")?1:0,y=g.pattern.includes("*")?1:0,p!==y)return p-y;if(x!==d)return x-d;return c.pattern.localeCompare(g.pattern)}),{routes:f,layouts:e}};we=function(n,r,o){let t,e,i,u;if(t=[],i=n.slice(r.length+1),u=i.split("/"),e="",o.has(""))t.push(o.get(""));for(let a=0;a<u.length;a++){let f=u[a];if(a===u.length-1)break;if(e=e?e+"/"+f:f,o.has(e))t.push(o.get(e))}return t};he=function(n,r){if(n.length!==r.length)return!1;for(let o=0;o<n.length;o++)if(n[o]!==r[o])return!1;return!0};te=function(n){for(let r in n){let o=n[r];if(typeof o==="function"&&(o.prototype?.mount||o.prototype?._create))return o}return typeof n.default==="function"?n.default:void 0};ee=function(n){let r;r={};for(let o in n){let t=n[o];if(typeof t==="function"&&(t.prototype?.mount||t.prototype?._create))r[o]=t}return r};ge=function(n){let r;return r=n.split("/").pop().replace(/\.rip$/,""),r.replace(/(^|[-_])([a-z])/g,function(o,t,e){return e.toUpperCase()})};me=function(n,r="components"){let o,t,e;t={};for(let i of n.listAll(r)){if(!i.endsWith(".rip"))continue;if(o=i.split("/").pop(),o.startsWith("_"))continue;if(e=ge(i),t[e])console.warn(`[Rip] Component name collision: ${e} (${t[e]} vs ${i})`);t[e]=i}return t};G=async function(n,r,o=null,t=null,e=null){let i,u,a,f,m,c,g,p,x,y,d;if(o&&t){if(u=o.getCompiled(t),u)return u}if(c=r(n),e){x={};for(let h in e.map){let v=e.map[h];if(v!==t&&c.includes(`new ${h}(`)){if(!e.classes[h]){if(f=o.read(v),f){a=await G(f,r,o,v,e),m=ee(a);for(let C in m){let s=m[C];e.classes[C]=s}}}if(e.classes[h])x[h]=!0}}if(p=Object.keys(x),p.length>0)y=`const {${p.join(", ")}} = globalThis['${e.key}'];
|
|
2
|
+
`,c=y+c}i=new Blob([c],{type:"application/javascript"}),d=URL.createObjectURL(i);try{g=await import(d)}finally{URL.revokeObjectURL(d)}if(e){m=ee(g);for(let h in m){let v=m[h];e.classes[h]=v}}if(o&&t)o.setCompiled(t,g);return g};ye=function(n,r,o,t,e=""){let i,u,a;return a=1000,u=30000,i=function(){let f;return f=new EventSource(t),f.addEventListener("connected",function(){return a=1000,console.log("[Rip] Hot reload connected")}),f.addEventListener("changed",async function(m){let c,g,p,x,y;({paths:p}=JSON.parse(m.data));for(let d of p)n.del(d);if(r.rebuild(),c=r.current,y=p.filter(function(d){return d===c.route?.file||c.layouts?.includes(d)}),y.length>0){x=await Promise.allSettled(y.map(async function(d){let h,v;return v=await fetch(e+"/"+d),h=await v.text(),n.write(d,h)})),g=x.filter(function(d){return d.status==="rejected"});for(let d of g)console.error("[Rip] Hot reload fetch error:",d.reason);return o.remount()}}),f.onerror=function(){return f.close(),console.log(`[Rip] Hot reload reconnecting in ${a/1000}s...`),setTimeout(i,a),a=Math.min(a*2,u)}},i()};var Te=function(n={}){return ie(n)},je=function(n){return n?.[W]?n[W]:n},Ae=function(n){return n?.[V]===!0},Ue=function(n,r={}){let o,t,e,i,u;if(o=S(r.initial||null),e=S(!1),t=S(null),i=async function(){let a;return e.value=!0,t.value=null,(async()=>{try{return a=await n(),o.value=a}catch(f){return t.value=f}finally{e.value=!1}})()},u={data:void 0,loading:void 0,error:void 0,refetch:i},Object.defineProperty(u,"data",{get:function(){return o.value}}),Object.defineProperty(u,"loading",{get:function(){return e.value}}),Object.defineProperty(u,"error",{get:function(){return t.value}}),!r.lazy)i();return u},$e=function(n,r){let o,t;return o=I(r),t=S(!!o()),M(function(){let e;if(o())return e=setTimeout(function(){return t.value=!0},n),function(){return clearTimeout(e)};else return t.value=!1}),typeof r!=="function"?H(t,r):t},We=function(n,r){let o,t;return o=I(r),t=S(o()),M(function(){let e,i;return i=o(),e=setTimeout(function(){return t.value=i},n),function(){return clearTimeout(e)}}),typeof r!=="function"?H(t,r):t},qe=function(n,r){let o,t,e;return o=I(r),e=S(o()),t=0,M(function(){let i,u,a,f;if(f=o(),i=Date.now(),u=n-(i-t),u<=0)return e.value=f,t=i;else return a=setTimeout(function(){return e.value=o(),t=Date.now()},u),function(){return clearTimeout(a)}}),typeof r!=="function"?H(e,r):e},De=function(n,r){let o,t;return o=I(r),t=S(!!o()),M(function(){let e;if(o())return t.value=!0;else return e=setTimeout(function(){return t.value=!1},n),function(){return clearTimeout(e)}}),typeof r!=="function"?H(t,r):t},Oe=function(){let n,r,o,t;return r=new Map,t=[],n=new Map,o=function(e,i){for(let u of t)u(e,i)},{read:function(e){return r.get(e)},write:function(e,i){let u;return u=!r.has(e),r.set(e,i),n.delete(e),o(u?"create":"change",e)},del:function(e){return r.delete(e),n.delete(e),o("delete",e)},exists:function(e){return r.has(e)},size:function(){return r.size},list:function(e=""){let i,u,a;a=[],i=e?e+"/":"";for(let[f]of r)if(f.startsWith(i)){if(u=f.slice(i.length),u.includes("/"))continue;a.push(f)}return a},listAll:function(e=""){let i,u;u=[],i=e?e+"/":"";for(let[a]of r)if(a.startsWith(i))u.push(a);return u},load:function(e){for(let i in e){let u=e[i];r.set(i,u)}},watch:function(e){return t.push(e),function(){return t.splice(t.indexOf(e),1)}},getCompiled:function(e){return n.get(e)},setCompiled:function(e,i){return n.set(e,i)}}},Le=function(n,r={}){let o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,C,s,P,b,w;if(C=r.root||"components",c=r.base||"",g=r.hash||!1,y=r.onError||null,P=function(l){return c&&l.startsWith(c)?l.slice(c.length)||"/":l},m=function(l){return c?c+l:l},h=function(){let l;if(g){if(l=location.hash.slice(1),!l)return"/";return l[0]==="/"?l:"/"+l}else return location.pathname+location.search+location.hash},w=function(l){return g?l==="/"?location.pathname:"#"+l.slice(1):m(l)},u=S(P(g?h():location.pathname)),i=S({}),f=S(null),t=S([]),a=S({}),o=S(""),e=$e(100,S(!1)),b=J(n,C),p=new Set,n.watch(function(l,E){if(!E.startsWith(C+"/"))return;return b=J(n,C)}),v=function(l){let E,_,R,A,T;if(A=l.split("?")[0].split("#")[0],_=P(A),_=_[0]==="/"?_:"/"+_,R=l.split("?")[1]?.split("#")[0]||"",E=l.includes("#")?l.split("#")[1]:"",T=be(_,b.routes),T){pe(function(){return u.value=_,i.value=T.params,f.value=T.route,t.value=we(T.route.file,C,b.layouts),a.value=Object.fromEntries(new URLSearchParams(R)),o.value=E});for(let $ of p)$(s.current);return!0}if(y)y({status:404,path:_});return!1},d=function(){return v(h())},typeof window<"u")window.addEventListener("popstate",d);if(x=function(l){let E,_,R;if(l.button!==0||l.metaKey||l.ctrlKey||l.shiftKey||l.altKey)return;_=l.target;while(_&&_.tagName!=="A")_=_.parentElement;if(!_?.href)return;if(R=new URL(_.href,location.origin),R.origin!==location.origin)return;if(_.target==="_blank"||_.hasAttribute("data-external"))return;return l.preventDefault(),E=g&&R.hash?R.hash.slice(1)||"/":R.pathname+R.search+R.hash,s.push(E)},typeof document<"u")document.addEventListener("click",x);return s={push:function(l){return v(l)?history.pushState(null,"",w(u.read())):void 0},replace:function(l){return v(l)?history.replaceState(null,"",w(u.read())):void 0},back:function(){return history.back()},forward:function(){return history.forward()},current:void 0,path:void 0,params:void 0,route:void 0,layouts:void 0,query:void 0,hash:void 0,navigating:void 0,onNavigate:function(l){return p.add(l),function(){return p.delete(l)}},rebuild:function(){return b=J(n,C)},routes:void 0,init:function(){return v(h()),s},destroy:function(){if(typeof window<"u")window.removeEventListener("popstate",d);if(typeof document<"u")document.removeEventListener("click",x);return p.clear()}},Object.defineProperty(s,"current",{get:function(){return{path:u.value,params:i.value,route:f.value,layouts:t.value,query:a.value,hash:o.value}}}),Object.defineProperty(s,"path",{get:function(){return u.value}}),Object.defineProperty(s,"params",{get:function(){return i.value}}),Object.defineProperty(s,"route",{get:function(){return f.value}}),Object.defineProperty(s,"layouts",{get:function(){return t.value}}),Object.defineProperty(s,"query",{get:function(){return a.value}}),Object.defineProperty(s,"hash",{get:function(){return o.value}}),Object.defineProperty(s,"navigating",{get:function(){return e.value},set:function(l){return e.value=l}}),Object.defineProperty(s,"routes",{get:function(){return b.routes}}),s},Me=function(n={}){let r,o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,C,s,P,b;if({router:s,app:r,components:i,resolver:C,compile:t,target:P,onError:h}=n,u=typeof P==="string"?document.querySelector(P):P||document.getElementById("app"),!u)u=document.createElement("div"),u.id="app",document.body.appendChild(u);return u.style.opacity="0",a=null,m=null,f=[],p=[],y=u,g=0,c=null,e=new Map,x=n.cacheSize||10,o=function(){let w,l;if(a&&m){if(a.beforeUnmount)a.beforeUnmount();if(e.set(m,a),e.size>x){if(l=e.keys().next().value,w=e.get(l),w.unmounted)w.unmounted();e.delete(l)}return a=null,m=null}},b=function(){o();for(let w=p.length-1;w>=0;w--){let l=p[w];if(l.beforeUnmount)l.beforeUnmount();if(l.unmounted)l.unmounted();l._root?.remove()}return p=[],y=u},i.watch(function(w,l){let E;if(e.has(l)){if(E=e.get(l),E.unmounted)E.unmounted();return e.delete(l)}}),d=async function(w){let l,E,_,R,A,T,$,q,ae,X,D,le,L,fe,K,z,F,Q,k,ce,Y,U;if({route:k,params:z,layouts:q,query:Q}=w,!k)return;if(k.file===m)return;return R=++g,s.navigating=!0,(async()=>{try{if(Y=i.read(k.file),!Y){if(h)h({status:404,message:`File not found: ${k.file}`});s.navigating=!1;return}if(le=await G(Y,t,i,k.file,C),R!==g){s.navigating=!1;return}if(l=te(le),!l){if(h)h({status:500,message:`No component found in ${k.file}`});s.navigating=!1;return}if(D=!he(q,f),fe=a?._root,D)b();else o();if(L=D?u:y,D&&q.length>0){u.innerHTML="",L=u;for(let j of q){if(X=i.read(j),!X)continue;if(ae=await G(X,t,i,j,C),R!==g){s.navigating=!1;return}if(E=te(ae),!E)continue;if(T=new E({app:r,params:z,router:s}),T.beforeMount)T.beforeMount();U=document.createElement("div"),U.setAttribute("data-layout",j),L.appendChild(U),T.mount(U),p.push(T),ce=U.querySelector("#content")||U,L=ce}f=[...q],y=L}else if(D)u.innerHTML="",f=[],y=u;if(_=e.get(k.file),_)e.delete(k.file),L.appendChild(_._root),a=_,m=k.file;else{if(K=document.createElement("div"),K.setAttribute("data-component",k.file),L.appendChild(K),$=new l({app:r,params:z,query:Q,router:s}),$.beforeMount)$.beforeMount();if($.mount(K),a=$,m=k.file,$.load)await $.load(z,Q)}return fe?.remove(),s.navigating=!1,u.style.opacity==="0"?document.fonts.ready.then(function(){return requestAnimationFrame(function(){return u.style.transition="opacity 150ms ease-in",u.style.opacity="1"})}):void 0}catch(j){if(s.navigating=!1,u.style.opacity="1",console.error(`Renderer: error mounting ${k.file}:`,j),h)h({status:500,message:j.message,error:j});A=!1;for(let Z=p.length-1;Z>=0;Z--){let se=p[Z];if(se.onError)try{se.onError(j),A=!0;break}catch(Ee){console.error("Renderer: error boundary failed:",Ee)}}return(()=>{if(!A)return F=document.createElement("pre"),F.style.cssText="color:red;padding:1em",F.textContent=j.stack||j.message,u.innerHTML="",u.appendChild(F)})()}})()},v={start:function(){return c=M(function(){let w;return w=s.current,w.route?d(w):void 0}),s.init(),v},stop:function(){if(b(),c)c(),c=null;return u.innerHTML=""},remount:function(){let w;return w=s.current,w.route?d(w):void 0},cache:e},v},Ne=async function(n="",r={}){let o,t,e,i,u,a,f,m,c,g,p,x,y,d,h,v,C,s,P;if(n=n.replace(/\/+$/,""),P=r.target||"#app",c=r.compile||null,x=r.persist||!1,p=r.hash||!1,!c)c=globalThis?.compileToJS||null;if(typeof document<"u"&&!document.querySelector(P))g=document.createElement("div"),g.id=P.replace(/^#/,""),document.body.prepend(g);if(r.bundle)a=r.bundle;else{if(f=`${n}/bundle`,d=await fetch(f),!d.ok)throw Error(`launch: ${f} (${d.status})`);a=await d.json()}if(i=Te({components:{},routes:{},data:{}}),a.data)i.data=a.data;if(a.routes)i.routes=a.routes;if(x&&typeof sessionStorage<"u"){e=`__rip_${n}`,t=x==="local"?localStorage:sessionStorage;try{if(C=t.getItem(e),C){s=JSON.parse(C);for(let b in s){let w=s[b];i.data[b]=w}}}catch{}o=function(){return(()=>{try{return t.setItem(e,JSON.stringify(je(i.data)))}catch{return null}})()},M(function(){let b;return re.value,b=setTimeout(o,2000),function(){return clearTimeout(b)}}),window.addEventListener("beforeunload",o)}if(u=Oe(),a.components)u.load(a.components);if(m=`__rip_${n.replace(/\//g,"_")||"app"}`,h={map:me(u),classes:{},key:m},typeof globalThis<"u")globalThis[m]=h.classes;if(i.data.title&&typeof document<"u")document.title=i.data.title;if(v=Le(u,{root:"components",base:n,hash:p,onError:function(b){return console.error(`[Rip] Error ${b.status}: ${b.message||b.path}`)}}),y=Me({router:v,app:i,components:u,resolver:h,compile:c,target:P,onError:function(b){return console.error(`[Rip] ${b.message}`,b.error)}}),y.start(),a.data?.watch)ye(u,v,y,`${n}/watch`,n);if(typeof window<"u")window.app=i,window.__RIP__={app:i,components:u,router:v,renderer:y,cache:y.cache,version:"0.3.0"};return{app:i,components:u,router:v,renderer:y}};export{qe as throttle,Te as stash,ke as setContext,je as raw,Ne as launch,Ae as isStash,De as hold,Pe as hasContext,Re as getContext,$e as delay,We as debounce,Le as createRouter,Ue as createResource,Me as createRenderer,Oe as createComponents};
|
package/docs/dist/ui.min.js.br
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/compiler.js
CHANGED
|
@@ -148,6 +148,7 @@ export class CodeGenerator {
|
|
|
148
148
|
|
|
149
149
|
// Special operators
|
|
150
150
|
'%%': 'generateModulo',
|
|
151
|
+
'%%=': 'generateModuloAssign',
|
|
151
152
|
'//': 'generateFloorDiv',
|
|
152
153
|
'//=': 'generateFloorDivAssign',
|
|
153
154
|
'..': 'generateRange',
|
|
@@ -213,12 +214,10 @@ export class CodeGenerator {
|
|
|
213
214
|
|
|
214
215
|
// Control flow — complex
|
|
215
216
|
'if': 'generateIf',
|
|
216
|
-
'unless': 'generateIf',
|
|
217
217
|
'for-in': 'generateForIn',
|
|
218
218
|
'for-of': 'generateForOf',
|
|
219
219
|
'for-as': 'generateForAs',
|
|
220
220
|
'while': 'generateWhile',
|
|
221
|
-
'until': 'generateUntil',
|
|
222
221
|
'try': 'generateTry',
|
|
223
222
|
'throw': 'generateThrow',
|
|
224
223
|
'control': 'generateControl',
|
|
@@ -318,7 +317,7 @@ export class CodeGenerator {
|
|
|
318
317
|
|
|
319
318
|
if (!trimmed || trimmed === '}' || trimmed === '});') continue;
|
|
320
319
|
if (trimmed.startsWith('let ') || trimmed.startsWith('var ')) continue;
|
|
321
|
-
if (trimmed.startsWith('const slice') || trimmed.startsWith('const modulo') || trimmed.startsWith('const
|
|
320
|
+
if (trimmed.startsWith('const slice') || trimmed.startsWith('const modulo') || trimmed.startsWith('const toMatchable')) continue;
|
|
322
321
|
if (trimmed.startsWith('const {') && trimmed.includes('__')) continue;
|
|
323
322
|
if (trimmed.startsWith('} else')) continue;
|
|
324
323
|
if (trimmed.startsWith('//# source')) continue;
|
|
@@ -382,13 +381,6 @@ export class CodeGenerator {
|
|
|
382
381
|
return;
|
|
383
382
|
}
|
|
384
383
|
|
|
385
|
-
if (head === 'unless') {
|
|
386
|
-
let [condition, body] = rest;
|
|
387
|
-
this.collectProgramVariables(condition);
|
|
388
|
-
this.collectProgramVariables(body);
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
384
|
if (head === 'try') {
|
|
393
385
|
this.collectProgramVariables(rest[0]);
|
|
394
386
|
if (rest.length >= 2 && Array.isArray(rest[1]) && rest[1].length === 2 && rest[1][0] !== 'block') {
|
|
@@ -543,7 +535,7 @@ export class CodeGenerator {
|
|
|
543
535
|
return `super.${this.currentMethodName}(${args})`;
|
|
544
536
|
}
|
|
545
537
|
|
|
546
|
-
// Postfix if
|
|
538
|
+
// Postfix if on single-arg call
|
|
547
539
|
if (context === 'statement' && rest.length === 1) {
|
|
548
540
|
let cond = this.findPostfixConditional(rest[0]);
|
|
549
541
|
if (cond) {
|
|
@@ -552,7 +544,7 @@ export class CodeGenerator {
|
|
|
552
544
|
let condCode = this.generate(cond.condition, 'value');
|
|
553
545
|
let valCode = this.generate(argWithout, 'value');
|
|
554
546
|
let callStr = `${callee}(${valCode})`;
|
|
555
|
-
return
|
|
547
|
+
return `if (${condCode}) ${callStr}`;
|
|
556
548
|
}
|
|
557
549
|
}
|
|
558
550
|
|
|
@@ -565,7 +557,7 @@ export class CodeGenerator {
|
|
|
565
557
|
|
|
566
558
|
// Statement sequence (comma operator)
|
|
567
559
|
if (Array.isArray(head) && typeof head[0] === 'string') {
|
|
568
|
-
let stmtOps = ['=', '+=', '-=', '*=', '/=', '%=', '**=', '&&=', '||=', '??=', 'if', '
|
|
560
|
+
let stmtOps = ['=', '+=', '-=', '*=', '/=', '%=', '**=', '&&=', '||=', '??=', 'if', 'return', 'throw'];
|
|
569
561
|
if (stmtOps.includes(head[0])) {
|
|
570
562
|
let exprs = sexpr.map(stmt => this.generate(stmt, 'value'));
|
|
571
563
|
return `(${exprs.join(', ')})`;
|
|
@@ -583,7 +575,7 @@ export class CodeGenerator {
|
|
|
583
575
|
return `new ${needsParens ? `(${ctorCode})` : ctorCode}(${args})`;
|
|
584
576
|
}
|
|
585
577
|
|
|
586
|
-
// Postfix if
|
|
578
|
+
// Postfix if on single-arg method call
|
|
587
579
|
if (context === 'statement' && rest.length === 1) {
|
|
588
580
|
let cond = this.findPostfixConditional(rest[0]);
|
|
589
581
|
if (cond) {
|
|
@@ -592,7 +584,7 @@ export class CodeGenerator {
|
|
|
592
584
|
let condCode = this.generate(cond.condition, 'value');
|
|
593
585
|
let valCode = this.generate(argWithout, 'value');
|
|
594
586
|
let callStr = `${calleeCode}(${valCode})`;
|
|
595
|
-
return
|
|
587
|
+
return `if (${condCode}) ${callStr}`;
|
|
596
588
|
}
|
|
597
589
|
}
|
|
598
590
|
|
|
@@ -636,7 +628,7 @@ export class CodeGenerator {
|
|
|
636
628
|
}
|
|
637
629
|
|
|
638
630
|
// Generate body first to detect needed helpers
|
|
639
|
-
let blockStmts = ['def', 'class', 'if', '
|
|
631
|
+
let blockStmts = ['def', 'class', 'if', 'for-in', 'for-of', 'for-as', 'while', 'loop', 'switch', 'try'];
|
|
640
632
|
let statementsCode = other.map((stmt, index) => {
|
|
641
633
|
let isSingle = other.length === 1 && imports.length === 0 && exports.length === 0;
|
|
642
634
|
let isObj = this.is(stmt, 'object');
|
|
@@ -678,8 +670,8 @@ export class CodeGenerator {
|
|
|
678
670
|
if (!skip) {
|
|
679
671
|
if (this.helpers.has('slice')) { code += 'const slice = [].slice;\n'; needsBlank = true; }
|
|
680
672
|
if (this.helpers.has('modulo')) { code += 'const modulo = (n, d) => { n = +n; d = +d; return (n % d + d) % d; };\n'; needsBlank = true; }
|
|
681
|
-
if (this.helpers.has('
|
|
682
|
-
code += 'const
|
|
673
|
+
if (this.helpers.has('toMatchable')) {
|
|
674
|
+
code += 'const toMatchable = (v, allowNewlines) => {\n';
|
|
683
675
|
code += ' if (typeof v === "string") return !allowNewlines && /[\\n\\r]/.test(v) ? null : v;\n';
|
|
684
676
|
code += ' if (v == null) return "";\n';
|
|
685
677
|
code += ' if (typeof v === "number" || typeof v === "bigint" || typeof v === "boolean") return String(v);\n';
|
|
@@ -779,6 +771,13 @@ export class CodeGenerator {
|
|
|
779
771
|
return `modulo(${this.generate(left, 'value')}, ${this.generate(right, 'value')})`;
|
|
780
772
|
}
|
|
781
773
|
|
|
774
|
+
generateModuloAssign(head, rest) {
|
|
775
|
+
let [target, value] = rest;
|
|
776
|
+
this.helpers.add('modulo');
|
|
777
|
+
let t = this.generate(target, 'value'), v = this.generate(value, 'value');
|
|
778
|
+
return `${t} = modulo(${t}, ${v})`;
|
|
779
|
+
}
|
|
780
|
+
|
|
782
781
|
generateFloorDiv(head, rest) {
|
|
783
782
|
let [left, right] = rest;
|
|
784
783
|
return `Math.floor(${this.generate(left, 'value')} / ${this.generate(right, 'value')})`;
|
|
@@ -823,7 +822,6 @@ export class CodeGenerator {
|
|
|
823
822
|
let ctrlOp = str(rawCtrlOp);
|
|
824
823
|
let isReturn = ctrlSexpr[0] === 'return';
|
|
825
824
|
let targetCode = this.generate(target, 'value');
|
|
826
|
-
if (typeof target === 'string') this.programVars.add(target);
|
|
827
825
|
let exprCode = this.generate(expr, 'value');
|
|
828
826
|
let ctrlValue = ctrlSexpr.length > 1 ? ctrlSexpr[1] : null;
|
|
829
827
|
let ctrlCode = isReturn
|
|
@@ -868,33 +866,29 @@ export class CodeGenerator {
|
|
|
868
866
|
}
|
|
869
867
|
}
|
|
870
868
|
|
|
871
|
-
// Postfix if
|
|
869
|
+
// Postfix if on assignment with || operator
|
|
872
870
|
if (context === 'statement' && head === '=' && Array.isArray(value) &&
|
|
873
871
|
(value[0] === '||' || value[0] === '&&') && value.length === 3) {
|
|
874
872
|
let [binOp, left, right] = value;
|
|
875
|
-
if (
|
|
876
|
-
let [
|
|
873
|
+
if (this.is(right, 'if') && right.length === 3) {
|
|
874
|
+
let [, condition, wrappedValue] = right;
|
|
877
875
|
let unwrapped = Array.isArray(wrappedValue) && wrappedValue.length === 1 ? wrappedValue[0] : wrappedValue;
|
|
878
876
|
let fullValue = [binOp, left, unwrapped];
|
|
879
877
|
let t = this.generate(target, 'value'), c = this.generate(condition, 'value'), v = this.generate(fullValue, 'value');
|
|
880
|
-
return
|
|
878
|
+
return `if (${c}) ${t} = ${v}`;
|
|
881
879
|
}
|
|
882
880
|
}
|
|
883
881
|
|
|
884
|
-
// Postfix if
|
|
882
|
+
// Postfix if on simple assignment
|
|
885
883
|
if (context === 'statement' && head === '=' && Array.isArray(value) && value.length === 3) {
|
|
886
884
|
let [valHead, condition, actualValue] = value;
|
|
887
885
|
let isPostfix = Array.isArray(actualValue) && actualValue.length === 1 &&
|
|
888
886
|
(!Array.isArray(actualValue[0]) || actualValue[0][0] !== 'block');
|
|
889
|
-
if (
|
|
887
|
+
if (valHead === 'if' && isPostfix) {
|
|
890
888
|
let unwrapped = Array.isArray(actualValue) && actualValue.length === 1 ? actualValue[0] : actualValue;
|
|
891
889
|
let t = this.generate(target, 'value');
|
|
892
890
|
let condCode = this.unwrapLogical(this.generate(condition, 'value'));
|
|
893
891
|
let v = this.generate(unwrapped, 'value');
|
|
894
|
-
if (valHead === 'unless') {
|
|
895
|
-
if (condCode.includes(' ') || /[<>=&|]/.test(condCode)) condCode = `(${condCode})`;
|
|
896
|
-
return `if (!${condCode}) ${t} = ${v}`;
|
|
897
|
-
}
|
|
898
892
|
return `if (${condCode}) ${t} = ${v}`;
|
|
899
893
|
}
|
|
900
894
|
}
|
|
@@ -951,12 +945,12 @@ export class CodeGenerator {
|
|
|
951
945
|
|
|
952
946
|
generateRegexIndex(head, rest) {
|
|
953
947
|
let [value, regex, captureIndex] = rest;
|
|
954
|
-
this.helpers.add('
|
|
948
|
+
this.helpers.add('toMatchable');
|
|
955
949
|
this.programVars.add('_');
|
|
956
950
|
let v = this.generate(value, 'value'), r = this.generate(regex, 'value');
|
|
957
951
|
let idx = captureIndex !== null ? this.generate(captureIndex, 'value') : '0';
|
|
958
952
|
let allowNL = r.includes('/m') ? ', true' : '';
|
|
959
|
-
return `(_ =
|
|
953
|
+
return `(_ = toMatchable(${v}${allowNL}).match(${r})) && _[${idx}]`;
|
|
960
954
|
}
|
|
961
955
|
|
|
962
956
|
generateIndexAccess(head, rest) {
|
|
@@ -1066,11 +1060,6 @@ export class CodeGenerator {
|
|
|
1066
1060
|
let [expr] = rest;
|
|
1067
1061
|
if (this.sideEffectOnly) return 'return';
|
|
1068
1062
|
|
|
1069
|
-
if (this.is(expr, 'unless')) {
|
|
1070
|
-
let [, condition, body] = expr;
|
|
1071
|
-
let val = Array.isArray(body) && body.length === 1 ? body[0] : body;
|
|
1072
|
-
return `if (!${this.generate(condition, 'value')}) return ${this.generate(val, 'value')}`;
|
|
1073
|
-
}
|
|
1074
1063
|
if (this.is(expr, 'if')) {
|
|
1075
1064
|
let [, condition, body, ...elseParts] = expr;
|
|
1076
1065
|
if (elseParts.length === 0) {
|
|
@@ -1078,11 +1067,10 @@ export class CodeGenerator {
|
|
|
1078
1067
|
return `if (${this.generate(condition, 'value')}) return ${this.generate(val, 'value')}`;
|
|
1079
1068
|
}
|
|
1080
1069
|
}
|
|
1081
|
-
if (this.is(expr, 'new') && Array.isArray(expr[1]) && expr[1][0] === '
|
|
1082
|
-
let [,
|
|
1083
|
-
let [, condition, body] = unlessNode;
|
|
1070
|
+
if (this.is(expr, 'new') && Array.isArray(expr[1]) && expr[1][0] === 'if') {
|
|
1071
|
+
let [, condition, body] = expr[1];
|
|
1084
1072
|
let val = Array.isArray(body) && body.length === 1 ? body[0] : body;
|
|
1085
|
-
return `if (
|
|
1073
|
+
return `if (${this.generate(condition, 'value')}) return ${this.generate(['new', val], 'value')}`;
|
|
1086
1074
|
}
|
|
1087
1075
|
return `return ${this.generate(expr, 'value')}`;
|
|
1088
1076
|
}
|
|
@@ -1200,16 +1188,6 @@ export class CodeGenerator {
|
|
|
1200
1188
|
// ---------------------------------------------------------------------------
|
|
1201
1189
|
|
|
1202
1190
|
generateIf(head, rest, context, sexpr) {
|
|
1203
|
-
if (head === 'unless') {
|
|
1204
|
-
let [condition, body] = rest;
|
|
1205
|
-
if (Array.isArray(body) && body.length === 1 && (!Array.isArray(body[0]) || body[0][0] !== 'block')) body = body[0];
|
|
1206
|
-
if (context === 'value') {
|
|
1207
|
-
return `(!${this.generate(condition, 'value')} ? ${this.extractExpression(body)} : undefined)`;
|
|
1208
|
-
}
|
|
1209
|
-
let condCode = this.unwrap(this.generate(condition, 'value'));
|
|
1210
|
-
if (/[ <>=&|]/.test(condCode)) condCode = `(${condCode})`;
|
|
1211
|
-
return `if (!${condCode}) ` + this.generate(body, 'statement');
|
|
1212
|
-
}
|
|
1213
1191
|
let [condition, thenBranch, ...elseBranches] = rest;
|
|
1214
1192
|
return context === 'value'
|
|
1215
1193
|
? this.generateIfAsExpression(condition, thenBranch, elseBranches)
|
|
@@ -1433,11 +1411,6 @@ export class CodeGenerator {
|
|
|
1433
1411
|
return code + (guard ? this.generateLoopBodyWithGuard(body, guard) : this.generateLoopBody(body));
|
|
1434
1412
|
}
|
|
1435
1413
|
|
|
1436
|
-
generateUntil(head, rest) {
|
|
1437
|
-
let [cond, body] = rest;
|
|
1438
|
-
return `while (!(${this.unwrap(this.generate(cond, 'value'))})) ` + this.generateLoopBody(body);
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
1414
|
generateRange(head, rest) {
|
|
1442
1415
|
if (head === '...') {
|
|
1443
1416
|
if (rest.length === 1) return `...${this.generate(rest[0], 'value')}`;
|
|
@@ -1506,11 +1479,11 @@ export class CodeGenerator {
|
|
|
1506
1479
|
|
|
1507
1480
|
generateRegexMatch(head, rest) {
|
|
1508
1481
|
let [left, right] = rest;
|
|
1509
|
-
this.helpers.add('
|
|
1482
|
+
this.helpers.add('toMatchable');
|
|
1510
1483
|
this.programVars.add('_');
|
|
1511
1484
|
let r = this.generate(right, 'value');
|
|
1512
1485
|
let allowNL = r.includes('/m') ? ', true' : '';
|
|
1513
|
-
return `(_ =
|
|
1486
|
+
return `(_ = toMatchable(${this.generate(left, 'value')}${allowNL}).match(${r}))`;
|
|
1514
1487
|
}
|
|
1515
1488
|
|
|
1516
1489
|
generateNew(head, rest) {
|
|
@@ -1648,20 +1621,18 @@ export class CodeGenerator {
|
|
|
1648
1621
|
let [expr] = rest;
|
|
1649
1622
|
if (Array.isArray(expr)) {
|
|
1650
1623
|
let checkExpr = expr, wrapperType = null;
|
|
1651
|
-
if (expr[0] === 'new' && Array.isArray(expr[1]) &&
|
|
1624
|
+
if (expr[0] === 'new' && Array.isArray(expr[1]) && expr[1][0] === 'if') {
|
|
1652
1625
|
wrapperType = 'new'; checkExpr = expr[1];
|
|
1653
|
-
} else if (expr[0] === 'if'
|
|
1626
|
+
} else if (expr[0] === 'if') {
|
|
1654
1627
|
checkExpr = expr;
|
|
1655
1628
|
}
|
|
1656
|
-
if (checkExpr[0] === 'if'
|
|
1657
|
-
let [
|
|
1629
|
+
if (checkExpr[0] === 'if') {
|
|
1630
|
+
let [, condition, body] = checkExpr;
|
|
1658
1631
|
let unwrapped = Array.isArray(body) && body.length === 1 ? body[0] : body;
|
|
1659
1632
|
expr = wrapperType === 'new' ? ['new', unwrapped] : unwrapped;
|
|
1660
1633
|
let condCode = this.generate(condition, 'value');
|
|
1661
1634
|
let throwCode = `throw ${this.generate(expr, 'value')}`;
|
|
1662
|
-
return
|
|
1663
|
-
? `if (!(${condCode})) {\n${this.indent()} ${throwCode};\n${this.indent()}}`
|
|
1664
|
-
: `if (${condCode}) {\n${this.indent()} ${throwCode};\n${this.indent()}}`;
|
|
1635
|
+
return `if (${condCode}) {\n${this.indent()} ${throwCode};\n${this.indent()}}`;
|
|
1665
1636
|
}
|
|
1666
1637
|
}
|
|
1667
1638
|
let throwStmt = `throw ${this.generate(expr, 'value')}`;
|
|
@@ -1834,11 +1805,11 @@ export class CodeGenerator {
|
|
|
1834
1805
|
if (typeof node === 'string' && (node === 'break' || node === 'continue')) return true;
|
|
1835
1806
|
if (!Array.isArray(node)) return false;
|
|
1836
1807
|
if (['break', 'continue', 'return', 'throw'].includes(node[0])) return true;
|
|
1837
|
-
if (node[0] === 'if'
|
|
1808
|
+
if (node[0] === 'if') return node.slice(1).some(hasCtrl);
|
|
1838
1809
|
return node.some(hasCtrl);
|
|
1839
1810
|
};
|
|
1840
1811
|
|
|
1841
|
-
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', '
|
|
1812
|
+
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', 'loop'];
|
|
1842
1813
|
if (this.is(expr, 'block')) {
|
|
1843
1814
|
for (let i = 0; i < expr.length - 1; i++) {
|
|
1844
1815
|
let s = expr[i + 1], isLast = i === expr.length - 2;
|
|
@@ -2142,7 +2113,7 @@ export class CodeGenerator {
|
|
|
2142
2113
|
findPostfixConditional(expr) {
|
|
2143
2114
|
if (!Array.isArray(expr)) return null;
|
|
2144
2115
|
let h = expr[0];
|
|
2145
|
-
if (
|
|
2116
|
+
if (h === 'if' && expr.length === 3) return {type: h, condition: expr[1], value: expr[2]};
|
|
2146
2117
|
if (h === '+' || h === '-' || h === '*' || h === '/') {
|
|
2147
2118
|
for (let i = 1; i < expr.length; i++) {
|
|
2148
2119
|
let found = this.findPostfixConditional(expr[i]);
|
|
@@ -2236,7 +2207,7 @@ export class CodeGenerator {
|
|
|
2236
2207
|
!this.scopeStack.some(s => s.has(v)) // don't re-declare variables from enclosing scopes
|
|
2237
2208
|
));
|
|
2238
2209
|
let noRetStmts = ['return', 'throw', 'break', 'continue'];
|
|
2239
|
-
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', '
|
|
2210
|
+
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', 'loop'];
|
|
2240
2211
|
|
|
2241
2212
|
// Track this function's scope so nested functions don't re-declare its variables
|
|
2242
2213
|
this.scopeStack.push(new Set([...newVars, ...paramNames]));
|
|
@@ -2284,7 +2255,7 @@ export class CodeGenerator {
|
|
|
2284
2255
|
return;
|
|
2285
2256
|
}
|
|
2286
2257
|
|
|
2287
|
-
if (!isConstructor && !sideEffectOnly && isLast &&
|
|
2258
|
+
if (!isConstructor && !sideEffectOnly && isLast && h === 'if') {
|
|
2288
2259
|
let [cond, thenB, ...elseB] = stmt.slice(1);
|
|
2289
2260
|
let hasMulti = (b) => this.is(b, 'block') && b.length > 2;
|
|
2290
2261
|
if (hasMulti(thenB) || elseB.some(hasMulti)) {
|
|
@@ -2510,7 +2481,7 @@ export class CodeGenerator {
|
|
|
2510
2481
|
generateIfElseWithEarlyReturns(ifStmt) {
|
|
2511
2482
|
let [head, condition, thenBranch, ...elseBranches] = ifStmt;
|
|
2512
2483
|
let code = '';
|
|
2513
|
-
let condCode =
|
|
2484
|
+
let condCode = this.generate(condition, 'value');
|
|
2514
2485
|
code += this.indent() + `if (${condCode}) {\n`;
|
|
2515
2486
|
code += this.withIndent(() => this.generateBranchWithReturn(thenBranch));
|
|
2516
2487
|
code += this.indent() + '}';
|
|
@@ -2660,7 +2631,7 @@ export class CodeGenerator {
|
|
|
2660
2631
|
if (!generated || generated.endsWith(';')) return false;
|
|
2661
2632
|
if (!generated.endsWith('}')) return true;
|
|
2662
2633
|
let h = Array.isArray(stmt) ? stmt[0] : null;
|
|
2663
|
-
return !['def', 'class', 'if', '
|
|
2634
|
+
return !['def', 'class', 'if', 'for-in', 'for-of', 'for-as', 'while', 'loop', 'switch', 'try'].includes(h);
|
|
2664
2635
|
}
|
|
2665
2636
|
|
|
2666
2637
|
addSemicolon(stmt, generated) { return generated + (this.needsSemicolon(stmt, generated) ? ';' : ''); }
|
|
@@ -2687,7 +2658,7 @@ export class CodeGenerator {
|
|
|
2687
2658
|
return stmts.some(s => Array.isArray(s) && ['return', 'throw', 'break', 'continue'].includes(s[0]));
|
|
2688
2659
|
});
|
|
2689
2660
|
}
|
|
2690
|
-
if (t === 'if'
|
|
2661
|
+
if (t === 'if') {
|
|
2691
2662
|
let [, , thenB, elseB] = body;
|
|
2692
2663
|
return this.branchHasControlFlow(thenB) && elseB && this.branchHasControlFlow(elseB);
|
|
2693
2664
|
}
|
package/src/grammar/grammar.rip
CHANGED
|
@@ -554,7 +554,7 @@ grammar =
|
|
|
554
554
|
]
|
|
555
555
|
|
|
556
556
|
UnlessBlock: [
|
|
557
|
-
o 'UNLESS Expression Block' , '["
|
|
557
|
+
o 'UNLESS Expression Block' , '["if", ["!", 2], 3]'
|
|
558
558
|
o 'UNLESS Expression Block ELSE Block' , '["if", ["!", 2], 3, 5]'
|
|
559
559
|
]
|
|
560
560
|
|
|
@@ -565,8 +565,8 @@ grammar =
|
|
|
565
565
|
o 'Statement POST_IF Expression' , '["if", 3, [1]]'
|
|
566
566
|
o 'Expression POST_IF Expression' , '["if", 3, [1]]'
|
|
567
567
|
o 'Expression POST_IF Expression ELSE INDENT Expression OUTDENT', '["?:", 3, 1, 6]'
|
|
568
|
-
o 'Statement POST_UNLESS Expression' , '["
|
|
569
|
-
o 'Expression POST_UNLESS Expression', '["
|
|
568
|
+
o 'Statement POST_UNLESS Expression' , '["if", ["!", 3], [1]]'
|
|
569
|
+
o 'Expression POST_UNLESS Expression', '["if", ["!", 3], [1]]'
|
|
570
570
|
]
|
|
571
571
|
|
|
572
572
|
# Try/Catch/Finally
|
|
@@ -609,8 +609,8 @@ grammar =
|
|
|
609
609
|
WhileSource: [
|
|
610
610
|
o 'WHILE Expression' , '["while", 2]'
|
|
611
611
|
o 'WHILE Expression WHEN Expression', '["while", 2, 4]'
|
|
612
|
-
o 'UNTIL Expression' , '["
|
|
613
|
-
o 'UNTIL Expression WHEN Expression', '["
|
|
612
|
+
o 'UNTIL Expression' , '["while", ["!", 2]]'
|
|
613
|
+
o 'UNTIL Expression WHEN Expression', '["while", ["!", 2], 4]'
|
|
614
614
|
]
|
|
615
615
|
|
|
616
616
|
While: [
|
package/src/parser-rd.js
CHANGED
|
@@ -108,12 +108,12 @@ const ruleActions = (rule, vals, locs, shared) => {
|
|
|
108
108
|
case 227: return ["yield-from", $[$0]];
|
|
109
109
|
case 228: return ["if", $[$0-1], $[$0]];
|
|
110
110
|
case 229: return $[$0-4].length === 3 ? ["if", $[$0-4][1], $[$0-4][2], ["if", $[$0-1], $[$0]]] : [...$[$0-4], ["if", $[$0-1], $[$0]]];
|
|
111
|
-
case 230: return ["
|
|
111
|
+
case 230: return ["if", ["!", $[$0-1]], $[$0]];
|
|
112
112
|
case 231: return ["if", ["!", $[$0-3]], $[$0-2], $[$0]];
|
|
113
113
|
case 233: return $[$0-2].length === 3 ? ["if", $[$0-2][1], $[$0-2][2], $[$0]] : [...$[$0-2], $[$0]];
|
|
114
114
|
case 235: case 236: return ["if", $[$0], [$[$0-2]]];
|
|
115
115
|
case 237: return ["?:", $[$0-4], $[$0-6], $[$0-1]];
|
|
116
|
-
case 238: case 239: return ["
|
|
116
|
+
case 238: case 239: return ["if", ["!", $[$0]], [$[$0-2]]];
|
|
117
117
|
case 240: return ["try", $[$0]];
|
|
118
118
|
case 241: return ["try", $[$0-1], $[$0]];
|
|
119
119
|
case 242: return ["try", $[$0-2], $[$0]];
|
|
@@ -128,8 +128,8 @@ const ruleActions = (rule, vals, locs, shared) => {
|
|
|
128
128
|
case 254: return ["when", $[$0-2], $[$0-1]];
|
|
129
129
|
case 255: return ["while", $[$0]];
|
|
130
130
|
case 256: return ["while", $[$0-2], $[$0]];
|
|
131
|
-
case 257: return ["
|
|
132
|
-
case 258: return ["
|
|
131
|
+
case 257: return ["while", ["!", $[$0]]];
|
|
132
|
+
case 258: return ["while", ["!", $[$0-2]], $[$0]];
|
|
133
133
|
case 259: return $[$0-1].length === 2 ? [$[$0-1][0], $[$0-1][1], $[$0]] : [$[$0-1][0], $[$0-1][1], $[$0-1][2], $[$0]];
|
|
134
134
|
case 260: case 261: return $[$0].length === 2 ? [$[$0][0], $[$0][1], [$[$0-1]]] : [$[$0][0], $[$0][1], $[$0][2], [$[$0-1]]];
|
|
135
135
|
case 263: return ["loop", $[$0]];
|
package/src/parser.js
CHANGED
|
@@ -113,12 +113,12 @@ const parserInstance = {
|
|
|
113
113
|
case 227: return ["yield-from", $[$0]];
|
|
114
114
|
case 228: return ["if", $[$0-1], $[$0]];
|
|
115
115
|
case 229: return $[$0-4].length === 3 ? ["if", $[$0-4][1], $[$0-4][2], ["if", $[$0-1], $[$0]]] : [...$[$0-4], ["if", $[$0-1], $[$0]]];
|
|
116
|
-
case 230: return ["
|
|
116
|
+
case 230: return ["if", ["!", $[$0-1]], $[$0]];
|
|
117
117
|
case 231: return ["if", ["!", $[$0-3]], $[$0-2], $[$0]];
|
|
118
118
|
case 233: return $[$0-2].length === 3 ? ["if", $[$0-2][1], $[$0-2][2], $[$0]] : [...$[$0-2], $[$0]];
|
|
119
119
|
case 235: case 236: return ["if", $[$0], [$[$0-2]]];
|
|
120
120
|
case 237: return ["?:", $[$0-4], $[$0-6], $[$0-1]];
|
|
121
|
-
case 238: case 239: return ["
|
|
121
|
+
case 238: case 239: return ["if", ["!", $[$0]], [$[$0-2]]];
|
|
122
122
|
case 240: return ["try", $[$0]];
|
|
123
123
|
case 241: return ["try", $[$0-1], $[$0]];
|
|
124
124
|
case 242: return ["try", $[$0-2], $[$0]];
|
|
@@ -133,8 +133,8 @@ const parserInstance = {
|
|
|
133
133
|
case 254: return ["when", $[$0-2], $[$0-1]];
|
|
134
134
|
case 255: return ["while", $[$0]];
|
|
135
135
|
case 256: return ["while", $[$0-2], $[$0]];
|
|
136
|
-
case 257: return ["
|
|
137
|
-
case 258: return ["
|
|
136
|
+
case 257: return ["while", ["!", $[$0]]];
|
|
137
|
+
case 258: return ["while", ["!", $[$0-2]], $[$0]];
|
|
138
138
|
case 259: return $[$0-1].length === 2 ? [$[$0-1][0], $[$0-1][1], $[$0]] : [$[$0-1][0], $[$0-1][1], $[$0-1][2], $[$0]];
|
|
139
139
|
case 260: case 261: return $[$0].length === 2 ? [$[$0][0], $[$0][1], [$[$0-1]]] : [$[$0][0], $[$0][1], $[$0][2], [$[$0-1]]];
|
|
140
140
|
case 263: return ["loop", $[$0]];
|