SRC = $(shell cd .. && pwd)
BUILD = $(SRC)/build
BIN = $(BUILD)/bin
LIB = $(BUILD)/lib
MLTON = mlton
TARGET = self
AOUT = mlton-compile
UP = upgrade-basis.sml
PATH = $(BIN):$(shell echo $$PATH)

FLAGS = @MLton ram-slop 0.7 gc-summary $(RUNTIME_ARGS) --

ifeq (self, $(shell if [ -x $(BIN)/mlton ]; then echo self; fi))
  # We're compiling MLton with itself, so don't use any stubs.
  CM = mlton.cm
  FLAGS += -sequence-unit true
else
ifeq (cygwin, $(shell $(SRC)/bin/host-os))
  # The stubs don't work on Cygwin, since they define spawn in terms of
  # fork, and fork doesn't work on Cygwin.  So, make without the stubs.
  CM = mlton.cm
else
  # We're compiling MLton with an older version of itself, so use the stubs for
  # the MLton structure.
  CM = mlton-stubs.cm
endif
endif

ifeq (new,$(shell PATH=$(BIN):$$PATH; mlton -target self >/dev/null 2>&1 && echo new))
  FLAGS += -target $(TARGET)
else
  FLAGS += -host $(TARGET)
endif
ifeq (new,$(shell PATH=$(BIN):$$PATH; mlton -verbose 1 >/dev/null 2>&1 && echo new))
  FLAGS += -verbose 2 -output $(AOUT)
else
  FLAGS += -v -o $(AOUT)
endif

SOURCES =			\
	mlton.cm		\
	$(UP)			\
	front-end/ml.lex.sml 	\
	front-end/ml.grm.sig 	\
	front-end/ml.grm.sml	\
	$(shell if [ -r mlton.cm ]; then mlton -stop f mlton.cm; fi)

.PHONY: all
all: $(AOUT)

front-end/ml.lex.sml front-end/ml.grm.sig front-end/ml.grm.sml:
	$(MAKE) -C front-end

$(AOUT): $(SOURCES)
	rm -f $(UP)
	$(MAKE) $(UP)
	@echo 'Compiling mlton (takes a while)'
	mlton $(FLAGS) $(CM)
	size $(AOUT)

#! Pass $(PATH) to upgrade-basis because it is run via #!/usr/bin/env
# bash, which resets the path.
$(UP):
	$(SRC)/bin/upgrade-basis "$(PATH)" >$(UP)

mlton.cm: mlton-stubs.cm
	grep -v mlton-stubs mlton-stubs.cm >mlton.cm

# This makes a version of MLton that can be compiled in the standard basis
# library.  I.E. it doesn't require a MLton structure.
.PHONY:	mlton-stubs_cm
mlton-stubs_cm:
	(								\
		echo 'Group is' &&					\
		cmcat sources.cm | grep -v 'basis-stubs' | 		\
			grep -v 'mlton-stubs-in-smlnj' |		\
			grep mlyacc &&					\
		echo '$(UP)' &&						\
		cmcat sources.cm | grep -v 'basis-stubs' | 		\
			grep -v 'mlton-stubs-in-smlnj' |		\
			grep -v mlyacc &&				\
		echo 'call-main.sml';					\
	) >mlton-stubs.cm

mlton.sml: $(SOURCES)
	rm -f mlton.sml && mlton -stop sml mlton.cm && chmod -w mlton.sml

.PHONY: clean
clean:
	../bin/clean

#
# The following rebuilds the heap file for the SML/NJ compiled version
# of MLton.
# It requires that you have SML/NJ with the Compilation
# Manager (CM) installed.  You may need to replace the following with
# 'sml-cm'.
#
SMLNJ_VERSION = 110.44
SML	= sml

.PHONY: nj-mlton
nj-mlton: $(SOURCES)
	@echo You must use SML/NJ $(SMLNJ_VERSION).
	(									\
		echo 'SMLofNJ.Internals.GC.messages false;';			\
		echo '#set CM.Control.verbose false;';				\
		echo '#set CM.Control.warn_obsolete false;';			\
		echo 'Control.polyEqWarn := false;';				\
		echo 'CM.make "sources.cm";';					\
		echo 'Main.exportNJ ("$(SRC)/basis-library", "$(LIB)/mlton");'	\
	) | $(SML)
	@echo You must use SML/NJ $(SMLNJ_VERSION).

.PHONY: nj-mlton-dual
nj-mlton-dual: $(SOURCES)
	@echo You must use SML/NJ $(SMLNJ_VERSION).
	(									\
		echo 'SMLofNJ.Internals.GC.messages false;';			\
		echo '#set CM.Control.verbose false;';				\
		echo '#set CM.Control.warn_obsolete false;';			\
		echo 'Control.polyEqWarn := false;';				\
		echo 'val _ = CM.Server.start {cmd = (CommandLine.name (), ["@CMslave"]), name = "server1", pathtrans = NONE, pref = 0};';\
		echo 'val _ = CM.Server.start {cmd = (CommandLine.name (), ["@CMslave"]), name = "server2", pathtrans = NONE, pref = 0};';\
		echo 'CM.make "sources.cm";';					\
		echo 'Main.exportNJ ("$(SRC)/basis-library", "$(LIB)/mlton");'	\
	) | $(SML)
	@echo You must use SML/NJ $(SMLNJ_VERSION).

.PHONY: nj-whole
nj-whole: $(SOURCES)
	@echo You must use SML/NJ $(SMLNJ_VERSION).
	(									\
		echo 'SMLofNJ.Internals.GC.messages false;';			\
		echo '#set CM.Control.verbose false;';				\
		echo '#set CM.Control.warn_obsolete false;';			\
		echo 'Control.polyEqWarn := false;'; 				\
		echo 'local'; 							\
		cmcat sources.cm | grep 'mlton-stubs-in-smlnj' | xargs cat;	\
		cmcat sources.cm | grep 'mlyacc' | xargs cat;			\
		cmcat sources.cm | grep -v 'mlyacc' |				\
			grep -v 'mlton-stubs-in-smlnj' | xargs cat; 		\
		echo 'in';							\
		echo 'val _ = Main.exportNJ ("$(SRC)/basis-library", "$(LIB)/mlton")';	\
		echo 'end';							\
	) >mlton.whole.sml
	$(SML) <mlton.whole.sml
	@echo You must use SML/NJ $(SMLNJ_VERSION).
