Chris@1706
|
1 #!/bin/bash
|
Chris@1706
|
2
|
Chris@1706
|
3 # Disable shellcheck warnings for useless-use-of-cat. UUOC is good
|
Chris@1706
|
4 # practice, not bad: clearer, safer, less error-prone.
|
Chris@1706
|
5 # shellcheck disable=SC2002
|
Chris@1706
|
6
|
Chris@1706
|
7 sml="$VEXT_SML"
|
Chris@1706
|
8
|
Chris@1706
|
9 set -eu
|
Chris@1706
|
10
|
Chris@1706
|
11 mydir=$(dirname "$0")
|
Chris@1706
|
12 program="$mydir/vext.sml"
|
Chris@1706
|
13
|
Chris@1706
|
14 # We need one of Poly/ML, SML/NJ, or MLton. Since we're running a
|
Chris@1706
|
15 # single-file SML program as if it were a script, our order of
|
Chris@1706
|
16 # preference is based on startup speed.
|
Chris@1706
|
17
|
Chris@1706
|
18 if [ -z "$sml" ]; then
|
Chris@1706
|
19 # I think there may be a race condition in the poly interpreter's
|
Chris@1706
|
20 # tests for open or closed I/O streams - without the "echo" here,
|
Chris@1706
|
21 # or with stderr redirection, this pipeline will sometimes hang
|
Chris@1706
|
22 if echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then
|
Chris@1706
|
23 sml="poly"
|
Chris@1706
|
24 elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then
|
Chris@1706
|
25 sml="smlnj"
|
Chris@1706
|
26 elif mlton 2>&1 | grep -q 'MLton'; then
|
Chris@1706
|
27 sml="mlton"
|
Chris@1706
|
28 else cat 1>&2 <<EOF
|
Chris@1706
|
29
|
Chris@1706
|
30 ERROR: No supported SML compiler or interpreter found
|
Chris@1706
|
31 EOF
|
Chris@1706
|
32 cat <<EOF
|
Chris@1706
|
33
|
Chris@1706
|
34 The Vext external source code manager needs a Standard ML (SML)
|
Chris@1706
|
35 compiler or interpreter to run.
|
Chris@1706
|
36
|
Chris@1706
|
37 Please ensure you have one of the following SML implementations
|
Chris@1706
|
38 installed and present in your PATH, and try again. These are listed
|
Chris@1706
|
39 approximately in order of preference for this task.
|
Chris@1706
|
40
|
Chris@1706
|
41 1. Poly/ML
|
Chris@1706
|
42 - often found in a distribution package called: polyml
|
Chris@1706
|
43 - executable name: poly
|
Chris@1706
|
44
|
Chris@1706
|
45 2. Standard ML of New Jersey
|
Chris@1706
|
46 - often found in a distribution package called: smlnj
|
Chris@1706
|
47 - executable name: sml
|
Chris@1706
|
48
|
Chris@1706
|
49 3. MLton
|
Chris@1706
|
50 - often found in a distribution package called: mlton
|
Chris@1706
|
51 - executable name: mlton
|
Chris@1706
|
52
|
Chris@1706
|
53 EOF
|
Chris@1706
|
54 exit 2
|
Chris@1706
|
55 fi
|
Chris@1706
|
56 fi
|
Chris@1706
|
57
|
Chris@1706
|
58 tmp_sml=$(mktemp /tmp/vext-XXXXXXXX.sml)
|
Chris@1706
|
59 tmp_out=$(mktemp /tmp/vext-XXXXXXXX.bin)
|
Chris@1706
|
60
|
Chris@1706
|
61 trap 'rm -f $tmp_sml $tmp_out' 0
|
Chris@1706
|
62
|
Chris@1706
|
63 arglist=""
|
Chris@1706
|
64 for arg in "$@"; do
|
Chris@1706
|
65 if [ -n "$arglist" ]; then arglist="$arglist,"; fi
|
Chris@1706
|
66 if echo "$arg" | grep -q '[^a-z]' ; then
|
Chris@1706
|
67 arglist="$arglist\"usage\""
|
Chris@1706
|
68 else
|
Chris@1706
|
69 arglist="$arglist\"$arg\""
|
Chris@1706
|
70 fi
|
Chris@1706
|
71 done
|
Chris@1706
|
72
|
Chris@1706
|
73 case "$sml" in
|
Chris@1706
|
74 poly) echo 'use "'"$program"'"; vext ['"$arglist"'];' |
|
Chris@1706
|
75 poly -q --error-exit ;;
|
Chris@1706
|
76 mlton)
|
Chris@1706
|
77 cat "$program" > "$tmp_sml"
|
Chris@1706
|
78 echo 'val _ = main ()' >> "$tmp_sml"
|
Chris@1706
|
79 mlton -output "$tmp_out" "$tmp_sml"
|
Chris@1706
|
80 "$tmp_out" "$@" ;;
|
Chris@1706
|
81 smlnj)
|
Chris@1706
|
82 cat "$program" | (
|
Chris@1706
|
83 cat <<EOF
|
Chris@1706
|
84 val smlrun__cp =
|
Chris@1706
|
85 let val x = !Control.Print.out in
|
Chris@1706
|
86 Control.Print.out := { say = fn _ => (), flush = fn () => () };
|
Chris@1706
|
87 x
|
Chris@1706
|
88 end;
|
Chris@1706
|
89 val smlrun__prev = ref "";
|
Chris@1706
|
90 Control.Print.out := {
|
Chris@1706
|
91 say = fn s =>
|
Chris@1706
|
92 (if String.isSubstring " Error" s
|
Chris@1706
|
93 then (Control.Print.out := smlrun__cp;
|
Chris@1706
|
94 (#say smlrun__cp) (!smlrun__prev);
|
Chris@1706
|
95 (#say smlrun__cp) s)
|
Chris@1706
|
96 else (smlrun__prev := s; ())),
|
Chris@1706
|
97 flush = fn s => ()
|
Chris@1706
|
98 };
|
Chris@1706
|
99 EOF
|
Chris@1706
|
100 cat -
|
Chris@1706
|
101 cat <<EOF
|
Chris@1706
|
102 val _ = vext [$arglist];
|
Chris@1706
|
103 val _ = OS.Process.exit (OS.Process.success);
|
Chris@1706
|
104 EOF
|
Chris@1706
|
105 ) > "$tmp_sml"
|
Chris@1706
|
106 CM_VERBOSE=false sml "$tmp_sml" ;;
|
Chris@1706
|
107 *)
|
Chris@1706
|
108 echo "Unknown SML implementation name: $sml";
|
Chris@1706
|
109 exit 2 ;;
|
Chris@1706
|
110 esac
|
Chris@1706
|
111
|