# Makefile: Compile and link main.asm using nasm and mold, intermediate files in target/

TARGET_DIR := target
SRC := src/lib.asm src/int_to_str.asm src/vec.asm src/tokeniser.asm src/file.asm src/alloc.asm src/ast.asm src/codegen.asm
OBJ := $(patsubst src/%.asm,$(TARGET_DIR)/%.o,$(SRC))

BIN_SRC := src/main.asm src/panic.asm
BIN_OBJ := $(patsubst src/%.asm,$(TARGET_DIR)/%.o,$(BIN_SRC))
BIN := $(TARGET_DIR)/main

TEST_SRCS := $(wildcard tests/*.rs)
TEST_BINS := $(patsubst tests/%.rs,$(TARGET_DIR)/tests/%,$(TEST_SRCS))
OBJ_LINK_ARGS := $(foreach o,$(OBJ),-C link-arg=$(o))

.PHONY: all clean

all: $(BIN)

test-bins: $(TEST_BINS)

test: test-bins 
	@echo "Running all tests.."
	@for b in $(TEST_BINS); do \
	  echo "==> Running $$b"; \
	  "$$b" || exit $$?; \
	done

fmt: $(wildcard tests/*.rs)
	@echo "Formatting test source files..."
	rustfmt --edition 2024 $^

tests/shared/defs.rs: $(wildcard src/*)
	@echo "Generating shared definitions for tests..."
	./tests/asm_to_rust.py $^ -o $@

# pattern rule: compile each .rs into a binary with the same base name
$(TARGET_DIR)/tests/%: tests/%.rs tests/shared/defs.rs $(OBJ) | $(TARGET_DIR)/tests
	@echo "[$(RUSTC)] $< -> $@"
	rustc -Clink-arg=-fuse-ld=mold --edition=2024 $(OBJ_LINK_ARGS) -g  -o $@ $< 

$(TARGET_DIR):
	mkdir -p $(TARGET_DIR)/tests

$(TARGET_DIR)/tests: $(TARGET_DIR)
	mkdir -p $(TARGET_DIR)/tests

$(TARGET_DIR)/%.o: src/%.asm | $(TARGET_DIR)
	nasm -wreloc-abs -f elf64 -g $< -o $@

$(BIN): $(OBJ) $(BIN_OBJ)
	mold -run ld -o $(BIN) $(OBJ)

run: $(BIN)
	$(BIN)

clean:
	rm -rf $(TARGET_DIR)
