rip-lang 3.8.8 → 3.8.9
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 +9 -0
- package/README.md +4 -4
- 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 -74
- 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 -71
- 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')})`;
|
|
@@ -868,33 +867,29 @@ export class CodeGenerator {
|
|
|
868
867
|
}
|
|
869
868
|
}
|
|
870
869
|
|
|
871
|
-
// Postfix if
|
|
870
|
+
// Postfix if on assignment with || operator
|
|
872
871
|
if (context === 'statement' && head === '=' && Array.isArray(value) &&
|
|
873
872
|
(value[0] === '||' || value[0] === '&&') && value.length === 3) {
|
|
874
873
|
let [binOp, left, right] = value;
|
|
875
|
-
if (
|
|
876
|
-
let [
|
|
874
|
+
if (this.is(right, 'if') && right.length === 3) {
|
|
875
|
+
let [, condition, wrappedValue] = right;
|
|
877
876
|
let unwrapped = Array.isArray(wrappedValue) && wrappedValue.length === 1 ? wrappedValue[0] : wrappedValue;
|
|
878
877
|
let fullValue = [binOp, left, unwrapped];
|
|
879
878
|
let t = this.generate(target, 'value'), c = this.generate(condition, 'value'), v = this.generate(fullValue, 'value');
|
|
880
|
-
return
|
|
879
|
+
return `if (${c}) ${t} = ${v}`;
|
|
881
880
|
}
|
|
882
881
|
}
|
|
883
882
|
|
|
884
|
-
// Postfix if
|
|
883
|
+
// Postfix if on simple assignment
|
|
885
884
|
if (context === 'statement' && head === '=' && Array.isArray(value) && value.length === 3) {
|
|
886
885
|
let [valHead, condition, actualValue] = value;
|
|
887
886
|
let isPostfix = Array.isArray(actualValue) && actualValue.length === 1 &&
|
|
888
887
|
(!Array.isArray(actualValue[0]) || actualValue[0][0] !== 'block');
|
|
889
|
-
if (
|
|
888
|
+
if (valHead === 'if' && isPostfix) {
|
|
890
889
|
let unwrapped = Array.isArray(actualValue) && actualValue.length === 1 ? actualValue[0] : actualValue;
|
|
891
890
|
let t = this.generate(target, 'value');
|
|
892
891
|
let condCode = this.unwrapLogical(this.generate(condition, 'value'));
|
|
893
892
|
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
893
|
return `if (${condCode}) ${t} = ${v}`;
|
|
899
894
|
}
|
|
900
895
|
}
|
|
@@ -951,12 +946,12 @@ export class CodeGenerator {
|
|
|
951
946
|
|
|
952
947
|
generateRegexIndex(head, rest) {
|
|
953
948
|
let [value, regex, captureIndex] = rest;
|
|
954
|
-
this.helpers.add('
|
|
949
|
+
this.helpers.add('toMatchable');
|
|
955
950
|
this.programVars.add('_');
|
|
956
951
|
let v = this.generate(value, 'value'), r = this.generate(regex, 'value');
|
|
957
952
|
let idx = captureIndex !== null ? this.generate(captureIndex, 'value') : '0';
|
|
958
953
|
let allowNL = r.includes('/m') ? ', true' : '';
|
|
959
|
-
return `(_ =
|
|
954
|
+
return `(_ = toMatchable(${v}${allowNL}).match(${r})) && _[${idx}]`;
|
|
960
955
|
}
|
|
961
956
|
|
|
962
957
|
generateIndexAccess(head, rest) {
|
|
@@ -1066,11 +1061,6 @@ export class CodeGenerator {
|
|
|
1066
1061
|
let [expr] = rest;
|
|
1067
1062
|
if (this.sideEffectOnly) return 'return';
|
|
1068
1063
|
|
|
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
1064
|
if (this.is(expr, 'if')) {
|
|
1075
1065
|
let [, condition, body, ...elseParts] = expr;
|
|
1076
1066
|
if (elseParts.length === 0) {
|
|
@@ -1078,11 +1068,10 @@ export class CodeGenerator {
|
|
|
1078
1068
|
return `if (${this.generate(condition, 'value')}) return ${this.generate(val, 'value')}`;
|
|
1079
1069
|
}
|
|
1080
1070
|
}
|
|
1081
|
-
if (this.is(expr, 'new') && Array.isArray(expr[1]) && expr[1][0] === '
|
|
1082
|
-
let [,
|
|
1083
|
-
let [, condition, body] = unlessNode;
|
|
1071
|
+
if (this.is(expr, 'new') && Array.isArray(expr[1]) && expr[1][0] === 'if') {
|
|
1072
|
+
let [, condition, body] = expr[1];
|
|
1084
1073
|
let val = Array.isArray(body) && body.length === 1 ? body[0] : body;
|
|
1085
|
-
return `if (
|
|
1074
|
+
return `if (${this.generate(condition, 'value')}) return ${this.generate(['new', val], 'value')}`;
|
|
1086
1075
|
}
|
|
1087
1076
|
return `return ${this.generate(expr, 'value')}`;
|
|
1088
1077
|
}
|
|
@@ -1200,16 +1189,6 @@ export class CodeGenerator {
|
|
|
1200
1189
|
// ---------------------------------------------------------------------------
|
|
1201
1190
|
|
|
1202
1191
|
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
1192
|
let [condition, thenBranch, ...elseBranches] = rest;
|
|
1214
1193
|
return context === 'value'
|
|
1215
1194
|
? this.generateIfAsExpression(condition, thenBranch, elseBranches)
|
|
@@ -1433,11 +1412,6 @@ export class CodeGenerator {
|
|
|
1433
1412
|
return code + (guard ? this.generateLoopBodyWithGuard(body, guard) : this.generateLoopBody(body));
|
|
1434
1413
|
}
|
|
1435
1414
|
|
|
1436
|
-
generateUntil(head, rest) {
|
|
1437
|
-
let [cond, body] = rest;
|
|
1438
|
-
return `while (!(${this.unwrap(this.generate(cond, 'value'))})) ` + this.generateLoopBody(body);
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
1415
|
generateRange(head, rest) {
|
|
1442
1416
|
if (head === '...') {
|
|
1443
1417
|
if (rest.length === 1) return `...${this.generate(rest[0], 'value')}`;
|
|
@@ -1506,11 +1480,11 @@ export class CodeGenerator {
|
|
|
1506
1480
|
|
|
1507
1481
|
generateRegexMatch(head, rest) {
|
|
1508
1482
|
let [left, right] = rest;
|
|
1509
|
-
this.helpers.add('
|
|
1483
|
+
this.helpers.add('toMatchable');
|
|
1510
1484
|
this.programVars.add('_');
|
|
1511
1485
|
let r = this.generate(right, 'value');
|
|
1512
1486
|
let allowNL = r.includes('/m') ? ', true' : '';
|
|
1513
|
-
return `(_ =
|
|
1487
|
+
return `(_ = toMatchable(${this.generate(left, 'value')}${allowNL}).match(${r}))`;
|
|
1514
1488
|
}
|
|
1515
1489
|
|
|
1516
1490
|
generateNew(head, rest) {
|
|
@@ -1648,20 +1622,18 @@ export class CodeGenerator {
|
|
|
1648
1622
|
let [expr] = rest;
|
|
1649
1623
|
if (Array.isArray(expr)) {
|
|
1650
1624
|
let checkExpr = expr, wrapperType = null;
|
|
1651
|
-
if (expr[0] === 'new' && Array.isArray(expr[1]) &&
|
|
1625
|
+
if (expr[0] === 'new' && Array.isArray(expr[1]) && expr[1][0] === 'if') {
|
|
1652
1626
|
wrapperType = 'new'; checkExpr = expr[1];
|
|
1653
|
-
} else if (expr[0] === 'if'
|
|
1627
|
+
} else if (expr[0] === 'if') {
|
|
1654
1628
|
checkExpr = expr;
|
|
1655
1629
|
}
|
|
1656
|
-
if (checkExpr[0] === 'if'
|
|
1657
|
-
let [
|
|
1630
|
+
if (checkExpr[0] === 'if') {
|
|
1631
|
+
let [, condition, body] = checkExpr;
|
|
1658
1632
|
let unwrapped = Array.isArray(body) && body.length === 1 ? body[0] : body;
|
|
1659
1633
|
expr = wrapperType === 'new' ? ['new', unwrapped] : unwrapped;
|
|
1660
1634
|
let condCode = this.generate(condition, 'value');
|
|
1661
1635
|
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()}}`;
|
|
1636
|
+
return `if (${condCode}) {\n${this.indent()} ${throwCode};\n${this.indent()}}`;
|
|
1665
1637
|
}
|
|
1666
1638
|
}
|
|
1667
1639
|
let throwStmt = `throw ${this.generate(expr, 'value')}`;
|
|
@@ -1834,11 +1806,11 @@ export class CodeGenerator {
|
|
|
1834
1806
|
if (typeof node === 'string' && (node === 'break' || node === 'continue')) return true;
|
|
1835
1807
|
if (!Array.isArray(node)) return false;
|
|
1836
1808
|
if (['break', 'continue', 'return', 'throw'].includes(node[0])) return true;
|
|
1837
|
-
if (node[0] === 'if'
|
|
1809
|
+
if (node[0] === 'if') return node.slice(1).some(hasCtrl);
|
|
1838
1810
|
return node.some(hasCtrl);
|
|
1839
1811
|
};
|
|
1840
1812
|
|
|
1841
|
-
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', '
|
|
1813
|
+
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', 'loop'];
|
|
1842
1814
|
if (this.is(expr, 'block')) {
|
|
1843
1815
|
for (let i = 0; i < expr.length - 1; i++) {
|
|
1844
1816
|
let s = expr[i + 1], isLast = i === expr.length - 2;
|
|
@@ -2142,7 +2114,7 @@ export class CodeGenerator {
|
|
|
2142
2114
|
findPostfixConditional(expr) {
|
|
2143
2115
|
if (!Array.isArray(expr)) return null;
|
|
2144
2116
|
let h = expr[0];
|
|
2145
|
-
if (
|
|
2117
|
+
if (h === 'if' && expr.length === 3) return {type: h, condition: expr[1], value: expr[2]};
|
|
2146
2118
|
if (h === '+' || h === '-' || h === '*' || h === '/') {
|
|
2147
2119
|
for (let i = 1; i < expr.length; i++) {
|
|
2148
2120
|
let found = this.findPostfixConditional(expr[i]);
|
|
@@ -2236,7 +2208,7 @@ export class CodeGenerator {
|
|
|
2236
2208
|
!this.scopeStack.some(s => s.has(v)) // don't re-declare variables from enclosing scopes
|
|
2237
2209
|
));
|
|
2238
2210
|
let noRetStmts = ['return', 'throw', 'break', 'continue'];
|
|
2239
|
-
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', '
|
|
2211
|
+
let loopStmts = ['for-in', 'for-of', 'for-as', 'while', 'loop'];
|
|
2240
2212
|
|
|
2241
2213
|
// Track this function's scope so nested functions don't re-declare its variables
|
|
2242
2214
|
this.scopeStack.push(new Set([...newVars, ...paramNames]));
|
|
@@ -2284,7 +2256,7 @@ export class CodeGenerator {
|
|
|
2284
2256
|
return;
|
|
2285
2257
|
}
|
|
2286
2258
|
|
|
2287
|
-
if (!isConstructor && !sideEffectOnly && isLast &&
|
|
2259
|
+
if (!isConstructor && !sideEffectOnly && isLast && h === 'if') {
|
|
2288
2260
|
let [cond, thenB, ...elseB] = stmt.slice(1);
|
|
2289
2261
|
let hasMulti = (b) => this.is(b, 'block') && b.length > 2;
|
|
2290
2262
|
if (hasMulti(thenB) || elseB.some(hasMulti)) {
|
|
@@ -2510,7 +2482,7 @@ export class CodeGenerator {
|
|
|
2510
2482
|
generateIfElseWithEarlyReturns(ifStmt) {
|
|
2511
2483
|
let [head, condition, thenBranch, ...elseBranches] = ifStmt;
|
|
2512
2484
|
let code = '';
|
|
2513
|
-
let condCode =
|
|
2485
|
+
let condCode = this.generate(condition, 'value');
|
|
2514
2486
|
code += this.indent() + `if (${condCode}) {\n`;
|
|
2515
2487
|
code += this.withIndent(() => this.generateBranchWithReturn(thenBranch));
|
|
2516
2488
|
code += this.indent() + '}';
|
|
@@ -2660,7 +2632,7 @@ export class CodeGenerator {
|
|
|
2660
2632
|
if (!generated || generated.endsWith(';')) return false;
|
|
2661
2633
|
if (!generated.endsWith('}')) return true;
|
|
2662
2634
|
let h = Array.isArray(stmt) ? stmt[0] : null;
|
|
2663
|
-
return !['def', 'class', 'if', '
|
|
2635
|
+
return !['def', 'class', 'if', 'for-in', 'for-of', 'for-as', 'while', 'loop', 'switch', 'try'].includes(h);
|
|
2664
2636
|
}
|
|
2665
2637
|
|
|
2666
2638
|
addSemicolon(stmt, generated) { return generated + (this.needsSemicolon(stmt, generated) ? ';' : ''); }
|
|
@@ -2687,7 +2659,7 @@ export class CodeGenerator {
|
|
|
2687
2659
|
return stmts.some(s => Array.isArray(s) && ['return', 'throw', 'break', 'continue'].includes(s[0]));
|
|
2688
2660
|
});
|
|
2689
2661
|
}
|
|
2690
|
-
if (t === 'if'
|
|
2662
|
+
if (t === 'if') {
|
|
2691
2663
|
let [, , thenB, elseB] = body;
|
|
2692
2664
|
return this.branchHasControlFlow(thenB) && elseB && this.branchHasControlFlow(elseB);
|
|
2693
2665
|
}
|
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]];
|