rip-lang 2.8.8 → 2.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/docs/GUIDE.md CHANGED
@@ -86,7 +86,7 @@ count := 0
86
86
  logger ~> console.log count
87
87
 
88
88
  logger.stop! # Pause reactions
89
- logger.run! # Resume reactions
89
+ logger.run! # Resume reactions
90
90
  logger.cancel! # Permanent disposal
91
91
  ```
92
92
 
@@ -443,10 +443,23 @@ status = active ? 'on' : 'off'
443
443
  # CoffeeScript style
444
444
  status = if active then 'on' else 'off'
445
445
 
446
+ # Works with property access, function calls, expressions
447
+ result = valid ? obj.field : null
448
+ output = ready ? compute() : fallback
449
+ value = x > 0 ? x + 1 : 0
450
+
446
451
  # Nested
447
452
  level = score > 90 ? 'A' : score > 80 ? 'B' : score > 70 ? 'C' : 'F'
448
453
  ```
449
454
 
455
+ **Note:** Subscript access in the true branch needs parentheses:
456
+
457
+ ```coffee
458
+ # Wrap subscript in parens
459
+ item = found ? (arr[0]) : default
460
+ value = valid ? (data[key]) : null
461
+ ```
462
+
450
463
  **Why possible:** By using `??` for nullish, `?` became available for ternary.
451
464
 
452
465
  ## Otherwise Operator (`!?`)
