| 2341 |      1 | (*  Title:      Pure/ML-Systems/polyml.ML
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
 | 
|  |      4 |     Copyright   1991  University of Cambridge
 | 
|  |      5 | 
 | 
| 11078 |      6 | Compatibility file for Poly/ML (version 4.0).
 | 
| 2341 |      7 | *)
 | 
|  |      8 | 
 | 
| 11078 |      9 | (** ML system related **)
 | 
| 2341 |     10 | 
 | 
| 11078 |     11 | (* old Poly/ML emulation *)
 | 
| 2341 |     12 | 
 | 
| 11078 |     13 | local
 | 
|  |     14 |   val orig_exit = exit;
 | 
|  |     15 | in
 | 
|  |     16 |   open PolyML;
 | 
|  |     17 |   val exit = orig_exit;
 | 
|  |     18 |   fun quit () = exit 0;
 | 
| 7148 |     19 | end;
 | 
| 6042 |     20 | 
 | 
| 2341 |     21 | 
 | 
| 11078 |     22 | (* restore old-style character / string functions *)
 | 
| 3588 |     23 | 
 | 
| 11078 |     24 | val ord = SML90.ord;
 | 
|  |     25 | val chr = SML90.chr;
 | 
|  |     26 | val explode = SML90.explode;
 | 
|  |     27 | val implode = SML90.implode;
 | 
|  |     28 | 
 | 
| 3588 |     29 | 
 | 
| 4326 |     30 | (*Note start point for timing*)
 | 
| 11078 |     31 | fun startTiming() =
 | 
|  |     32 |   let val CPUtimer = Timer.startCPUTimer();
 | 
|  |     33 |       val time = Timer.checkCPUTimer(CPUtimer)
 | 
|  |     34 |   in  (CPUtimer,time)  end;
 | 
| 2341 |     35 | 
 | 
| 4326 |     36 | (*Finish timing and return string*)
 | 
| 11078 |     37 | fun endTiming (CPUtimer, {sys,usr}) =
 | 
|  |     38 |   let open Time  (*...for Time.toString, Time.+ and Time.- *)
 | 
|  |     39 |       val {sys=sys2,usr=usr2} = Timer.checkCPUTimer(CPUtimer)
 | 
|  |     40 |   in  "User " ^ toString (usr2-usr) ^
 | 
|  |     41 |       "  All "^ toString (sys2-sys + usr2-usr) ^
 | 
|  |     42 |       " secs"
 | 
|  |     43 |       handle Time => ""
 | 
|  |     44 |   end;
 | 
| 2341 |     45 | 
 | 
|  |     46 | 
 | 
| 4977 |     47 | (* prompts *)
 | 
|  |     48 | 
 | 
| 4984 |     49 | fun ml_prompts p1 p2 = (PolyML.Compiler.prompt1 := p1; PolyML.Compiler.prompt2 := p2);
 | 
| 4977 |     50 | 
 | 
|  |     51 | 
 | 
| 3588 |     52 | (* toplevel pretty printing (see also Pure/install_pp.ML) *)
 | 
| 2341 |     53 | 
 | 
| 11078 |     54 | fun make_pp _ pprint (str, blk, brk, en) _ _ obj =
 | 
| 2341 |     55 |   pprint obj (str, fn ind => blk (ind, false), fn wd => brk (wd, 0),
 | 
|  |     56 |     fn () => brk (99999, 0), en);
 | 
|  |     57 | 
 | 
|  |     58 | 
 | 
| 3588 |     59 | (* ML command execution -- 'eval' *)
 | 
|  |     60 | 
 | 
| 7890 |     61 | local
 | 
|  |     62 | 
 | 
|  |     63 | fun drop_last [] = []
 | 
|  |     64 |   | drop_last [x] = []
 | 
|  |     65 |   | drop_last (x :: xs) = x :: drop_last xs;
 | 
|  |     66 | 
 | 
|  |     67 | val drop_last_char = implode o drop_last o explode;
 | 
|  |     68 | 
 | 
|  |     69 | in
 | 
|  |     70 | 
 | 
| 10914 |     71 | fun use_text (print, err) verbose txt =
 | 
| 3588 |     72 |   let
 | 
| 5090 |     73 |     val in_buffer = ref (explode txt);
 | 
|  |     74 |     val out_buffer = ref ([]: string list);
 | 
| 10914 |     75 |     fun output () = drop_last_char (implode (rev (! out_buffer)));
 | 
| 5090 |     76 | 
 | 
| 5038 |     77 |     fun get () =
 | 
| 5090 |     78 |       (case ! in_buffer of
 | 
| 5038 |     79 |         [] => ""
 | 
| 5090 |     80 |       | c :: cs => (in_buffer := cs; c));
 | 
