spec: string-buffer primitive — make-string-buffer/append!/->string/length
OCaml: StringBuffer of Buffer.t in sx_types.ml; 5 primitives in sx_primitives.ml (make-string-buffer, string-buffer?, string-buffer-append!, string-buffer->string, string-buffer-length); inspect case added. JS: SxStringBuffer with array+join backend; _string_buffer marker for typeOf dispatch and dict? exclusion (also excludes _vector from dict?). spec/primitives.sx: 5 define-primitive entries. 17/17 tests pass on both OCaml and JS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1368,6 +1368,23 @@ let () =
|
||||
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)"));
|
||||
|
||||
(* String buffers — O(1) amortised append for string building in loops *)
|
||||
register "make-string-buffer" (fun _ -> StringBuffer (Buffer.create 64));
|
||||
register "string-buffer?" (fun args ->
|
||||
match args with [StringBuffer _] -> Bool true | [_] -> Bool false
|
||||
| _ -> raise (Eval_error "string-buffer?: expected 1 arg"));
|
||||
register "string-buffer-append!" (fun args ->
|
||||
match args with
|
||||
| [StringBuffer buf; String s] -> Buffer.add_string buf s; Nil
|
||||
| [StringBuffer _; v] -> raise (Eval_error ("string-buffer-append!: expected string, got " ^ type_of v))
|
||||
| _ -> raise (Eval_error "string-buffer-append!: expected (buffer string)"));
|
||||
register "string-buffer->string" (fun args ->
|
||||
match args with [StringBuffer buf] -> String (Buffer.contents buf)
|
||||
| _ -> raise (Eval_error "string-buffer->string: expected (buffer)"));
|
||||
register "string-buffer-length" (fun args ->
|
||||
match args with [StringBuffer buf] -> Integer (Buffer.length buf)
|
||||
| _ -> raise (Eval_error "string-buffer-length: expected (buffer)"));
|
||||
|
||||
(* Capability-based sandboxing — gate IO operations *)
|
||||
let cap_stack : string list ref = ref [] in
|
||||
register "with-capabilities" (fun args ->
|
||||
|
||||
@@ -73,6 +73,7 @@ and value =
|
||||
| Record of record (** R7RS record — opaque, generative, field-indexed. *)
|
||||
| Parameter of parameter (** R7RS parameter — dynamic binding via kont-stack provide frames. *)
|
||||
| Vector of value array (** R7RS vector — mutable fixed-size array. *)
|
||||
| StringBuffer of Buffer.t (** Mutable string buffer — O(1) amortized append. *)
|
||||
|
||||
(** CEK machine state — record instead of Dict for performance.
|
||||
5 fields × 55K steps/sec = 275K Hashtbl allocations/sec eliminated. *)
|
||||
@@ -491,6 +492,7 @@ let type_of = function
|
||||
| Record r -> r.r_type.rt_name
|
||||
| Parameter _ -> "parameter"
|
||||
| Vector _ -> "vector"
|
||||
| StringBuffer _ -> "string-buffer"
|
||||
|
||||
let is_nil = function Nil -> true | _ -> false
|
||||
let is_lambda = function Lambda _ -> true | _ -> false
|
||||
@@ -836,3 +838,4 @@ let rec inspect = function
|
||||
Printf.sprintf "#(%s)" (String.concat " " elts)
|
||||
| VmFrame f -> Printf.sprintf "<vm-frame:ip=%d base=%d>" f.vf_ip f.vf_base
|
||||
| VmMachine m -> Printf.sprintf "<vm-machine:sp=%d frames=%d>" m.vm_sp (List.length m.vm_frames)
|
||||
| StringBuffer buf -> Printf.sprintf "<string-buffer:%d>" (Buffer.length buf)
|
||||
|
||||
Reference in New Issue
Block a user