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