summaryrefslogtreecommitdiff
path: root/Jennisys/Options.fs
blob: 4bd59b111dc57085e6e8443cfb178fc3b320da24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//  ####################################################################
///   This module is intended to store and handle configuration options
///
///   author: Aleksandar Milicevic (t-alekm@microsoft.com)
//  ####################################################################

module Options

open Utils

type Config = {
   inputFilename: string;
   methodToSynth: string;
   verifyPartialSolutions: bool;
   verifySolutions: bool;
   checkUnifications: bool;
   genRepr: bool;
   timeout: int;
   numLoopUnrolls: int;
}

let defaultConfig: Config = {
  inputFilename     = "";
  methodToSynth     = "*";
  verifyPartialSolutions = true;
  verifySolutions   = true;
  checkUnifications = false;
  genRepr           = false;
  timeout           = 0;
  numLoopUnrolls    = 2;
}

/// Should not be mutated outside the ParseCmdLineArgs method, which is 
/// typically called only once at the beginning of the program execution 
let mutable CONFIG = defaultConfig

exception InvalidCmdLineArg of string
exception InvalidCmdLineOption of string

let ParseCmdLineArgs args = 
  let __StripSwitches str =
    match str with 
    | Prefix "--" x 
    | Prefix "-" x
    | Prefix "/" x -> x
    | _ -> str

  let __Split (str: string) =
    let stripped = __StripSwitches str
    if stripped = str then
      ("",str) 
    else
      let splits = stripped.Split([| ':' |])
      if splits.Length > 2 then raise (InvalidCmdLineOption("more than 2 colons in " + str))
      if splits.Length = 2 then
        let opt = splits.[0]
        let value = splits.[1]
        (opt,value)
      else
        let x = __StripSwitches splits.[0]
        (x, "")

  let __CheckNonEmpty value optName =
    if value = "" then raise (InvalidCmdLineArg("A value for option " + optName + " must not be empty"))

  let __CheckInt value optName =
    try 
      System.Int32.Parse value
    with 
      | ex -> raise (InvalidCmdLineArg("A value for option " + optName + " must be a boolean"))

  let __CheckBool value optName =
    if value = "" then
      true
    else
      try 
        System.Boolean.Parse value
      with 
        | ex -> raise (InvalidCmdLineArg("A value for option " + optName + " must be an integer"))
               
  let rec __Parse args cfg =
    match args with
    | fs :: rest -> 
        let opt,value = __Split fs
        match opt with
        | "method"    -> 
            __CheckNonEmpty value opt
            __Parse rest { cfg with methodToSynth = value }
        | "verifyParSol" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with verifyPartialSolutions = b }
        | "noVerifyParSol" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with verifyPartialSolutions = not b }
        | "verifySol" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with verifySolutions = b }
        | "noVerifySol" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with verifySolutions = not b }
        | "checkUnifs" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with checkUnifications = b }
        | "noCheckUnifs" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with checkUnifications = not b }
        | "genRepr" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with genRepr = b }
        | "noGenRepr" -> 
            let b = __CheckBool value opt
            __Parse rest { cfg with genRepr = not b }
        | "timeout" ->
            let t = __CheckInt value opt
            __Parse rest { cfg with timeout = t }
        | "unrolls" ->
            let t = __CheckInt value opt
            __Parse rest { cfg with numLoopUnrolls = t }
        | "" -> 
            __Parse rest { cfg with inputFilename = value }
        | _ -> 
            raise (InvalidCmdLineOption("Unknown option: " + opt))
    | [] -> cfg   
    
  (* --- function body starts here --- *)           
  CONFIG <- __Parse args defaultConfig