rip-lang 3.14.3 → 3.14.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/docs/dist/rip.js +117 -12
- package/docs/dist/rip.min.js +53 -37
- package/docs/dist/rip.min.js.br +0 -0
- package/package.json +1 -1
- package/src/compiler.js +78 -10
- package/src/lexer.js +1 -1
package/docs/dist/rip.min.js.br
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/compiler.js
CHANGED
|
@@ -2611,8 +2611,24 @@ export class CodeEmitter {
|
|
|
2611
2611
|
}
|
|
2612
2612
|
}
|
|
2613
2613
|
|
|
2614
|
+
if (!isConstructor && !sideEffectOnly && isLast && loopStmts.includes(h)) {
|
|
2615
|
+
if (this.containsYield(stmt)) {
|
|
2616
|
+
code += this.indent() + this.addSemicolon(stmt, this.emit(stmt, 'statement')) + '\n';
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
code += this.indent() + 'const _result = [];\n';
|
|
2620
|
+
this.comprehensionTarget = '_result';
|
|
2621
|
+
let saved = this._skipCompTargetInit;
|
|
2622
|
+
this._skipCompTargetInit = true;
|
|
2623
|
+
code += this.emit(stmt, 'value');
|
|
2624
|
+
this._skipCompTargetInit = saved;
|
|
2625
|
+
this.comprehensionTarget = null;
|
|
2626
|
+
code += this.indent() + 'return _result;\n';
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2614
2630
|
let needsReturn = !isConstructor && !sideEffectOnly && isLast &&
|
|
2615
|
-
!noRetStmts.includes(h) &&
|
|
2631
|
+
!noRetStmts.includes(h) &&
|
|
2616
2632
|
!this.hasExplicitControlFlow(stmt);
|
|
2617
2633
|
let ctx = needsReturn ? 'value' : 'statement';
|
|
2618
2634
|
let sc = this.emit(stmt, ctx);
|
|
@@ -2727,28 +2743,80 @@ export class CodeEmitter {
|
|
|
2727
2743
|
|
|
2728
2744
|
emitComprehensionWithTarget(expr, iterators, guards, targetVar) {
|
|
2729
2745
|
let code = '';
|
|
2730
|
-
code += this.indent() + `${targetVar} = [];\n`;
|
|
2731
|
-
|
|
2746
|
+
if (!this._skipCompTargetInit) code += this.indent() + `${targetVar} = [];\n`;
|
|
2747
|
+
|
|
2748
|
+
let hasCtrl = (node) => {
|
|
2749
|
+
if (typeof node === 'string' && (node === 'break' || node === 'continue')) return true;
|
|
2750
|
+
if (!Array.isArray(node)) return false;
|
|
2751
|
+
if (['break', 'continue', 'return', 'throw'].includes(node[0])) return true;
|
|
2752
|
+
if (node[0] === 'if') return node.slice(1).some(hasCtrl);
|
|
2753
|
+
return node.some(hasCtrl);
|
|
2754
|
+
};
|
|
2755
|
+
|
|
2756
|
+
let emitBody = () => {
|
|
2757
|
+
let loopTypes = ['for-in', 'for-of', 'for-as', 'while', 'loop'];
|
|
2758
|
+
if (this.is(expr, 'block')) {
|
|
2759
|
+
for (let i = 0; i < expr.length - 1; i++) {
|
|
2760
|
+
let s = expr[i + 1], isLast = i === expr.length - 2;
|
|
2761
|
+
if (!isLast || hasCtrl(s) || (Array.isArray(s) && loopTypes.includes(s[0]))) {
|
|
2762
|
+
code += this.indent() + this.emit(s, 'statement') + ';\n';
|
|
2763
|
+
} else {
|
|
2764
|
+
code += this.indent() + `${targetVar}.push(${this.emit(s, 'value')});\n`;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
} else if (hasCtrl(expr)) {
|
|
2768
|
+
code += this.indent() + this.emit(expr, 'statement') + ';\n';
|
|
2769
|
+
} else {
|
|
2770
|
+
code += this.indent() + `${targetVar}.push(${this.emit(expr, 'value')});\n`;
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2732
2773
|
|
|
2733
2774
|
if (iterators.length === 1) {
|
|
2734
2775
|
let [iterType, vars, iterable, stepOrOwn] = iterators[0];
|
|
2776
|
+
|
|
2735
2777
|
if (iterType === 'for-in') {
|
|
2736
2778
|
let { header, setup } = this._forInHeader(vars, iterable, stepOrOwn);
|
|
2737
2779
|
code += this.indent() + header + ' {\n';
|
|
2738
2780
|
this.indentLevel++;
|
|
2739
2781
|
if (setup) code += this.indent() + setup + '\n';
|
|
2740
|
-
if (guards
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
code += this.indent() +
|
|
2745
|
-
|
|
2782
|
+
if (guards?.length > 0) { code += this.indent() + `if (${guards.map(g => this.emit(g, 'value')).join(' && ')}) {\n`; this.indentLevel++; }
|
|
2783
|
+
emitBody();
|
|
2784
|
+
if (guards?.length > 0) { this.indentLevel--; code += this.indent() + '}\n'; }
|
|
2785
|
+
this.indentLevel--;
|
|
2786
|
+
code += this.indent() + '}\n';
|
|
2787
|
+
return code;
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
if (iterType === 'for-of') {
|
|
2791
|
+
let { header, own, vv, oc, kvp } = this._forOfHeader(vars, iterable, stepOrOwn);
|
|
2792
|
+
code += this.indent() + header + ' {\n';
|
|
2793
|
+
this.indentLevel++;
|
|
2794
|
+
if (own) code += this.indent() + `if (!Object.hasOwn(${oc}, ${kvp})) continue;\n`;
|
|
2795
|
+
if (vv) code += this.indent() + `${vv} = ${oc}[${kvp}];\n`;
|
|
2796
|
+
if (guards?.length > 0) { code += this.indent() + `if (${guards.map(g => this.emit(g, 'value')).join(' && ')}) {\n`; this.indentLevel++; }
|
|
2797
|
+
emitBody();
|
|
2798
|
+
if (guards?.length > 0) { this.indentLevel--; code += this.indent() + '}\n'; }
|
|
2799
|
+
this.indentLevel--;
|
|
2800
|
+
code += this.indent() + '}\n';
|
|
2801
|
+
return code;
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
if (iterType === 'for-as') {
|
|
2805
|
+
let { header } = this._forAsHeader(vars, iterable, stepOrOwn);
|
|
2806
|
+
code += this.indent() + header + ' {\n';
|
|
2807
|
+
this.indentLevel++;
|
|
2808
|
+
if (guards?.length > 0) { code += this.indent() + `if (${guards.map(g => this.emit(g, 'value')).join(' && ')}) {\n`; this.indentLevel++; }
|
|
2809
|
+
emitBody();
|
|
2810
|
+
if (guards?.length > 0) { this.indentLevel--; code += this.indent() + '}\n'; }
|
|
2746
2811
|
this.indentLevel--;
|
|
2747
2812
|
code += this.indent() + '}\n';
|
|
2748
2813
|
return code;
|
|
2749
2814
|
}
|
|
2750
2815
|
}
|
|
2751
|
-
|
|
2816
|
+
|
|
2817
|
+
code = '';
|
|
2818
|
+
code += this.indent() + `${targetVar} = ${this.emit(['comprehension', expr, iterators, guards || []], 'value')};\n`;
|
|
2819
|
+
return code;
|
|
2752
2820
|
}
|
|
2753
2821
|
|
|
2754
2822
|
emitComprehensionAsLoop(expr, iterators, guards) {
|
package/src/lexer.js
CHANGED
|
@@ -172,7 +172,7 @@ let IMPLICIT_FUNC = new Set([
|
|
|
172
172
|
let TAGGABLE = new Set(['IDENTIFIER', 'PROPERTY', ')', 'CALL_END', ']', 'INDEX_END']);
|
|
173
173
|
|
|
174
174
|
// Control flow tokens that don't end implicit calls/objects
|
|
175
|
-
let CONTROL_IN_IMPLICIT = new Set(['IF', 'TRY', 'FINALLY', 'CATCH', 'CLASS', 'SWITCH', 'COMPONENT']);
|
|
175
|
+
let CONTROL_IN_IMPLICIT = new Set(['IF', 'TRY', 'FINALLY', 'CATCH', 'CLASS', 'SWITCH', 'COMPONENT', 'FOR']);
|
|
176
176
|
|
|
177
177
|
// Single-liner keywords that get implicit INDENT/OUTDENT
|
|
178
178
|
let SINGLE_LINERS = new Set(['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']);
|