summaryrefslogtreecommitdiff
path: root/driver.fun
blob: ff990916903894a4c62132da94e28947cb753be4 (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
functor Driver(P: PARSER): DRIVER = struct
  structure P = P

  datatype execMode = Normal | DebugE | DebugT

  type config = {
    file: string option,
    includeDirs: string list,
    mode: execMode
  }

  val updateC = fn z =>
  let
    fun from file includeDirs mode = { file, includeDirs, mode }
    fun to f { file, includeDirs, mode } = f file includeDirs mode
  in
    FRU.makeUpdate3 (from, from, to)
  end z

  val initConfig: config = { file = NONE, includeDirs = [], mode = Normal }

  val die = fn z => die 1 z

  fun finish ({ file = NONE, ... }: config) = die `"missing input file" %
    | finish conf = updateC conf u#includeDirs rev %

  fun parseFlag conf "-dE" tail =
    parseCmdArgs (updateC conf s#mode DebugE %) tail
    | parseFlag conf "-dT" tail =
        parseCmdArgs (updateC conf s#mode DebugT %) tail
    | parseFlag _ arg _ = die `arg `": unknown flag" %

  and parseCmdArgs conf [] = finish conf
    | parseCmdArgs _ ("-I" :: []) =
        die `"-I: expected directory path after flag" %
    | parseCmdArgs conf ("-I" :: path :: tail) =
        parseCmdArgs (updateC conf u#includeDirs
            (fn dirs => path :: dirs) %) tail
    | parseCmdArgs (C as { file, ... }) (arg :: tail) =
      if String.sub (arg, 0) = #"-" then
        parseFlag C arg tail
      else
        case file of
          NONE => parseCmdArgs (updateC C s#file (SOME arg) %) tail
        | SOME _ => die `arg `": file already specified" %

  fun exec () =
  let
    val config = parseCmdArgs initConfig (CommandLine.arguments ())
    val file = valOf $ #file config
  in
    case (#mode config) of
      Normal =>
        let
          val parseCtx = P.createParseCtx file (#includeDirs config)

          fun collect ctx =
          let
            val result = P.parseDef ctx
          in
            case result of
              NONE => ()
            | SOME (def, ctx) => (
              P.printDef def;
              collect ctx
            )
          end
        in
          collect parseCtx
        end
    | DebugT => P.P.T.debugPrint file
    | DebugE => P.P.debugPrint file (#includeDirs config)
  end
end