#!/bin/sh

# This script calls MLton.


LIB_REL_BIN="../lib/mlton"

set -e

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

# Find if "-target" is set, to read cross-specific variables.
# Default to "self".
TARGET=self
prev_arg=
for arg in "$@"
do
    if [ "$prev_arg" = "-target" ]; then
        TARGET="$arg"
    fi
    prev_arg="$arg"
done

TARGET_VARS="$lib/targets/$TARGET/vars"
if [ ! -f "$TARGET_VARS" ]; then
        echo "Unable to read $TARGET_VARS." >&2
        exit 1
fi
. "$TARGET_VARS"




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 <= 14.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 wasi '-D_WASI_EMULATED_SIGNAL'            \
               -target-cc-opt wasi '-D_WASI_EMULATED_PROCESS_CLOCKS'    \
               -target-cc-opt wasi '-D_WASI_EMULATED_GETPID'            \
               -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 openbsd '-Wl,--no-execute-only'         \
               -target-link-opt solaris '-lnsl -lsocket -lrt'           \
               -target-link-opt wasi '-lwasi-emulated-signal'           \
               -target-link-opt wasi '-lwasi-emulated-process-clocks'   \
               -target-link-opt wasi '-lwasi-emulated-getpid'           \
               -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
