(* Top-level of the MicroC compiler: scan & parse the input,
   check the resulting AST, generate LLVM IR, and dump the module *)
type action = AST | LLVM_IR | Compile

let append files =
    let channel = open_out "excute.pn" in
        List.iter ( fun filename ->
            let read_file = open_in filename in
            try while true do
                output_string channel (input_line read_file);
                output_string channel ("\n")
            done
            with End_of_file -> close_in read_file
        ) files;
    close_out channel;;

let _ =
  let action = ref Compile in
  let set_action a () = action := a in
  let speclist = [
    ("-l", Arg.Unit (set_action LLVM_IR), "Print the generated LLVM IR");
    ("-c", Arg.Unit (set_action Compile),
      "Check and print the generated LLVM IR (default)");
  ] in
  let usage_msg = "usage: ./pienum.native [-a|-l|-c] [file.pn]" in
  let channel = ref stdin in
    Arg.parse speclist (fun filename -> channel := open_in filename) usage_msg;
  let lexbuf = Lexing.from_channel !channel in
  let ast = Parser.program Scanner.token lexbuf in
  Semant.check ast;
  match !action with
  LLVM_IR -> print_string (Llvm.string_of_llmodule (Codegen.translate ast))
  | Compile -> let m = Codegen.translate ast in
    Llvm_analysis.assert_valid_module m;
    print_string (Llvm.string_of_llmodule m)
