@@ -293,6 +293,56 @@ impl Compiler {
293
293
}
294
294
}
295
295
296
+ fn compile_conditional_control (
297
+ & mut self ,
298
+ opcode : & str ,
299
+ cond : & Expr ,
300
+ substacks : ( Option < & Vec < Stmt > > , Option < & Vec < Stmt > > ) ,
301
+ current_id : String ,
302
+ parent_id : String ,
303
+ index : usize ,
304
+ body_len : usize ,
305
+ ) {
306
+ let condition_id = self . gen_block_id ( ) ;
307
+
308
+ self . compile_condition ( cond, current_id. clone ( ) , condition_id. clone ( ) ) ;
309
+
310
+ let mut inputs = HashMap :: new ( ) ;
311
+ inputs. insert ( "CONDITION" . to_string ( ) , json ! ( [ 2 , condition_id] ) ) ;
312
+
313
+ // TODO: remove this code-duplication
314
+ if let Some ( substack) = substacks. 0 {
315
+ let substack_id = self . peek_next_block_id ( ) ;
316
+ self . compile_body_statements ( substack, current_id. clone ( ) ) ;
317
+ inputs. insert ( "SUBSTACK" . to_string ( ) , json ! ( [ 2 , substack_id] ) ) ;
318
+ }
319
+
320
+ if let Some ( substack) = substacks. 1 {
321
+ let substack_id = self . peek_next_block_id ( ) ;
322
+ self . compile_body_statements ( substack, current_id. clone ( ) ) ;
323
+ inputs. insert ( "SUBSTACK2" . to_string ( ) , json ! ( [ 2 , substack_id] ) ) ;
324
+ }
325
+
326
+ let next_id = if ( index + 1 ) >= body_len {
327
+ None
328
+ } else {
329
+ Some ( self . peek_next_block_id ( ) )
330
+ } ;
331
+
332
+ self . push_block (
333
+ & Block {
334
+ opcode : opcode. to_string ( ) ,
335
+ next : next_id,
336
+ parent : Some ( parent_id. clone ( ) ) ,
337
+ inputs : Some ( inputs) ,
338
+ shadow : Some ( false ) ,
339
+ top_level : Some ( false ) ,
340
+ ..Default :: default ( )
341
+ } ,
342
+ current_id,
343
+ ) ;
344
+ }
345
+
296
346
fn value_from_expr ( & mut self , expr : & Expr , parent_id : String ) -> Value {
297
347
match expr {
298
348
Expr :: String ( value) => json ! ( [ 1 , [ 10 , value. to_string( ) ] ] ) ,
@@ -610,56 +660,40 @@ impl Compiler {
610
660
current_id,
611
661
) ;
612
662
}
663
+ Stmt :: While ( cond, body_true) => {
664
+ self . compile_conditional_control (
665
+ "control_while" ,
666
+ cond,
667
+ ( Some ( body_true) , None ) ,
668
+ current_id,
669
+ parent_id. clone ( ) ,
670
+ index,
671
+ body. len ( ) ,
672
+ ) ;
673
+ }
613
674
Stmt :: If ( cond, body_true, body_false) => {
614
- let condition_id = self . gen_block_id ( ) ;
615
-
616
- let next_id = if ( index + 1 ) >= body. len ( ) {
617
- None
618
- } else {
619
- Some ( self . peek_next_block_id ( ) )
620
- } ;
621
-
622
- self . compile_condition ( cond, current_id. clone ( ) , condition_id. clone ( ) ) ;
623
-
624
- let substack_id = self . peek_next_block_id ( ) ;
625
- self . compile_body_statements ( body_true, current_id. clone ( ) ) ;
626
-
627
- let mut inputs = HashMap :: new ( ) ;
628
- inputs. insert ( "CONDITION" . to_string ( ) , json ! ( [ 2 , condition_id] ) ) ;
629
- inputs. insert ( "SUBSTACK" . to_string ( ) , json ! ( [ 2 , substack_id] ) ) ;
630
-
631
675
// if-else
632
676
if let Some ( body_false) = body_false {
633
- let substack2_id = self . peek_next_block_id ( ) ;
634
- self . compile_body_statements ( body_false, current_id. clone ( ) ) ;
635
- inputs. insert ( "SUBSTACK2" . to_string ( ) , json ! ( [ 2 , substack2_id] ) ) ;
636
-
637
- self . push_block (
638
- & Block {
639
- opcode : "control_if_else" . to_string ( ) ,
640
- next : next_id,
641
- parent : Some ( parent_id. clone ( ) ) ,
642
- inputs : Some ( inputs) ,
643
- shadow : Some ( false ) ,
644
- top_level : Some ( false ) ,
645
- ..Default :: default ( )
646
- } ,
677
+ self . compile_conditional_control (
678
+ "control_if_else" ,
679
+ cond,
680
+ ( Some ( body_true) , Some ( body_false) ) ,
647
681
current_id,
682
+ parent_id. clone ( ) ,
683
+ index,
684
+ body. len ( ) ,
648
685
) ;
649
686
}
650
687
// if
651
688
else {
652
- self . push_block (
653
- & Block {
654
- opcode : "control_if" . to_string ( ) ,
655
- next : next_id,
656
- parent : Some ( parent_id. clone ( ) ) ,
657
- inputs : Some ( inputs) ,
658
- shadow : Some ( false ) ,
659
- top_level : Some ( false ) ,
660
- ..Default :: default ( )
661
- } ,
689
+ self . compile_conditional_control (
690
+ "control_if" ,
691
+ cond,
692
+ ( Some ( body_true) , None ) ,
662
693
current_id,
694
+ parent_id. clone ( ) ,
695
+ index,
696
+ body. len ( ) ,
663
697
) ;
664
698
}
665
699
}
0 commit comments