open Core type fuel_amount = [ `Limited | `Unlimited ] type eval_strategy = [ `Shallow | `Deep ] type options = { eval_strategy : eval_strategy ref; fuel_amount : fuel_amount ref; imports_def_file : string option ref; print_input : bool ref; print_parsed : bool ref; print_elaborated : bool ref; print_nix_sexp : bool ref; print_mininix_sexp : bool ref; print_mininix_sexp_w_prelude : bool ref; print_result_mininix_sexp : bool ref; print_result_nix_sexp : bool ref; } let opts = { eval_strategy = ref `Deep; fuel_amount = ref `Unlimited; imports_def_file = ref None; print_input = ref false; print_parsed = ref false; print_elaborated = ref false; print_nix_sexp = ref false; print_mininix_sexp = ref false; print_mininix_sexp_w_prelude = ref false; print_result_mininix_sexp = ref false; print_result_nix_sexp = ref false; } type 'a setter = 'a -> unit type setting = | BoolSetting of bool ref | EvalStrategySetting of eval_strategy ref | FilenameOptionSetting of string option ref | FuelAmountSetting of fuel_amount ref let allowed_values s = match s with | BoolSetting _ -> [ "true"; "false" ] | EvalStrategySetting _ -> [ "shallow"; "deep" ] | FilenameOptionSetting _ -> [ "none"; "some " ] | FuelAmountSetting _ -> [ "limited"; "unlimited" ] let set_to s v = match s with | BoolSetting vref -> ( match v with | [ "true" ] -> vref := true; None | [ "false" ] -> vref := false; None | _ -> Some "expected one argument: 'true' or 'false'") | EvalStrategySetting vref -> ( match v with | [ "shallow" ] -> vref := `Shallow; None | [ "deep" ] -> vref := `Deep; None | _ -> Some "expected one argument: 'shallow' or 'deep'") | FilenameOptionSetting vref -> ( match v with | [ "none" ] -> vref := None; None | [ "some"; filename ] -> vref := Some (String.strip filename); None | _ -> Some "expected 'none' or 'some '") | FuelAmountSetting vref -> ( match v with | [ "limited" ] -> vref := `Limited; None | [ "unlimited" ] -> vref := `Unlimited; None | _ -> Some "expected 'limited' or 'unlimited'") let to_string s = match s with | BoolSetting vref -> Bool.to_string !vref | EvalStrategySetting vref -> ( match !vref with `Shallow -> "shallow" | `Deep -> "deep") | FilenameOptionSetting vref -> ( match !vref with None -> "none" | Some v -> "some " ^ v) | FuelAmountSetting vref -> ( match !vref with `Limited -> "limited" | `Unlimited -> "unlimited") let settings = Map.of_alist_exn (module String) [ ("print_input", BoolSetting opts.print_input); ("print_parsed", BoolSetting opts.print_parsed); ("print_elaborated", BoolSetting opts.print_elaborated); ("print_nix_sexp", BoolSetting opts.print_nix_sexp); ("print_mininix_sexp", BoolSetting opts.print_mininix_sexp); ( "print_mininix_sexp_w_prelude", BoolSetting opts.print_mininix_sexp_w_prelude ); ("print_result_mininix_sexp", BoolSetting opts.print_result_mininix_sexp); ("print_result_nix_sexp", BoolSetting opts.print_result_nix_sexp); ("eval_strategy", EvalStrategySetting opts.eval_strategy); ("fuel_amount", FuelAmountSetting opts.fuel_amount); ("imports_def_file", FilenameOptionSetting opts.imports_def_file); ] let print () = printf "==> Settings:\n"; Map.iteri settings ~f:(fun ~key:name ~data:setting -> printf " %s: %s\n" name (to_string setting))