ocaml: phase 6 Array module + (op) operator sections (+6 tests, 512 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Array module (runtime.sx, OCaml syntax):
Backed by a 'ref of list'. make/length/get/init build the cell;
set rewrites the underlying list with one cell changed (O(n) but
works for short arrays in baseline programs). Includes
iter/iteri/map/mapi/fold_left/to_list/of_list/copy/blit/fill.
(op) operator sections (parser.sx, parse-atom):
When the token after '(' is a binop (any op with non-zero
precedence in the binop table) and the next token is ')', emit
(:fun ('a' 'b') (:op OP a b)) — i.e. (+) becomes fun a b -> a + b.
Recognises every binop including 'mod', 'land', '^', '@', '::',
etc.
Lets us write:
List.fold_left (+) 0 [1;2;3;4;5] = 15
let f = ( * ) in f 6 7 = 42
List.map ((-) 10) [1;2;3] = [9;8;7]
let a = Array.make 5 7 in
Array.set a 2 99;
Array.fold_left (+) 0 a = 127
This commit is contained in:
@@ -525,6 +525,49 @@
|
||||
let force lz = _lazy_force lz
|
||||
end ;;
|
||||
|
||||
module Array = struct
|
||||
(* Backed by a ref-of-list. Mutating set! replaces the underlying
|
||||
list with a new one in which one cell is changed. O(n) set, but
|
||||
good enough for short arrays in baseline programs. *)
|
||||
let make n v =
|
||||
let rec build i acc =
|
||||
if i = 0 then acc else build (i - 1) (v :: acc)
|
||||
in
|
||||
ref (build n [])
|
||||
|
||||
let length a = List.length !a
|
||||
let get a i = List.nth !a i
|
||||
|
||||
let set a i v =
|
||||
let rec replace lst k =
|
||||
match lst with
|
||||
| [] -> []
|
||||
| h :: t -> if k = 0 then v :: t else h :: replace t (k - 1)
|
||||
in
|
||||
a := replace !a i
|
||||
|
||||
let init n f =
|
||||
let rec build i acc =
|
||||
if i = 0 then acc else build (i - 1) (f (i - 1) :: acc)
|
||||
in
|
||||
ref (build n [])
|
||||
|
||||
let iter f a = List.iter f !a
|
||||
let iteri f a = List.iteri f !a
|
||||
let map f a = ref (List.map f !a)
|
||||
let mapi f a = ref (List.mapi f !a)
|
||||
let fold_left f init a = List.fold_left f init !a
|
||||
let to_list a = !a
|
||||
let of_list xs = ref xs
|
||||
let copy a = ref !a
|
||||
let blit src si dst di n =
|
||||
for k = 0 to n - 1 do
|
||||
set dst (di + k) (get src (si + k))
|
||||
done
|
||||
let fill a pos n v =
|
||||
for k = 0 to n - 1 do set a (pos + k) v done
|
||||
end ;;
|
||||
|
||||
module Stack = struct
|
||||
let create () = ref []
|
||||
let push x s = s := x :: !s
|
||||
|
||||
Reference in New Issue
Block a user