c@50: #!/bin/bash c@50: c@50: # Disable shellcheck warnings for useless-use-of-cat. UUOC is good c@50: # practice, not bad: clearer, safer, less error-prone. c@50: # shellcheck disable=SC2002 c@50: c@50: sml="$VEXT_SML" c@50: c@50: set -eu c@50: c@50: mydir=$(dirname "$0") c@50: program="$mydir/vext.sml" c@50: c@50: # We need one of Poly/ML, SML/NJ, or MLton. Since we're running a c@50: # single-file SML program as if it were a script, our order of c@50: # preference is based on startup speed. c@50: c@50: if [ -z "$sml" ]; then c@50: if sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then c@50: sml="smlnj" c@50: # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a c@50: # nasty bug that occasionally causes it to deadlock on startup. c@50: # That appears to be fixed in their repo, so we could promote it c@50: # up the order again at some point in future c@50: elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then c@50: sml="poly" c@50: elif mlton 2>&1 | grep -q 'MLton'; then c@50: sml="mlton" c@50: else cat 1>&2 < "$tmp_sml" c@50: echo 'val _ = main ()' >> "$tmp_sml" c@50: mlton -output "$tmp_out" "$tmp_sml" c@50: "$tmp_out" "$@" ;; c@50: smlnj) c@50: cat "$program" | ( c@50: cat < (), flush = fn () => () }; c@50: x c@50: end; c@50: val smlrun__prev = ref ""; c@50: Control.Print.out := { c@50: say = fn s => c@50: (if String.isSubstring " Error" s c@50: then (Control.Print.out := smlrun__cp; c@50: (#say smlrun__cp) (!smlrun__prev); c@50: (#say smlrun__cp) s) c@50: else (smlrun__prev := s; ())), c@50: flush = fn s => () c@50: }; c@50: EOF c@50: cat - c@50: cat < "$tmp_sml" c@50: CM_VERBOSE=false sml "$tmp_sml" ;; c@50: *) c@50: echo "Unknown SML implementation name: $sml"; c@50: exit 2 ;; c@50: esac c@50: