#!/bin/sh

# This script calls MLton.


LIB_REL_BIN="../lib/mlton"

EXE=

CC="cc"

# You may need to set 'GMP_INC_DIR' so the C compiler can find gmp.h.
GMP_INC_DIR=
# You may need to set 'GMP_LIB_DIR' so the C compiler can find libgmp.
GMP_LIB_DIR=


set -e

dir=$(dirname "$0")
lib=$(cd "$dir/$LIB_REL_BIN" && pwd)


doitMLton () {
    mlton_mlton="$lib/mlton-compile$EXE"
    if [ -x "$mlton_mlton" ]; then
        exec "$mlton_mlton" "$@"
    fi
}
doitSMLNJ () {
    SMLNJ="sml"
    if [ -x "$(command -v "$SMLNJ")" ]; then
        mlton_smlnj_heap="$lib/mlton-compile-smlnj.$("$SMLNJ" @SMLsuffix)"
        if [ -s "$mlton_smlnj_heap" ]; then
            exec "$SMLNJ" @SMLload="$mlton_smlnj_heap" "$@"
        fi
    fi
}
doitPolyML () {
    mlton_polyml="$lib/mlton-compile-polyml$EXE"
    if [ -x "$mlton_polyml" ]; then
        exec "$mlton_polyml" "$@"
    fi
}
doitMLKit () {
    mlton_mlkit="$lib/mlton-compile-mlkit$EXE"
    if [ -x "$mlton_mlkit" ]; then
        exec "$mlton_mlkit" "$@"
    fi
}


if [ -n "$GMP_INC_DIR" ]; then
    gmpCCOpts="-cc-opt -I$GMP_INC_DIR"
fi
if [ -n "$GMP_LIB_DIR" ]; then
    gmpLinkOpts="-link-opt -L$GMP_LIB_DIR -target-link-opt netbsd -Wl,-R$GMP_LIB_DIR"
fi

# "Legacy" Pass Manager; LLVM < 13.0
llvmOptOpt="-mem2reg -O2"
# "New" Pass Manager; LLVM >= 13.0
llvmOptOpt="--passes=function(mem2reg),default<O2>"


# insert @MLton runtime arguments
case "$1" in
@MLton)
    shift
    ;;
*)
    set -- -- "$@"
    ;;
esac
set -- @MLton \
       ram-slop 0.5 \
       "$@"

# insert compile arguments
looking='yes'
for arg in "$@"; do
    set -- "$@" "$arg"
    if [ "$arg" = '--' ] && [ "$looking" = 'yes' ]; then
        looking='no'
        set -- "$@" "$lib" \
               -ar-script "$lib/static-library"                         \
               -cc "$CC"                                                \
               -cc-opt '-std=gnu11 -fno-common'                         \
               -cc-opt '-O1 -fno-strict-aliasing'                       \
               -cc-opt '-foptimize-sibling-calls'                       \
               -cc-opt '-w'                                             \
               -cc-opt-quote "-I$lib/include"                           \
               $gmpCCOpts $gmpLinkOpts                                  \
               -llvm-llc-opt '-O2'                                      \
               -llvm-opt-opt "$llvmOptOpt"                              \
               -mlb-path-var 'SML_LIB $(LIB_MLTON_DIR)/sml'             \
               -target-as-opt amd64 '-m64'                              \
               -target-as-opt x86 '-m32'                                \
               -target-cc-opt aix '-maix64'                             \
               -target-cc-opt alpha                                     \
                       '-mieee -mbwx -mtune=ev6 -mfp-rounding-mode=d'   \
               -target-cc-opt amd64 '-m64'                              \
               -target-cc-opt amd64-darwin '-arch x86_64'               \
               -target-cc-opt arm64-darwin '-arch arm64'                \
               -target-cc-opt powerpc-darwin '-arch ppc'                \
               -target-cc-opt powerpc64-darwin '-arch ppc64'            \
               -target-cc-opt ia64-hpux "-mlp64"                        \
               -target-cc-opt ia64 "-mtune=itanium2"                    \
               -target-cc-opt sparc '-m32 -mcpu=v8 -Wa,-xarch=v8plusa'  \
               -target-cc-opt x86 '-m32'                                \
               -target-link-opt aix '-maix64'                           \
               -target-link-opt alpha                                   \
                       '-mieee -mbwx -mtune=ev6 -mfp-rounding-mode=d'   \
               -target-link-opt amd64 '-m64'                            \
               -target-link-opt amd64-darwin '-arch x86_64'             \
               -target-link-opt arm64-darwin '-arch arm64'              \
               -target-link-opt powerpc-darwin '-arch ppc'              \
               -target-link-opt powerpc64-darwin '-arch ppc64'          \
               -target-link-opt ia64-hpux "-mlp64"                      \
               -target-link-opt linux '-Wl,-znoexecstack'               \
               -target-link-opt mingw                                   \
                       '-lws2_32 -lkernel32 -lpsapi -lnetapi32 -lwinmm' \
               -target-link-opt mingw '-Wl,--enable-stdcall-fixup'      \
               -target-link-opt solaris '-lnsl -lsocket -lrt'           \
               -target-link-opt x86 '-m32'                              \
               -profile-exclude '\$\(SML_LIB\)'
    fi
    shift
done
if [ "$looking" = 'yes' ]; then
    echo '@MLton missing --'
    exit 1
fi

doitMLton "$@"

# drop @MLton runtime arguments
while [ "$1" != "--" ]; do
    shift
done
shift

doitSMLNJ "$@"
doitPolyML "$@"
doitMLKit "$@"

echo 'Unable to run MLton.  Check that lib is set properly.' >&2
exit 1