@@ -5218,6 +5218,8 @@ ${this.indent()}}`;
5218
5218
  if (Array.isArray(key2) && key2[0] === "dynamicKey") {
5219
5219
  const expr = key2[1];
5220
5220
  keyCode = `[${this.generate(expr, "value")}]`;
5221
+ } else if (Array.isArray(key2) && key2[0] === "str") {
5222
+ keyCode = `[${this.generate(key2, "value")}]`;
5221
5223
  } else {
5222
5224
  keyCode = this.generate(key2, "value");
5223
5225
  }
@@ -7630,8 +7632,8 @@ function compileToJS(source, options = {}) {
7630
7632
  return new Compiler(options).compileToJS(source);
7631
7633
  }
7632
7634
  // src/browser.js
7633
- var VERSION = "2.8.8";
7634
- var BUILD_DATE = "2026-02-04@12:47:34GMT";
7635
+ var VERSION = "2.8.9";
7636
+ var BUILD_DATE = "2026-02-06@03:14:34GMT";
7635
7637
  var dedent = (s) => {
7636
7638
  const m = s.match(/^[ \t]*(?=\S)/gm);
7637
7639
  const i = Math.min(...(m || []).map((x) => x.length));
@@ -96,7 +96,7 @@ ${J.map((K)=>this.indent()+K).join(`
96
96
  ${this.indent()}}`}else D+=`{ const ${Z} = ${M}[${G}]; ${this.generate(F,"statement")}; }`;else if(Y)D+=this.generateLoopBodyWithGuard(F,Y);else D+=this.generateLoopBody(F);return D}generateForFrom($,_,E,X){let R=Array.isArray(_[0])?_[0]:[_[0]],[A]=R,U=_[1],Y=_[2],F=_[3],G=_[4],Z=!1,M=[];if(Array.isArray(A)&&A[0]==="array"){let q=A.slice(1),N=q.findIndex((W)=>Array.isArray(W)&&W[0]==="..."||W==="...");if(N!==-1&&N<q.length-1){Z=!0;let W=q.slice(N+1),z=W.length,H=q.slice(0,N),O=q[N],S=Array.isArray(O)&&O[0]==="..."?O[1]:"_rest",T=H.map((w)=>{if(w===",")return"";if(typeof w==="string")return w;return this.generate(w,"value")}).join(", "),B=T?`${T}, ...${S}`:`...${S}`,L=W.map((w)=>{if(w===",")return"";if(typeof w==="string")return w;return this.generate(w,"value")}).join(", ");M.push(`[${B}] = _item`),M.push(`[${L}] = ${S}.splice(-${z})`),this.helpers.add("slice"),((w)=>{w.slice(1).forEach((P)=>{if(P===","||P==="...")return;if(typeof P==="string")this.programVars.add(P);else if(Array.isArray(P)&&P[0]==="..."){if(typeof P[1]==="string")this.programVars.add(P[1])}})})(A)}}let D=this.generate(U,"value"),Q=Y?"await ":"",J;if(Z)J="_item";else if(Array.isArray(A)&&(A[0]==="array"||A[0]==="object"))J=this.generateDestructuringPattern(A);else J=A;let K=`for ${Q}(const ${J} of ${D}) `;if(Z&&M.length>0){let q=this.unwrapBlock(G),N=this.withIndent(()=>[...M.map((W)=>this.indent()+W+";"),...this.formatStatements(q)]);K+=`{
97
97
  ${N.join(`
98
98
  `)}
99
- ${this.indent()}}`}else if(F)K+=this.generateLoopBodyWithGuard(G,F);else K+=this.generateLoopBody(G);return K}generateWhile($,_,E,X){let R=_[0],A=_.length===3?_[1]:null,U=_[_.length-1],F=`while (${this.unwrap(this.generate(R,"value"))}) `;if(A)F+=this.generateLoopBodyWithGuard(U,A);else F+=this.generateLoopBody(U);return F}generateUntil($,_,E,X){let[R,A]=_,Y=`while (!(${this.unwrap(this.generate(R,"value"))})) `;return Y+=this.generateLoopBody(A),Y}generateRange($,_,E,X){if($==="..."){if(_.length===1){let[D]=_;return`...${this.generate(D,"value")}`}let[F,G]=_,Z=this.generate(F,"value"),M=this.generate(G,"value");return`((s, e) => Array.from({length: Math.max(0, Math.abs(e - s))}, (_, i) => s + (i * (s <= e ? 1 : -1))))(${Z}, ${M})`}let[R,A]=_,U=this.generate(R,"value"),Y=this.generate(A,"value");return`((s, e) => Array.from({length: Math.abs(e - s) + 1}, (_, i) => s + (i * (s <= e ? 1 : -1))))(${U}, ${Y})`}generateNot($,_,E,X){let[R]=_;if(typeof R==="string"||R instanceof String)return`!${this.generate(R,"value")}`;if(Array.isArray(R)){let U=R[0];if([".","?.","::","?::","[]","?[]","optindex","optcall"].includes(U))return`!${this.generate(R,"value")}`}let A=this.generate(R,"value");if(A.startsWith("("))return`!${A}`;return`(!${A})`}generateBitwiseNot($,_,E,X){let[R]=_;return`(~${this.generate(R,"value")})`}generateIncDec($,_,E,X){let[R,A]=_,U=this.generate(R,"value");if(A)return`(${U}${$})`;else return`(${$}${U})`}generateTypeof($,_,E,X){let[R]=_;return`typeof ${this.generate(R,"value")}`}generateDelete($,_,E,X){let[R]=_;return`(delete ${this.generate(R,"value")})`}generateInstanceof($,_,E,X){let[R,A]=_,U=X[0]?.invert,Y=`(${this.generate(R,"value")} instanceof ${this.generate(A,"value")})`;return U?`(!${Y})`:Y}generateIn($,_,E,X){let[R,A]=_,U=this.generate(R,"value"),Y=X[0]?.invert;if(Array.isArray(A)&&A[0]==="object"){let Z=this.generate(A,"value"),M=`(${U} in ${Z})`;return Y?`(!${M})`:M}let F=this.generate(A,"value"),G=`(Array.isArray(${F}) || typeof ${F} === 'string' ? ${F}.includes(${U}) : (${U} in ${F}))`;return Y?`(!${G})`:G}generateOf($,_,E,X){let[R,A]=_,U=this.generate(R,"value"),Y=this.generate(A,"value"),F=X[0]?.invert,G=`(${U} in ${Y})`;return F?`(!${G})`:G}generateRegexMatch($,_,E,X){let[R,A]=_;this.helpers.add("toSearchable"),this.programVars.add("_");let U=this.generate(A,"value"),F=U.includes("/m")?", true":"";return`(_ = toSearchable(${this.generate(R,"value")}${F}).match(${U}))`}generateNew($,_,E,X){let[R]=_;if(Array.isArray(R)&&(R[0]==="."||R[0]==="?.")){let[A,U,Y]=R;if(Array.isArray(U)&&!U[0].startsWith)return`(${this.generate(["new",U],"value")}).${Y}`;return`new ${this.generate(U,"value")}.${Y}`}if(Array.isArray(R)){let[A,...U]=R,Y=this.generate(A,"value"),F=U.map((G)=>this.unwrap(this.generate(G,"value"))).join(", ");return`new ${Y}(${F})`}return`new ${this.generate(R,"value")}()`}generateLogicalAnd($,_,E,X){let A=this.flattenBinaryChain(X).slice(1);if(A.length===0)return"true";if(A.length===1)return this.generate(A[0],"value");return`(${A.map((Y)=>this.generate(Y,"value")).join(" && ")})`}generateLogicalOr($,_,E,X){let A=this.flattenBinaryChain(X).slice(1);if(A.length===0)return"true";if(A.length===1)return this.generate(A[0],"value");return`(${A.map((Y)=>this.generate(Y,"value")).join(" || ")})`}generateArray($,_,E,X){let R=_.length>0&&_[_.length-1]===",",A=_.map((U)=>{if(U===",")return"";if(U==="...")return"";if(Array.isArray(U)&&U[0]==="...")return`...${this.generate(U[1],"value")}`;return this.generate(U,"value")}).join(", ");return R?`[${A},]`:`[${A}]`}generateObject($,_,E,X){if(_.length===1&&Array.isArray(_[0])&&Array.isArray(_[0][1])&&_[0][1][0]==="comprehension"){let[A,U]=_[0],[,Y,F,G]=U;return this.generate(["object-comprehension",A,Y,F,G],E)}return`{${_.map((A)=>{if(Array.isArray(A)&&A[0]==="...")return`...${this.generate(A[1],"value")}`;let[U,Y,F]=A,G;if(Array.isArray(U)&&U[0]==="dynamicKey"){let M=U[1];G=`[${this.generate(M,"value")}]`}else G=this.generate(U,"value");let Z=this.generate(Y,"value");if(F==="=")return`${G} = ${Z}`;else if(F===":")return`${G}: ${Z}`;else{if(G===Z&&!Array.isArray(U))return G;return`${G}: ${Z}`}}).join(", ")}}`}generateBlock($,_,E,X){if(E==="statement")return`{
99
+ ${this.indent()}}`}else if(F)K+=this.generateLoopBodyWithGuard(G,F);else K+=this.generateLoopBody(G);return K}generateWhile($,_,E,X){let R=_[0],A=_.length===3?_[1]:null,U=_[_.length-1],F=`while (${this.unwrap(this.generate(R,"value"))}) `;if(A)F+=this.generateLoopBodyWithGuard(U,A);else F+=this.generateLoopBody(U);return F}generateUntil($,_,E,X){let[R,A]=_,Y=`while (!(${this.unwrap(this.generate(R,"value"))})) `;return Y+=this.generateLoopBody(A),Y}generateRange($,_,E,X){if($==="..."){if(_.length===1){let[D]=_;return`...${this.generate(D,"value")}`}let[F,G]=_,Z=this.generate(F,"value"),M=this.generate(G,"value");return`((s, e) => Array.from({length: Math.max(0, Math.abs(e - s))}, (_, i) => s + (i * (s <= e ? 1 : -1))))(${Z}, ${M})`}let[R,A]=_,U=this.generate(R,"value"),Y=this.generate(A,"value");return`((s, e) => Array.from({length: Math.abs(e - s) + 1}, (_, i) => s + (i * (s <= e ? 1 : -1))))(${U}, ${Y})`}generateNot($,_,E,X){let[R]=_;if(typeof R==="string"||R instanceof String)return`!${this.generate(R,"value")}`;if(Array.isArray(R)){let U=R[0];if([".","?.","::","?::","[]","?[]","optindex","optcall"].includes(U))return`!${this.generate(R,"value")}`}let A=this.generate(R,"value");if(A.startsWith("("))return`!${A}`;return`(!${A})`}generateBitwiseNot($,_,E,X){let[R]=_;return`(~${this.generate(R,"value")})`}generateIncDec($,_,E,X){let[R,A]=_,U=this.generate(R,"value");if(A)return`(${U}${$})`;else return`(${$}${U})`}generateTypeof($,_,E,X){let[R]=_;return`typeof ${this.generate(R,"value")}`}generateDelete($,_,E,X){let[R]=_;return`(delete ${this.generate(R,"value")})`}generateInstanceof($,_,E,X){let[R,A]=_,U=X[0]?.invert,Y=`(${this.generate(R,"value")} instanceof ${this.generate(A,"value")})`;return U?`(!${Y})`:Y}generateIn($,_,E,X){let[R,A]=_,U=this.generate(R,"value"),Y=X[0]?.invert;if(Array.isArray(A)&&A[0]==="object"){let Z=this.generate(A,"value"),M=`(${U} in ${Z})`;return Y?`(!${M})`:M}let F=this.generate(A,"value"),G=`(Array.isArray(${F}) || typeof ${F} === 'string' ? ${F}.includes(${U}) : (${U} in ${F}))`;return Y?`(!${G})`:G}generateOf($,_,E,X){let[R,A]=_,U=this.generate(R,"value"),Y=this.generate(A,"value"),F=X[0]?.invert,G=`(${U} in ${Y})`;return F?`(!${G})`:G}generateRegexMatch($,_,E,X){let[R,A]=_;this.helpers.add("toSearchable"),this.programVars.add("_");let U=this.generate(A,"value"),F=U.includes("/m")?", true":"";return`(_ = toSearchable(${this.generate(R,"value")}${F}).match(${U}))`}generateNew($,_,E,X){let[R]=_;if(Array.isArray(R)&&(R[0]==="."||R[0]==="?.")){let[A,U,Y]=R;if(Array.isArray(U)&&!U[0].startsWith)return`(${this.generate(["new",U],"value")}).${Y}`;return`new ${this.generate(U,"value")}.${Y}`}if(Array.isArray(R)){let[A,...U]=R,Y=this.generate(A,"value"),F=U.map((G)=>this.unwrap(this.generate(G,"value"))).join(", ");return`new ${Y}(${F})`}return`new ${this.generate(R,"value")}()`}generateLogicalAnd($,_,E,X){let A=this.flattenBinaryChain(X).slice(1);if(A.length===0)return"true";if(A.length===1)return this.generate(A[0],"value");return`(${A.map((Y)=>this.generate(Y,"value")).join(" && ")})`}generateLogicalOr($,_,E,X){let A=this.flattenBinaryChain(X).slice(1);if(A.length===0)return"true";if(A.length===1)return this.generate(A[0],"value");return`(${A.map((Y)=>this.generate(Y,"value")).join(" || ")})`}generateArray($,_,E,X){let R=_.length>0&&_[_.length-1]===",",A=_.map((U)=>{if(U===",")return"";if(U==="...")return"";if(Array.isArray(U)&&U[0]==="...")return`...${this.generate(U[1],"value")}`;return this.generate(U,"value")}).join(", ");return R?`[${A},]`:`[${A}]`}generateObject($,_,E,X){if(_.length===1&&Array.isArray(_[0])&&Array.isArray(_[0][1])&&_[0][1][0]==="comprehension"){let[A,U]=_[0],[,Y,F,G]=U;return this.generate(["object-comprehension",A,Y,F,G],E)}return`{${_.map((A)=>{if(Array.isArray(A)&&A[0]==="...")return`...${this.generate(A[1],"value")}`;let[U,Y,F]=A,G;if(Array.isArray(U)&&U[0]==="dynamicKey"){let M=U[1];G=`[${this.generate(M,"value")}]`}else if(Array.isArray(U)&&U[0]==="str")G=`[${this.generate(U,"value")}]`;else G=this.generate(U,"value");let Z=this.generate(Y,"value");if(F==="=")return`${G} = ${Z}`;else if(F===":")return`${G}: ${Z}`;else{if(G===Z&&!Array.isArray(U))return G;return`${G}: ${Z}`}}).join(", ")}}`}generateBlock($,_,E,X){if(E==="statement")return`{
100
100
  ${this.withIndent(()=>this.formatStatements(_)).join(`
101
101
  `)}
102
102
  ${this.indent()}}`;if(_.length===0)return"undefined";if(_.length===1)return this.generate(_[0],E);let R=_[_.length-1];if(Array.isArray(R)&&["break","continue","return","throw"].includes(R[0])){let Y=_.map((F)=>this.addSemicolon(F,this.generate(F,"statement")));return`{
@@ -530,4 +530,4 @@ function __catchErrors(fn) {
530
530
  `),X=E.findIndex((G)=>G==="__DATA__");if(X!==-1){let G=E.slice(X+1);_=G.length>0?G.join(`
531
531
  `)+`
532
532
  `:"",$=E.slice(0,X).join(`
533
- `)}let A=new m1().tokenize($);if(this.options.showTokens)A.forEach((G)=>console.log(`${G[0].padEnd(12)} ${JSON.stringify(G[1])}`)),console.log();$1.lexer={tokens:A,pos:0,setInput:function(){},lex:function(){if(this.pos>=this.tokens.length)return 1;let G=this.tokens[this.pos++];return this.yytext=G[1],this.yylloc=G[2],G[0]}};let U;try{U=$1.parse($)}catch(G){if(/\?\s*\([^)]*\?[^)]*:[^)]*\)\s*:/.test($)||/\?\s+\w+\s+\?\s+/.test($))throw Error("Nested ternary operators are not supported. Use if/else statements instead.");throw G}if(this.options.showSExpr)console.log(o(U,0,!0)),console.log();let Y=new c({dataSection:_,skipReactiveRuntime:this.options.skipReactiveRuntime,reactiveVars:this.options.reactiveVars}),F=Y.compile(U);return{tokens:A,sexpr:U,code:F,data:_,reactiveVars:Y.reactiveVars}}compileToJS($){return this.compile($).code}compileToSExpr($){return this.compile($).sexpr}}function U3($,_={}){return new O1(_).compile($)}function S1($,_={}){return new O1(_).compileToJS($)}var Q3="2.8.8",W3="2026-02-04@12:47:34GMT",$3=($)=>{let _=$.match(/^[ \t]*(?=\S)/gm),E=Math.min(...(_||[]).map((X)=>X.length));return $.replace(RegExp(`^[ ]{${E}}`,"gm"),"").trim()};async function k2(){let $=document.querySelectorAll('script[type="text/rip"]');for(let _ of $){if(_.hasAttribute("data-rip-processed"))continue;try{let E=$3(_.textContent),X=S1(E);(0,eval)(X),_.setAttribute("data-rip-processed","true")}catch(E){console.error("Error compiling Rip script:",E),console.error("Script content:",_.textContent)}}}if(typeof document<"u")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",k2);else k2();function X3($){try{let E=S1($).replace(/^let\s+[^;]+;\s*\n\s*/m,"");E=E.replace(/^const\s+/gm,"var ");let X=(0,eval)(E);if(X!==void 0)globalThis._=X;return X}catch(_){console.error("Rip compilation error:",_.message);return}}if(typeof globalThis<"u")globalThis.rip=X3;export{X3 as rip,k2 as processRipScripts,$1 as parser,o as formatSExpr,S1 as compileToJS,U3 as compile,Q3 as VERSION,m1 as Lexer,O1 as Compiler,c as CodeGenerator,W3 as BUILD_DATE};
533
+ `)}let A=new m1().tokenize($);if(this.options.showTokens)A.forEach((G)=>console.log(`${G[0].padEnd(12)} ${JSON.stringify(G[1])}`)),console.log();$1.lexer={tokens:A,pos:0,setInput:function(){},lex:function(){if(this.pos>=this.tokens.length)return 1;let G=this.tokens[this.pos++];return this.yytext=G[1],this.yylloc=G[2],G[0]}};let U;try{U=$1.parse($)}catch(G){if(/\?\s*\([^)]*\?[^)]*:[^)]*\)\s*:/.test($)||/\?\s+\w+\s+\?\s+/.test($))throw Error("Nested ternary operators are not supported. Use if/else statements instead.");throw G}if(this.options.showSExpr)console.log(o(U,0,!0)),console.log();let Y=new c({dataSection:_,skipReactiveRuntime:this.options.skipReactiveRuntime,reactiveVars:this.options.reactiveVars}),F=Y.compile(U);return{tokens:A,sexpr:U,code:F,data:_,reactiveVars:Y.reactiveVars}}compileToJS($){return this.compile($).code}compileToSExpr($){return this.compile($).sexpr}}function U3($,_={}){return new O1(_).compile($)}function S1($,_={}){return new O1(_).compileToJS($)}var Q3="2.8.9",W3="2026-02-06@03:14:34GMT",$3=($)=>{let _=$.match(/^[ \t]*(?=\S)/gm),E=Math.min(...(_||[]).map((X)=>X.length));return $.replace(RegExp(`^[ ]{${E}}`,"gm"),"").trim()};async function k2(){let $=document.querySelectorAll('script[type="text/rip"]');for(let _ of $){if(_.hasAttribute("data-rip-processed"))continue;try{let E=$3(_.textContent),X=S1(E);(0,eval)(X),_.setAttribute("data-rip-processed","true")}catch(E){console.error("Error compiling Rip script:",E),console.error("Script content:",_.textContent)}}}if(typeof document<"u")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",k2);else k2();function X3($){try{let E=S1($).replace(/^let\s+[^;]+;\s*\n\s*/m,"");E=E.replace(/^const\s+/gm,"var ");let X=(0,eval)(E);if(X!==void 0)globalThis._=X;return X}catch(_){console.error("Rip compilation error:",_.message);return}}if(typeof globalThis<"u")globalThis.rip=X3;export{X3 as rip,k2 as processRipScripts,$1 as parser,o as formatSExpr,S1 as compileToJS,U3 as compile,Q3 as VERSION,m1 as Lexer,O1 as Compiler,c as CodeGenerator,W3 as BUILD_DATE};
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rip-lang",
3
- "version": "2.8.8",
3
+ "version": "2.8.9",
4
4
  "description": "A modern language that compiles to JavaScript",
5
5
  "type": "module",
6
6
  "main": "src/compiler.js",
package/src/compiler.js CHANGED
@@ -2587,12 +2587,15 @@ export class CodeGenerator {
2587
2587
  // All regular pairs now have format: [key, value, operator]
2588
2588
  const [key, value, operator] = pair;
2589
2589
 
2590
- // Check if key is dynamic: ["dynamicKey", expression]
2590
+ // Check if key is dynamic: ["dynamicKey", expression] or interpolated: ["str", ...]
2591
2591
  let keyCode;
2592
2592
  if (Array.isArray(key) && key[0] === 'dynamicKey') {
2593
2593
  // Dynamic property key: [expr] syntax
2594
2594
  const expr = key[1];
2595
2595
  keyCode = `[${this.generate(expr, 'value')}]`;
2596
+ } else if (Array.isArray(key) && key[0] === 'str') {
2597
+ // Interpolated string as key: {"#{x}": v} → {[`${x}`]: v}
2598
+ keyCode = `[${this.generate(key, 'value')}]`;
2596
2599
  } else {
2597
2600
  // Regular key (string or identifier)
2598
2601
  keyCode = this.generate(key, 'value');