src/Pure/ML-Systems/smlnj.ML
author berghofe
Fri Dec 21 17:31:45 2001 +0100 (2001-12-21)
changeset 12581 dceea9dbdedd
parent 12108 b6f10dcde803
child 12874 368966ceafe5
permissions -rw-r--r--
Redundant patterns no longer cause errors.
     1 (*  Title:      Pure/ML-Systems/smlnj.ML
     2     ID:         $Id$
     3     Author:     Carsten Clasohm and Markus Wenzel, TU Muenchen
     4 
     5 Compatibility file for Standard ML of New Jersey 110 or later.
     6 *)
     7 
     8 (** ML system related **)
     9 
    10 (* restore old-style character / string functions *)
    11 
    12 val ord     = SML90.ord;
    13 val chr     = SML90.chr;
    14 val explode = SML90.explode;
    15 val implode = SML90.implode;
    16 
    17 
    18 (* New Jersey ML parameters *)
    19 
    20 val _ =
    21  (Compiler.Control.Print.printLength := 1000;
    22   Compiler.Control.Print.printDepth := 350;
    23   Compiler.Control.Print.stringDepth := 250;
    24   Compiler.Control.Print.signatures := 2;
    25   Compiler.Control.MC.matchRedundantError := false);
    26 
    27 
    28 (* Poly/ML emulation *)
    29 
    30 fun quit () = exit 0;
    31 
    32 (*limit the printing depth -- divided by 2 for comparibility with Poly/ML*)
    33 fun print_depth n =
    34  (Compiler.Control.Print.printDepth := n div 2;
    35   Compiler.Control.Print.printLength := n);
    36 
    37 
    38 (* compiler-independent timing functions *)
    39 
    40 (*Note start point for timing*)
    41 fun startTiming() =
    42   let val CPUtimer = Timer.startCPUTimer();
    43       val time = Timer.checkCPUTimer(CPUtimer)
    44   in  (CPUtimer,time)  end;
    45 
    46 (*Finish timing and return string*)
    47 fun endTiming (CPUtimer, {gc,sys,usr}) =
    48   let open Time  (*...for Time.toString, Time.+ and Time.- *)
    49       val {gc=gc2,sys=sys2,usr=usr2} = Timer.checkCPUTimer(CPUtimer)
    50   in  "User " ^ toString (usr2-usr) ^
    51       "  GC " ^ toString (gc2-gc) ^
    52       "  All "^ toString (sys2-sys + usr2-usr + gc2-gc) ^
    53       " secs"
    54       handle Time => ""
    55   end;
    56 
    57 
    58 (* prompts *)
    59 
    60 fun ml_prompts p1 p2 =
    61   (Compiler.Control.primaryPrompt := p1; Compiler.Control.secondaryPrompt := p2);
    62 
    63 
    64 (* toplevel pretty printing (see also Pure/install_pp.ML) *)
    65 
    66 fun make_pp path pprint =
    67   let
    68     open Compiler.PrettyPrint;
    69 
    70     fun pp pps obj =
    71       pprint obj
    72         (add_string pps, begin_block pps INCONSISTENT,
    73           fn wd => add_break pps (wd, 0), fn () => add_newline pps,
    74           fn () => end_block pps);
    75   in
    76     (path, pp)
    77   end;
    78 
    79 fun install_pp (path, pp) = Compiler.PPTable.install_pp path pp;
    80 
    81 
    82 (* ML command execution *)
    83 
    84 fun use_text (print, err) verbose txt =
    85   let
    86     val ref out_orig = Compiler.Control.Print.out;
    87 
    88     val out_buffer = ref ([]: string list);
    89     val out = {say = (fn s => out_buffer := s :: ! out_buffer), flush = (fn () => ())};
    90     fun output () =
    91       let val str = implode (rev (! out_buffer))
    92       in String.substring (str, 0, Int.max (0, size str - 1)) end;
    93   in
    94     Compiler.Control.Print.out := out;
    95     Compiler.Interact.useStream (TextIO.openString txt) handle exn =>
    96       (Compiler.Control.Print.out := out_orig; err (output ()); raise exn);
    97     Compiler.Control.Print.out := out_orig;
    98     if verbose then print (output ()) else ()
    99   end;
   100 
   101 
   102 
   103 (** interrupts **)
   104 
   105 local
   106 
   107 datatype 'a result =
   108   Result of 'a |
   109   Exn of exn;
   110 
   111 fun capture f x = Result (f x) handle exn => Exn exn;
   112 
   113 fun release (Result x) = x
   114   | release (Exn exn) = raise exn;
   115 
   116 
   117 val sig_int = Signals.sigINT;
   118 val sig_int_mask = Signals.MASK [Signals.sigINT];
   119 
   120 fun interruptible () =
   121   (case Signals.masked () of
   122     Signals.MASKALL => false
   123   | Signals.MASK sigs => List.all (fn s => s <> sig_int) sigs);
   124 
   125 val mask_signals = Signals.maskSignals;
   126 val unmask_signals = Signals.unmaskSignals;
   127 
   128 fun change_mask ok change unchange f x =
   129   if ok () then f x
   130   else
   131     let
   132       val _ = change sig_int_mask;
   133       val result = capture f x;
   134       val _ = unchange sig_int_mask;
   135     in release result end;
   136 
   137 in
   138 
   139 
   140 (* mask / unmask interrupt *)
   141 
   142 fun mask_interrupt f = change_mask (not o interruptible) mask_signals unmask_signals f;
   143 fun unmask_interrupt f = change_mask interruptible unmask_signals mask_signals f;
   144 
   145 
   146 (* exhibit interrupt (via exception) *)
   147 
   148 exception Interrupt;
   149 
   150 fun exhibit_interrupt f x =
   151   let
   152     val orig_handler = Signals.inqHandler sig_int;
   153     fun reset_handler () = (Signals.setHandler (sig_int, orig_handler); ());
   154 
   155     val interrupted = ref false;
   156 
   157     fun set_handler cont =
   158       Signals.setHandler (sig_int, Signals.HANDLER (fn _ => (interrupted := true; cont)));
   159 
   160     fun proceed cont =
   161       let
   162         val _ = set_handler cont;
   163         val result = unmask_interrupt (capture f) x;
   164         val _ = reset_handler ();
   165       in release result end;
   166   in
   167     SMLofNJ.Cont.callcc proceed;
   168     reset_handler ();
   169     if ! interrupted then raise Interrupt else ()
   170    end;
   171 
   172 end;
   173 
   174 
   175 
   176 (** OS related **)
   177 
   178 (* system command execution *)
   179 
   180 (*execute Unix command which doesn't take any input from stdin and
   181   sends its output to stdout; could be done more easily by Unix.execute,
   182   but that function doesn't use the PATH*)
   183 fun execute command =
   184   let
   185     val tmp_name = OS.FileSys.tmpName ();
   186     val is = (OS.Process.system (command ^ " > " ^ tmp_name); TextIO.openIn tmp_name);
   187     val result = TextIO.inputAll is;
   188   in
   189     TextIO.closeIn is;
   190     OS.FileSys.remove tmp_name;
   191     result
   192   end;
   193 
   194 (*plain version; with return code*)
   195 val system = OS.Process.system: string -> int; 
   196 
   197 
   198 (* file handling *)
   199 
   200 (*get time of last modification*)
   201 fun file_info name = Time.toString (OS.FileSys.modTime name) handle _ => "";
   202 
   203 
   204 (* getenv *)
   205 
   206 fun getenv var =
   207   (case OS.Process.getEnv var of
   208     NONE => ""
   209   | SOME txt => txt);