@@ -416,6 +416,7 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
416
416
( Prim :: FormatArray32 , [ FunApp ( len) , FunApp ( format) ] ) => self . read_array ( reader, span, len, format) ,
417
417
( Prim :: FormatArray64 , [ FunApp ( len) , FunApp ( format) ] ) => self . read_array ( reader, span, len, format) ,
418
418
( Prim :: FormatRepeatUntilEnd , [ FunApp ( format) ] ) => self . read_repeat_until_end ( reader, format) ,
419
+ ( Prim :: FormatRepeatUntilFull , [ FunApp ( len) , FunApp ( format) , FunApp ( replicate) ] ) => self . read_repeat_until_full ( reader, len, replicate, format) ,
419
420
( Prim :: FormatLimit8 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
420
421
( Prim :: FormatLimit16 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
421
422
( Prim :: FormatLimit32 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
@@ -485,6 +486,50 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
485
486
}
486
487
}
487
488
489
+ fn read_repeat_until_full (
490
+ & mut self ,
491
+ reader : & mut BufferReader < ' data > ,
492
+ len : & ArcValue < ' arena > ,
493
+ replicate : & ArcValue < ' arena > ,
494
+ elem_format : & ArcValue < ' arena > ,
495
+ ) -> Result < ArcValue < ' arena > , ReadError < ' arena > > {
496
+ let len = match self . elim_env ( ) . force ( len) . as_ref ( ) {
497
+ Value :: ConstLit ( Const :: U8 ( len, _) ) => Some ( usize:: from ( * len) ) ,
498
+ Value :: ConstLit ( Const :: U16 ( len, _) ) => Some ( usize:: from ( * len) ) ,
499
+ Value :: ConstLit ( Const :: U32 ( len, _) ) => usize:: try_from ( * len) . ok ( ) ,
500
+ Value :: ConstLit ( Const :: U64 ( len, _) ) => usize:: try_from ( * len) . ok ( ) ,
501
+ _ => return Err ( ReadError :: InvalidValue ( len. span ( ) ) ) ,
502
+ }
503
+ . ok_or_else ( || ReadError :: InvalidValue ( len. span ( ) ) ) ?;
504
+
505
+ // TODO: Do we need to force replicate as well?
506
+ // let replicate = self.elim_env().force(replicate);
507
+
508
+ let mut elems = Vec :: with_capacity ( len) ;
509
+ while elems. len ( ) < len {
510
+ match self . read_format ( reader, elem_format) {
511
+ Ok ( elem) => {
512
+ // Call the function to determine how many items this represents
513
+ let closure_res = self . elim_env ( ) . fun_app ( replicate. clone ( ) , elem. clone ( ) ) ;
514
+ let repeat = match closure_res. as_ref ( ) {
515
+ Value :: ConstLit ( Const :: U16 ( n, _) ) => * n,
516
+ _ => return Err ( ReadError :: InvalidValue ( replicate. span ( ) ) ) ,
517
+ } ;
518
+
519
+ // Push it that many times onto the array
520
+ // TODO: Error/limit if this exceeds len?
521
+ elems. extend ( std:: iter:: repeat ( elem) . take ( usize:: from ( repeat) ) ) ;
522
+ }
523
+ Err ( err) => return Err ( err) ,
524
+ } ;
525
+ }
526
+
527
+ Ok ( Spanned :: new (
528
+ elem_format. span ( ) ,
529
+ Arc :: new ( Value :: ArrayLit ( elems) ) ,
530
+ ) )
531
+ }
532
+
488
533
fn read_limit (
489
534
& mut self ,
490
535
reader : & BufferReader < ' data > ,
0 commit comments