# Radiance build file.

# Core standard library modules.
STD := -pkg std $(patsubst %,-mod %,$(shell cat std.lib))

# Full standard library with test modules.
STD_TEST := $(STD) $(patsubst %,-mod %,$(shell cat std.lib.test))

# Source files.
STD_LIB := $(shell find lib -name '*.rad')
RAD_BIN := bin/radiance.rv64.dev

# Emulator command used to invoke the self-hosted compiler.
EMU       := $(or $(RAD_EMULATOR),emulator)
EMU_FLAGS := -memory-size=385024 \
			 -data-size=348160 \
			 -stack-size=512 \
			 -count-instructions
RADIANCE  := $(EMU) $(EMU_FLAGS) -run $(RAD_BIN)

# Verify the emulator binary exists.
EMU_PATH := $(shell command -v $(EMU) 2>/dev/null)

default: emulator $(RAD_BIN)
test: emulator std-test lower-test asm-test

# Emulator command check

emulator:
ifeq ($(EMU_PATH),)
	$(error Emulator not found. Install it or set RAD_EMULATOR to its path)
endif

# Compiler build

SEED      := seed/radiance.rv64
SEED_OPTS := $(STD) -pkg radiance -mod compiler/radiance.rad -entry radiance

$(RAD_BIN): $(STD_LIB) compiler/radiance.rad
	@echo "radiance $(SEED) => $@"
	@$(EMU) $(EMU_FLAGS) -run $(SEED) $(SEED_OPTS) -o $@

# Standard Library Tests

STD_LIB_TEST := lib/std.test.rv64

std-test: $(STD_LIB_TEST)
	@echo
	@$(EMU) $(EMU_FLAGS) -run $(STD_LIB_TEST)

$(STD_LIB_TEST): $(STD_LIB) $(RAD_BIN)
	@echo "radiance -test $(STD_TEST) -entry std -o $@"
	@$(RADIANCE) -test $(STD_TEST) -entry std -o $@

clean-std-test:
	@rm -f lib/std.test.rv64 \
		lib/std.test.rv64.debug \
		lib/std.test.rv64.s \
		lib/std.test.rv64.o \
		lib/std.test.rv64.rw.data \
		lib/std.test.rv64.ro.data

# Lowering Tests

LOWER_TEST     := test/lower/lower-test.rv64
LOWER_TEST_RUN := test/lower/run

lower-test: $(LOWER_TEST)
	@echo
	@$(LOWER_TEST_RUN)

$(LOWER_TEST): test/lower/lower-test.rad $(STD_LIB) $(RAD_BIN)
	@echo "radiance $(STD) -pkg lower -mod test/lower/lower-test.rad -entry lower -o $@"
	@$(RADIANCE) $(STD) -pkg lower -mod test/lower/lower-test.rad -entry lower -o $@

clean-lower-test:
	@rm -f $(LOWER_TEST) \
		test/lower/lower-test.rv64.debug \
		test/lower/lower-test.rv64.s \
		test/lower/lower-test.rv64.o \
		test/lower/lower-test.rv64.rw.data \
		test/lower/lower-test.rv64.ro.data

# Code generation tests.

ASM_TEST_DIR := lib/std/arch/rv64/tests
ASM_TEST_SRC := $(wildcard $(ASM_TEST_DIR)/*.rad)
ASM_TEST_BIN := $(ASM_TEST_SRC:.rad=.rv64)
ASM_TEST_RUN := test/asm/run

asm-test: $(ASM_TEST_BIN) $(RAD_BIN)
	@echo
	@$(ASM_TEST_RUN) $(ASM_TEST_SRC)

$(ASM_TEST_DIR)/%.rv64: $(ASM_TEST_DIR)/%.rad $(RAD_BIN)
	@echo "radiance $< => $@"
	@$(RADIANCE) -pkg test -mod $< -o $@

clean-asm-test:
	@rm -f $(ASM_TEST_BIN) \
		$(wildcard $(ASM_TEST_DIR)/*.rv64.debug) \
		$(wildcard $(ASM_TEST_DIR)/*.rv64.s) \
		$(wildcard $(ASM_TEST_DIR)/*.rv64) \
		$(wildcard $(ASM_TEST_DIR)/*.rv64.rw.data) \
		$(wildcard $(ASM_TEST_DIR)/*.rv64.ro.data)

seed:
	seed/update

clean-rad:
	rm -f $(RAD_BIN) $(RAD_BIN).ro.data $(RAD_BIN).rw.data
	rm -f seed/radiance.rv64.s[0-9]*

clean: clean-std-test clean-lower-test clean-asm-test clean-rad

t: test
c: clean

.PHONY: test clean default std-test lower-test asm-test seed \
	clean-std-test clean-lower-test clean-asm-test clean-rad emulator
.SUFFIXES:
.DELETE_ON_ERROR:
.SILENT:
