rip-lang 2.8.2 → 2.8.4
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 +1 -1
- package/bin/rip +8 -4
- package/docs/dist/rip.browser.js +74 -26
- package/docs/dist/rip.browser.min.js +235 -232
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/package.json +1 -1
- package/src/compiler.js +40 -18
- package/src/grammar/grammar.rip +6 -6
- package/src/lexer.js +32 -2
- package/src/parser.js +5 -6
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
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.
|
|
12
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-2.8.4-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
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>
|
package/bin/rip
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync, statSync } from 'fs';
|
|
4
4
|
import { execSync, spawn } from 'child_process';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname, join } from 'path';
|
|
@@ -183,9 +183,13 @@ async function main() {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
// Helper to check if path is a regular file (not a directory)
|
|
187
|
+
const isFile = (path) => existsSync(path) && statSync(path).isFile();
|
|
188
|
+
|
|
186
189
|
// Fallback: Check for bin/ script in git repo root
|
|
187
190
|
// Allows `rip migrate --status` to find and run {repo}/bin/migrate
|
|
188
|
-
if
|
|
191
|
+
// Also triggers if inputFile is a directory (not a compilable file)
|
|
192
|
+
if (inputFile && !inputFile.startsWith('-') && !isFile(inputFile)) {
|
|
189
193
|
try {
|
|
190
194
|
// Check if we're in a git repo
|
|
191
195
|
const repoRoot = execSync('git rev-parse --show-toplevel', {
|
|
@@ -220,8 +224,8 @@ async function main() {
|
|
|
220
224
|
// Read from stdin if no file specified (file descriptor 0)
|
|
221
225
|
source = readFileSync(0, 'utf-8');
|
|
222
226
|
} else {
|
|
223
|
-
// Check if file exists
|
|
224
|
-
if (!
|
|
227
|
+
// Check if file exists and is a regular file
|
|
228
|
+
if (!isFile(inputFile)) {
|
|
225
229
|
console.error(`Error: File not found: ${inputFile}`);
|
|
226
230
|
process.exit(1);
|
|
227
231
|
}
|
package/docs/dist/rip.browser.js
CHANGED
|
@@ -1946,16 +1946,16 @@ Rewriter = function() {
|
|
|
1946
1946
|
val.generated = true;
|
|
1947
1947
|
return tokens.splice(idx, 0, generate("{", val, token, prevToken));
|
|
1948
1948
|
};
|
|
1949
|
-
endImplicitObject = function(
|
|
1950
|
-
|
|
1949
|
+
endImplicitObject = function(j2) {
|
|
1950
|
+
j2 = j2 != null ? j2 : i;
|
|
1951
1951
|
stack.pop();
|
|
1952
|
-
tokens.splice(
|
|
1952
|
+
tokens.splice(j2, 0, generate("}", "}", token, prevToken));
|
|
1953
1953
|
return i += 1;
|
|
1954
1954
|
};
|
|
1955
|
-
implicitObjectContinues = (
|
|
1955
|
+
implicitObjectContinues = (j2) => {
|
|
1956
1956
|
var nextTerminatorIdx;
|
|
1957
1957
|
nextTerminatorIdx = null;
|
|
1958
|
-
this.detectEnd(
|
|
1958
|
+
this.detectEnd(j2, function(token2) {
|
|
1959
1959
|
return token2[0] === "TERMINATOR";
|
|
1960
1960
|
}, function(token2, i2) {
|
|
1961
1961
|
return nextTerminatorIdx = i2;
|
|
@@ -2100,12 +2100,35 @@ Rewriter = function() {
|
|
|
2100
2100
|
}
|
|
2101
2101
|
}
|
|
2102
2102
|
newLine = prevTag === "OUTDENT" || prevToken.newLine;
|
|
2103
|
-
|
|
2103
|
+
var isLogicalOp = tag === "||" || tag === "&&";
|
|
2104
|
+
var logicalOpHasMoreArgs = false;
|
|
2105
|
+
if (isLogicalOp && i + 1 < tokens.length) {
|
|
2106
|
+
var nextTok = tokens[i + 1][0];
|
|
2107
|
+
var j = i + 1;
|
|
2108
|
+
if (nextTok === "(" || nextTok === "[" || nextTok === "{") {
|
|
2109
|
+
var depth = 1;
|
|
2110
|
+
j++;
|
|
2111
|
+
while (j < tokens.length && depth > 0) {
|
|
2112
|
+
var lt = tokens[j][0];
|
|
2113
|
+
if (lt === "(" || lt === "[" || lt === "{")
|
|
2114
|
+
depth++;
|
|
2115
|
+
else if (lt === ")" || lt === "]" || lt === "}")
|
|
2116
|
+
depth--;
|
|
2117
|
+
j++;
|
|
2118
|
+
}
|
|
2119
|
+
} else if (nextTok !== "TERMINATOR" && nextTok !== "OUTDENT" && nextTok !== ",") {
|
|
2120
|
+
j++;
|
|
2121
|
+
}
|
|
2122
|
+
if (j < tokens.length && tokens[j][0] === ",") {
|
|
2123
|
+
logicalOpHasMoreArgs = true;
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
if (indexOf.call(IMPLICIT_END, tag) >= 0 && !(isLogicalOp && logicalOpHasMoreArgs) || indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine || (tag === ".." || tag === "...") && this.findTagsBackwards(i, ["INDEX_START"])) {
|
|
2104
2127
|
while (inImplicit()) {
|
|
2105
2128
|
[stackTag, stackIdx, { sameLine, startsLine }] = stackTop();
|
|
2106
2129
|
if (inImplicitCall() && prevTag !== "," || prevTag === "," && tag === "TERMINATOR" && nextTag == null) {
|
|
2107
2130
|
endImplicitCall();
|
|
2108
|
-
} else if (inImplicitObject() && sameLine && tag !== "TERMINATOR" && prevTag !== ":" && !((tag === "POST_IF" || tag === "FOR" || tag === "WHILE" || tag === "UNTIL") && startsLine && implicitObjectContinues(i + 1))) {
|
|
2131
|
+
} else if (inImplicitObject() && !isLogicalOp && sameLine && tag !== "TERMINATOR" && prevTag !== ":" && !((tag === "POST_IF" || tag === "FOR" || tag === "WHILE" || tag === "UNTIL") && startsLine && implicitObjectContinues(i + 1))) {
|
|
2109
2132
|
endImplicitObject();
|
|
2110
2133
|
} else if (inImplicitObject() && tag === "TERMINATOR" && prevTag !== "," && !(startsLine && this.looksObjectish(i + 1))) {
|
|
2111
2134
|
endImplicitObject();
|
|
@@ -2670,6 +2693,7 @@ var parserInstance = {
|
|
|
2670
2693
|
case 267:
|
|
2671
2694
|
case 281:
|
|
2672
2695
|
case 285:
|
|
2696
|
+
case 289:
|
|
2673
2697
|
case 344:
|
|
2674
2698
|
case 350:
|
|
2675
2699
|
return [$[$0]];
|
|
@@ -2679,6 +2703,7 @@ var parserInstance = {
|
|
|
2679
2703
|
case 213:
|
|
2680
2704
|
case 236:
|
|
2681
2705
|
case 268:
|
|
2706
|
+
case 290:
|
|
2682
2707
|
return [...$[$0 - 2], $[$0]];
|
|
2683
2708
|
case 5:
|
|
2684
2709
|
case 63:
|
|
@@ -2766,7 +2791,6 @@ var parserInstance = {
|
|
|
2766
2791
|
case 273:
|
|
2767
2792
|
case 274:
|
|
2768
2793
|
case 276:
|
|
2769
|
-
case 289:
|
|
2770
2794
|
case 309:
|
|
2771
2795
|
case 342:
|
|
2772
2796
|
case 358:
|
|
@@ -3093,8 +3117,6 @@ var parserInstance = {
|
|
|
3093
3117
|
return [...$[$0 - 5], ...$[$0 - 4], ...$[$0 - 2], ...$[$0 - 1]];
|
|
3094
3118
|
case 284:
|
|
3095
3119
|
return [...$[$0]];
|
|
3096
|
-
case 290:
|
|
3097
|
-
return Array.isArray($[$0 - 2]) ? [...$[$0 - 2], $[$0]] : [$[$0 - 2], $[$0]];
|
|
3098
3120
|
case 291:
|
|
3099
3121
|
return ["try", $[$0]];
|
|
3100
3122
|
case 292:
|
|
@@ -3116,9 +3138,9 @@ var parserInstance = {
|
|
|
3116
3138
|
case 299:
|
|
3117
3139
|
return ["throw", $[$0 - 1]];
|
|
3118
3140
|
case 300:
|
|
3119
|
-
return $[$0 - 1].length === 1 ? $[$0 - 1][0] :
|
|
3141
|
+
return $[$0 - 1].length === 1 ? $[$0 - 1][0] : ["block", ...$[$0 - 1]];
|
|
3120
3142
|
case 301:
|
|
3121
|
-
return $[$0 - 2].length === 1 ? $[$0 - 2][0] :
|
|
3143
|
+
return $[$0 - 2].length === 1 ? $[$0 - 2][0] : ["block", ...$[$0 - 2]];
|
|
3122
3144
|
case 302:
|
|
3123
3145
|
return ["while", $[$0]];
|
|
3124
3146
|
case 303:
|
|
@@ -5182,7 +5204,21 @@ ${stmts.join(`
|
|
|
5182
5204
|
`)}
|
|
5183
5205
|
${this.indent()}}`;
|
|
5184
5206
|
}
|
|
5185
|
-
|
|
5207
|
+
if (statements.length === 0)
|
|
5208
|
+
return "undefined";
|
|
5209
|
+
if (statements.length === 1)
|
|
5210
|
+
return this.generate(statements[0], context);
|
|
5211
|
+
const last = statements[statements.length - 1];
|
|
5212
|
+
const lastIsControl = Array.isArray(last) && ["break", "continue", "return", "throw"].includes(last[0]);
|
|
5213
|
+
if (lastIsControl) {
|
|
5214
|
+
const bodyParts = statements.map((s) => this.addSemicolon(s, this.generate(s, "statement")));
|
|
5215
|
+
return `{
|
|
5216
|
+
${this.withIndent(() => bodyParts.map((p) => this.indent() + p).join(`
|
|
5217
|
+
`))}
|
|
5218
|
+
${this.indent()}}`;
|
|
5219
|
+
}
|
|
5220
|
+
const parts = statements.map((s) => this.generate(s, "value"));
|
|
5221
|
+
return `(${parts.join(", ")})`;
|
|
5186
5222
|
}
|
|
5187
5223
|
generateTry(head, rest, context, sexpr) {
|
|
5188
5224
|
const needsReturns = context === "value";
|
|
@@ -5281,9 +5317,7 @@ ${this.indent()}}`;
|
|
|
5281
5317
|
const normalize = (v) => v instanceof String ? v.valueOf() : v;
|
|
5282
5318
|
for (const whenClause of whens) {
|
|
5283
5319
|
const [, test, body] = whenClause;
|
|
5284
|
-
const
|
|
5285
|
-
const isTestList = Array.isArray(test) && test.length > 0 && typeof firstTest === "string" && !firstTest.match(/^[-+*\/%<>=!&|^~]$|^(typeof|delete|new|not|await|yield)$/);
|
|
5286
|
-
const tests = isTestList ? test : [test];
|
|
5320
|
+
const tests = test;
|
|
5287
5321
|
for (const t of tests) {
|
|
5288
5322
|
const tValue = normalize(t);
|
|
5289
5323
|
let caseValue;
|
|
@@ -6887,18 +6921,31 @@ ${this.indent()}}`;
|
|
|
6887
6921
|
if (typeof code !== "string")
|
|
6888
6922
|
return code;
|
|
6889
6923
|
while (code.startsWith("(") && code.endsWith(")")) {
|
|
6890
|
-
let
|
|
6924
|
+
let parenDepth = 0;
|
|
6925
|
+
let bracketDepth = 0;
|
|
6891
6926
|
let canUnwrap = true;
|
|
6927
|
+
let hasCommaAtDepth1 = false;
|
|
6892
6928
|
for (let i = 0;i < code.length; i++) {
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6929
|
+
const ch = code[i];
|
|
6930
|
+
if (ch === "(")
|
|
6931
|
+
parenDepth++;
|
|
6932
|
+
if (ch === ")")
|
|
6933
|
+
parenDepth--;
|
|
6934
|
+
if (ch === "[" || ch === "{")
|
|
6935
|
+
bracketDepth++;
|
|
6936
|
+
if (ch === "]" || ch === "}")
|
|
6937
|
+
bracketDepth--;
|
|
6938
|
+
if (ch === "," && parenDepth === 1 && bracketDepth === 0) {
|
|
6939
|
+
hasCommaAtDepth1 = true;
|
|
6940
|
+
}
|
|
6941
|
+
if (parenDepth === 0 && i < code.length - 1) {
|
|
6898
6942
|
canUnwrap = false;
|
|
6899
6943
|
break;
|
|
6900
6944
|
}
|
|
6901
6945
|
}
|
|
6946
|
+
if (hasCommaAtDepth1) {
|
|
6947
|
+
canUnwrap = false;
|
|
6948
|
+
}
|
|
6902
6949
|
if (canUnwrap) {
|
|
6903
6950
|
code = code.slice(1, -1);
|
|
6904
6951
|
} else {
|
|
@@ -7124,11 +7171,12 @@ ${this.indent()}}`;
|
|
|
7124
7171
|
for (let i = 0;i < whens.length; i++) {
|
|
7125
7172
|
const whenClause = whens[i];
|
|
7126
7173
|
const [, test, body] = whenClause;
|
|
7174
|
+
const condition = Array.isArray(test) ? test[0] : test;
|
|
7127
7175
|
if (i === 0) {
|
|
7128
|
-
code += `if (${this.generate(
|
|
7176
|
+
code += `if (${this.generate(condition, "value")}) {
|
|
7129
7177
|
`;
|
|
7130
7178
|
} else {
|
|
7131
|
-
code += ` else if (${this.generate(
|
|
7179
|
+
code += ` else if (${this.generate(condition, "value")}) {
|
|
7132
7180
|
`;
|
|
7133
7181
|
}
|
|
7134
7182
|
this.indentLevel++;
|
|
@@ -7511,8 +7559,8 @@ function compileToJS(source, options = {}) {
|
|
|
7511
7559
|
return new Compiler(options).compileToJS(source);
|
|
7512
7560
|
}
|
|
7513
7561
|
// src/browser.js
|
|
7514
|
-
var VERSION = "2.8.
|
|
7515
|
-
var BUILD_DATE = "2026-02-04@
|
|
7562
|
+
var VERSION = "2.8.4";
|
|
7563
|
+
var BUILD_DATE = "2026-02-04@10:18:01GMT";
|
|
7516
7564
|
var dedent = (s) => {
|
|
7517
7565
|
const m = s.match(/^[ \t]*(?=\S)/gm);
|
|
7518
7566
|
const i = Math.min(...(m || []).map((x) => x.length));
|