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