CFA?=cfa

DEMOS?=control treatment
LANGS?=cfa c cc

CFLAGS=-O3 #-DNDEBUG

SOURCES=$(foreach demo,$(DEMOS),$(foreach lang,$(LANGS),$(demo).$(lang)))
TGT_SLUGS=$(call BOUND_ALTS,$(SOURCES))
EXES=$(addsuffix .runme,$(TGT_SLUGS))
ASMS=$(addsuffix .s,$(TGT_SLUGS))
TGTS=$(EXES) $(ASMS)
define BOUND_ALTS
$(1) $(addsuffix .unsound,$(1))
endef
define COMPILER_FOR
$(strip
	$(if $(findstring .cfa,$(1)),$(CFA),
	$(if $(findstring .cc,$(1)),$(CXX),
	$(if $(findstring .c,$(1)),$(CC),
	unknown$(1)))))
endef


.SUFFIXES:  # disable make built-in rules, notably `% : %.s`, which introduces circularity
.SECONDEXPANSION:  # evaluate prereq dynamically

all: $(TGTS)
exes: $(EXES)
asms: $(ASMS)

.PHONY: all exes asms echo_% clean

$(TGTS): tgt_slug=$(basename $@)
$(TGTS): unsound_flag=$(if $(findstring .unsound,$(tgt_slug)),-DUNSOUND_BOUND)
$(TGTS): source=$(subst .unsound,,$(tgt_slug))
$(TGTS): compiler=$(call COMPILER_FOR,$(suffix $(source)))

$(EXES): out_type_flag=-DRUNIT
$(ASMS): out_type_flag=-S

$(TGTS): Makefile
$(TGTS): $$(source)
	$(compiler) $< $(unsound_flag) $(out_type_flag) $(CFLAGS) -MMD -MF $@.d -o $@

echo_%:
	@echo '$($(@:echo_%=%))'

clean:
	rm -f *.s *.runme *.d

-include *.d
