this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Switch RPC transport from JSON-RPC to CBOR

- Update lib/worker.ml to use Transport.Cbor for encoding/decoding
- Update idl/js_top_worker_client.ml to use CBOR transport
- Update idl/js_top_worker_client_fut.ml to use CBOR transport
- Update example/unix_worker.ml to use CBOR and fix partial read issue
- Update example/unix_client.ml to use CBOR transport
- Add comprehensive directive tests (test/cram/directives.t)

The CBOR transport provides more compact binary encoding compared to
JSON-RPC, which is beneficial for web worker communication.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+1004 -13
+2 -2
example/unix_client.ml
··· 11 11 Unix.connect s sockaddr; 12 12 let ic = Unix.in_channel_of_descr s in 13 13 let oc = Unix.out_channel_of_descr s in 14 - let msg_buf = Jsonrpc.string_of_call call in 14 + let msg_buf = Transport.Cbor.string_of_call call in 15 15 let len = Printf.sprintf "%016d" (String.length msg_buf) in 16 16 output_string oc len; 17 17 output_string oc msg_buf; ··· 22 22 let msg_buf = Bytes.make len '\000' in 23 23 really_input ic msg_buf 0 len; 24 24 let (response : Rpc.response) = 25 - Jsonrpc.response_of_string (Bytes.unsafe_to_string msg_buf) 25 + Transport.Cbor.response_of_string (Bytes.unsafe_to_string msg_buf) 26 26 in 27 27 response 28 28 (*
+12 -4
example/unix_worker.ml
··· 52 52 53 53 let ( let* ) = Lwt.bind 54 54 55 + let rec read_exact s buf off len = 56 + if len <= 0 then Lwt.return () 57 + else 58 + let* n = Lwt_unix.read s buf off len in 59 + if n = 0 then Lwt.fail End_of_file 60 + else read_exact s buf (off + n) (len - n) 61 + 55 62 let binary_handler process s = 56 63 (* Read a 16 byte length encoded as a string *) 57 64 let len_buf = Bytes.make 16 '\000' in 58 - let* _ = Lwt_unix.read s len_buf 0 (Bytes.length len_buf) in 65 + let* () = read_exact s len_buf 0 16 in 59 66 let len = int_of_string (Bytes.unsafe_to_string len_buf) in 60 67 let msg_buf = Bytes.make len '\000' in 61 - let* _ = Lwt_unix.read s msg_buf 0 (Bytes.length msg_buf) in 68 + let* () = read_exact s msg_buf 0 len in 62 69 let* result = process msg_buf in 63 70 let len_buf = Printf.sprintf "%016d" (String.length result) in 64 71 let* _ = Lwt_unix.write s (Bytes.of_string len_buf) 0 16 in ··· 169 176 let rpc_fn = IdlM.server Server.implementation in 170 177 let process x = 171 178 let open Lwt in 172 - rpc_fn (Jsonrpc.call_of_string (Bytes.unsafe_to_string x)) 173 - >>= fun response -> Jsonrpc.string_of_response response |> return 179 + let _, call = Js_top_worker_rpc.Transport.Cbor.id_and_call_of_string (Bytes.unsafe_to_string x) in 180 + rpc_fn call >>= fun response -> 181 + Js_top_worker_rpc.Transport.Cbor.string_of_response ~id:(Rpc.Int 0L) response |> return 174 182 in 175 183 serve_requests process Js_top_worker_rpc.Toplevel_api_gen.sockpath 176 184
+2 -2
idl/js_top_worker_client.ml
··· 36 36 Js_of_ocaml.Console.console##log msg; 37 37 let msg = Js_of_ocaml.Js.to_string msg in 38 38 (* log (Printf.sprintf "Client received: %s" msg); *) 39 - Lwt_mvar.put mv (Ok (Jsonrpc.response_of_string msg))) 39 + Lwt_mvar.put mv (Ok (Transport.Cbor.response_of_string msg))) 40 40 41 41 let rpc : context -> Rpc.call -> Rpc.response Lwt.t = 42 42 fun context call -> 43 43 let open Lwt in 44 - let jv = Jsonrpc.string_of_call call |> Js_of_ocaml.Js.string in 44 + let jv = Transport.Cbor.string_of_call call |> Js_of_ocaml.Js.string in 45 45 (* log (Printf.sprintf "Client sending: %s" jv); *) 46 46 let mv = Lwt_mvar.create_empty () in 47 47 let outstanding_execution =
+2 -2
idl/js_top_worker_client_fut.ml
··· 32 32 (* Js_of_ocaml.Console.console##log msg; *) 33 33 let msg = Js_of_ocaml.Js.to_string msg in 34 34 (* log (Printf.sprintf "Client received: %s" msg); *) 35 - mv (Ok (Jsonrpc.response_of_string msg)) 35 + mv (Ok (Transport.Cbor.response_of_string msg)) 36 36 37 37 let rpc : context -> Rpc.call -> Rpc.response Fut.t = 38 38 fun context call -> 39 39 let open Fut.Syntax in 40 - let jv = Jsonrpc.string_of_call call |> Js_of_ocaml.Js.string in 40 + let jv = Transport.Cbor.string_of_call call |> Js_of_ocaml.Js.string in 41 41 (* log (Printf.sprintf "Client sending: %s" jv); *) 42 42 let v, mv = Fut.create () in 43 43 let outstanding_execution =
+3 -3
lib/worker.ml
··· 10 10 11 11 let server process e = 12 12 (* Jslib.log "Worker received: %s" e; *) 13 - let _, id, call = Jsonrpc.version_id_and_call_of_string e in 13 + let id, call = Transport.Cbor.id_and_call_of_string e in 14 14 Lwt.bind (process call) (fun response -> 15 - let rtxt = Jsonrpc.string_of_response ~id response in 16 - Jslib.log "Worker sending: %s" rtxt; 15 + let rtxt = Transport.Cbor.string_of_response ~id response in 16 + (* Jslib.log "Worker sending CBOR response"; *) 17 17 Js_of_ocaml.Worker.post_message (Js_of_ocaml.Js.string rtxt); 18 18 Lwt.return ()) 19 19
+983
test/cram/directives.t/run.t
··· 1 + Comprehensive test suite for OCaml toplevel directives. 2 + Most tests will initially FAIL - this is TDD! 3 + 4 + References: 5 + - OCaml Manual: https://ocaml.org/manual/5.4/toplevel.html 6 + - Findlib: http://projects.camlcity.org/projects/dl/findlib-1.7.1/doc/ref-html/lib/Topfind.html 7 + 8 + $ export OCAMLRUNPARAM=b 9 + $ unix_worker & 10 + unix_worker: [INFO] init() 11 + unix_worker: [INFO] init() finished 12 + unix_worker: [INFO] setup() ... 13 + unix_worker: [INFO] Setup complete 14 + unix_worker: [INFO] setup() finished 15 + $ sleep 2 16 + $ unix_client init '{ findlib_requires:[], execute: true }' 17 + N 18 + $ unix_client setup 19 + {mime_vals:[];stderr:S(error while evaluating #enable "pretty";; 20 + error while evaluating #disable "shortvar";;);stdout:S(OCaml version 5.4.0 21 + Unknown directive enable. 22 + Unknown directive disable.)} 23 + 24 + ============================================== 25 + SECTION 1: Basic Code Execution (Baseline) 26 + ============================================== 27 + 28 + $ unix_client exec_toplevel '# 1 + 2;;' 29 + {mime_vals:[];parts:[];script:S(# 1 + 2;; 30 + - : int = 3)} 31 + 32 + $ unix_client exec_toplevel '# let x = 42;;' 33 + {mime_vals:[];parts:[];script:S(# let x = 42;; 34 + val x : int = 42)} 35 + 36 + ============================================== 37 + SECTION 2: #show Directives (Environment Query) 38 + ============================================== 39 + 40 + Define some types and values to query: 41 + 42 + $ unix_client exec_toplevel '# type point = { x: float; y: float };;' 43 + {mime_vals:[];parts:[];script:S(# type point = { x: float; y: float };; 44 + type point = { x : float; y : float; })} 45 + 46 + $ unix_client exec_toplevel '# let origin = { x = 0.0; y = 0.0 };;' 47 + {mime_vals:[];parts:[];script:S(# let origin = { x = 0.0; y = 0.0 };; 48 + val origin : point = {x = 0.; y = 0.})} 49 + 50 + $ unix_client exec_toplevel '# module MyMod = struct type t = int let zero = 0 end;;' 51 + {mime_vals:[];parts:[];script:S(# module MyMod = struct type t = int let zero = 0 end;; 52 + module MyMod : sig type t = int val zero : int end)} 53 + 54 + $ unix_client exec_toplevel '# exception My_error of string;;' 55 + {mime_vals:[];parts:[];script:S(# exception My_error of string;; 56 + exception My_error of string)} 57 + 58 + Test #show directive: 59 + 60 + $ unix_client exec_toplevel '# #show point;;' 61 + {mime_vals:[];parts:[];script:S(# #show point;; 62 + type point = { x : float; y : float; })} 63 + 64 + $ unix_client exec_toplevel '# #show origin;;' 65 + {mime_vals:[];parts:[];script:S(# #show origin;; 66 + val origin : point)} 67 + 68 + $ unix_client exec_toplevel '# #show MyMod;;' 69 + {mime_vals:[];parts:[];script:S(# #show MyMod;; 70 + module MyMod : sig type t = int val zero : int end)} 71 + 72 + $ unix_client exec_toplevel '# #show My_error;;' 73 + {mime_vals:[];parts:[];script:S(# #show My_error;; 74 + exception My_error of string)} 75 + 76 + Test #show_type directive: 77 + 78 + $ unix_client exec_toplevel '# #show_type point;;' 79 + {mime_vals:[];parts:[];script:S(# #show_type point;; 80 + type point = { x : float; y : float; })} 81 + 82 + $ unix_client exec_toplevel '# #show_type list;;' 83 + {mime_vals:[];parts:[];script:S(# #show_type list;; 84 + type 'a list = [] | (::) of 'a * 'a list)} 85 + 86 + Test #show_val directive: 87 + 88 + $ unix_client exec_toplevel '# #show_val origin;;' 89 + {mime_vals:[];parts:[];script:S(# #show_val origin;; 90 + val origin : point)} 91 + 92 + $ unix_client exec_toplevel '# #show_val List.map;;' 93 + {mime_vals:[];parts:[];script:S(# #show_val List.map;; 94 + val map : ('a -> 'b) -> 'a list -> 'b list)} 95 + 96 + Test #show_module directive: 97 + 98 + $ unix_client exec_toplevel '# #show_module List;;' 99 + {mime_vals:[];parts:[];script:S(# #show_module List;; 100 + module List : 101 + sig 102 + type 'a t = 'a list = [] | (::) of 'a * 'a list 103 + val length : 'a list -> int 104 + val compare_lengths : 'a list -> 'b list -> int 105 + val compare_length_with : 'a list -> int -> int 106 + val is_empty : 'a list -> bool 107 + val cons : 'a -> 'a list -> 'a list 108 + val singleton : 'a -> 'a list 109 + val hd : 'a list -> 'a 110 + val tl : 'a list -> 'a list 111 + val nth : 'a list -> int -> 'a 112 + val nth_opt : 'a list -> int -> 'a option 113 + val rev : 'a list -> 'a list 114 + val init : int -> (int -> 'a) -> 'a list 115 + val append : 'a list -> 'a list -> 'a list 116 + val rev_append : 'a list -> 'a list -> 'a list 117 + val concat : 'a list list -> 'a list 118 + val flatten : 'a list list -> 'a list 119 + val equal : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool 120 + val compare : ('a -> 'a -> int) -> 'a list -> 'a list -> int 121 + val iter : ('a -> unit) -> 'a list -> unit 122 + val iteri : (int -> 'a -> unit) -> 'a list -> unit 123 + val map : ('a -> 'b) -> 'a list -> 'b list 124 + val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list 125 + val rev_map : ('a -> 'b) -> 'a list -> 'b list 126 + val filter_map : ('a -> 'b option) -> 'a list -> 'b list 127 + val concat_map : ('a -> 'b list) -> 'a list -> 'b list 128 + val fold_left_map : 129 + ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a list -> 'acc * 'b list 130 + val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a list -> 'acc 131 + val fold_right : ('a -> 'acc -> 'acc) -> 'a list -> 'acc -> 'acc 132 + val iter2 : ('a -> 'b -> unit) -> 'a list -> 'b list -> unit 133 + val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list 134 + val rev_map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list 135 + val fold_left2 : 136 + ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a list -> 'b list -> 'acc 137 + val fold_right2 : 138 + ('a -> 'b -> 'acc -> 'acc) -> 'a list -> 'b list -> 'acc -> 'acc 139 + val for_all : ('a -> bool) -> 'a list -> bool 140 + val exists : ('a -> bool) -> 'a list -> bool 141 + val for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool 142 + val exists2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool 143 + val mem : 'a -> 'a list -> bool 144 + val memq : 'a -> 'a list -> bool 145 + val find : ('a -> bool) -> 'a list -> 'a 146 + val find_opt : ('a -> bool) -> 'a list -> 'a option 147 + val find_index : ('a -> bool) -> 'a list -> int option 148 + val find_map : ('a -> 'b option) -> 'a list -> 'b option 149 + val find_mapi : (int -> 'a -> 'b option) -> 'a list -> 'b option 150 + val filter : ('a -> bool) -> 'a list -> 'a list 151 + val find_all : ('a -> bool) -> 'a list -> 'a list 152 + val filteri : (int -> 'a -> bool) -> 'a list -> 'a list 153 + val take : int -> 'a list -> 'a list 154 + val drop : int -> 'a list -> 'a list 155 + val take_while : ('a -> bool) -> 'a list -> 'a list 156 + val drop_while : ('a -> bool) -> 'a list -> 'a list 157 + val partition : ('a -> bool) -> 'a list -> 'a list * 'a list 158 + val partition_map : 159 + ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list 160 + val assoc : 'a -> ('a * 'b) list -> 'b 161 + val assoc_opt : 'a -> ('a * 'b) list -> 'b option 162 + val assq : 'a -> ('a * 'b) list -> 'b 163 + val assq_opt : 'a -> ('a * 'b) list -> 'b option 164 + val mem_assoc : 'a -> ('a * 'b) list -> bool 165 + val mem_assq : 'a -> ('a * 'b) list -> bool 166 + val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list 167 + val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list 168 + val split : ('a * 'b) list -> 'a list * 'b list 169 + val combine : 'a list -> 'b list -> ('a * 'b) list 170 + val sort : ('a -> 'a -> int) -> 'a list -> 'a list 171 + val stable_sort : ('a -> 'a -> int) -> 'a list -> 'a list 172 + val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list 173 + val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list 174 + val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list 175 + val to_seq : 'a list -> 'a Seq.t 176 + val of_seq : 'a Seq.t -> 'a list 177 + end)} 178 + 179 + Test #show_exception directive: 180 + 181 + $ unix_client exec_toplevel '# #show_exception Not_found;;' 182 + {mime_vals:[];parts:[];script:S(# #show_exception Not_found;; 183 + exception Not_found)} 184 + 185 + $ unix_client exec_toplevel '# #show_exception Invalid_argument;;' 186 + {mime_vals:[];parts:[];script:S(# #show_exception Invalid_argument;; 187 + exception Invalid_argument of string)} 188 + 189 + ============================================== 190 + SECTION 3: #print_depth and #print_length 191 + ============================================== 192 + 193 + $ unix_client exec_toplevel '# let nested = [[[[1;2;3]]]];;' 194 + {mime_vals:[];parts:[];script:S(# let nested = [[[[1;2;3]]]];; 195 + val nested : int list list list list = [[[[1; 2; 3]]]])} 196 + 197 + Test #print_depth: 198 + 199 + $ unix_client exec_toplevel '# #print_depth 2;;' 200 + {mime_vals:[];parts:[];script:S(# #print_depth 2;;)} 201 + 202 + $ unix_client exec_toplevel '# nested;;' 203 + {mime_vals:[];parts:[];script:S(# nested;; 204 + - : int list list list list = [[[...]]])} 205 + 206 + $ unix_client exec_toplevel '# #print_depth 100;;' 207 + {mime_vals:[];parts:[];script:S(# #print_depth 100;;)} 208 + 209 + $ unix_client exec_toplevel '# nested;;' 210 + {mime_vals:[];parts:[];script:S(# nested;; 211 + - : int list list list list = [[[[1; 2; 3]]]])} 212 + 213 + Test #print_length: 214 + 215 + $ unix_client exec_toplevel '# let long_list = [1;2;3;4;5;6;7;8;9;10];;' 216 + {mime_vals:[];parts:[];script:S(# let long_list = [1;2;3;4;5;6;7;8;9;10];; 217 + val long_list : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10])} 218 + 219 + $ unix_client exec_toplevel '# #print_length 3;;' 220 + {mime_vals:[];parts:[];script:S(# #print_length 3;;)} 221 + 222 + $ unix_client exec_toplevel '# long_list;;' 223 + {mime_vals:[];parts:[];script:S(# long_list;; 224 + - : int list = [1; 2; ...])} 225 + 226 + $ unix_client exec_toplevel '# #print_length 100;;' 227 + {mime_vals:[];parts:[];script:S(# #print_length 100;;)} 228 + 229 + ============================================== 230 + SECTION 4: #install_printer and #remove_printer 231 + ============================================== 232 + 233 + $ unix_client exec_toplevel '# type color = Red | Green | Blue;;' 234 + {mime_vals:[];parts:[];script:S(# type color = Red | Green | Blue;; 235 + type color = Red | Green | Blue)} 236 + 237 + $ unix_client exec_toplevel '# let pp_color fmt c = Format.fprintf fmt "<color:%s>" (match c with Red -> "red" | Green -> "green" | Blue -> "blue");;' 238 + {mime_vals:[];parts:[];script:S(# let pp_color fmt c = Format.fprintf fmt "<color:%s>" (match c with Red -> "red" | Green -> "green" | Blue -> "blue");; 239 + val pp_color : Format.formatter -> color -> unit = <fun>)} 240 + 241 + Test #install_printer: 242 + 243 + $ unix_client exec_toplevel '# #install_printer pp_color;;' 244 + {mime_vals:[];parts:[];script:S(# #install_printer pp_color;;)} 245 + 246 + $ unix_client exec_toplevel '# Red;;' 247 + {mime_vals:[];parts:[];script:S(# Red;; 248 + - : color = <color:red>)} 249 + 250 + $ unix_client exec_toplevel '# [Red; Green; Blue];;' 251 + {mime_vals:[];parts:[];script:S(# [Red; Green; Blue];; 252 + - : color list = [<color:red>; <color:green>; <color:blue>])} 253 + 254 + Test #remove_printer: 255 + 256 + $ unix_client exec_toplevel '# #remove_printer pp_color;;' 257 + {mime_vals:[];parts:[];script:S(# #remove_printer pp_color;;)} 258 + 259 + $ unix_client exec_toplevel '# Red;;' 260 + {mime_vals:[];parts:[];script:S(# Red;; 261 + - : color = Red)} 262 + 263 + ============================================== 264 + SECTION 5: #warnings and #warn_error 265 + ============================================== 266 + 267 + $ unix_client exec_toplevel '# #warnings "-26";;' 268 + {mime_vals:[];parts:[];script:S(# #warnings "-26";;)} 269 + 270 + Code with unused variable should not warn: 271 + 272 + $ unix_client exec_toplevel '# let _ = let unused = 1 in 2;;' 273 + {mime_vals:[];parts:[];script:S(# let _ = let unused = 1 in 2;; 274 + - : int = 2)} 275 + 276 + Re-enable warning: 277 + 278 + $ unix_client exec_toplevel '# #warnings "+26";;' 279 + {mime_vals:[];parts:[];script:S(# #warnings "+26";;)} 280 + 281 + Now should warn: 282 + 283 + $ unix_client exec_toplevel '# let _ = let unused2 = 1 in 2;;' 284 + {mime_vals:[];parts:[];script:S(# let _ = let unused2 = 1 in 2;; 285 + Line 1, characters 12-19: 286 + Warning 26 [unused-var]: unused variable unused2. 287 + - : int = 2)} 288 + 289 + Test #warn_error: 290 + 291 + $ unix_client exec_toplevel '# #warn_error "+26";;' 292 + {mime_vals:[];parts:[];script:S(# #warn_error "+26";;)} 293 + 294 + $ unix_client exec_toplevel '# let _ = let unused3 = 1 in 2;;' 295 + {mime_vals:[];parts:[];script:S(# let _ = let unused3 = 1 in 2;; 296 + Line 1, characters 12-19: 297 + Error (warning 26 [unused-var]): unused variable unused3.)} 298 + 299 + Reset: 300 + 301 + $ unix_client exec_toplevel '# #warn_error "-a";;' 302 + {mime_vals:[];parts:[];script:S(# #warn_error "-a";;)} 303 + 304 + ============================================== 305 + SECTION 6: #rectypes 306 + ============================================== 307 + 308 + Without rectypes, recursive type should fail: 309 + 310 + $ unix_client exec_toplevel "# type 'a t = 'a t -> int;;" 311 + {mime_vals:[];parts:[];script:S(# type 'a t = 'a t -> int;; 312 + Line 1, characters 0-23: 313 + Error: The type abbreviation t is cyclic: 314 + 'a t = 'a t -> int, 315 + 'a t -> int contains 'a t)} 316 + 317 + Enable rectypes: 318 + 319 + $ unix_client exec_toplevel '# #rectypes;;' 320 + {mime_vals:[];parts:[];script:S(# #rectypes;;)} 321 + 322 + Now recursive type should work: 323 + 324 + $ unix_client exec_toplevel "# type 'a u = 'a u -> int;;" 325 + {mime_vals:[];parts:[];script:S(# type 'a u = 'a u -> int;; 326 + type 'a u = 'a u -> int)} 327 + 328 + ============================================== 329 + SECTION 7: #directory 330 + ============================================== 331 + 332 + $ unix_client exec_toplevel '# #directory "/tmp";;' 333 + {mime_vals:[];parts:[];script:S(# #directory "/tmp";;)} 334 + 335 + $ unix_client exec_toplevel '# #remove_directory "/tmp";;' 336 + {mime_vals:[];parts:[];script:S(# #remove_directory "/tmp";;)} 337 + 338 + ============================================== 339 + SECTION 8: #help 340 + ============================================== 341 + 342 + $ unix_client exec_toplevel '# #help;;' 343 + {mime_vals:[];parts:[];script:S(# #help;; 344 + General 345 + #help 346 + Prints a list of all available directives, with corresponding argument type 347 + if appropriate. 348 + #quit 349 + Exit the toplevel. 350 + 351 + Loading code 352 + #cd <str> 353 + Change the current working directory. 354 + #directory <str> 355 + Add the given directory to search path for source and compiled files. 356 + #load <str> 357 + Load in memory a bytecode object, produced by ocamlc. 358 + #load_rec <str> 359 + As #load, but loads dependencies recursively. 360 + #mod_use <str> 361 + Usage is identical to #use but #mod_use wraps the contents in a module. 362 + #remove_directory <str> 363 + Remove the given directory from the search path. 364 + #show_dirs 365 + List directories currently in the search path. 366 + #use <str> 367 + Read, compile and execute source phrases from the given file. 368 + #use_output <str> 369 + Execute a command and read, compile and execute source phrases from its 370 + output. 371 + 372 + Environment queries 373 + #show <ident> 374 + Print the signatures of components from any of the categories below. 375 + #show_class <ident> 376 + Print the signature of the corresponding class. 377 + #show_class_type <ident> 378 + Print the signature of the corresponding class type. 379 + #show_constructor <ident> 380 + Print the signature of the corresponding value constructor. 381 + #show_exception <ident> 382 + Print the signature of the corresponding exception. 383 + #show_module <ident> 384 + Print the signature of the corresponding module. 385 + #show_module_type <ident> 386 + Print the signature of the corresponding module type. 387 + #show_type <ident> 388 + Print the signature of the corresponding type constructor. 389 + #show_val <ident> 390 + Print the signature of the corresponding value. 391 + 392 + Pretty-printing 393 + #install_printer <ident> 394 + Registers a printer for values of a certain type. 395 + #print_depth <int> 396 + Limit the printing of values to a maximal depth of n. 397 + #print_length <int> 398 + Limit the number of value nodes printed to at most n. 399 + #remove_printer <ident> 400 + Remove the named function from the table of toplevel printers. 401 + 402 + Tracing 403 + #trace <ident> 404 + All calls to the function named function-name will be traced. 405 + #untrace <ident> 406 + Stop tracing the given function. 407 + #untrace_all 408 + Stop tracing all functions traced so far. 409 + 410 + Compiler options 411 + #debug <bool> 412 + Choose whether to generate debugging events. 413 + #labels <bool> 414 + Choose whether to ignore labels in function types. 415 + #ppx <str> 416 + After parsing, pipe the abstract syntax tree through the preprocessor 417 + command. 418 + #principal <bool> 419 + Make sure that all types are derived in a principal way. 420 + #rectypes 421 + Allow arbitrary recursive types during type-checking. 422 + #warn_error <str> 423 + Treat as errors the warnings enabled by the argument. 424 + #warnings <str> 425 + Enable or disable warnings according to the argument. 426 + 427 + Undocumented 428 + #camlp4o 429 + #camlp4r 430 + #list 431 + #predicates <str> 432 + #require <str> 433 + #thread)} 434 + 435 + ============================================== 436 + SECTION 9: #use (File Loading) 437 + ============================================== 438 + 439 + Create a test file: 440 + 441 + $ cat > /tmp/test_use.ml << 'EOF' 442 + > let from_file = "loaded via #use" 443 + > let add x y = x + y 444 + > EOF 445 + 446 + $ unix_client exec_toplevel '# #use "/tmp/test_use.ml";;' 447 + {mime_vals:[];parts:[];script:S(# #use "/tmp/test_use.ml";; 448 + val from_file : string = "loaded via #use" 449 + 450 + val add : int -> int -> int = <fun>)} 451 + 452 + $ unix_client exec_toplevel '# from_file;;' 453 + {mime_vals:[];parts:[];script:S(# from_file;; 454 + - : string = "loaded via #use")} 455 + 456 + $ unix_client exec_toplevel '# add 1 2;;' 457 + {mime_vals:[];parts:[];script:S(# add 1 2;; 458 + - : int = 3)} 459 + 460 + ============================================== 461 + SECTION 10: #mod_use 462 + ============================================== 463 + 464 + Create a test file: 465 + 466 + $ cat > /tmp/test_mod.ml << 'EOF' 467 + > let value = 42 468 + > type t = A | B 469 + > EOF 470 + 471 + $ unix_client exec_toplevel '# #mod_use "/tmp/test_mod.ml";;' 472 + {mime_vals:[];parts:[];script:S(# #mod_use "/tmp/test_mod.ml";; 473 + module Test_mod : sig val value : int type t = A | B end)} 474 + 475 + $ unix_client exec_toplevel '# Test_mod.value;;' 476 + {mime_vals:[];parts:[];script:S(# Test_mod.value;; 477 + - : int = 42)} 478 + 479 + ============================================== 480 + SECTION 11: Findlib #require 481 + ============================================== 482 + 483 + $ unix_client exec_toplevel '# #require "str";;' 484 + {mime_vals:[];parts:[];script:S(# #require "str";; 485 + /home/node/.opam/default/lib/ocaml/str: added to search path)} 486 + 487 + $ unix_client exec_toplevel '# Str.regexp "test";;' 488 + {mime_vals:[];parts:[];script:S(# Str.regexp "test";; 489 + - : Str.regexp = <abstr>)} 490 + 491 + ============================================== 492 + SECTION 12: Findlib #list 493 + ============================================== 494 + 495 + $ unix_client exec_toplevel '# #list;;' 496 + {mime_vals:[];parts:[];script:S(# #list;; 497 + afl-persistent (version: n/a) 498 + alcotest (version: 1.9.1) 499 + alcotest.engine (version: 1.9.1) 500 + alcotest.stdlib_ext (version: 1.9.1) 501 + angstrom (version: 0.16.1) 502 + angstrom.async (version: n/a) 503 + angstrom.lwt-unix (version: n/a) 504 + angstrom.unix (version: n/a) 505 + astring (version: 0.8.5) 506 + astring.top (version: 0.8.5) 507 + base (version: v0.17.3) 508 + base.base_internalhash_types (version: v0.17.3) 509 + base.md5 (version: v0.17.3) 510 + base.shadow_stdlib (version: v0.17.3) 511 + base64 (version: 3.4.0) 512 + base64.rfc2045 (version: 3.4.0) 513 + base_bigstring (version: v0.17.0) 514 + base_quickcheck (version: v0.17.1) 515 + base_quickcheck.ppx_quickcheck (version: v0.17.1) 516 + base_quickcheck.ppx_quickcheck.expander (version: v0.17.1) 517 + base_quickcheck.ppx_quickcheck.runtime (version: v0.17.1) 518 + bigstringaf (version: 0.9.0) 519 + bin_prot (version: v0.17.0) 520 + bin_prot.shape (version: v0.17.0) 521 + bos (version: 0.2.1) 522 + bos.setup (version: 0.2.1) 523 + bos.top (version: 0.2.1) 524 + brr (version: 0.0.8) 525 + brr.ocaml_poke (version: 0.0.8) 526 + brr.ocaml_poke_ui (version: 0.0.8) 527 + brr.poke (version: 0.0.8) 528 + brr.poked (version: 0.0.8) 529 + bytes (version: [distributed with OCaml 4.02 or above]) 530 + bytesrw (version: 0.3.0) 531 + bytesrw.sysrandom (version: 0.3.0) 532 + bytesrw.unix (version: 0.3.0) 533 + camlp-streams (version: n/a) 534 + capitalization (version: v0.17.0) 535 + cbor (version: n/a) 536 + cbort (version: 529a03c) 537 + checkseum (version: 0.5.2) 538 + checkseum.c (version: 0.5.2) 539 + checkseum.ocaml (version: 0.5.2) 540 + chrome-trace (version: 3.21.0) 541 + cmdliner (version: 2.1.0) 542 + compiler-libs (version: 5.4.0) 543 + compiler-libs.bytecomp (version: 5.4.0) 544 + compiler-libs.common (version: 5.4.0) 545 + compiler-libs.native-toplevel (version: 5.4.0) 546 + compiler-libs.optcomp (version: 5.4.0) 547 + compiler-libs.toplevel (version: 5.4.0) 548 + core (version: v0.17.1) 549 + core.base_for_tests (version: v0.17.1) 550 + core.command (version: v0.17.1) 551 + core.filename_base (version: v0.17.1) 552 + core.heap_block (version: v0.17.1) 553 + core.top (version: v0.17.1) 554 + core.univ_map (version: v0.17.1) 555 + core.validate (version: v0.17.1) 556 + cppo (version: n/a) 557 + crowbar (version: n/a) 558 + crunch (version: 4.0.0) 559 + csexp (version: 1.5.2) 560 + cstruct (version: 6.2.0) 561 + ctypes (version: 0.24.0) 562 + ctypes-foreign (version: 0.24.0) 563 + ctypes.foreign (version: 0.24.0) 564 + ctypes.stubs (version: 0.24.0) 565 + ctypes.top (version: 0.24.0) 566 + decompress (version: n/a) 567 + decompress.de (version: 1.5.3) 568 + decompress.gz (version: 1.5.3) 569 + decompress.lz (version: 1.5.3) 570 + decompress.lzo (version: 1.5.3) 571 + decompress.zl (version: 1.5.3) 572 + domain-local-await (version: 0.1.0) 573 + dot-merlin-reader (version: n/a) 574 + dune (version: n/a) 575 + dune-build-info (version: 3.21.0) 576 + dune-configurator (version: 3.21.0) 577 + dune-rpc (version: 3.21.0) 578 + dune-rpc.private (version: 3.21.0) 579 + dune.configurator (version: 3.21.0) 580 + dyn (version: 3.21.0) 581 + dynlink (version: 5.4.0) 582 + eio (version: n/a) 583 + eio.core (version: n/a) 584 + eio.mock (version: n/a) 585 + eio.runtime_events (version: n/a) 586 + eio.unix (version: n/a) 587 + eio.utils (version: n/a) 588 + eio_linux (version: n/a) 589 + eio_main (version: n/a) 590 + eio_posix (version: n/a) 591 + either (version: 1.0.0) 592 + fiber (version: 3.7.0) 593 + fieldslib (version: v0.17.0) 594 + findlib (version: 1.9.8) 595 + findlib.dynload (version: 1.9.8) 596 + findlib.internal (version: 1.9.8) 597 + findlib.top (version: 1.9.8) 598 + fix (version: n/a) 599 + fmt (version: 0.11.0) 600 + fmt.cli (version: 0.11.0) 601 + fmt.top (version: 0.11.0) 602 + fmt.tty (version: 0.11.0) 603 + fpath (version: 0.7.3) 604 + fpath.top (version: 0.7.3) 605 + fs-io (version: 3.21.0) 606 + gel (version: v0.17.0) 607 + gen (version: 0.5.3) 608 + hmap (version: 0.8.1) 609 + int_repr (version: v0.17.0) 610 + integers (version: n/a) 611 + integers.top (version: n/a) 612 + iomux (version: v0.2) 613 + jane-street-headers (version: v0.17.0) 614 + js_of_ocaml (version: 6.2.0) 615 + js_of_ocaml-compiler (version: 6.2.0) 616 + js_of_ocaml-compiler.dynlink (version: 6.2.0) 617 + js_of_ocaml-compiler.findlib-support (version: 6.2.0) 618 + js_of_ocaml-compiler.runtime (version: 6.2.0) 619 + js_of_ocaml-compiler.runtime-files (version: 6.2.0) 620 + js_of_ocaml-lwt (version: 6.2.0) 621 + js_of_ocaml-ppx (version: 6.2.0) 622 + js_of_ocaml-ppx.as-lib (version: 6.2.0) 623 + js_of_ocaml-toplevel (version: 6.2.0) 624 + js_of_ocaml.deriving (version: 6.2.0) 625 + js_top_worker (version: 0.0.1) 626 + js_top_worker-bin (version: n/a) 627 + js_top_worker-client (version: 0.0.1) 628 + js_top_worker-client_fut (version: 0.0.1) 629 + js_top_worker-rpc (version: 0.0.1) 630 + js_top_worker-unix (version: n/a) 631 + js_top_worker-web (version: 0.0.1) 632 + js_top_worker_rpc_def (version: n/a) 633 + js_top_worker_rpc_def.__private__ (version: n/a) 634 + js_top_worker_rpc_def.__private__.js_top_worker_rpc_def (version: 0.0.1) 635 + jsonm (version: 1.0.2) 636 + jsonrpc (version: 1.25.0) 637 + jst-config (version: v0.17.0) 638 + logs (version: 0.10.0) 639 + logs.browser (version: 0.10.0) 640 + logs.cli (version: 0.10.0) 641 + logs.fmt (version: 0.10.0) 642 + logs.lwt (version: 0.10.0) 643 + logs.threaded (version: 0.10.0) 644 + logs.top (version: 0.10.0) 645 + lsp (version: 1.25.0) 646 + lwt (version: 6.0.0) 647 + lwt-dllist (version: 1.0.0) 648 + lwt.unix (version: 6.0.0) 649 + lwt_react (version: 1.2.0) 650 + menhir (version: n/a) 651 + menhirCST (version: 20250912) 652 + menhirLib (version: 20250912) 653 + menhirSdk (version: 20250912) 654 + merlin (version: n/a) 655 + merlin-lib (version: n/a) 656 + merlin-lib.analysis (version: 5.6.1-504) 657 + merlin-lib.commands (version: 5.6.1-504) 658 + merlin-lib.config (version: 5.6.1-504) 659 + merlin-lib.dot_protocol (version: 5.6.1-504) 660 + merlin-lib.extend (version: 5.6.1-504) 661 + merlin-lib.index_format (version: 5.6.1-504) 662 + merlin-lib.kernel (version: 5.6.1-504) 663 + merlin-lib.ocaml_compression (version: 5.6.1-504) 664 + merlin-lib.ocaml_merlin_specific (version: 5.6.1-504) 665 + merlin-lib.ocaml_parsing (version: 5.6.1-504) 666 + merlin-lib.ocaml_preprocess (version: 5.6.1-504) 667 + merlin-lib.ocaml_typing (version: 5.6.1-504) 668 + merlin-lib.ocaml_utils (version: 5.6.1-504) 669 + merlin-lib.os_ipc (version: 5.6.1-504) 670 + merlin-lib.query_commands (version: 5.6.1-504) 671 + merlin-lib.query_protocol (version: 5.6.1-504) 672 + merlin-lib.sherlodoc (version: 5.6.1-504) 673 + merlin-lib.utils (version: 5.6.1-504) 674 + mew (version: n/a) 675 + mew_vi (version: n/a) 676 + mime_printer (version: e46cb08) 677 + mtime (version: 2.1.0) 678 + mtime.clock (version: 2.1.0) 679 + mtime.clock.os (version: 2.1.0) 680 + mtime.top (version: 2.1.0) 681 + num (version: 1.7~dev) 682 + num-top (version: 1.7~dev) 683 + num.core (version: 1.7~dev) 684 + ocaml-compiler-libs (version: n/a) 685 + ocaml-compiler-libs.bytecomp (version: v0.17.0) 686 + ocaml-compiler-libs.common (version: v0.17.0) 687 + ocaml-compiler-libs.optcomp (version: v0.17.0) 688 + ocaml-compiler-libs.shadow (version: v0.17.0) 689 + ocaml-compiler-libs.toplevel (version: v0.17.0) 690 + ocaml-index (version: n/a) 691 + ocaml-lsp-server (version: n/a) 692 + ocaml-syntax-shims (version: n/a) 693 + ocaml-version (version: n/a) 694 + ocaml_intrinsics_kernel (version: v0.17.1) 695 + ocamlbuild (version: 0.16.1) 696 + ocamlc-loc (version: 3.21.0) 697 + ocamldoc (version: 5.4.0) 698 + ocamlformat (version: n/a) 699 + ocamlformat-lib (version: 0.28.1) 700 + ocamlformat-lib.format_ (version: 0.28.1) 701 + ocamlformat-lib.ocaml_common (version: 0.28.1) 702 + ocamlformat-lib.ocamlformat_stdlib (version: 0.28.1) 703 + ocamlformat-lib.odoc_parser (version: 0.28.1) 704 + ocamlformat-lib.parser_extended (version: 0.28.1) 705 + ocamlformat-lib.parser_shims (version: 0.28.1) 706 + ocamlformat-lib.parser_standard (version: 0.28.1) 707 + ocamlformat-lib.stdlib_shims (version: 0.28.1) 708 + ocamlformat-rpc-lib (version: 0.28.1) 709 + ocamlformat.bin_conf (version: 0.28.1) 710 + ocamlformat.rpc (version: 0.28.1) 711 + ocamlformat.rpc_lib_protocol (version: 0.28.1) 712 + ocamlgraph (version: 2.0.0) 713 + ocp-indent (version: n/a) 714 + ocp-indent.dynlink (version: 1.9.0) 715 + ocp-indent.lexer (version: 1.9.0) 716 + ocp-indent.lib (version: 1.9.0) 717 + ocp-indent.utils (version: 1.9.0) 718 + ocplib-endian (version: n/a) 719 + ocplib-endian.bigstring (version: n/a) 720 + odoc (version: n/a) 721 + odoc-parser (version: 3.1.0) 722 + odoc.document (version: 3.1.0) 723 + odoc.examples (version: 3.1.0) 724 + odoc.html (version: 3.1.0) 725 + odoc.html_support_files (version: 3.1.0) 726 + odoc.index (version: 3.1.0) 727 + odoc.json_index (version: 3.1.0) 728 + odoc.latex (version: 3.1.0) 729 + odoc.loader (version: 3.1.0) 730 + odoc.manpage (version: 3.1.0) 731 + odoc.markdown (version: 3.1.0) 732 + odoc.model (version: 3.1.0) 733 + odoc.model_desc (version: 3.1.0) 734 + odoc.ocamlary (version: 3.1.0) 735 + odoc.occurrences (version: 3.1.0) 736 + odoc.odoc (version: 3.1.0) 737 + odoc.odoc_utils (version: 3.1.0) 738 + odoc.search (version: 3.1.0) 739 + odoc.search_html_frontend (version: 3.1.0) 740 + odoc.syntax_highlighter (version: 3.1.0) 741 + odoc.xref2 (version: 3.1.0) 742 + odoc.xref_test (version: 3.1.0) 743 + opam-core (version: n/a) 744 + opam-core.cmdliner (version: n/a) 745 + opam-file-format (version: 2.2.0) 746 + opam-format (version: n/a) 747 + optint (version: 0.3.0) 748 + ordering (version: 3.21.0) 749 + parsexp (version: v0.17.0) 750 + patch (version: 3.1.0) 751 + pp (version: 2.0.0) 752 + ppx_assert (version: v0.17.0) 753 + ppx_assert.runtime-lib (version: v0.17.0) 754 + ppx_base (version: v0.17.0) 755 + ppx_bench (version: v0.17.1) 756 + ppx_bench.runtime-lib (version: v0.17.1) 757 + ppx_bin_prot (version: v0.17.1) 758 + ppx_bin_prot.shape-expander (version: v0.17.1) 759 + ppx_cold (version: v0.17.0) 760 + ppx_compare (version: v0.17.0) 761 + ppx_compare.expander (version: v0.17.0) 762 + ppx_compare.runtime-lib (version: v0.17.0) 763 + ppx_custom_printf (version: v0.17.0) 764 + ppx_derivers (version: n/a) 765 + ppx_deriving_rpc (version: 10.0.0) 766 + ppx_diff (version: n/a) 767 + ppx_diff.diffable (version: v0.17.1) 768 + ppx_diff.diffable_cinaps (version: v0.17.1) 769 + ppx_diff.ppx_diff (version: v0.17.1) 770 + ppx_disable_unused_warnings (version: v0.17.0) 771 + ppx_enumerate (version: v0.17.0) 772 + ppx_enumerate.runtime-lib (version: v0.17.0) 773 + ppx_expect (version: v0.17.3) 774 + ppx_expect.config (version: v0.17.3) 775 + ppx_expect.config_types (version: v0.17.3) 776 + ppx_expect.evaluator (version: v0.17.3) 777 + ppx_expect.make_corrected_file (version: v0.17.3) 778 + ppx_expect.runtime (version: v0.17.3) 779 + ppx_fields_conv (version: v0.17.0) 780 + ppx_fixed_literal (version: v0.17.0) 781 + ppx_globalize (version: v0.17.2) 782 + ppx_hash (version: v0.17.0) 783 + ppx_hash.expander (version: v0.17.0) 784 + ppx_hash.runtime-lib (version: v0.17.0) 785 + ppx_here (version: v0.17.0) 786 + ppx_here.expander (version: v0.17.0) 787 + ppx_here.runtime-lib (version: v0.17.0) 788 + ppx_ignore_instrumentation (version: v0.17.0) 789 + ppx_inline_test (version: v0.17.1) 790 + ppx_inline_test.config (version: v0.17.1) 791 + ppx_inline_test.drop (version: v0.17.1) 792 + ppx_inline_test.libname (version: v0.17.1) 793 + ppx_inline_test.runner (version: v0.17.1) 794 + ppx_inline_test.runner.lib (version: v0.17.1) 795 + ppx_inline_test.runtime-lib (version: v0.17.1) 796 + ppx_jane (version: v0.17.0) 797 + ppx_jane.kernel (version: v0.17.0) 798 + ppx_let (version: v0.17.1) 799 + ppx_let.expander (version: v0.17.1) 800 + ppx_log (version: v0.17.0) 801 + ppx_log.kernel (version: v0.17.0) 802 + ppx_log.syntax (version: v0.17.0) 803 + ppx_log.types (version: v0.17.0) 804 + ppx_module_timer (version: v0.17.0) 805 + ppx_module_timer.runtime (version: v0.17.0) 806 + ppx_optcomp (version: v0.17.1) 807 + ppx_optional (version: v0.17.0) 808 + ppx_pipebang (version: v0.17.0) 809 + ppx_sexp_conv (version: v0.17.1) 810 + ppx_sexp_conv.expander (version: v0.17.1) 811 + ppx_sexp_conv.runtime-lib (version: v0.17.1) 812 + ppx_sexp_message (version: v0.17.0) 813 + ppx_sexp_message.expander (version: v0.17.0) 814 + ppx_sexp_value (version: v0.17.0) 815 + ppx_stable (version: v0.17.1) 816 + ppx_stable_witness (version: v0.17.0) 817 + ppx_stable_witness.runtime (version: v0.17.0) 818 + ppx_stable_witness.stable_witness (version: v0.17.0) 819 + ppx_string (version: v0.17.0) 820 + ppx_string.runtime (version: v0.17.0) 821 + ppx_string_conv (version: v0.17.0) 822 + ppx_tydi (version: v0.17.1) 823 + ppx_typerep_conv (version: v0.17.1) 824 + ppx_variants_conv (version: v0.17.1) 825 + ppx_yojson_conv_lib (version: v0.17.0) 826 + ppxlib (version: 0.37.0) 827 + ppxlib.__private__ (version: n/a) 828 + ppxlib.__private__.ppx_foo_deriver (version: 0.37.0) 829 + ppxlib.ast (version: 0.37.0) 830 + ppxlib.astlib (version: 0.37.0) 831 + ppxlib.metaquot (version: 0.37.0) 832 + ppxlib.metaquot_lifters (version: 0.37.0) 833 + ppxlib.print_diff (version: 0.37.0) 834 + ppxlib.runner (version: 0.37.0) 835 + ppxlib.runner_as_ppx (version: 0.37.0) 836 + ppxlib.stdppx (version: 0.37.0) 837 + ppxlib.traverse (version: 0.37.0) 838 + ppxlib.traverse_builtins (version: 0.37.0) 839 + ppxlib_jane (version: v0.17.4) 840 + psq (version: 0.2.0) 841 + ptime (version: 1.2.0) 842 + ptime.clock (version: 1.2.0) 843 + ptime.clock.os (version: 1.2.0) 844 + ptime.top (version: 1.2.0) 845 + re (version: n/a) 846 + re.emacs (version: n/a) 847 + re.glob (version: n/a) 848 + re.pcre (version: n/a) 849 + re.perl (version: n/a) 850 + re.posix (version: n/a) 851 + re.str (version: n/a) 852 + react (version: 1.2.2) 853 + react.top (version: 1.2.2) 854 + result (version: 1.5) 855 + rpclib (version: 10.0.0) 856 + rpclib-lwt (version: 10.0.0) 857 + rpclib.cmdliner (version: 10.0.0) 858 + rpclib.core (version: 10.0.0) 859 + rpclib.internals (version: 10.0.0) 860 + rpclib.json (version: 10.0.0) 861 + rpclib.markdown (version: 10.0.0) 862 + rpclib.xml (version: 10.0.0) 863 + rresult (version: 0.7.0) 864 + rresult.top (version: 0.7.0) 865 + runtime_events (version: 5.4.0) 866 + sedlex (version: 3.7) 867 + sedlex.ppx (version: 3.7) 868 + sedlex.utils (version: 3.7) 869 + seq (version: [distributed with OCaml 4.07 or above]) 870 + sexplib (version: v0.17.0) 871 + sexplib.num (version: v0.17.0) 872 + sexplib.unix (version: v0.17.0) 873 + sexplib0 (version: v0.17.0) 874 + sha (version: v1.15.4) 875 + spawn (version: v0.17.0) 876 + splittable_random (version: v0.17.0) 877 + stdio (version: v0.17.0) 878 + stdlib (version: 5.4.0) 879 + stdlib-shims (version: 0.3.0) 880 + stdune (version: 3.21.0) 881 + str (version: 5.4.0) 882 + stringext (version: 1.6.0) 883 + swhid_core (version: n/a) 884 + threads (version: 5.4.0) 885 + threads.posix (version: [internal]) 886 + time_now (version: v0.17.0) 887 + top-closure (version: 3.21.0) 888 + topkg (version: 1.1.1) 889 + trie (version: n/a) 890 + typerep (version: v0.17.1) 891 + tyxml (version: 4.6.0) 892 + tyxml.functor (version: 4.6.0) 893 + uchar (version: distributed with OCaml 4.03 or above) 894 + unix (version: 5.4.0) 895 + uri (version: 4.4.0) 896 + uri.services (version: 4.4.0) 897 + uri.services_full (version: 4.4.0) 898 + uring (version: v2.7.0) 899 + uucp (version: 17.0.0) 900 + uuseg (version: 17.0.0) 901 + uuseg.string (version: 17.0.0) 902 + uutf (version: 1.0.4) 903 + variantslib (version: v0.17.0) 904 + xdg (version: 3.21.0) 905 + xmlm (version: 1.4.0) 906 + yojson (version: 3.0.0) 907 + zarith (version: 1.14) 908 + zarith.top (version: 1.13) 909 + zarith_stubs_js (version: v0.17.0) 910 + zed (version: n/a))} 911 + 912 + ============================================== 913 + SECTION 13: #labels and #principal 914 + ============================================== 915 + 916 + $ unix_client exec_toplevel '# #labels true;;' 917 + {mime_vals:[];parts:[];script:S(# #labels true;;)} 918 + 919 + $ unix_client exec_toplevel '# #labels false;;' 920 + {mime_vals:[];parts:[];script:S(# #labels false;;)} 921 + 922 + $ unix_client exec_toplevel '# #principal true;;' 923 + {mime_vals:[];parts:[];script:S(# #principal true;;)} 924 + 925 + $ unix_client exec_toplevel '# #principal false;;' 926 + {mime_vals:[];parts:[];script:S(# #principal false;;)} 927 + 928 + ============================================== 929 + SECTION 14: Error Cases 930 + ============================================== 931 + 932 + Unknown directive: 933 + 934 + $ unix_client exec_toplevel '# #unknown_directive;;' 935 + {mime_vals:[];parts:[];script:S(# #unknown_directive;; 936 + Unknown directive unknown_directive.)} 937 + 938 + #show with non-existent identifier: 939 + 940 + $ unix_client exec_toplevel '# #show nonexistent_value;;' 941 + {mime_vals:[];parts:[];script:S(# #show nonexistent_value;; 942 + Unknown element.)} 943 + 944 + #require non-existent package: 945 + 946 + $ unix_client exec_toplevel '# #require "nonexistent_package_12345";;' 947 + {mime_vals:[];parts:[];script:S(# #require "nonexistent_package_12345";; 948 + No such package: nonexistent_package_12345)} 949 + 950 + #use non-existent file: 951 + 952 + $ unix_client exec_toplevel '# #use "/nonexistent/file.ml";;' 953 + {mime_vals:[];parts:[];script:S(# #use "/nonexistent/file.ml";; 954 + Cannot find file /nonexistent/file.ml.)} 955 + 956 + ============================================== 957 + SECTION 15: #load (bytecode loading) 958 + ============================================== 959 + 960 + Note: #load may not work in js_of_ocaml context 961 + 962 + $ unix_client exec_toplevel '# #load "str.cma";;' 963 + {mime_vals:[];parts:[];script:S(# #load "str.cma";;)} 964 + 965 + ============================================== 966 + SECTION 16: Classes (#show_class) 967 + ============================================== 968 + 969 + $ unix_client exec_toplevel '# class counter = object val mutable n = 0 method incr = n <- n + 1 method get = n end;;' 970 + {mime_vals:[];parts:[];script:S(# class counter = object val mutable n = 0 method incr = n <- n + 1 method get = n end;; 971 + class counter : 972 + object val mutable n : int method get : int method incr : unit end)} 973 + 974 + $ unix_client exec_toplevel '# #show_class counter;;' 975 + {mime_vals:[];parts:[];script:S(# #show_class counter;; 976 + class counter : 977 + object val mutable n : int method get : int method incr : unit end)} 978 + 979 + ============================================== 980 + Cleanup 981 + ============================================== 982 + 983 + $ pkill -f "unix_worker" || true