qmcchem/ocaml/qptypes_generator.ml

414 lines
10 KiB
OCaml
Raw Permalink Normal View History

2019-07-14 18:50:44 +02:00
let global_replace x =
x
|> Str.global_replace (Str.regexp "Float.to_string") "string_of_float"
|> Str.global_replace (Str.regexp "Float.of_string") "float_of_string"
|> Str.global_replace (Str.regexp "Int.to_string") "string_of_int"
|> Str.global_replace (Str.regexp "Int.of_string") "int_of_string"
2022-01-06 17:43:31 +01:00
|> Str.global_replace (Str.regexp "Int.to_bytes") "bytes_of_int"
|> Str.global_replace (Str.regexp "Int64.to_bytes") "bytes_of_int64"
|> Str.global_replace (Str.regexp "Float.to_bytes") "bytes_of_float"
2022-01-11 13:41:13 +01:00
|> Str.global_replace (Str.regexp "Float.of_bytes") "float_of_bytes"
2022-01-06 17:43:31 +01:00
|> Str.global_replace (Str.regexp "Int.of_bytes") "int_of_bytes"
2022-01-11 13:41:13 +01:00
|> Str.global_replace (Str.regexp "Int64.of_bytes") "int64_of_bytes"
2022-01-06 17:43:31 +01:00
|> Str.global_replace (Str.regexp "String.\\(to\\|of\\)_string") ""
|> Str.global_replace (Str.regexp "String.to_bytes") "Bytes.of_string"
2022-01-11 13:41:13 +01:00
|> Str.global_replace (Str.regexp "String.of_bytes") "Bytes.to_string"
2015-12-19 02:35:13 +01:00
let input_data = "
2019-07-14 18:50:44 +02:00
* Positive_float : float
if not (x >= 0.) then
raise (Invalid_argument (Printf.sprintf \"Positive_float : (x >= 0.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Strictly_positive_float : float
if not (x > 0.) then
raise (Invalid_argument (Printf.sprintf \"Strictly_positive_float : (x > 0.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Negative_float : float
if not (x <= 0.) then
raise (Invalid_argument (Printf.sprintf \"Negative_float : (x <= 0.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Strictly_negative_float : float
if not (x < 0.) then
raise (Invalid_argument (Printf.sprintf \"Strictly_negative_float : (x < 0.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Positive_int64 : int64
if not (x >= 0L) then
raise (Invalid_argument (Printf.sprintf \"Positive_int64 : (x >= 0L) : x=%s\" (Int64.to_string x)));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Positive_int : int
if not (x >= 0) then
raise (Invalid_argument (Printf.sprintf \"Positive_int : (x >= 0) : x=%d\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Strictly_positive_int : int
if not (x > 0) then
raise (Invalid_argument (Printf.sprintf \"Strictly_positive_int : (x > 0) : x=%d\" x));
* Negative_int : int
if not (x <= 0) then
raise (Invalid_argument (Printf.sprintf \"Negative_int : (x <= 0) : x=%d\" x));
2022-01-06 17:43:31 +01:00
assert (x <= 0) ;
2015-12-19 02:35:13 +01:00
* Det_coef : float
2019-07-14 18:50:44 +02:00
if (x < -1.) || (x > 1.) then
raise (Invalid_argument (Printf.sprintf \"Det_coef : (-1. <= x <= 1.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
* Normalized_float : float
2019-07-14 18:50:44 +02:00
if (x < 0.) || (x > 1.) then
raise (Invalid_argument (Printf.sprintf \"Normalized_float : (0. <= x <= 1.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Strictly_negative_int : int
if not (x < 0) then
raise (Invalid_argument (Printf.sprintf \"Strictly_negative_int : (x < 0) : x=%d\" x));
2015-12-19 02:35:13 +01:00
* Non_empty_string : string
2019-07-14 18:50:44 +02:00
if (x = \"\") then
raise (Invalid_argument \"Non_empty_string\");
2015-12-19 02:35:13 +01:00
2019-07-14 18:50:44 +02:00
* Det_number_max : int
assert (x > 0) ;
if (x > 100_000_000) then
2015-12-19 02:35:13 +01:00
warning \"More than 100 million determinants\";
2019-07-14 18:50:44 +02:00
* States_number : int
assert (x > 0) ;
if (x > 1000) then
warning \"More than 1000 states\";
* Bit_kind_size : int
2015-12-19 02:35:13 +01:00
begin match x with
| 8 | 16 | 32 | 64 -> ()
2019-07-14 18:50:44 +02:00
| _ -> raise (Invalid_argument \"Bit_kind_size should be (8|16|32|64).\")
2015-12-19 02:35:13 +01:00
end;
2019-07-14 18:50:44 +02:00
* Bit_kind : int
2015-12-19 02:35:13 +01:00
begin match x with
| 1 | 2 | 4 | 8 -> ()
2019-07-14 18:50:44 +02:00
| _ -> raise (Invalid_argument \"Bit_kind should be (1|2|4|8).\")
2015-12-19 02:35:13 +01:00
end;
* Bitmask_number : int
assert (x > 0) ;
* MO_coef : float
* MO_occ : float
2019-07-14 18:50:44 +02:00
if x < 0. then 0. else
if x > 2. then 2. else
2015-12-19 02:35:13 +01:00
* AO_coef : float
2019-07-14 18:50:44 +02:00
* AO_expo : float
if (x < 0.) then
raise (Invalid_argument (Printf.sprintf \"AO_expo : (x >= 0.) : x=%f\" x));
2015-12-19 02:35:13 +01:00
* AO_prim_number : int
assert (x > 0) ;
* Threshold : float
assert (x >= 0.) ;
assert (x <= 1.) ;
* PT2_energy : float
assert (x >=0.) ;
* Elec_alpha_number : int
assert (x > 0) ;
* Elec_beta_number : int
assert (x >= 0) ;
* Elec_number : int
assert (x > 0) ;
* MD5 : string
assert ((String.length x) = 32);
2019-07-14 18:50:44 +02:00
assert (
let a =
Array.init (String.length x) (fun i -> x.[i])
in
Array.fold_left (fun accu x -> accu && (x < 'g')) true a
);
2015-12-19 02:35:13 +01:00
* Rst_string : string
* Weight : float
assert (x >= 0.) ;
* Block_id : int
assert (x > 0) ;
* Compute_node : string
assert (x <> \"\") ;
"
2019-07-14 18:50:44 +02:00
2015-12-19 02:35:13 +01:00
let input_ezfio = "
* MO_number : int
2019-09-27 15:20:02 +02:00
mo_basis_mo_num
2019-07-14 18:50:44 +02:00
1 : 10_000
More than 10_000 MOs
2015-12-19 02:35:13 +01:00
* AO_number : int
ao_basis_ao_num
2019-07-14 18:50:44 +02:00
1 : 10_000
More than 10_000 AOs
2015-12-19 02:35:13 +01:00
* Nucl_number : int
nuclei_nucl_num
2019-07-14 18:50:44 +02:00
1 : 10_000
More than 10_000 nuclei
2015-12-19 02:35:13 +01:00
* N_int_number : int
2019-07-14 18:50:44 +02:00
spindeterminants_n_int
2015-12-19 02:35:13 +01:00
1 : 30
N_int > 30
* Det_number : int
2019-07-14 18:50:44 +02:00
spindeterminants_n_det
1 : 100_000_000
2015-12-19 02:35:13 +01:00
More than 100 million determinants
2019-07-14 18:50:44 +02:00
"
2015-12-19 02:35:13 +01:00
let untouched = "
2022-01-06 17:43:31 +01:00
let bytes_of_int64 i =
let result = Bytes.create 8 in
2022-01-12 12:48:08 +01:00
Bytes.set_int64_ne result 0 i;
2022-01-06 17:43:31 +01:00
result
let bytes_of_int i =
Int64.of_int i
|> bytes_of_int64
2022-01-11 13:41:13 +01:00
let int64_of_bytes b =
2022-01-12 12:48:08 +01:00
Bytes.get_int64_ne b 0
2022-01-11 13:41:13 +01:00
let int_of_bytes b =
int64_of_bytes b
|> Int64.to_int
let float_of_bytes b =
int64_of_bytes b
|> Int64.float_of_bits
2022-01-06 17:43:31 +01:00
let bytes_of_float f =
2022-01-11 13:41:13 +01:00
Int64.bits_of_float f
2022-01-06 17:43:31 +01:00
|> bytes_of_int64
2015-12-19 02:35:13 +01:00
"
let template = format_of_string "
module %s : sig
2019-07-14 18:50:44 +02:00
type t [@@deriving sexp]
2015-12-19 02:35:13 +01:00
val to_%s : t -> %s
val of_%s : %s %s -> t
val to_string : t -> string
2022-01-06 17:43:31 +01:00
val to_bytes : t -> bytes
2022-01-11 13:41:13 +01:00
val of_bytes : bytes -> t
2015-12-19 02:35:13 +01:00
end = struct
2019-07-14 18:50:44 +02:00
type t = %s [@@deriving sexp]
2015-12-19 02:35:13 +01:00
let to_%s x = x
let of_%s %s x = ( %s x )
let to_string x = %s.to_string x
2022-01-06 17:43:31 +01:00
let to_bytes x = %s.to_bytes x
2022-01-11 13:41:13 +01:00
let of_bytes b = %s.of_bytes b
2015-12-19 02:35:13 +01:00
end
"
2019-07-14 18:50:44 +02:00
2015-12-19 02:35:13 +01:00
let parse_input input=
2019-07-14 18:50:44 +02:00
print_string "open Sexplib.Std\nlet warning = print_string\n" ;
2015-12-19 02:35:13 +01:00
let rec parse result = function
| [] -> result
| ( "" , "" )::tail -> parse result tail
2019-07-14 18:50:44 +02:00
| ( t , text )::tail ->
let name,typ,params,params_val =
match String.split_on_char ':' t with
2015-12-19 02:35:13 +01:00
| [name;typ] -> (name,typ,"","")
| name::typ::params::params_val -> (name,typ,params,
2019-07-14 18:50:44 +02:00
(String.concat ":" params_val) )
2015-12-19 02:35:13 +01:00
| _ -> assert false
in
2019-07-14 18:50:44 +02:00
let typ = String_ext.strip typ
and name = String_ext.strip name in
let typ_cap = String.capitalize_ascii typ in
let newstring = Printf.sprintf template name typ typ typ params_val typ typ
2022-01-11 13:41:13 +01:00
typ typ params ( String_ext.strip text ) typ_cap typ_cap typ_cap
2015-12-19 02:35:13 +01:00
in
List.rev (parse (newstring::result) tail )
in
2019-07-14 18:50:44 +02:00
String_ext.split ~on:'*' input
|> List.map (String_ext.lsplit2_exn ~on:'\n')
2015-12-19 02:35:13 +01:00
|> parse []
2019-07-14 18:50:44 +02:00
|> String.concat ""
|> global_replace
|> print_string
2015-12-19 02:35:13 +01:00
let ezfio_template = format_of_string "
module %s : sig
2019-07-14 18:50:44 +02:00
type t [@@deriving sexp]
2015-12-19 02:35:13 +01:00
val to_%s : t -> %s
val get_max : unit -> %s
val of_%s : ?min:%s -> ?max:%s -> %s -> t
val to_string : t -> string
2022-01-06 17:43:31 +01:00
val to_bytes : t -> bytes
2015-12-19 02:35:13 +01:00
end = struct
2019-07-14 18:50:44 +02:00
type t = %s [@@deriving sexp]
2015-12-19 02:35:13 +01:00
let to_string x = %s.to_string x
2022-01-06 17:43:31 +01:00
let to_bytes x = %s.to_bytes x
2015-12-19 02:35:13 +01:00
let get_max () =
if (Ezfio.has_%s ()) then
Ezfio.get_%s ()
else
%s
let get_min () =
%s
let to_%s x = x
2019-07-14 18:50:44 +02:00
let of_%s ?(min=get_min ()) ?(max=get_max ()) x =
2015-12-19 02:35:13 +01:00
begin
assert (x >= min) ;
if (x > %s) then
warning \"%s\";
begin
match max with
| %s -> ()
2019-07-14 18:50:44 +02:00
| i ->
if ( x > i ) then
raise (Invalid_argument (Printf.sprintf \"%s: %%s\" (%s.to_string x) ))
2015-12-19 02:35:13 +01:00
end ;
x
end
end
"
2022-01-11 13:41:13 +01:00
(*
val of_bytes : bytes -> t
let of_bytes x = %s.of_bytes x
*)
2015-12-19 02:35:13 +01:00
let parse_input_ezfio input=
2019-07-14 18:50:44 +02:00
let parse s =
2015-12-19 02:35:13 +01:00
match (
2019-07-14 18:50:44 +02:00
String_ext.split s ~on:'\n'
|> List.filter (fun x -> (String_ext.strip x) <> "")
2015-12-19 02:35:13 +01:00
) with
| [] -> ""
| a :: b :: c :: d :: [] ->
begin
2019-07-14 18:50:44 +02:00
let (name,typ) = String_ext.lsplit2_exn ~on:':' a
2015-12-19 02:35:13 +01:00
and ezfio_func = b
2019-07-14 18:50:44 +02:00
and (min, max) = String_ext.lsplit2_exn ~on:':' c
2015-12-19 02:35:13 +01:00
and msg = d
2019-07-14 18:50:44 +02:00
in
let (name, typ, ezfio_func, min, max, msg) =
match List.map String_ext.strip [ name ; typ ; ezfio_func ; min ; max ; msg ] with
2015-12-19 02:35:13 +01:00
| [ name ; typ ; ezfio_func ; min ; max ; msg ] -> (name, typ, ezfio_func, min, max, msg)
| _ -> assert false
in
2022-01-06 17:43:31 +01:00
let typ_cap = String.capitalize_ascii typ in
2019-07-14 18:50:44 +02:00
Printf.sprintf ezfio_template
2022-01-06 17:43:31 +01:00
name typ typ typ typ typ typ typ typ typ_cap typ_cap
ezfio_func ezfio_func max min typ typ max msg min name typ_cap
2015-12-19 02:35:13 +01:00
end
| _ -> failwith "Error in input_ezfio"
in
2019-07-14 18:50:44 +02:00
String_ext.split ~on:'*' input
|> List.map parse
|> String.concat ""
|> global_replace
|> print_string
2015-12-19 02:35:13 +01:00
(** EZFIO *)
2019-07-14 18:50:44 +02:00
let input_lines filename =
let ic = open_in filename in
let result = String_ext.input_lines ic in
close_in ic;
result
2015-12-19 02:35:13 +01:00
let create_ezfio_handler () =
2022-01-06 17:43:31 +01:00
let lines =
2019-07-14 18:50:44 +02:00
input_lines "ezfio.ml"
2022-01-11 13:41:13 +01:00
(* /!\ Change when ezfio.ml changes *)
2022-01-11 14:47:04 +01:00
|> List.mapi (fun i l -> if i > 442 then Some l else None)
2019-07-14 18:50:44 +02:00
|> List.filter (fun x -> x <> None)
|> List.map (fun x ->
match x with
| Some x -> x
| None -> assert false)
2015-12-19 02:35:13 +01:00
in
2022-01-06 17:43:31 +01:00
let functions =
2019-07-14 18:50:44 +02:00
List.map (fun x ->
match String.split_on_char ' ' x with
2015-12-19 02:35:13 +01:00
| _ :: x :: "()" :: "=" :: f :: dir :: item :: _-> (x, f, dir, item)
| _ :: x :: "=" :: f :: dir :: item :: _-> (x, f, dir, item)
| _ -> ("","","","")
2022-01-06 17:43:31 +01:00
) lines
2015-12-19 02:35:13 +01:00
in
2022-01-06 17:43:31 +01:00
let has_functions =
List.filter (fun (x,_,_,_) -> String.sub x 0 4 = "has_") functions
and get_functions =
2019-07-14 18:50:44 +02:00
List.filter (fun (x,_,_,_) -> String.sub x 0 4 = "get_") functions
in
2022-01-06 17:43:31 +01:00
let chop s =
2019-07-14 18:50:44 +02:00
match (Str.split_delim (Str.regexp ";;") s) with
| x :: _ -> x
| _ -> assert false
2015-12-19 02:35:13 +01:00
in
2019-07-14 18:50:44 +02:00
2015-12-19 02:35:13 +01:00
let result =
[ "let decode_ezfio_message msg =
match msg with " ] @
(
2019-07-14 18:50:44 +02:00
List.map (fun (x,f,d,i) ->
let i = chop i in
if (String.sub f ((String.length f)-6) 6 = "_array") then
2022-01-06 17:43:31 +01:00
Printf.sprintf " | \"%s\" ->
2015-12-19 02:35:13 +01:00
Ezfio.read_string_array %s %s
2022-01-06 17:43:31 +01:00
|> Ezfio.flattened_ezfio
2015-12-19 02:35:13 +01:00
|> Array.to_list
2019-07-14 18:50:44 +02:00
|> String.concat \" \"" x d i
2015-12-19 02:35:13 +01:00
else
Printf.sprintf " | \"%s\" -> Ezfio.read_string %s %s" x d i
2022-01-06 17:43:31 +01:00
) get_functions
2015-12-19 02:35:13 +01:00
) @ (
2019-07-14 18:50:44 +02:00
List.map (fun (x,_,_,_) ->
2022-01-06 17:43:31 +01:00
Printf.sprintf " | \"%s\" -> if (Ezfio.%s ()) then \"T\" else \"F\"" x x
2019-07-14 18:50:44 +02:00
) has_functions
)
@ [" | x -> failwith (x^\" : Unknown EZFIO function\")\n;;" ;
"" ; "let all_ezfio_messages = [ " ] @
(
List.rev_map (fun (x,_,_,_) ->
Printf.sprintf " \"%s\" ; " (String.sub x 4 ((String.length x)-4))
2022-01-06 17:43:31 +01:00
) has_functions
) @ ["]"]
2015-12-19 02:35:13 +01:00
in
2022-01-06 17:43:31 +01:00
String.concat "\n" result
2019-07-19 17:06:01 +02:00
|> print_endline
2015-12-19 02:35:13 +01:00
(** Main *)
2019-07-14 18:50:44 +02:00
let () =
2022-01-06 17:43:31 +01:00
print_endline untouched;
2019-07-14 18:50:44 +02:00
parse_input input_data ;
parse_input_ezfio input_ezfio;
2019-07-19 17:06:01 +02:00
create_ezfio_handler ()
2015-12-19 02:35:13 +01:00