summaryrefslogtreecommitdiff
path: root/minijazz/src/global/misc.ml
blob: 3a454567aee8041d87556435f9fec62d993d5b51 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
(* Functions to decompose a list into a tuple *)
exception Arity_error of int * int (*expected, found*)
exception Arity_min_error of int * int (*expected, found*)

let try_1 = function
  | [v] -> v
  | l -> raise (Arity_error(1, List.length l))

let try_2 = function
  | [v1; v2] -> v1, v2
  | l -> raise (Arity_error(2, List.length l))

let try_3 = function
  | [v1; v2; v3] -> v1, v2, v3
  | l -> raise (Arity_error(3, List.length l))

let try_4 = function
  | [v1; v2; v3; v4] -> v1, v2, v3, v4
  | l -> raise (Arity_error(4, List.length l))

let try_1min = function
  | v::l -> v, l
  | l -> raise (Arity_min_error(1, List.length l))

let assert_fun f l =
  try
    f l
  with
      Arity_error(expected, found) ->
        Format.eprintf "Internal compiler error: \
     wrong list size (found %d, expected %d).@." found expected;
        assert false

let assert_min_fun f l =
  try
    f l
  with
      Arity_min_error(expected, found) ->
        Format.eprintf "Internal compiler error: \
     wrong list size (found %d, expected %d at least).@." found expected;
        assert false

let assert_1 l = assert_fun try_1 l
let assert_2 l = assert_fun try_2 l
let assert_3 l = assert_fun try_3 l
let assert_4 l = assert_fun try_4 l

let assert_1min l = assert_min_fun try_1min l

let mapfold f acc l =
  let l,acc = List.fold_left
                (fun (l,acc) e -> let e,acc = f acc e in e::l, acc)
                ([],acc) l in
  List.rev l, acc

let mapi f l =
  let rec aux i = function
    | [] -> []
    | v::l -> (f i v)::(aux (i+1) l)
  in
    aux 1 l

let unique l =
  let tbl = Hashtbl.create (List.length l) in
  List.iter (fun i -> Hashtbl.replace tbl i ()) l;
  Hashtbl.fold (fun key _ accu -> key :: accu) tbl []

let is_empty = function | [] -> true | _ -> false

let gen_symbol =
  let counter = ref 0 in
  let _gen_symbol () =
    counter := !counter + 1;
    "_"^(string_of_int !counter)
  in
    _gen_symbol

let bool_of_string s = match s with
  | "t" | "1" -> true
  | "f" | "0" -> false
  | _ -> raise (Invalid_argument ("bool_of_string"))

let bool_array_of_string s =
  let a = Array.make (String.length s) false in
  for i = 0 to String.length s - 1 do
    a.(i) <- bool_of_string (String.sub s i 1)
  done;
  a

exception Int_too_big
let convert_size s n =
  let m = String.length s in
  if m > n then
    raise Int_too_big
  else
    if m = n then s else (String.make (n - m) '0')^s

let binary_not s =
  for i=0 to String.length s - 1 do
    s.[i] <- if s.[i] = '0' then '1' else '0'
  done;
  s

let rec binary_string_of_int i n =
  let rec s_of_i i = match i with
    | 0 -> "0"
    | 1 -> "1"
    | i when i < 0 -> binary_not (binary_string_of_int (-i-1) n)
    | _ ->
      let q, r = i / 2, i mod 2 in
      (s_of_i q) ^ (s_of_i r)
  in
  convert_size (s_of_i i) n