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