| author | wenzelm | 
| Fri, 06 Jan 2006 18:18:16 +0100 | |
| changeset 18598 | 94d658871c98 | 
| parent 18384 | fa38cca42913 | 
| child 18760 | 97aaecb84afe | 
| permissions | -rw-r--r-- | 
| 4403 | 1 | (* Title: Pure/ML-Systems/smlnj.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Carsten Clasohm and Markus Wenzel, TU Muenchen | |
| 4 | ||
| 5708 | 5 | Compatibility file for Standard ML of New Jersey 110 or later. | 
| 4403 | 6 | *) | 
| 7 | ||
| 12874 
368966ceafe5
ML-Systems/smlnj-compiler.ML compatibility tweak;
 wenzelm parents: 
12581diff
changeset | 8 | (case #version_id (Compiler.version) of | 
| 
368966ceafe5
ML-Systems/smlnj-compiler.ML compatibility tweak;
 wenzelm parents: 
12581diff
changeset | 9 | [110, x] => if x >= 35 then use "ML-Systems/smlnj-compiler.ML" else () | 
| 
368966ceafe5
ML-Systems/smlnj-compiler.ML compatibility tweak;
 wenzelm parents: 
12581diff
changeset | 10 | | _ => ()); | 
| 
368966ceafe5
ML-Systems/smlnj-compiler.ML compatibility tweak;
 wenzelm parents: 
