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