@@ -416,6 +416,7 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
416416 ( Prim :: FormatArray32 , [ FunApp ( len) , FunApp ( format) ] ) => self . read_array ( reader, span, len, format) ,
417417 ( Prim :: FormatArray64 , [ FunApp ( len) , FunApp ( format) ] ) => self . read_array ( reader, span, len, format) ,
418418 ( 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) ,
419420 ( Prim :: FormatLimit8 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
420421 ( Prim :: FormatLimit16 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
421422 ( Prim :: FormatLimit32 , [ FunApp ( limit) , FunApp ( format) ] ) => self . read_limit ( reader, limit, format) ,
@@ -485,6 +486,50 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
485486 }
486487 }
487488
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+
488533 fn read_limit (
489534 & mut self ,
490535 reader : & BufferReader < ' data > ,
0 commit comments