Skip to content

Commit 6db6d0d

Browse files
committed
Fix while cond() -> $x { ... } compilation on Moar
1 parent a5cb2dc commit 6db6d0d

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,10 @@ QAST::MASTOperations.add_core_op('chain', -> $qastcomp, $op {
617617
});
618618

619619
# Conditionals.
620+
sub needs_cond_passed($n) {
621+
nqp::istype($n, QAST::Block) && $n.arity > 0 &&
622+
($n.blocktype eq 'immediate' || $n.blocktype eq 'immediate_static')
623+
}
620624
for <if unless> -> $op_name {
621625
QAST::MASTOperations.add_core_op($op_name, -> $qastcomp, $op {
622626
# Check operand count.
@@ -632,10 +636,6 @@ for <if unless> -> $op_name {
632636
# Compile each of the children, handling any that want the conditional
633637
# value to be passed.
634638
my @comp_ops;
635-
sub needs_cond_passed($n) {
636-
nqp::istype($n, QAST::Block) && $n.arity > 0 &&
637-
($n.blocktype eq 'immediate' || $n.blocktype eq 'immediate_static')
638-
}
639639
my $cond_temp_lbl := needs_cond_passed($op[1]) || needs_cond_passed($op[2])
640640
?? $qastcomp.unique('__im_cond_')
641641
!! '';
@@ -901,23 +901,35 @@ for ('', 'repeat_') -> $repness {
901901
my $redo_lbl := MAST::Label.new(:name($while_id ~ '_redo'));
902902
my $done_lbl := MAST::Label.new(:name($while_id ~ '_done'));
903903

904+
# Pick out applicable children; detect no handler case and munge
905+
# immediate arg case.
906+
my @children;
907+
my $handler := 1;
908+
for $op.list {
909+
if $_.named eq 'nohandler' { $handler := 0; }
910+
else { nqp::push(@children, $_) }
911+
}
912+
if needs_cond_passed(@children[1]) {
913+
my $cond_temp := $qastcomp.unique('__im_cond_');
914+
@children[0] := QAST::Op.new(
915+
:op('bind'),
916+
QAST::Var.new( :name($cond_temp), :scope('local'), :decl('var') ),
917+
@children[0]);
918+
@children[1].blocktype('declaration');
919+
@children[1] := QAST::Op.new(
920+
:op('call'),
921+
@children[1],
922+
QAST::Var.new( :name($cond_temp), :scope('local') ));
923+
}
924+
904925
# Compile each of the children; we'll need to look at the result
905926
# types and pick an overall result type if in non-void context.
906927
my @comp_ops;
907928
my @comp_types;
908-
my $handler := 1;
909-
my $*IMM_ARG;
910-
for $op.list {
911-
if $_.named eq 'nohandler' { $handler := 0; }
912-
else {
913-
my $*HAVE_IMM_ARG := nqp::istype($_, QAST::Block) && $_.arity > 0 && $_ =:= $op.list[1];
914-
my $comp := $qastcomp.as_mast($_);
915-
@comp_ops.push($comp);
916-
@comp_types.push($comp.result_kind);
917-
if $*HAVE_IMM_ARG && !$*IMM_ARG {
918-
nqp::die("$op_name block expects an argument, but there's no immediate block to take it");
919-
}
920-
}
929+
for @children {
930+
my $comp := $qastcomp.as_mast($_);
931+
@comp_ops.push($comp);
932+
@comp_types.push($comp.result_kind);
921933
}
922934
my $res_kind := @comp_types[0] == @comp_types[1]
923935
?? @comp_types[0]

0 commit comments

Comments
 (0)