rip-lang 2.8.0 → 2.8.2

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/README.md CHANGED
@@ -9,9 +9,9 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-2.8.0-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-2.8.2-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
- <a href="#"><img src="https://img.shields.io/badge/tests-979%2F979-brightgreen.svg" alt="Tests"></a>
14
+ <a href="#"><img src="https://img.shields.io/badge/tests-1021%2F1021-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
16
16
  </p>
17
17
 
@@ -231,6 +231,28 @@ bun add @rip-lang/api @rip-lang/server
231
231
 
232
232
  ---
233
233
 
234
+ ## Implicit Commas
235
+
236
+ Rip rescues what would be invalid syntax and gives it elegant meaning. When a literal value is followed directly by an arrow function, Rip inserts the comma for you:
237
+
238
+ ```coffee
239
+ # Clean route handlers (no comma needed!)
240
+ get '/users' -> User.all!
241
+ get '/users/:id' -> User.find params.id
242
+ post '/users' -> User.create body
243
+
244
+ # Works with all literal types
245
+ handle 404 -> { error: 'Not found' }
246
+ match /^\/api/ -> { version: 'v1' }
247
+ check true -> enable()
248
+ ```
249
+
250
+ This works because `'/users' ->` was previously a syntax error — there's no valid interpretation. Rip detects this pattern and transforms it into `'/users', ->`, giving dead syntax a beautiful new life.
251
+
252
+ **Supported literals:** strings, numbers, regex, booleans, null, undefined, arrays, objects
253
+
254
+ ---
255
+
234
256
  ## Quick Reference
235
257
 
236
258
  ```bash
@@ -239,7 +261,7 @@ rip file.rip # Run
239
261
  rip -c file.rip # Compile
240
262
  rip -t file.rip # Tokens
241
263
  rip -s file.rip # S-expressions
242
- bun run test # 979 tests
264
+ bun run test # 1021 tests
243
265
  bun run parser # Rebuild parser
244
266
  bun run browser # Build browser bundle
245
267
  ```
@@ -23,6 +23,7 @@ var HEREGEX_COMMENT;
23
23
  var HERE_JSTOKEN;
24
24
  var IDENTIFIER;
25
25
  var IMPLICIT_CALL;
26
+ var IMPLICIT_COMMA_BEFORE_ARROW;
26
27
  var IMPLICIT_END;
27
28
  var IMPLICIT_FUNC;
28
29
  var IMPLICIT_UNSPACED_CALL;
@@ -2029,7 +2030,7 @@ Rewriter = function() {
2029
2030
  });
2030
2031
  return isFunc;
2031
2032
  };
2032
- if ((indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced || tag === "?" && i > 0 && !tokens[i - 1].spaced) && (indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || nextTag === "..." && (ref = this.tag(i + 2), indexOf.call(IMPLICIT_CALL, ref) >= 0) && !this.findTagsBackwards(i, ["INDEX_START", "["]) || indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !nextToken.spaced && !nextToken.newLine) && !inControlFlow()) {
2033
+ if ((indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced || tag === "?" && i > 0 && !tokens[i - 1].spaced) && (indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || nextTag === "..." && (ref = this.tag(i + 2), indexOf.call(IMPLICIT_CALL, ref) >= 0) && !this.findTagsBackwards(i, ["INDEX_START", "["]) || indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !nextToken.spaced && !nextToken.newLine) && !inControlFlow() && !((tag === "]" || tag === "}") && (nextTag === "->" || nextTag === "=>"))) {
2033
2034
  if (tag === "?") {
2034
2035
  tag = token[0] = "FUNC_EXIST";
2035
2036
  }
@@ -2125,7 +2126,7 @@ Rewriter = function() {
2125
2126
  });
2126
2127
  }
