Skip to content

Commit b26314e

Browse files
committed
[js] Implement if $expr -> $value {...} and similiar.
1 parent 354b474 commit b26314e

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/vm/js/QAST/Compiler.nqp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,7 @@ class QAST::OperationsJS {
997997
"\}\n"], :node($node));
998998
});
999999

1000+
10001001
for <if unless> -> $op_name {
10011002
add_op($op_name, sub ($comp, $node, :$want) {
10021003
unless nqp::defined($want) {
@@ -1007,8 +1008,17 @@ class QAST::OperationsJS {
10071008
nqp::die("Operation '"~$node.op~"' needs either 2 or 3 operands")
10081009
if $operands < 2 || $operands > 3;
10091010

1011+
my sub needs_cond_passed($n) {
1012+
nqp::istype($n, QAST::Block) && $n.arity > 0 &&
1013+
($n.blocktype eq 'immediate' || $n.blocktype eq 'immediate_static')
1014+
}
1015+
1016+
my $cond_type := (needs_cond_passed($node[1]) || needs_cond_passed($node[2]))
1017+
?? $T_OBJ
1018+
!! (($operands == 3 || $want == $T_VOID) ?? $T_BOOL !! $want);
1019+
10101020
# The 2 operand form of if in a non-void context also uses the cond as the return value
1011-
my $cond := $comp.as_js($node[0], :want( ($operands == 3 || $want == $T_VOID) ?? $T_BOOL !! $want));
1021+
my $cond := $comp.as_js($node[0], :want($cond_type));
10121022
my $then;
10131023
my $else;
10141024

@@ -1033,21 +1043,32 @@ class QAST::OperationsJS {
10331043

10341044
my $cond_without_sideeffects := Chunk.new($cond.type, $cond.expr, []);
10351045

1046+
1047+
my sub compile_block($node) {
1048+
if needs_cond_passed($node) {
1049+
my $block := try $*BLOCK;
1050+
my $loop := try $*LOOP;
1051+
$comp.compile_block($node, $block, $loop, :$want, :extra_args([$cond_without_sideeffects]));
1052+
} else {
1053+
$comp.as_js($node, :$want);
1054+
}
1055+
}
1056+
10361057
if $node.op eq 'if' {
1037-
$then := $comp.as_js($node[1], :$want);
1058+
$then := compile_block($node[1]);
10381059

10391060
if $operands == 3 {
1040-
$else := $comp.as_js($node[2], :$want);
1061+
$else := compile_block($node[2]);
10411062
} else {
10421063
$else := $comp.coerce($cond_without_sideeffects, $want);
10431064
}
10441065
} else {
10451066
if $operands == 3 {
1046-
$then := $comp.as_js($node[2], :$want);
1067+
$then := compile_block($node[2]);
10471068
} else {
10481069
$then := $comp.coerce($cond_without_sideeffects, $want);
10491070
}
1050-
$else := $comp.as_js($node[1], :$want);
1071+
$else := compile_block($node[1]);
10511072
}
10521073

10531074

0 commit comments

Comments
 (0)