aboutsummaryrefslogtreecommitdiffstats
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 <filename>'")
  | 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))