2127
2128
  addImplicitCallCommas() {
2128
- var callDepth, i, prevTag, tag, tokens;
2129
+ var callDepth, i, prevTag, ref, tag, tokens;
2129
2130
  tokens = this.tokens;
2130
2131
  callDepth = 0;
2131
2132
  i = 0;
@@ -2137,7 +2138,7 @@ Rewriter = function() {
2137
2138
  } else if (tag === "CALL_END" || tag === ")") {
2138
2139
  callDepth--;
2139
2140
  }
2140
- if (callDepth > 0 && (tag === "->" || tag === "=>") && (prevTag === "STRING" || prevTag === "STRING_END")) {
2141
+ if (callDepth > 0 && (tag === "->" || tag === "=>") && (ref = prevTag, indexOf.call(IMPLICIT_COMMA_BEFORE_ARROW, ref) >= 0)) {
2141
2142
  tokens.splice(i, 0, generate(",", ",", tokens[i], tokens[i - 1]));
2142
2143
  i++;
2143
2144
  }
@@ -2623,7 +2624,8 @@ EXPRESSION_CLOSE = ["CATCH", "THEN", "ELSE", "FINALLY"].concat(EXPRESSION_END);
2623
2624
  IMPLICIT_FUNC = ["IDENTIFIER", "PROPERTY", "SUPER", ")", "CALL_END", "]", "INDEX_END", "@", "THIS"];
2624
2625
  IMPLICIT_CALL = ["IDENTIFIER", "PROPERTY", "NUMBER", "INFINITY", "NAN", "STRING", "STRING_START", "REGEX", "REGEX_START", "JS", "NEW", "PARAM_START", "CLASS", "IF", "TRY", "SWITCH", "THIS", "DYNAMIC_IMPORT", "IMPORT_META", "NEW_TARGET", "UNDEFINED", "NULL", "BOOL", "UNARY", "DO", "DO_IIFE", "YIELD", "AWAIT", "UNARY_MATH", "SUPER", "THROW", "@", "->", "=>", "[", "(", "{", "--", "++"];
2625
2626
  IMPLICIT_UNSPACED_CALL = ["+", "-"];
2626
- IMPLICIT_END = ["POST_IF", "FOR", "WHILE", "UNTIL", "WHEN", "BY", "LOOP", "TERMINATOR"];
2627
+ IMPLICIT_END = ["POST_IF", "FOR", "WHILE", "UNTIL", "WHEN", "BY", "LOOP", "TERMINATOR", "||", "&&"];
2628
+ IMPLICIT_COMMA_BEFORE_ARROW = ["STRING", "STRING_END", "REGEX", "REGEX_END", "NUMBER", "BOOL", "NULL", "UNDEFINED", "INFINITY", "NAN", "]", "}"];
2627
2629
  SINGLE_LINERS = ["ELSE", "->", "=>", "TRY", "FINALLY", "THEN"];
2628
2630
  SINGLE_CLOSERS = ["TERMINATOR", "CATCH", "FINALLY", "ELSE", "OUTDENT", "LEADING_WHEN"];
2629
2631
  LINEBREAKS = ["TERMINATOR", "INDENT", "OUTDENT"];
@@ -4646,27 +4648,27 @@ ${this.indent()}}`;
4646
4648
  }
4647
4649
  if (step && step !== null) {
4648
4650
  const iterableCode = this.generate(iterable, "value");
4649
- const indexVarName2 = indexVar || "_i";
4651
+ const indexVarName = indexVar || "_i";
4650
4652
  const stepCode = this.generate(step, "value");
4651
4653
  const isNegativeStep = this.isNegativeStep(step);
4652
4654
  const isMinusOne = isNegativeStep && (step[1] === "1" || step[1] === 1 || step[1] instanceof String && step[1].valueOf() === "1");
4653
4655
  const isPlusOne = !isNegativeStep && (step === "1" || step === 1 || step instanceof String && step.valueOf() === "1");
4654
4656
  let loopHeader;
4655
4657
  if (isMinusOne) {
4656
- loopHeader = `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2}--) `;
4658
+ loopHeader = `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName}--) `;
4657
4659
  } else if (isPlusOne) {
4658
- loopHeader = `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2}++) `;
4660
+ loopHeader = `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName}++) `;
4659
4661
  } else if (isNegativeStep) {
4660
- loopHeader = `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2} += ${stepCode}) `;
4662
+ loopHeader = `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName} += ${stepCode}) `;
4661
4663
  } else {
4662
- loopHeader = `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2} += ${stepCode}) `;
4664
+ loopHeader = `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName} += ${stepCode}) `;
4663
4665
  }
4664
4666
  if (Array.isArray(body) && body[0] === "block") {
4665
4667
  const statements = body.slice(1);
4666
4668
  this.indentLevel++;
4667
4669
  const stmts = [];
4668
4670
  if (!noVar) {
4669
- stmts.push(`const ${itemVarPattern} = ${iterableCode}[${indexVarName2}];`);
4671
+ stmts.push(`const ${itemVarPattern} = ${iterableCode}[${indexVarName}];`);
4670
4672
  }
4671
4673
  if (guard) {
4672
4674
  const guardCode = this.generate(guard, "value");
@@ -4694,9 +4696,9 @@ ${this.indent()}}`;
4694
4696
  } else {
4695
4697
  if (guard) {
4696
4698
  const guardCode = this.generate(guard, "value");
4697
- return loopHeader + `{ const ${itemVarPattern} = ${iterableCode}[${indexVarName2}]; if (${guardCode}) ${this.generate(body, "statement")}; }`;
4699
+ return loopHeader + `{ const ${itemVarPattern} = ${iterableCode}[${indexVarName}]; if (${guardCode}) ${this.generate(body, "statement")}; }`;
4698
4700
  } else {
4699
- return loopHeader + `{ const ${itemVarPattern} = ${iterableCode}[${indexVarName2}]; ${this.generate(body, "statement")}; }`;
4701
+ return loopHeader + `{ const ${itemVarPattern} = ${iterableCode}[${indexVarName}]; ${this.generate(body, "statement")}; }`;
4700
4702
  }
4701
4703
  }
4702
4704
  }
