Skip to content

Commit 6a1103d

Browse files
committed
Add array slice method
1 parent 7979470 commit 6a1103d

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

aiscript-vm/src/builtins/array.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
237284
fn count<'gc>(
238285
_mc: &'gc Mutation<'gc>,

tests/integration/builtin_methods/array.ai

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ print(empty); // expect: [1]
7373
numbers.clear();
7474
print(numbers); // expect: []
7575

76+
// Test slice method
77+
let nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
78+
print(nums.slice(3, 7)); // expect: [3, 4, 5, 6]
79+
print(nums.slice(5)); // expect: [5, 6, 7, 8, 9]
80+
print(nums.slice(-3)); // expect: [7, 8, 9]
81+
print(nums.slice(-6, -2)); // expect: [4, 5, 6, 7]
82+
print(nums.slice(8, 5)); // expect: []
83+
84+
// Complex examples
85+
let letters = ["a", "b", "c", "d", "e"];
86+
let reversed = letters.slice(1, 4).reverse();
87+
print(reversed); // expect: [d, c, b]
88+
7689
let nums = [1, 5, 2, 4, 3].sort();
7790
print(nums.pop(0)); // expect: 1
7891
print(nums); // expect: [2, 3, 4, 5]

0 commit comments

Comments
 (0)