annotate vext @ 70:2d3e1d1f99c0

Use Vext
author Chris Cannam
date Wed, 07 Feb 2018 20:32:48 +0000
parents
children
rev   line source
Chris@70 1 #!/bin/bash
Chris@70 2
Chris@70 3 # Disable shellcheck warnings for useless-use-of-cat. UUOC is good
Chris@70 4 # practice, not bad: clearer, safer, less error-prone.
Chris@70 5 # shellcheck disable=SC2002
Chris@70 6
Chris@70 7 sml="$VEXT_SML"
Chris@70 8
Chris@70 9 set -eu
Chris@70 10
Chris@70 11 mydir=$(dirname "$0")
Chris@70 12 program="$mydir/vext.sml"
Chris@70 13
Chris@70 14 hasher=
Chris@70 15 local_install=
Chris@70 16 if [ -w "$mydir" ]; then
Chris@70 17 if echo | sha256sum >/dev/null 2>&1 ; then
Chris@70 18 hasher=sha256sum
Chris@70 19 local_install=true
Chris@70 20 elif echo | shasum >/dev/null 2>&1 ; then
Chris@70 21 hasher=shasum
Chris@70 22 local_install=true
Chris@70 23 else
Chris@70 24 echo "WARNING: sha256sum or shasum program not found" 1>&2
Chris@70 25 fi
Chris@70 26 fi
Chris@70 27
Chris@70 28 if [ -n "$local_install" ]; then
Chris@70 29 hash=$(echo "$sml" | cat "$program" - | $hasher | cut -c1-16)
Chris@70 30 gen_sml=$mydir/.vext-$hash.sml
Chris@70 31 gen_out=$mydir/.vext-$hash.bin
Chris@70 32 trap 'rm -f $gen_sml' 0
Chris@70 33 else
Chris@70 34 gen_sml=$(mktemp /tmp/vext-XXXXXXXX.sml)
Chris@70 35 gen_out=$(mktemp /tmp/vext-XXXXXXXX.bin)
Chris@70 36 trap 'rm -f $gen_sml $gen_out' 0
Chris@70 37 fi
Chris@70 38
Chris@70 39 if [ -x "$gen_out" ]; then
Chris@70 40 exec "$gen_out" "$@"
Chris@70 41 fi
Chris@70 42
Chris@70 43 # We need one of Poly/ML, SML/NJ, or MLton. Since we're running a
Chris@70 44 # single-file SML program as if it were a script, our order of
Chris@70 45 # preference is based on startup speed, except in the local_install
Chris@70 46 # case where we retain a persistent binary.
Chris@70 47
Chris@70 48 if [ -z "$sml" ]; then
Chris@70 49 if [ -n "$local_install" ] && mlton 2>&1 | grep -q 'MLton'; then
Chris@70 50 sml="mlton"
Chris@70 51 elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then
Chris@70 52 sml="smlnj"
Chris@70 53 # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a
Chris@70 54 # nasty bug that occasionally causes it to deadlock on startup.
Chris@70 55 # That appears to be fixed in their repo, so we could promote it
Chris@70 56 # up the order again at some point in future
Chris@70 57 elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then
Chris@70 58 sml="poly"
Chris@70 59 elif mlton 2>&1 | grep -q 'MLton'; then
Chris@70 60 sml="mlton"
Chris@70 61 else cat 1>&2 <<EOF
Chris@70 62
Chris@70 63 ERROR: No supported SML compiler or interpreter found
Chris@70 64 EOF
Chris@70 65 cat 1>&2 <<EOF
Chris@70 66
Chris@70 67 The Vext external source code manager needs a Standard ML (SML)
Chris@70 68 compiler or interpreter to run.
Chris@70 69
Chris@70 70 Please ensure you have one of the following SML implementations
Chris@70 71 installed and present in your PATH, and try again.
Chris@70 72
Chris@70 73 1. Standard ML of New Jersey
Chris@70 74 - often found in a distribution package called: smlnj
Chris@70 75 - executable name: sml
Chris@70 76
Chris@70 77 2. Poly/ML
Chris@70 78 - often found in a distribution package called: polyml
Chris@70 79 - executable name: poly
Chris@70 80
Chris@70 81 3. MLton
Chris@70 82 - often found in a distribution package called: mlton
Chris@70 83 - executable name: mlton
Chris@70 84
Chris@70 85 EOF
Chris@70 86 exit 2
Chris@70 87 fi
Chris@70 88 fi
Chris@70 89
Chris@70 90 arglist=""
Chris@70 91 for arg in "$@"; do
Chris@70 92 if [ -n "$arglist" ]; then arglist="$arglist,"; fi
Chris@70 93 if echo "$arg" | grep -q '["'"'"']' ; then
Chris@70 94 arglist="$arglist\"usage\""
Chris@70 95 else
Chris@70 96 arglist="$arglist\"$arg\""
Chris@70 97 fi
Chris@70 98 done
Chris@70 99
Chris@70 100 case "$sml" in
Chris@70 101 poly)
Chris@70 102 if [ -n "$local_install" ] && polyc --help >/dev/null 2>&1 ; then
Chris@70 103 if [ ! -x "$gen_out" ]; then
Chris@70 104 polyc -o "$gen_out" "$program"
Chris@70 105 fi
Chris@70 106 "$gen_out" "$@"
Chris@70 107 else
Chris@70 108 echo 'use "'"$program"'"; vext ['"$arglist"'];' |
Chris@70 109 poly -q --error-exit
Chris@70 110 fi ;;
Chris@70 111 mlton)
Chris@70 112 if [ ! -x "$gen_out" ]; then
Chris@70 113 echo "[Precompiling Vext binary...]" 1>&2
Chris@70 114 echo "val _ = main ()" | cat "$program" - > "$gen_sml"
Chris@70 115 mlton -output "$gen_out" "$gen_sml"
Chris@70 116 fi
Chris@70 117 "$gen_out" "$@" ;;
Chris@70 118 smlnj)
Chris@70 119 cat "$program" | (
Chris@70 120 cat <<EOF
Chris@70 121 val smlrun__cp =
Chris@70 122 let val x = !Control.Print.out in
Chris@70 123 Control.Print.out := { say = fn _ => (), flush = fn () => () };
Chris@70 124 x
Chris@70 125 end;
Chris@70 126 val smlrun__prev = ref "";
Chris@70 127 Control.Print.out := {
Chris@70 128 say = fn s =>
Chris@70 129 (if String.isSubstring " Error" s
Chris@70 130 then (Control.Print.out := smlrun__cp;
Chris@70 131 (#say smlrun__cp) (!smlrun__prev);
Chris@70 132 (#say smlrun__cp) s)
Chris@70 133 else (smlrun__prev := s; ())),
Chris@70 134 flush = fn s => ()
Chris@70 135 };
Chris@70 136 EOF
Chris@70 137 cat -
Chris@70 138 cat <<EOF
Chris@70 139 val _ = vext [$arglist];
Chris@70 140 val _ = OS.Process.exit (OS.Process.success);
Chris@70 141 EOF
Chris@70 142 ) > "$gen_sml"
Chris@70 143 CM_VERBOSE=false sml "$gen_sml" ;;
Chris@70 144 *)
Chris@70 145 echo "ERROR: Unknown SML implementation name: $sml" 1>&2;
Chris@70 146 exit 2 ;;
Chris@70 147 esac
Chris@70 148