@@ -50,12 +50,26 @@ pub(crate) type StmtCompiled =
50
50
51
51
pub ( crate ) enum StmtCompiledValue {
52
52
Compiled ( StmtCompiled ) ,
53
+ Return ( Span , Option < ExprCompiledValue > ) ,
53
54
}
54
55
55
56
impl StmtCompiledValue {
56
- pub ( crate ) fn as_compiled ( self ) -> StmtCompiled {
57
+ pub ( crate ) fn as_compiled ( self , compiler : & mut Compiler ) -> StmtCompiled {
57
58
match self {
58
59
StmtCompiledValue :: Compiled ( c) => c,
60
+ StmtCompiledValue :: Return ( span, None ) => {
61
+ stmt ! ( compiler, "return_none" , span, |_eval| {
62
+ return Err ( EvalException :: Return ( Value :: new_none( ) ) ) ;
63
+ } )
64
+ . as_compiled ( compiler)
65
+ }
66
+ StmtCompiledValue :: Return ( span, Some ( e) ) => {
67
+ let e = e. as_compiled ( ) ;
68
+ stmt ! ( compiler, "return" , span, |eval| {
69
+ return Err ( EvalException :: Return ( e( eval) ?) ) ;
70
+ } )
71
+ . as_compiled ( compiler)
72
+ }
59
73
}
60
74
}
61
75
}
@@ -122,13 +136,13 @@ impl StmtsCompiled {
122
136
self . 0 . extend ( right. 0 ) ;
123
137
}
124
138
125
- pub ( crate ) fn as_compiled ( self ) -> StmtCompiled {
139
+ pub ( crate ) fn as_compiled ( self , compiler : & mut Compiler ) -> StmtCompiled {
126
140
match self . 0 {
127
141
SmallVec1 :: Empty => box |_eval| Ok ( ( ) ) ,
128
- SmallVec1 :: One ( stmt) => stmt. as_compiled ( ) ,
142
+ SmallVec1 :: One ( stmt) => stmt. as_compiled ( compiler ) ,
129
143
SmallVec1 :: Many ( vec) => {
130
144
debug_assert ! ( vec. len( ) > 1 ) ;
131
- let vec = vec. into_map ( |s| s. as_compiled ( ) ) ;
145
+ let vec = vec. into_map ( |s| s. as_compiled ( compiler ) ) ;
132
146
box move |eval| {
133
147
for stmt in & vec {
134
148
stmt ( eval) ?;
@@ -425,7 +439,7 @@ impl Compiler<'_> {
425
439
fn maybe_wrap_before_stmt ( & mut self , span : Span , stmt : StmtsCompiled ) -> StmtsCompiled {
426
440
assert ! ( stmt. len( ) == 1 ) ;
427
441
if self . has_before_stmt {
428
- let stmt = stmt. as_compiled ( ) ;
442
+ let stmt = stmt. as_compiled ( self ) ;
429
443
StmtsCompiled :: one ( StmtCompiledValue :: Compiled ( box move |eval| {
430
444
before_stmt ( span, eval) ;
431
445
stmt ( eval)
@@ -442,7 +456,7 @@ impl Compiler<'_> {
442
456
if allow_gc && !is_statements {
443
457
// We could do this more efficiently by fusing the possible_gc
444
458
// into the inner closure, but no real need - we insert allow_gc fairly rarely
445
- let res = res. as_compiled ( ) ;
459
+ let res = res. as_compiled ( self ) ;
446
460
StmtsCompiled :: one ( StmtCompiledValue :: Compiled ( box move |eval| {
447
461
possible_gc ( eval) ;
448
462
res ( eval)
@@ -462,7 +476,7 @@ impl Compiler<'_> {
462
476
if then_block. is_empty ( ) {
463
477
self . stmt_expr_compiled ( span, ExprCompiledValue :: Compiled ( cond) )
464
478
} else {
465
- let then_block = then_block. as_compiled ( ) ;
479
+ let then_block = then_block. as_compiled ( self ) ;
466
480
if cond_is_positive {
467
481
stmt ! ( self , "if_then" , span, |eval| if cond( eval) ?. to_bool( ) {
468
482
then_block( eval) ?
@@ -512,8 +526,8 @@ impl Compiler<'_> {
512
526
} else if t. is_empty ( ) {
513
527
self . stmt_if_compiled ( span, cond, false , f)
514
528
} else {
515
- let t = t. as_compiled ( ) ;
516
- let f = f. as_compiled ( ) ;
529
+ let t = t. as_compiled ( self ) ;
530
+ let f = f. as_compiled ( self ) ;
517
531
stmt ! (
518
532
self ,
519
533
"if_then_else" ,
@@ -565,7 +579,7 @@ impl Compiler<'_> {
565
579
let over_span = over. span ;
566
580
let var = self . assign ( var) ;
567
581
let over = self . expr ( over) . as_compiled ( ) ;
568
- let st = self . stmt ( body, false ) . as_compiled ( ) ;
582
+ let st = self . stmt ( body, false ) . as_compiled ( self ) ;
569
583
stmt ! ( self , "for" , span, |eval| {
570
584
let heap = eval. heap( ) ;
571
585
let iterable = over( eval) ?;
@@ -587,15 +601,9 @@ impl Compiler<'_> {
587
601
) ??;
588
602
} )
589
603
}
590
- StmtP :: Return ( Some ( e) ) => {
591
- let e = self . expr ( e) . as_compiled ( ) ;
592
- stmt ! ( self , "return_value" , span, |eval| {
593
- return Err ( EvalException :: Return ( e( eval) ?) ) ;
594
- } )
604
+ StmtP :: Return ( e) => {
605
+ StmtsCompiled :: one ( StmtCompiledValue :: Return ( span, e. map ( |e| self . expr ( e) ) ) )
595
606
}
596
- StmtP :: Return ( None ) => stmt ! ( self , "return" , span, |_eval| {
597
- return Err ( EvalException :: Return ( Value :: new_none( ) ) ) ;
598
- } ) ,
599
607
StmtP :: If ( cond, box then_block) => self . stmt_if ( span, cond, then_block, allow_gc) ,
600
608
StmtP :: IfElse ( cond, box ( then_block, else_block) ) => {
601
609
self . stmt_if_else ( span, cond, then_block, else_block, allow_gc)
0 commit comments