|
62 | 62 | module Int = struct |
63 | 63 | let compare x y = |
64 | 64 | if x < y then -1 else if x > y then 1 else 0 |
| 65 | + let max x y = if x > y then x else y |
65 | 66 | let to_string x = Cake.Int.toString x |
66 | 67 | end;; |
67 | 68 |
|
@@ -169,6 +170,7 @@ end;; |
169 | 170 |
|
170 | 171 | module Array = struct |
171 | 172 | let make n x = Cake.Array.array n x |
| 173 | + let length a = Cake.Array.length a |
172 | 174 | let set a n x = try Cake.Array.update a n x |
173 | 175 | with Subscript -> raise (Invalid_argument "Array.set") |
174 | 176 | let get a n = try Cake.Array.sub a n |
@@ -263,11 +265,39 @@ module Hashtbl = struct |
263 | 265 | Cake.List.foldl (fun (x,y) acc -> f x y acc) init (Cake.Hashtable.toAscList tbl) |
264 | 266 | end;; |
265 | 267 |
|
| 268 | +module Bytes = struct |
| 269 | + let length s = Cake.Word8_array.length s |
| 270 | + (* NOTE OCaml also raises Invalid_argument if n > Sys.max_string_length; |
| 271 | + additionally, OCaml returns an uninitialized sequence with |
| 272 | + arbitrary bytes. *) |
| 273 | + let create n = |
| 274 | + if n < 0 then invalid_arg "Bytes.create: negative argument" else |
| 275 | + Cake.Word8_array.array n (Cake.Word8.fromInt 0) |
| 276 | + (* NOTE OCaml can raise Invalid_argument in get, set, blit_string. |
| 277 | + Unsure how the CakeML handle out-of-bounds accesses. *) |
| 278 | + let get s n = Cake.Word8_array.sub s n |
| 279 | + let set s n c = Cake.Word8_array.update s n c |
| 280 | + let blit_string src src_pos dst dst_pos len = |
| 281 | + Cake.Word8_array.copyVec src src_pos len dst dst_pos |
| 282 | + let to_string s = Cake.Word8_array.substring s 0 (length s) |
| 283 | +end;; |
| 284 | + |
266 | 285 | module Sys = struct |
267 | 286 | let remove (s: string) = print "TODO Sys.remove (noop)\n" |
268 | 287 | let command (s: string) = |
269 | | - print_endline "TODO Sys.command (noop, always returns 1)"; |
270 | | - 1 |
| 288 | + let slen = String.length s in |
| 289 | + (* slen + 1: null-terminated string; 2: status bytes *) |
| 290 | + let blen = Int.max 2 (slen + 1) in |
| 291 | + let bytes = Bytes.create blen in |
| 292 | + (* Avoid recomputing length by using blit_string instead of of_string *) |
| 293 | + let _ = Bytes.blit_string s 0 bytes 0 slen in |
| 294 | + let _ = Cake.Runtime.customFFI "system" bytes in |
| 295 | + let ret = Cake.Word8.toInt (Bytes.get bytes 0) in |
| 296 | + let _ = |
| 297 | + if 0 < ret |
| 298 | + then raise (Sys_error "Sys.command: no termination status for child") |
| 299 | + else () in |
| 300 | + Cake.Word8.toInt (Bytes.get bytes 1);; |
271 | 301 | let time () = |
272 | 302 | print_endline "TODO Sys.time (always returns 0)"; |
273 | 303 | Float.zero;; |
|
0 commit comments