type generator = Json | C let write_file path content = let oc = open_out_bin path in Fun.protect ~finally:(fun () -> close_out oc) (fun () -> output_string oc content) let () = let generator = ref Json in let input_path = ref "" in let output_path = ref None in let set_generator = function | "json" -> generator := Json | "c" -> generator := C | _ -> invalid_arg "unsupported generator" in let specs = [ ( "--generator", Arg.Symbol ([ "json"; "c" ], set_generator), "Code generator to run: json or c" ); ("--input", Arg.String (fun p -> input_path := p), "Input source file path"); ("--output", Arg.String (fun p -> output_path := Some p), "Optional output file path"); ] in let usage = "Usage: spooky --generator --input [--output ]" in Arg.parse specs (fun _ -> ()) usage; if String.equal !input_path "" then ( prerr_endline "Missing required --input argument."; Arg.usage specs usage; exit 2); let ast = match Spooky.parse_file !input_path with | Error msg -> prerr_endline msg; exit 1 | Ok ast -> ast in (match Spooky.type_check ast with | Error msg -> prerr_endline ("type error: " ^ msg); exit 1 | Ok () -> ()); let generated = match !generator with | Json -> Spooky.generate_json ast | C -> Spooky.generate_c ast in match !output_path with | Some path -> (try write_file path generated with Sys_error msg -> prerr_endline ("Output error: " ^ msg); exit 1) | None -> print_endline generated