porffor 0.18.39 → 0.18.40
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/compiler/codegen.js +59 -2
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -111,6 +111,9 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
111
111
|
case 'ForOfStatement':
|
112
112
|
return generateForOf(scope, decl);
|
113
113
|
|
114
|
+
case 'SwitchStatement':
|
115
|
+
return generateSwitch(scope, decl);
|
116
|
+
|
114
117
|
case 'BreakStatement':
|
115
118
|
return generateBreak(scope, decl);
|
116
119
|
|
@@ -3623,10 +3626,63 @@ const generateForOf = (scope, decl) => {
|
|
3623
3626
|
return out;
|
3624
3627
|
};
|
3625
3628
|
|
3629
|
+
const generateSwitch = (scope, decl) => {
|
3630
|
+
const tmp = localTmp(scope, '#switch_disc');
|
3631
|
+
const out = [
|
3632
|
+
...generate(scope, decl.discriminant),
|
3633
|
+
[ Opcodes.local_set, tmp ],
|
3634
|
+
|
3635
|
+
[ Opcodes.block, Blocktype.void ]
|
3636
|
+
];
|
3637
|
+
|
3638
|
+
depth.push('switch');
|
3639
|
+
|
3640
|
+
const cases = decl.cases.slice();
|
3641
|
+
const defaultCase = cases.findIndex(x => x.test == null);
|
3642
|
+
if (defaultCase != -1) {
|
3643
|
+
// move default case to last
|
3644
|
+
cases.push(cases.splice(defaultCase, 1)[0]);
|
3645
|
+
}
|
3646
|
+
|
3647
|
+
for (let i = 0; i < cases.length; i++) {
|
3648
|
+
out.push([ Opcodes.block, Blocktype.void ]);
|
3649
|
+
depth.push('block');
|
3650
|
+
}
|
3651
|
+
|
3652
|
+
for (let i = 0; i < cases.length; i++) {
|
3653
|
+
const x = cases[i];
|
3654
|
+
if (x.test) {
|
3655
|
+
out.push(
|
3656
|
+
[ Opcodes.local_get, tmp ],
|
3657
|
+
...generate(scope, x.test),
|
3658
|
+
[ Opcodes.eq ],
|
3659
|
+
[ Opcodes.br_if, i ]
|
3660
|
+
);
|
3661
|
+
} else {
|
3662
|
+
out.push(
|
3663
|
+
[ Opcodes.br, i ]
|
3664
|
+
);
|
3665
|
+
}
|
3666
|
+
}
|
3667
|
+
|
3668
|
+
for (let i = 0; i < cases.length; i++) {
|
3669
|
+
depth.pop();
|
3670
|
+
out.push(
|
3671
|
+
[ Opcodes.end ],
|
3672
|
+
...generateCode(scope, { body: cases[i].consequent })
|
3673
|
+
);
|
3674
|
+
}
|
3675
|
+
|
3676
|
+
out.push([ Opcodes.end ]);
|
3677
|
+
depth.pop();
|
3678
|
+
|
3679
|
+
return out;
|
3680
|
+
};
|
3681
|
+
|
3626
3682
|
// find the nearest loop in depth map by type
|
3627
3683
|
const getNearestLoop = () => {
|
3628
3684
|
for (let i = depth.length - 1; i >= 0; i--) {
|
3629
|
-
if (['while', 'dowhile', 'for', 'forof'].includes(depth[i])) return i;
|
3685
|
+
if (['while', 'dowhile', 'for', 'forof', 'switch'].includes(depth[i])) return i;
|
3630
3686
|
}
|
3631
3687
|
|
3632
3688
|
return -1;
|
@@ -3645,7 +3701,8 @@ const generateBreak = (scope, decl) => {
|
|
3645
3701
|
while: 2, // loop > if (wanted branch) (we are here)
|
3646
3702
|
dowhile: 2, // loop > block (wanted branch) > block (we are here)
|
3647
3703
|
forof: 2, // loop > block (wanted branch) > block (we are here)
|
3648
|
-
if: 1 // break inside if, branch 0 to skip the rest of the if
|
3704
|
+
if: 1, // break inside if, branch 0 to skip the rest of the if
|
3705
|
+
switch: 1
|
3649
3706
|
})[type];
|
3650
3707
|
|
3651
3708
|
return [
|
package/package.json
CHANGED