@@ -5364,19 +5366,19 @@ ${this.indent()}}`;
5364
5366
  this.indentLevel++;
5365
5367
  } else {
5366
5368
  const iterableCode = this.generate(iterable, "value");
5367
- const indexVarName2 = indexVar || "_i";
5369
+ const indexVarName = indexVar || "_i";
5368
5370
  const stepCode = this.generate(step, "value");
5369
5371
  const isNegativeStep = this.isNegativeStep(step);
5370
5372
  if (isNegativeStep) {
5371
- code += this.indent() + `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2} += ${stepCode}) {
5373
+ code += this.indent() + `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName} += ${stepCode}) {
5372
5374
  `;
5373
5375
  } else {
5374
- code += this.indent() + `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2} += ${stepCode}) {
5376
+ code += this.indent() + `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName} += ${stepCode}) {
5375
5377
  `;
5376
5378
  }
5377
5379
  this.indentLevel++;
5378
5380
  if (!noVar) {
5379
- code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName2}];
5381
+ code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName}];
5380
5382
  `;
5381
5383
  }
5382
5384
  }
@@ -6572,19 +6574,19 @@ ${this.indent()}}`;
6572
6574
  `;
6573
6575
  } else {
6574
6576
  const iterableCode = this.generate(iterable, "value");
6575
- const indexVarName2 = indexVar || "_i";
6577
+ const indexVarName = indexVar || "_i";
6576
6578
  const stepCode = this.generate(step, "value");
6577
6579
  const isNegativeStep = this.isNegativeStep(step);
6578
6580
  if (isNegativeStep) {
6579
- code += this.indent() + `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2} += ${stepCode}) {
6581
+ code += this.indent() + `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName} += ${stepCode}) {
6580
6582
  `;
6581
6583
  } else {
6582
- code += this.indent() + `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2} += ${stepCode}) {
6584
+ code += this.indent() + `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName} += ${stepCode}) {
6583
6585
  `;
6584
6586
  }
6585
6587
  this.indentLevel++;
6586
6588
  if (!noVar) {
6587
- code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName2}];
6589
+ code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName}];
6588
6590
  `;
6589
6591
  }
6590
6592
  }
@@ -6648,25 +6650,25 @@ ${this.indent()}}`;
6648
6650
  code += `for (let ${itemVarPattern} = ${startCode}; ${itemVarPattern} ${comparison} ${endCode}; ${itemVarPattern} += ${stepCode}) `;
6649
6651
  } else {
6650
6652
  const iterableCode = this.generate(iterable, "value");
6651
- const indexVarName2 = indexVar || "_i";
6653
+ const indexVarName = indexVar || "_i";
6652
6654
  const stepCode = this.generate(step, "value");
6653
6655
  const isNegativeStep = this.isNegativeStep(step);
6654
6656
  const isMinusOne = isNegativeStep && (step[1] === "1" || step[1] === 1 || step[1] instanceof String && step[1].valueOf() === "1");
6655
6657
  const isPlusOne = !isNegativeStep && (step === "1" || step === 1 || step instanceof String && step.valueOf() === "1");
6656
6658
  if (isMinusOne) {
6657
- code += `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2}--) `;
6659
+ code += `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName}--) `;
6658
6660
  } else if (isPlusOne) {
6659
- code += `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2}++) `;
6661
+ code += `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName}++) `;
6660
6662
  } else if (isNegativeStep) {
6661
- code += `for (let ${indexVarName2} = ${iterableCode}.length - 1; ${indexVarName2} >= 0; ${indexVarName2} += ${stepCode}) `;
6663
+ code += `for (let ${indexVarName} = ${iterableCode}.length - 1; ${indexVarName} >= 0; ${indexVarName} += ${stepCode}) `;
6662
6664
  } else {
6663
- code += `for (let ${indexVarName2} = 0; ${indexVarName2} < ${iterableCode}.length; ${indexVarName2} += ${stepCode}) `;
6665
+ code += `for (let ${indexVarName} = 0; ${indexVarName} < ${iterableCode}.length; ${indexVarName} += ${stepCode}) `;
6664
6666
  }
6665
6667
  code += `{
6666
6668
  `;
6667
6669
  this.indentLevel++;
6668
6670
  if (!noVar) {
6669
- code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName2}];
6671
+ code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName}];
6670
6672
  `;
6671
6673
  }
6672
6674
  }
@@ -6709,7 +6711,7 @@ ${this.indent()}}`;
6709
6711
  code += `{
6710
6712
  `;
6711
6713
  this.indentLevel++;
6712
- code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVarName}];
6714
+ code += this.indent() + `const ${itemVarPattern} = ${iterableCode}[${indexVar}];
6713
6715
  `;
6714
6716
  } else {
6715
6717
  code += `for (const ${itemVarPattern} of ${this.generate(iterable, "value")}) `;
@@ -7509,8 +7511,8 @@ function compileToJS(source, options = {}) {
7509
7511
  return new Compiler(options).compileToJS(source);
7510
7512
  }
7511
7513
  // src/browser.js
7512
- var VERSION = "2.8.0";
7513
- var BUILD_DATE = "2026-02-04@03:22:39GMT";
7514
+ var VERSION = "2.8.2";
7515
+ var BUILD_DATE = "2026-02-04@07:57:52GMT";
7514
7516
  var dedent = (s) => {
7515
7517
  const m = s.match(/^[ \t]*(?=\S)/gm);
7516
7518
  const i = Math.min(...(m || []).map((x) => x.length));