spooky/bin/main.ml

69 lines
1.8 KiB
OCaml

type generator = Json | C
let read_file path =
let ic = open_in_bin path in
Fun.protect
~finally:(fun () -> close_in ic)
(fun () -> really_input_string ic (in_channel_length ic))
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 src =
try read_file !input_path
with Sys_error msg ->
prerr_endline ("Input error: " ^ msg);
exit 1
in
let ast =
match Spooky.parse_string src 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