|  |     81 |     fun put s = out_buffer := s :: ! out_buffer;
 | 
|  |     82 | 
 | 
| 5038 |     83 |     fun exec () =
 | 
| 5090 |     84 |       (case ! in_buffer of
 | 
| 5038 |     85 |         [] => ()
 | 
| 5090 |     86 |       | _ => (PolyML.compiler (get, put) (); exec ()));
 | 
|  |     87 |   in
 | 
| 10914 |     88 |     exec () handle exn => (err (output ()); raise exn);
 | 
|  |     89 |     if verbose then print (output ()) else ()
 | 
| 5090 |     90 |   end;
 | 
| 3588 |     91 | 
 | 
| 11078 |     92 | end;
 | 
|  |     93 | 
 | 
|  |     94 | 
 | 
|  |     95 | 
 | 
|  |     96 | (** interrupts **)
 | 
|  |     97 | 
 | 
|  |     98 | exception Interrupt = SML90.Interrupt;
 | 
|  |     99 | 
 | 
|  |    100 | local
 | 
|  |    101 | 
 | 
| 12989 |    102 | fun capture f x = ((f x): unit; NONE) handle exn => SOME exn;
 | 
| 11078 |    103 | 
 | 
| 12989 |    104 | fun release NONE = ()
 | 
|  |    105 |   | release (SOME exn) = raise exn;
 | 
| 3588 |    106 | 
 | 
| 11078 |    107 | val sig_int = 2;
 | 
|  |    108 | 
 | 
|  |    109 | fun change_signal new_handler f x =
 | 
|  |    110 |   let
 | 
|  |    111 |     (*RACE wrt. other signals*)
 | 
|  |    112 |     val old_handler = Signal.signal (sig_int, new_handler);
 | 
|  |    113 |     val result = capture f x;
 | 
|  |    114 |     val _ = Signal.signal (sig_int, old_handler);
 | 
|  |    115 |   in release result end;
 | 
| 5813 |    116 | 
 | 
| 11078 |    117 | val default_handler = Signal.SIG_HANDLE (fn _ => Process.interruptConsoleProcesses ());
 | 
|  |    118 | 
 | 
|  |    119 | in
 | 
|  |    120 | 
 | 
|  |    121 | val _ = Signal.signal (sig_int, default_handler);
 | 
|  |    122 | 
 | 
| 12989 |    123 | fun ignore_interrupt f = change_signal Signal.SIG_IGN f;
 | 
|  |    124 | fun raise_interrupt f = change_signal default_handler f;
 | 
| 11078 |    125 | 
 | 
|  |    126 | end;
 | 
| 5813 |    127 | 
 | 
|  |    128 | 
 | 
|  |    129 | 
 | 
| 3588 |    130 | (** OS related **)
 | 
| 2341 |    131 | 
 | 
| 3588 |    132 | (* system command execution *)
 | 
| 2341 |    133 | 
 | 
| 3588 |    134 | (*execute Unix command which doesn't take any input from stdin and
 | 
| 11078 |    135 |   sends its output to stdout; could be done more easily by Unix.execute,
 | 
|  |    136 |   but that function doesn't use the PATH*)
 | 
| 3588 |    137 | fun execute command =
 | 
|  |    138 |   let
 | 
| 11078 |    139 |     val tmp_name = OS.FileSys.tmpName ();
 | 
|  |    140 |     val is = (OS.Process.system (command ^ " > " ^ tmp_name); TextIO.openIn tmp_name);
 | 
|  |    141 |     val result = TextIO.inputAll is;
 | 
|  |    142 |   in
 | 
|  |    143 |     TextIO.closeIn is;
 | 
|  |    144 |     OS.FileSys.remove tmp_name;
 | 
|  |    145 |     result
 | 
|  |    146 |   end;
 | 
| 7855 |    147 | 
 | 
| 11078 |    148 | (*plain version; with return code*)
 | 
|  |    149 | fun system cmd =
 | 
|  |    150 |   if OS.Process.isSuccess (OS.Process.system cmd) then 0 else 1;
 | 
| 2341 |    151 | 
 | 
|  |    152 | 
 | 
| 3588 |    153 | (* file handling *)
 | 
| 2341 |    154 | 
 | 
| 6227 |    155 | (*get time of last modification*)
 | 
| 11078 |    156 | fun file_info name = Time.toString (OS.FileSys.modTime name) handle _ => "";
 | 
| 3588 |    157 | 
 | 
|  |    158 | 
 | 
|  |    159 | (* getenv *)
 | 
|  |    160 | 
 | 
| 11078 |    161 | fun getenv var =
 | 
|  |    162 |   (case OS.Process.getEnv var of
 | 
|  |    163 |     NONE => ""
 | 
|  |    164 |   | SOME txt => txt);
 |