(* -*- tuareg -*- *)

open StdLabels
open Printf

let nl () = printf "\n"

let supported_versions = [
  ("402", "4.02");
  ("403", "4.03");
  ("404", "4.04");
  ("405", "4.05");
  ("406", "4.06");
  ("407", "4.07");
  ("408", "4.08");
  ("409", "4.09");
  ("410", "4.10");
  ("411", "4.11");
  ("412", "4.12");
]

let qualified_types = [
  "Parsetree",
  [ "structure"
  ; "signature"
  ; "toplevel_phrase"
  ; "core_type"
  ; "expression"
  ; "pattern"
  ; "case"
  ; "type_declaration"
  ; "type_extension"
  ; "extension_constructor"
  ];

  "Outcometree",
  [ "out_value"
  ; "out_type"
  ; "out_class_type"
  ; "out_module_type"
  ; "out_sig_item"
  ; "out_type_extension"
  ; "out_phrase"
  ];

  "Ast_mapper",
  [ "mapper"
  ];
]

let all_types = List.concat (List.map ~f:snd qualified_types)

let foreach_module f =
  nl ();
  List.iter qualified_types ~f:(fun (m, types) -> f m types)

let foreach_type f =
  foreach_module (fun m -> List.iter ~f:(f m))

let foreach_version f =
  nl ();
  List.iter supported_versions ~f:(fun (suffix, version) -> f suffix version)

let foreach_version_pair f =
  nl ();
  let rec aux = function
    | (x,_) :: ((y,_) :: _ as tail) -> f x y; aux tail
    | [_] | [] -> ()
  in
  aux supported_versions

let with_then_and () =
  let first = ref true in fun oc ->
    output_string oc (if !first then "with" else "and");
    first := false
