#load "q_MLast.cmo";;

let loc = (Lexing.dummy_pos, Lexing.dummy_pos)

let usage =
"Usage: cdo2ml [-static] <module>.cdo

 Can also be used as a preprocessor for OCaml:

 ocamlc -c -pp cdo2ml -impl <module>.cdo
 ocamlc -c -pp \"cdo2ml -static\" -impl <module>.cdo
" 

let err () = prerr_endline usage; exit 1

let str = String.escaped

let list_lit el =
  List.fold_right (fun a e -> <:expr< [$a$ :: $e$] >>) el <:expr< [] >>

let () =
  let fn,static = 
    match Array.length Sys.argv with
      | 2 -> Sys.argv.(1),false
      | 3 ->
	  if Sys.argv.(1) <> "-static" then err ();
	  Sys.argv.(2),true
      | _ -> err ()
  in
  let ic = 
    try open_in fn
    with Sys_error x ->
      prerr_endline x;
      exit 1 in
  let (name,digest,depend,raw,stub) : 
    string * Digest.t * (string*string) list * string * 
    (string * 'a) option =
    input_value ic in
  let (prolog,code) = 
    match stub with
      | None ->
	  Printf.eprintf "Error: no stub found in this cdo file !\n";
	  exit 1
      | Some x -> x in
  print_endline "(* Automatically generated by cdo2ml.ml. Do no edit ! *)";
  print_endline prolog;

  let cu =
    if static then
      let dep = 
	list_lit 
	  (List.map 
	     (fun (cu,chk) -> <:expr< ($str:str cu$,$str:str chk$) >>)
	     depend)
      in
      <:expr< Cduce_lib.Librarian.register_unit 
	$str:str name$ $str:str raw$ $str:str digest$ $dep$ >>
    else 
      <:expr< Cduce_lib.Librarian.load_unit $str:str name$ $str:str digest$ >>
  in
  let cu = <:str_item< value cu = $cu$ >> in

  let (pat,items,exp) = code in
  let items = cu :: items in
  let str_items = 
    [ <:str_item< 
      value $pat$ = let module C = struct $list:items$ end in $exp$ >> ]
  in
  let str_items = List.map (fun x -> (x,loc)) str_items in
  !Pcaml.print_implem str_items
