spec: vector primitives — bounds-checked ref/set!, vector-copy start/end slice

vector-ref and vector-set! now raise Eval_error on out-of-bounds index instead of
an OCaml array exception. vector-copy accepts optional start and end parameters for
slicing (R7RS §6.8). spec/primitives.sx doc updated to reflect slice params.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 19:27:54 +00:00
parent 3759575b29
commit d1a00562a4
3 changed files with 30 additions and 7 deletions

View File

@@ -1227,11 +1227,19 @@ let () =
| _ -> raise (Eval_error "vector-length: expected vector"));
register "vector-ref" (fun args ->
match args with
| [Vector arr; Number n] -> arr.(int_of_float n)
| [Vector arr; Number n] ->
let i = int_of_float n in
if i < 0 || i >= Array.length arr then
raise (Eval_error (Printf.sprintf "vector-ref: index %d out of bounds (length %d)" i (Array.length arr)));
arr.(i)
| _ -> raise (Eval_error "vector-ref: expected (vector index)"));
register "vector-set!" (fun args ->
match args with
| [Vector arr; Number n; v] -> arr.(int_of_float n) <- v; Nil
| [Vector arr; Number n; v] ->
let i = int_of_float n in
if i < 0 || i >= Array.length arr then
raise (Eval_error (Printf.sprintf "vector-set!: index %d out of bounds (length %d)" i (Array.length arr)));
arr.(i) <- v; Nil
| _ -> raise (Eval_error "vector-set!: expected (vector index value)"));
register "vector->list" (fun args ->
match args with [Vector arr] -> List (Array.to_list arr)
@@ -1246,8 +1254,18 @@ let () =
| [Vector arr; v] -> Array.fill arr 0 (Array.length arr) v; Nil
| _ -> raise (Eval_error "vector-fill!: expected (vector value)"));
register "vector-copy" (fun args ->
match args with [Vector arr] -> Vector (Array.copy arr)
| _ -> raise (Eval_error "vector-copy: expected vector"));
match args with
| [Vector arr] -> Vector (Array.copy arr)
| [Vector arr; Number s] ->
let start = int_of_float s in
let len = Array.length arr - start in
if len <= 0 then Vector [||] else Vector (Array.sub arr start len)
| [Vector arr; Number s; Number e] ->
let start = int_of_float s in
let stop = min (int_of_float e) (Array.length arr) in
let len = stop - start in
if len <= 0 then Vector [||] else Vector (Array.sub arr start len)
| _ -> raise (Eval_error "vector-copy: expected (vector) or (vector start) or (vector start end)"));
(* Capability-based sandboxing — gate IO operations *)
let cap_stack : string list ref = ref [] in