57 lines
1.5 KiB
OCaml
57 lines
1.5 KiB
OCaml
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 <json|c> --input <path> [--output <path>]" 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
|