VERSION = Bison
#VERSION = LLnextgen

SOURCES =	declaration.c error.c expression.c io.c list.c main.c salloc.c scope.c statement.c token.c type.c
Y_SOURCES =	grammar.y
G_SOURCES =	grammar.g
L_SOURCES =	lex.l
RTS_SOURCES =	libcb.c rts.c

CC =		gcc
INCLUDES =	-I.
DEBUG_FLAGS =	-g -std=c99 -pedantic -Wall -W
DEP_FLAGS =	-MM -MG
CFLAGS =	$(INCLUDES) $(DEBUG_FLAGS) -MMD -O
LIBRARIES =

BISON =		bison
BISONFLAGS =	-d

LLGEN =		LLnextgen
LLGENFLAGS =

LEX =		flex
LEXFLAGS =

BISON_C_SRC =	$(Y_SOURCES:%.y=%.tab.c)
BISON_H_SRC =	$(Y_SOURCES:%.y=%.tab.h)
LLGEN_C_SRC =	$(G_SOURCES:%.g=%.c)
LLGEN_H_SRC =	$(G_SOURCES:%.g=%.h)

ifeq "$(VERSION)" "Bison"
GEN_C_SRC =	$(BISON_C_SRC) $(L_SOURCES:%.l=%.yy.c)
GEN_H_SRC =	$(BISON_H_SRC)
PARSER =	$(Y_SOURCES)
endif
ifeq "$(VERSION)" "LLnextgen"
GEN_C_SRC =     $(LLGEN_C_SRC) $(L_SOURCES:%.l=%.yy.c)
GEN_H_SRC =     $(LLGEN_H_SRC)
PARSER =	$(G_SOURCES)
endif

GEN_SOURCES =	$(GEN_C_SRC) $(GEN_H_SRC)

C_SOURCES =	$(SOURCES) $(GEN_C_SRC)
OBJECTS =	$(C_SOURCES:%.c=%.o)
RTS_OBJECTS =	$(RTS_SOURCES:%.c=%.o)

FILES=		Makefile README cbc $(SOURCES) $(RTS_SOURCES) \
		$(PARSER) $(L_SOURCES) \
		bool.h declaration.h error.h expression.h io.h lex.h \
		libcb.h list.h rts.h salloc.h scope.h statement.h token.h type.h

DEPENDENCIES=	$(C_SOURCES:%.c=%.d)

%.d:		%.c
		@$(CC) $(CFLAGS) $(DEP_FLAGS) $<

%.o:		%.c
		$(CC) $(CFLAGS) -c $<

all::		compiler libcb.a

compiler::	$(GEN_C_SRC) cbf

libcb.a:	$(RTS_OBJECTS)
		@$(AR) rcs $@ $?

cbf:		$(OBJECTS)
		$(CC) $(CFLAGS) $(OBJECTS) $(LIBRARIES) -o $@

submit::
		@tar cfz submit.tgz $(FILES)
clean::
		@echo "cleaning"
		@$(RM) $(GEN_SOURCES) $(OBJECTS) $(RTS_OBJECTS)\
		    $(OBJECTS:%.o=%.d) $(RTS_OBJECTS:%.o=%.d)\
		    cbf libcb.a parser cb.[ch] a.out submit.tgz

ifeq "$(VERSION)" "Bison"
$(BISON_C_SRC):	$(Y_SOURCES)
		@$(RM) -rf $(LLGEN_C_SRC:%.c=%.[cdo]) $(LLGEN_H_SRC)
		$(BISON) $(BISONFLAGS) $<
		@touch parser
endif

ifeq "$(VERSION)" "LLnextgen"
$(LLGEN_C_SRC): $(G_SOURCES)
		@$(RM) -rf $(BISON_C_SRC:%.c=%.[cdo]) $(BISON_H_SRC)
		$(LLGEN) $(LLGENFLAGS) $<
		@touch parser

endif

%.yy.c:		%.l
		$(LEX) $(LEXFLAGS) $<


libcb.o:	libcb.c libcb.h
rts.o:		rts.c rts.h
gc.o:		gc.c gc.h rts.h

ifeq		($(filter clean, $(MAKECMDGOALS)),)
-include	$(DEPENDENCIES)
endif

.PHONY:all clean compiler
.SECONDARY:lex.yy.c
