@@ -545,10 +545,24 @@ impl<'eng> FnCompiler<'eng> {
545
545
ty:: TyExpressionVariant :: VariableExpression {
546
546
name, call_path, ..
547
547
} => self . compile_var_expr ( context, call_path, name, span_md_idx) ,
548
- ty:: TyExpressionVariant :: Array {
548
+ ty:: TyExpressionVariant :: ArrayExplicit {
549
549
elem_type,
550
550
contents,
551
- } => self . compile_array_expr ( context, md_mgr, * elem_type, contents, span_md_idx) ,
551
+ } => {
552
+ self . compile_array_explicit_expr ( context, md_mgr, * elem_type, contents, span_md_idx)
553
+ }
554
+ ty:: TyExpressionVariant :: ArrayRepeat {
555
+ elem_type,
556
+ value,
557
+ length,
558
+ } => self . compile_array_repeat_expr (
559
+ context,
560
+ md_mgr,
561
+ * elem_type,
562
+ value,
563
+ length,
564
+ span_md_idx,
565
+ ) ,
552
566
ty:: TyExpressionVariant :: ArrayIndex { prefix, index } => {
553
567
self . compile_array_index ( context, md_mgr, prefix, index, span_md_idx)
554
568
}
@@ -3635,7 +3649,67 @@ impl<'eng> FnCompiler<'eng> {
3635
3649
Ok ( TerminatorValue :: new ( val, context) )
3636
3650
}
3637
3651
3638
- fn compile_array_expr (
3652
+ fn compile_array_repeat_expr (
3653
+ & mut self ,
3654
+ context : & mut Context ,
3655
+ md_mgr : & mut MetadataManager ,
3656
+ elem_type : TypeId ,
3657
+ value : & ty:: TyExpression ,
3658
+ length : & ty:: TyExpression ,
3659
+ span_md_idx : Option < MetadataIndex > ,
3660
+ ) -> Result < TerminatorValue , CompileError > {
3661
+ let elem_type = convert_resolved_typeid_no_span (
3662
+ self . engines . te ( ) ,
3663
+ self . engines . de ( ) ,
3664
+ context,
3665
+ elem_type,
3666
+ ) ?;
3667
+
3668
+ let length_as_u64 = length. as_literal_u64 ( ) . unwrap ( ) ;
3669
+ let array_type = Type :: new_array ( context, elem_type, length_as_u64) ;
3670
+
3671
+ let temp_name = self . lexical_map . insert_anon ( ) ;
3672
+ let array_local_var = self
3673
+ . function
3674
+ . new_local_var ( context, temp_name, array_type, None , false )
3675
+ . map_err ( |ir_error| CompileError :: InternalOwned ( ir_error. to_string ( ) , Span :: dummy ( ) ) ) ?;
3676
+ let array_value = self
3677
+ . current_block
3678
+ . append ( context)
3679
+ . get_local ( array_local_var)
3680
+ . add_metadatum ( context, span_md_idx) ;
3681
+
3682
+ let value_value = return_on_termination_or_extract ! (
3683
+ self . compile_expression_to_value( context, md_mgr, value) ?
3684
+ ) ;
3685
+
3686
+ if length_as_u64 > 5 {
3687
+ self . compile_array_init_loop (
3688
+ context,
3689
+ array_value,
3690
+ elem_type,
3691
+ value_value,
3692
+ length_as_u64,
3693
+ span_md_idx,
3694
+ ) ;
3695
+ } else {
3696
+ for i in 0 ..length_as_u64 {
3697
+ let gep_val = self . current_block . append ( context) . get_elem_ptr_with_idx (
3698
+ array_value,
3699
+ elem_type,
3700
+ i,
3701
+ ) ;
3702
+ self . current_block
3703
+ . append ( context)
3704
+ . store ( gep_val, value_value)
3705
+ . add_metadatum ( context, span_md_idx) ;
3706
+ }
3707
+ }
3708
+
3709
+ Ok ( TerminatorValue :: new ( array_value, context) )
3710
+ }
3711
+
3712
+ fn compile_array_explicit_expr (
3639
3713
& mut self ,
3640
3714
context : & mut Context ,
3641
3715
md_mgr : & mut MetadataManager ,
@@ -3700,59 +3774,14 @@ impl<'eng> FnCompiler<'eng> {
3700
3774
} )
3701
3775
} ) ;
3702
3776
if let Some ( const_initializer) = const_initialiser_opt {
3703
- // Create a loop to insert const_initializer to all array elements.
3704
- let loop_block = self
3705
- . function
3706
- . create_block ( context, Some ( "array_init_loop" . into ( ) ) ) ;
3707
- // The loop begins with 0.
3708
- let zero = Constant :: new_uint ( context, 64 , 0 ) ;
3709
- let zero = Value :: new_constant ( context, zero) ;
3710
- // Branch to the loop block, passing the initial iteration value.
3711
- self . current_block
3712
- . append ( context)
3713
- . branch ( loop_block, vec ! [ zero] ) ;
3714
- // Add a block argument (for the IV) to the loop block.
3715
- let index_var_index = loop_block. new_arg ( context, Type :: get_uint64 ( context) ) ;
3716
- let index = loop_block. get_arg ( context, index_var_index) . unwrap ( ) ;
3717
- // Create an exit block.
3718
- let exit_block = self
3719
- . function
3720
- . create_block ( context, Some ( "array_init_exit" . into ( ) ) ) ;
3721
- // Start building the loop block.
3722
- self . current_block = loop_block;
3723
- let gep_val = self . current_block . append ( context) . get_elem_ptr (
3777
+ self . compile_array_init_loop (
3778
+ context,
3724
3779
array_value,
3725
3780
elem_type,
3726
- vec ! [ index] ,
3727
- ) ;
3728
- self . current_block
3729
- . append ( context)
3730
- . store ( gep_val, * const_initializer)
3731
- . add_metadatum ( context, span_md_idx) ;
3732
- // Increment index by one.
3733
- let one = Constant :: new_uint ( context, 64 , 1 ) ;
3734
- let one = Value :: new_constant ( context, one) ;
3735
- let index_inc =
3736
- self . current_block
3737
- . append ( context)
3738
- . binary_op ( BinaryOpKind :: Add , index, one) ;
3739
- // continue = index_inc < contents.len()
3740
- let len = Constant :: new_uint ( context, 64 , contents. len ( ) as u64 ) ;
3741
- let len = Value :: new_constant ( context, len) ;
3742
- let r#continue =
3743
- self . current_block
3744
- . append ( context)
3745
- . cmp ( Predicate :: LessThan , index_inc, len) ;
3746
- // if continue then loop_block else exit_block.
3747
- self . current_block . append ( context) . conditional_branch (
3748
- r#continue,
3749
- loop_block,
3750
- exit_block,
3751
- vec ! [ index_inc] ,
3752
- vec ! [ ] ,
3781
+ * const_initializer,
3782
+ contents. len ( ) as u64 ,
3783
+ span_md_idx,
3753
3784
) ;
3754
- // Continue compilation in the exit block.
3755
- self . current_block = exit_block;
3756
3785
} else {
3757
3786
// Insert each element separately.
3758
3787
for ( idx, elem_value) in compiled_elems. iter ( ) . enumerate ( ) {
@@ -3788,6 +3817,71 @@ impl<'eng> FnCompiler<'eng> {
3788
3817
Ok ( TerminatorValue :: new ( array_value, context) )
3789
3818
}
3790
3819
3820
+ // initialize an array with all elements equals to "init_value",
3821
+ // which should be "Copy", concept that sway still don´t have.
3822
+ fn compile_array_init_loop (
3823
+ & mut self ,
3824
+ context : & mut Context ,
3825
+ array_value : Value ,
3826
+ elem_type : Type ,
3827
+ init_value : Value ,
3828
+ length : u64 ,
3829
+ span_md_idx : Option < MetadataIndex > ,
3830
+ ) {
3831
+ // Create a loop to insert const_initializer to all array elements.
3832
+ let loop_block = self
3833
+ . function
3834
+ . create_block ( context, Some ( "array_init_loop" . into ( ) ) ) ;
3835
+ // The loop begins with 0.
3836
+ let zero = Constant :: new_uint ( context, 64 , 0 ) ;
3837
+ let zero = Value :: new_constant ( context, zero) ;
3838
+ // Branch to the loop block, passing the initial iteration value.
3839
+ self . current_block
3840
+ . append ( context)
3841
+ . branch ( loop_block, vec ! [ zero] ) ;
3842
+ // Add a block argument (for the IV) to the loop block.
3843
+ let index_var_index = loop_block. new_arg ( context, Type :: get_uint64 ( context) ) ;
3844
+ let index = loop_block. get_arg ( context, index_var_index) . unwrap ( ) ;
3845
+ // Create an exit block.
3846
+ let exit_block = self
3847
+ . function
3848
+ . create_block ( context, Some ( "array_init_exit" . into ( ) ) ) ;
3849
+ // Start building the loop block.
3850
+ self . current_block = loop_block;
3851
+ let gep_val =
3852
+ self . current_block
3853
+ . append ( context)
3854
+ . get_elem_ptr ( array_value, elem_type, vec ! [ index] ) ;
3855
+ self . current_block
3856
+ . append ( context)
3857
+ . store ( gep_val, init_value)
3858
+ . add_metadatum ( context, span_md_idx) ;
3859
+ // Increment index by one.
3860
+ let one = Constant :: new_uint ( context, 64 , 1 ) ;
3861
+ let one = Value :: new_constant ( context, one) ;
3862
+ let index_inc = self
3863
+ . current_block
3864
+ . append ( context)
3865
+ . binary_op ( BinaryOpKind :: Add , index, one) ;
3866
+ // continue = index_inc < contents.len()
3867
+ let len = Constant :: new_uint ( context, 64 , length) ;
3868
+ let len = Value :: new_constant ( context, len) ;
3869
+ let r#continue =
3870
+ self . current_block
3871
+ . append ( context)
3872
+ . cmp ( Predicate :: LessThan , index_inc, len) ;
3873
+ // if continue then loop_block else exit_block.
3874
+ self . current_block . append ( context) . conditional_branch (
3875
+ r#continue,
3876
+ loop_block,
3877
+ exit_block,
3878
+ vec ! [ index_inc] ,
3879
+ vec ! [ ] ,
3880
+ ) ;
3881
+ // Continue compilation in the exit block.
3882
+ self . current_block = exit_block;
3883
+ }
3884
+
3791
3885
fn compile_array_index (
3792
3886
& mut self ,
3793
3887
context : & mut Context ,
0 commit comments