12581diff
changeset | 11 | |
| 16542 | 12 | |
| 4403 | 13 | (** ML system related **) | 
| 14 | ||
| 16542 | 15 | (*low-level pointer equality*) | 
| 16502 | 16 | |
| 16542 | 17 | (*dummy version -- may get overridden in smlnj-ptreql.ML*) | 
| 18 | fun pointer_eq (x:'a, y) = false; | |
| 16502 | 19 | |
| 16528 | 20 | (case #version_id (Compiler.version) of | 
| 21 | [110, x] => if x >= 49 then use "ML-Systems/smlnj-ptreql.ML" else () | |
| 22 | | _ => ()); | |
| 23 | ||
| 16502 | 24 | |
| 4403 | 25 | (* restore old-style character / string functions *) | 
| 26 | ||
| 10725 | 27 | val ord = SML90.ord; | 
| 28 | val chr = SML90.chr; | |
| 29 | val explode = SML90.explode; | |
| 30 | val implode = SML90.implode; | |
| 4403 | 31 | |
| 32 | ||
| 33 | (* New Jersey ML parameters *) | |
| 34 | ||
| 35 | val _ = | |
| 36 | (Compiler.Control.Print.printLength := 1000; | |
| 37 | Compiler.Control.Print.printDepth := 350; | |
| 38 | Compiler.Control.Print.stringDepth := 250; | |
| 12581 | 39 | Compiler.Control.Print.signatures := 2; | 
| 40 | Compiler.Control.MC.matchRedundantError := false); | |
| 4403 | 41 | |
| 42 | ||
| 43 | (* Poly/ML emulation *) | |
| 44 | ||
| 45 | fun quit () = exit 0; | |
| 46 | ||
| 47 | (*limit the printing depth -- divided by 2 for comparibility with Poly/ML*) | |
| 48 | fun print_depth n = | |
| 49 | (Compiler.Control.Print.printDepth := n div 2; | |
| 50 | Compiler.Control.Print.printLength := n); | |
| 51 | ||
| 52 | ||
| 5816 | 53 | (* compiler-independent timing functions *) | 
| 4403 | 54 | |
| 14519 
4ca3608fdf4f
Added support for the newer versions of SML/NJ, which break several of the
 skalberg parents: 
12990diff
changeset | 55 | (case #version_id (Compiler.version) of | 
| 14656 | 56 | [110, x] => if x >= 44 | 
| 16542 | 57 | then use "ML-Systems/cpu-timer-basis.ML" | 
| 58 | else use "ML-Systems/cpu-timer-gc.ML" | |
| 14520 | 59 | | _ => use "ML-Systems/cpu-timer-gc.ML"); | 
| 4403 | 60 | |
| 61 | ||
| 16660 | 62 | (*prompts*) | 
| 4977 | 63 | fun ml_prompts p1 p2 = | 
| 64 | (Compiler.Control.primaryPrompt := p1; Compiler.Control.secondaryPrompt := p2); | |
| 65 | ||
| 17511 | 66 | (*dummy implementation*) | 
| 16681 | 67 | fun profile (n: int) f x = f x; | 
| 68 | ||
| 17511 | 69 | (*dummy implementation*) | 
| 16681 | 70 | fun exception_trace f = f (); | 
| 4977 | 71 | |
| 18384 | 72 | (*dummy implementation*) | 
| 73 | fun print x = x; | |
| 16681 | 74 | |
| 4403 | 75 | (* toplevel pretty printing (see also Pure/install_pp.ML) *) | 
| 76 | ||
| 14519 
4ca3608fdf4f
Added support for the newer versions of SML/NJ, which break several of the
 skalberg parents: 
12990diff
changeset | 77 | (case #version_id (Compiler.version) of | 
| 14656 | 78 | [110, x] => if x >= 44 | 
| 16542 | 79 | then use "ML-Systems/smlnj-pp-new.ML" | 
| 80 | else use "ML-Systems/smlnj-pp-old.ML" | |
| 14520 | 81 | | _ => use "ML-Systems/smlnj-pp-old.ML"); | 
| 4403 | 82 | |
| 83 | fun install_pp (path, pp) = Compiler.PPTable.install_pp path pp; | |
| 84 | ||
| 85 | ||
| 86 | (* ML command execution *) | |
| 87 | ||
| 10914 | 88 | fun use_text (print, err) verbose txt = | 
| 5090 | 89 | let | 
| 90 | val ref out_orig = Compiler.Control.Print.out; | |
| 91 | ||
| 92 | val out_buffer = ref ([]: string list); | |
| 93 |     val out = {say = (fn s => out_buffer := s :: ! out_buffer), flush = (fn () => ())};
 | |
| 10914 | 94 | fun output () = | 
| 7890 | 95 | let val str = implode (rev (! out_buffer)) | 
| 10914 | 96 | in String.substring (str, 0, Int.max (0, size str - 1)) end; | 
| 5090 | 97 | in | 
| 98 | Compiler.Control.Print.out := out; | |
| 99 | Compiler.Interact.useStream (TextIO.openString txt) handle exn => | |
| 10914 | 100 | (Compiler.Control.Print.out := out_orig; err (output ()); raise exn); | 
| 5090 | 101 | Compiler.Control.Print.out := out_orig; | 
| 10914 | 102 | if verbose then print (output ()) else () | 
| 5090 | 103 | end; | 
| 4403 | 104 | |
| 105 | ||
| 106 | ||
| 5816 | 107 | (** interrupts **) | 
| 108 | ||
| 12990 | 109 | exception Interrupt; | 
| 110 | ||
| 5816 | 111 | local | 
| 112 | ||
| 12990 | 113 | fun capture f x = ((f x): unit; NONE) handle exn => SOME exn; | 
| 5816 | 114 | |
| 12990 | 115 | fun release NONE = () | 
| 116 | | release (SOME exn) = raise exn; | |
| 5816 | 117 | |
| 118 | in | |
| 119 | ||
| 12990 | 120 | fun ignore_interrupt f x = | 
| 5816 | 121 | let | 
| 12990 | 122 | val old_handler = Signals.setHandler (Signals.sigINT, Signals.IGNORE); | 
| 123 | val result = capture f x; | |
| 124 | val _ = Signals.setHandler (Signals.sigINT, old_handler); | |
| 125 | in release result end; | |
| 5816 | 126 | |
| 12990 | 127 | fun raise_interrupt f x = | 
| 128 | let | |
| 5816 | 129 | val interrupted = ref false; | 
| 12990 | 130 | val result = ref NONE; | 
| 131 | val old_handler = Signals.inqHandler Signals.sigINT; | |
| 5816 | 132 | in | 
| 12990 | 133 | SMLofNJ.Cont.callcc (fn cont => | 
| 134 | (Signals.setHandler (Signals.sigINT, Signals.HANDLER (fn _ => (interrupted := true; cont))); | |
| 135 | result := capture f x)); | |
| 136 | Signals.setHandler (Signals.sigINT, old_handler); | |
| 137 | if ! interrupted then raise Interrupt else release (! result) | |
| 138 | end; | |
| 5816 | 139 | |
| 140 | end; | |
| 141 | ||
| 17529 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 142 | (case #version_id (Compiler.version) of | 
| 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 143 | [110, x] => if x >= 44 | 
| 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 144 | then use "ML-Systems/smlnj-basis-compat.ML" | 
| 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 145 | else () | 
| 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 146 | | _ => ()); | 
| 
a436d89845af
use "ML-Systems/smlnj-basis-compat.ML" *after* Interrupt;
 wenzelm parents: 
17511diff
changeset | 147 | |
| 17511 | 148 | |
| 16542 | 149 | (** Signal handling: emulation of the Poly/ML Signal structure. Note that types | 
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 150 | Posix.Signal.signal and Signals.signal differ **) | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 151 | |
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 152 | structure IsaSignal = | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 153 | struct | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 154 | |
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 155 | datatype sig_handle = SIG_DFL | SIG_IGN | SIG_HANDLE of Signals.signal -> unit; | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 156 | |
| 16542 | 157 | (*From the SML/NJ documentation: "HANDLER(f) installs a handler for a | 
| 158 | signal. When signal is delivered to the process, the execution state | |
| 159 | of the current thread will be bundled up as a continuation k, then | |
| 160 | f(signal,n,k) will be called. The number n is the number of times | |
| 161 | signal has been signalled since the last time f was invoked for it."*) | |
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 162 | |
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 163 | fun toAction SIG_DFL = Signals.DEFAULT | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 164 | | toAction SIG_IGN = Signals.IGNORE | 
| 16542 | 165 | | toAction (SIG_HANDLE iu) = | 
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 166 | Signals.HANDLER (fn (signo,_,cont) => (iu signo; cont)); | 
| 16542 | 167 | |
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 168 | (*The types are correct, but I'm not sure about the semantics!*) | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 169 | fun fromAction Signals.DEFAULT = SIG_DFL | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 170 | | fromAction Signals.IGNORE = SIG_IGN | 
| 16542 | 171 | | fromAction (Signals.HANDLER f) = | 
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 172 | SIG_HANDLE (fn signo => SMLofNJ.Cont.callcc (fn k => (f (signo,0,k); ()))); | 
| 16542 | 173 | |
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 174 | (*Poly/ML version has type int * sig_handle -> sig_handle*) | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 175 | fun signal (signo, sh) = fromAction (Signals.setHandler (signo, toAction sh)); | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 176 | |
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 177 | val usr1 = UnixSignals.sigUSR1 | 
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 178 | val usr2 = UnixSignals.sigUSR2 | 
| 17763 | 179 | val alrm = UnixSignals.sigALRM | 
| 180 | val chld = UnixSignals.sigCHLD | |
| 181 | val cont = UnixSignals.sigCONT | |
| 182 | val int = UnixSignals.sigINT | |
| 183 | val quit = UnixSignals.sigQUIT | |
| 184 | val term = UnixSignals.sigTERM | |
| 15702 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 185 | |
| 
2677db44c795
new signalling primmitives for sml/nj compatibility
 paulson parents: 
14981diff
changeset | 186 | end; | 
| 5816 | 187 | |
| 188 | ||
| 4403 | 189 | (** OS related **) | 
| 190 | ||
| 191 | (* system command execution *) | |
| 192 | ||
| 193 | (*execute Unix command which doesn't take any input from stdin and | |
| 194 | sends its output to stdout; could be done more easily by Unix.execute, | |
| 195 | but that function doesn't use the PATH*) | |
| 196 | fun execute command = | |
| 197 | let | |
| 198 | val tmp_name = OS.FileSys.tmpName (); | |
| 199 | val is = (OS.Process.system (command ^ " > " ^ tmp_name); TextIO.openIn tmp_name); | |
| 200 | val result = TextIO.inputAll is; | |
| 201 | in | |
| 202 | TextIO.closeIn is; | |
| 203 | OS.FileSys.remove tmp_name; | |
| 204 | result | |
| 205 | end; | |
| 206 | ||
| 7855 | 207 | (*plain version; with return code*) | 
| 12990 | 208 | val system = OS.Process.system: string -> int; | 
| 7855 | 209 | |
| 4403 | 210 | |
| 17824 | 211 | (*Convert a process ID to a decimal string (chiefly for tracing)*) | 
| 212 | fun string_of_pid pid = | |
| 213 | Word.fmt StringCvt.DEC (Word.fromLargeWord (Posix.Process.pidToWord pid)); | |
| 214 | ||
| 215 | ||
| 4403 | 216 | (* getenv *) | 
| 217 | ||
| 218 | fun getenv var = | |
| 219 | (case OS.Process.getEnv var of | |
| 220 | NONE => "" | |
| 221 | | SOME txt => txt); |