1open OS.Process
2open filter.UserDeclarations
3
4fun slave (input, outstream) state = let
5   val lexer = filter.makeLexer input state
6in
7   lexer();
8   TextIO.closeOut outstream;
9   exit success
10end
11
12fun noninteractive (is,os) = let
13  fun input n = TextIO.input is
14in
15  (fn () => slave(input, os) (newstate os))
16end
17
18fun interactive () = let
19  open MLton.Thread
20  val out = TextIO.stdOut
21  fun input _ = TextIO.input TextIO.stdIn
22  fun go() = prepare (new (slave (input, out)), newstate out)
23  fun interrupt_handler _ = go()
24
25  val h = MLton.Signal.Handler.handler interrupt_handler
26in
27  MLton.Signal.setHandler(Posix.Signal.int, h);
28  switch interrupt_handler
29end
30
31val go : unit -> unit =
32    case CommandLine.arguments() of
33        [] => interactive
34      | [ifile, ofile] =>
35        let
36          open TextIO
37          val is = openIn ifile
38                   handle OS.SysErr _ =>
39                          (output(stdErr, "Error opening "^ifile^"\n");
40                           exit failure)
41          val os = openOut ofile
42                   handle IO.Io {cause = OS.SysErr (_, eo), ...} =>
43                          (case eo of
44                             SOME e => output(stdErr, OS.errorMsg e)
45                            | NONE => ();
46                           exit failure)
47        in
48          noninteractive (is,os)
49        end
50      | _ => (TextIO.output(TextIO.stdErr,
51                            "Usage:\n  " ^ CommandLine.name() ^
52                            " [<inputfile> <outputfile>]\n");
53              exit failure)
54
55val _ = go()
56