# -*- makefile -*-
#
# Test the compiler by compiling and running all .cmlt programs in this dir and
# comparing stdout and stderr with pre-recorded files.
# Type
#  make
# to test all programs in this dir.
# Type
#  make check-all
# to compile, generate .thy file from the .class file and check the syntax.
# Type
#  make cert-all
# to generate certificates (producer- and consumer-side) and check them
#
# ---------------------------------------------------------------------------

PRGROOT=../..

CAMELOT=$(PRGROOT)/Camelot/src/camelot
GDF=$(PRGROOT)/Grail/gdf/src/gdf
GF=$(PRGROOT)/Grail/gf/src/gf
JAVAC=javac
JAVA=java
TIME=
MAKE=make

# compiler flags used for all programs
CAMELOT_FLAGS=-s
# compiler flags for certificate generation
CAMELOT_CERT_FLAGS=-C -lfd

# program specific compiler flags

# RTS flags used for all executions
RTS_FLAGS=

# program specific RTS flags

# runtime arguments for execution
RTS_ARGS_Fib1=33
RTS_ARGS_Fib2=33
RTS_ARGS_Fac1=7
RTS_ARGS_Fac2=7
RTS_ARGS_InsSort=3 8 1 2
RTS_ARGS_HeapSort=3 8 1 2

RUN_NOTES=(expected fails: Append)
CHECK_NOTES=
CERT_NOTES=

# setup for Isabelle; currently only for checking syntax of .thy files
LOGIC=VCG
#IMG_DIR=$(HOME)
IMG_DIR=/tmp
IMG_NAME=VCG_LRT2
IMG=$(IMG_DIR)/$(IMG_NAME)
ISABELLE=isabelle

# 
GF_FLAGS=-t $(LOGIC)
GF_CERT_FLAGS=

# names of all programs in this dir
PROGS=$(subst .cmlt,,$(shell ls *.cmlt))
# HACK: only a few progs run through a full check of heap consumption
PROGS_CERTIFIABLE=Append

URL=ftp://ftp.macs.hw.ac.uk/pub/gph/hwloidl

all::	run-all

$(IMG):
	@echo "Downloading image from $(URL)"
	wget --output-document=$(IMG) $(URL)/$(IMG_NAME)

run-all: 
	@echo "Running all programs: $(PROGS) $(RUN_NOTES)"
	@-for p in $(PROGS) ; do $(MAKE) -s run-$$p ; done

check-all: $(IMG)
	@echo "Checking syntax of all programs: $(PROGS) $(CHECK_NOTES)"
	@-for p in $(PROGS) ; do $(MAKE) -s check-$$p ; done

cert-all: $(IMG)
	@echo "Certifying all programs: $(PROGS_CERTIFIABLE) $(CERT_NOTES)"
	@-for p in $(PROGS_CERTIFIABLE) ; do $(MAKE) -s cert-$$p ; done

run-%:	%.class Camelotlib.class
	echo "Testing $< ..."
	$(TIME) $(JAVA) $(RTS_FLAGS) $(RTS_FLAGS_$(subst .class,,$<)) $(subst .class,,$<) $(RTS_ARGS_$(subst .class,,$<)) 1>STDOUT 2>STDERR
	@if [ -f DIFF_STDOUT ] ; then rm DIFF_STDOUT ; fi
	@-diff STDOUT $(subst .class,,$<).stdout 1>DIFF_STDOUT 2>/dev/null
	@if [ -s DIFF_STDOUT ] ; then echo "** Mismatching STDOUT for $<" ; fi
	@if [ -f DIFF_STDOUT ] ; then rm DIFF_STDOUT ; fi
	@-diff STDERR $(subst .class,,$<).stderr 1>DIFF_STDOUT 2>/dev/null
	@if [ -s DIFF_STDOUT ] ; then echo "** Mismatching STDERR for $<" ; fi
	@if [ -f DIFF_STDOUT ] ; then rm DIFF_STDOUT ; fi
	@if [ -f STDOUT ] ; then rm STDOUT ; fi
	@if [ -f STDERR ] ; then rm STDERR ; fi

check-%:	%.class
	echo "Checking the syntax of the .thy file generated from $< ..."
	$(GF) $(GF_FLAGS) $(GF_FLAGS_$(subst .class,,$<)) $< 1>/dev/null
	# hack to use old VCG theory
	echo "WARNING: hacking generated .thy file to use VCG rather than SlackVCG image"
	cat $(subst .class,.thy,$<) | sed 's/SlackVCG/VCG/g' > bonzo
	mv bonzo $(subst .class,.thy,$<)
	@echo "use_thy \"$(subst .class,,$<)\";" > ROOT.ML
	$(ISABELLE) -r $(IMG) DUMMY < ROOT.ML
	@if [ -f ROOT.ML ] ; then rm ROOT.ML ; fi

cert-%:	%.class
	@echo "Certifying the inferred heap consumption of $(subst .class,.cmlt,$<) ..."
	@echo "Doing the producer on $(subst .class,.cmlt,$<), woof woof (this should generate $(subst .class,,$<)Certificate1.thy)"
	$(CAMELOT) $(CAMELOT_CERT_FLAGS) $(CAMELOT_FLAGS) $(CAMELOT_FLAGS_$(subst .class,,$<)) $(subst .class,.cmlt,$<)
	@echo "Doing the consumer from $<, woof woof (this should generate $(subst .class,,$<)Certificate2/3.thy)"
	$(GF) $(GF_CERT_FLAGS) $(GF_FLAGS) $(GF_FLAGS_$(subst .class,,$<)) $< 1>/dev/null
	@echo "use_thy \"$(subst .class,,$<)Certificate3\";" > ROOT.ML
	$(ISABELLE) -r $(IMG) DUMMY < ROOT.ML
	@if [ -f ROOT.ML ] ; then rm ROOT.ML ; fi

Camelotlib.class:	../examples/Camelotlib.class
	cp $< $@

%.class:	%.cmlt
	$(CAMELOT) $(CAMELOT_FLAGS) $(CAMELOT_FLAGS_$(subst .cmlt,,$<)) $<

clean:
	-rm *.class *.thy *.lfd *.constraints ROOT.ML STDOUT STDERR DIFF_STDOUT

