@@ -19,6 +19,8 @@ pub(crate) fn define_array_methods(ctx: Context) -> HashMap<InternedString, Buil
1919 // Ordering operations
2020 ( "sort" , BuiltinMethod ( sort) ) ,
2121 ( "reverse" , BuiltinMethod ( reverse) ) ,
22+ // Subarray operations
23+ ( "slice" , BuiltinMethod ( slice) ) ,
2224 ]
2325 . into_iter ( )
2426 . map ( |( name, f) | ( ctx. intern_static ( name) , f) )
@@ -233,6 +235,51 @@ fn index<'gc>(
233235 ) ) )
234236}
235237
238+ // Returns a shallow copy of a portion of the array
239+ fn slice < ' gc > (
240+ mc : & ' gc Mutation < ' gc > ,
241+ receiver : Value < ' gc > ,
242+ args : Vec < Value < ' gc > > ,
243+ ) -> Result < Value < ' gc > , VmError > {
244+ let list = receiver. as_array ( ) ?;
245+
246+ if args. is_empty ( ) {
247+ return Err ( VmError :: RuntimeError (
248+ "slice: expected at least 1 argument" . into ( ) ,
249+ ) ) ;
250+ }
251+
252+ let start = float_arg ! ( & args, 0 , "slice" ) ? as isize ;
253+
254+ let list_ref = list. borrow ( ) ;
255+ let list_len = list_ref. data . len ( ) as isize ;
256+
257+ // Calculate start index (handle negative indices)
258+ let start_idx = if start < 0 {
259+ ( list_len + start) . max ( 0 ) as usize
260+ } else {
261+ start. min ( list_len) as usize
262+ } ;
263+
264+ // Calculate end index (handle negative indices and optional end parameter)
265+ let end_idx = if args. len ( ) > 1 {
266+ let end = float_arg ! ( & args, 1 , "slice" ) ? as isize ;
267+ if end < 0 {
268+ ( list_len + end) . max ( 0 ) as usize
269+ } else {
270+ end. min ( list_len) as usize
271+ }
272+ } else {
273+ list_len as usize
274+ } ;
275+
276+ // Create a new array with the sliced elements
277+ let start_idx = start_idx. min ( end_idx) ; // Ensure start <= end
278+ let result = list_ref. data [ start_idx..end_idx] . to_vec ( ) ;
279+
280+ Ok ( Value :: array ( mc, result) )
281+ }
282+
236283// Return the number of times x appears in the list
237284fn count < ' gc > (
238285 _mc : & ' gc Mutation < ' gc > ,
0 commit comments