rip-lang 1.2.2 → 1.3.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 +14 -3
- package/bin/rip +33 -19
- package/docs/dist/rip.browser.js +72 -59
- package/docs/dist/rip.browser.min.js +6 -6
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/package.json +2 -2
- package/src/codegen.js +15 -0
- package/src/grammar/grammar.rip +8 -2
- package/src/grammar/solar.rip +100 -71
- package/src/lexer.js +2 -1
- package/src/parser.js +215 -215
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-1.
|
|
12
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-1.3.0-blue.svg" alt="Version"></a>
|
|
13
13
|
<a href="#es2022-target"><img src="https://img.shields.io/badge/target-ES2022-blue.svg" alt="Target"></a>
|
|
14
|
-
<a href="#current-status"><img src="https://img.shields.io/badge/tests-
|
|
14
|
+
<a href="#current-status"><img src="https://img.shields.io/badge/tests-878%2F878-brightgreen.svg" alt="Tests"></a>
|
|
15
15
|
<a href="#current-status"><img src="https://img.shields.io/badge/coverage-100%25-brightgreen.svg" alt="Coverage"></a>
|
|
16
16
|
<a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
|
|
17
17
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
|
@@ -634,9 +634,20 @@ user?.profile?.name # ES6 optional chaining (native)
|
|
|
634
634
|
arr?[0] # CoffeeScript soak (existence check)
|
|
635
635
|
fn?(arg) # CoffeeScript soak call
|
|
636
636
|
|
|
637
|
-
# Nullish coalescing
|
|
637
|
+
# Nullish coalescing (?? - rejects null OR undefined)
|
|
638
638
|
port = config.port ?? 8080
|
|
639
639
|
|
|
640
|
+
# Otherwise operator (!? - rejects ONLY undefined)
|
|
641
|
+
timeout = config.timeout !? 5000 # null and 0 are valid!
|
|
642
|
+
enabled = options.enabled !? true # false means disabled, undefined means default
|
|
643
|
+
|
|
644
|
+
# Comparison:
|
|
645
|
+
null ?? 'default' # → 'default' (null fails)
|
|
646
|
+
null !? 'default' # → null (null is defined!)
|
|
647
|
+
|
|
648
|
+
# Use ?? when: Both null and undefined should use default
|
|
649
|
+
# Use !? when: Only undefined should use default (null/false/0 are meaningful)
|
|
650
|
+
|
|
640
651
|
# Legacy existential operator (CoffeeScript compatibility)
|
|
641
652
|
value = x ? y # SPACE? syntax (auto-converts to ??)
|
|
642
653
|
value = x ?? y # Preferred modern syntax
|
package/bin/rip
CHANGED
|
@@ -57,18 +57,38 @@ Shebang support:
|
|
|
57
57
|
async function main() {
|
|
58
58
|
const args = process.argv.slice(2);
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
// Find the script file position (first non-option argument)
|
|
61
|
+
// Everything BEFORE it is rip options, everything AFTER it is script arguments
|
|
62
|
+
let scriptFileIndex = -1;
|
|
63
|
+
for (let i = 0; i < args.length; i++) {
|
|
64
|
+
// Skip option values (like -o filename)
|
|
65
|
+
if (i > 0 && (args[i - 1] === '-o' || args[i - 1] === '--output')) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// First non-option arg is the script file
|
|
69
|
+
if (!args[i].startsWith('-')) {
|
|
70
|
+
scriptFileIndex = i;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Split into rip options and script arguments
|
|
76
|
+
const ripOptions = scriptFileIndex === -1 ? args : args.slice(0, scriptFileIndex);
|
|
77
|
+
const scriptArgs = scriptFileIndex === -1 ? [] : args.slice(scriptFileIndex + 1);
|
|
78
|
+
|
|
79
|
+
// Only check ripOptions for rip's flags (not script args!)
|
|
80
|
+
if (ripOptions.includes('-h') || ripOptions.includes('--help')) {
|
|
61
81
|
printHelp();
|
|
62
82
|
process.exit(0);
|
|
63
83
|
}
|
|
64
84
|
|
|
65
|
-
if (
|
|
85
|
+
if (ripOptions.includes('-v') || ripOptions.includes('--version')) {
|
|
66
86
|
console.log(`Rip ${VERSION} - ${SUMMARY}`);
|
|
67
87
|
process.exit(0);
|
|
68
88
|
}
|
|
69
89
|
|
|
70
90
|
// Launch local browser REPL (starts server + opens browser)
|
|
71
|
-
if (
|
|
91
|
+
if (ripOptions.includes('-w') || ripOptions.includes('--web')) {
|
|
72
92
|
console.log('🚀 Starting Rip browser REPL...\n');
|
|
73
93
|
|
|
74
94
|
// Start the server and capture output to get the actual port
|
|
@@ -109,15 +129,15 @@ async function main() {
|
|
|
109
129
|
// Check if REPL should be started
|
|
110
130
|
// Launch REPL if: no args AND stdin is a TTY (not piped), OR explicit -r flag
|
|
111
131
|
const isTTY = process.stdin.isTTY;
|
|
112
|
-
if ((args.length === 0 && isTTY) ||
|
|
132
|
+
if ((args.length === 0 && isTTY) || ripOptions.includes('-r') || ripOptions.includes('--repl')) {
|
|
113
133
|
startREPL();
|
|
114
134
|
return;
|
|
115
135
|
}
|
|
116
136
|
|
|
117
|
-
const showTokens =
|
|
118
|
-
const showSExpr =
|
|
119
|
-
const showCompiled =
|
|
120
|
-
const quiet =
|
|
137
|
+
const showTokens = ripOptions.includes('-t') || ripOptions.includes('--tokens');
|
|
138
|
+
const showSExpr = ripOptions.includes('-s') || ripOptions.includes('--sexpr');
|
|
139
|
+
const showCompiled = ripOptions.includes('-c') || ripOptions.includes('--compile');
|
|
140
|
+
const quiet = ripOptions.includes('-q') || ripOptions.includes('--quiet');
|
|
121
141
|
|
|
122
142
|
const options = {
|
|
123
143
|
showTokens,
|
|
@@ -125,16 +145,14 @@ async function main() {
|
|
|
125
145
|
quiet
|
|
126
146
|
};
|
|
127
147
|
|
|
128
|
-
// Find input file
|
|
129
|
-
let inputFile = null;
|
|
148
|
+
// Find input file and output file from ripOptions only
|
|
149
|
+
let inputFile = scriptFileIndex === -1 ? null : args[scriptFileIndex];
|
|
130
150
|
let outputFile = null;
|
|
131
151
|
|
|
132
|
-
for (let i = 0; i <
|
|
133
|
-
if (
|
|
134
|
-
outputFile =
|
|
152
|
+
for (let i = 0; i < ripOptions.length; i++) {
|
|
153
|
+
if (ripOptions[i] === '-o' || ripOptions[i] === '--output') {
|
|
154
|
+
outputFile = ripOptions[i + 1];
|
|
135
155
|
i++;
|
|
136
|
-
} else if (!args[i].startsWith('-') && !inputFile) {
|
|
137
|
-
inputFile = args[i]; // Only take first non-option as input file
|
|
138
156
|
}
|
|
139
157
|
}
|
|
140
158
|
|
|
@@ -150,10 +168,6 @@ async function main() {
|
|
|
150
168
|
// Execute the script with Bun using our loader
|
|
151
169
|
const loaderPath = join(__dirname, '../rip-loader.ts');
|
|
152
170
|
|
|
153
|
-
// Get script arguments (everything after the input file)
|
|
154
|
-
const inputFileIndex = args.indexOf(inputFile);
|
|
155
|
-
const scriptArgs = args.slice(inputFileIndex + 1);
|
|
156
|
-
|
|
157
171
|
try {
|
|
158
172
|
execSync(`bun --preload ${loaderPath} ${inputFile} ${scriptArgs.join(' ')}`, {
|
|
159
173
|
stdio: 'inherit'
|