@@ -617,6 +617,10 @@ QAST::MASTOperations.add_core_op('chain', -> $qastcomp, $op {
617
617
});
618
618
619
619
# 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
+ }
620
624
for <if unless > -> $ op_name {
621
625
QAST ::MASTOperations. add_core_op($ op_name , -> $ qastcomp , $ op {
622
626
# Check operand count.
@@ -632,10 +636,6 @@ for <if unless> -> $op_name {
632
636
# Compile each of the children, handling any that want the conditional
633
637
# value to be passed.
634
638
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
- }
639
639
my $ cond_temp_lbl := needs_cond_passed($ op [1 ]) || needs_cond_passed($ op [2 ])
640
640
?? $ qastcomp . unique (' __im_cond_' )
641
641
!! ' ' ;
@@ -901,23 +901,35 @@ for ('', 'repeat_') -> $repness {
901
901
my $ redo_lbl := MAST::Label. new (: name($ while_id ~ ' _redo' ));
902
902
my $ done_lbl := MAST::Label. new (: name($ while_id ~ ' _done' ));
903
903
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
+
904
925
# Compile each of the children; we'll need to look at the result
905
926
# types and pick an overall result type if in non-void context.
906
927
my @ comp_ops ;
907
928
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);
921
933
}
922
934
my $ res_kind := @ comp_types [0 ] == @ comp_types [1 ]
923
935
?? @ comp_types [0 ]
0 commit comments