# ================================================================
# NOTE: This makefile is not intended to be used in a packaging system --
# rather, Miller uses autconfig for that. This makefile is intended for users
# who prefer (for whatever reason) to bypass autoconfig.  Please also see
# http://johnkerl.org/miller/doc/build.html#Without_using_autoconfig
# ================================================================

CC=gcc

# We cannot use the same flags as the parent-directory makefile since
# lex emits a couple of unused static functions which don't pass gcc -Wall -Werror.
#DSLCFLAGS=-I.. -O3 -Wextra -Wpedantic
DSLCFLAGS=-I.. -O3 -g

#CC=clang
#DSLCFLAGS=-I.. -Wall -O2 -fsanitize=address

# ----------------------------------------------------------------
top: mlr_dsl_lexer.o mlr_dsl_parse.o mlr_dsl_wrapper.o

# ----------------------------------------------------------------
mlr_dsl_wrapper.o: mlr_dsl_wrapper.c mlr_dsl_wrapper.h mlr_dsl_parse.h \
../lib/mlrutil.h ../dsl/mlr_dsl_ast.h ../containers/sllv.h
	$(CC) -Wall $(DSLCFLAGS) -c -std=gnu99 mlr_dsl_wrapper.c

mlr_dsl_parse.o: mlr_dsl_parse.c mlr_dsl_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 mlr_dsl_parse.c
mlr_dsl_parse.c mlr_dsl_parse.h: mlr_dsl_parse.y lemon ../dsl/mlr_dsl_ast.h ../containers/sllv.h
	./lemon -s mlr_dsl_parse.y
	mv mlr_dsl_parse.c mlr_dsl_parse.c.tmp
	sed \
			-e 's/ParseTrace/mlr_dsl_ParseTrace/g' \
			-e 's/ParseTokenName/mlr_dsl_ParseTokenName/g' \
			-e 's/lemon_parser_alloc/mlr_dsl_lemon_parser_alloc/g' \
			-e 's/lemon_parser_free/mlr_dsl_lemon_parser_free/g' \
			-e 's/lemon_parser_parse_token/mlr_dsl_lemon_parser_parse_token/g' \
			-e 's/yy_destructor/mlr_dsl_yy_destructor/g' \
		mlr_dsl_parse.c.tmp > mlr_dsl_parse.c
	rm -f mlr_dsl_parse.c.tmp

# muldef:
#   ParseTrace
#   ParseTokenName
#   lemon_parser_alloc
#   lemon_parser_free
#   lemon_parser_parse_token
#   yy_destructor

mlr_dsl_lexer.o: mlr_dsl_lexer.c mlr_dsl_lexer.h mlr_dsl_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 mlr_dsl_lexer.c
mlr_dsl_lexer.c mlr_dsl_lexer.h: mlr_dsl_lexer.l ../dsl/mlr_dsl_ast.h
	flex --prefix=mlr_dsl_lexer_ --outfile=mlr_dsl_lexer.c --header-file=mlr_dsl_lexer.h mlr_dsl_lexer.l

mlr_dsl: mlr_dsl_wrapper_main.c mlr_dsl_wrapper.c mlr_dsl_wrapper.h mlr_dsl_parse.h mlr_dsl_lexer.o mlr_dsl_parse.o ../lib/mlrutil.c ../lib/mlrutil.h ../lib/mlr_globals.c ../lib/mlr_globals.h ./../dsl/mlr_dsl_ast.h \
../lib/mlrutil.c ../containers/sllv.c ./../dsl/mlr_dsl_ast.c
	$(CC) -Wall $(DSLCFLAGS) -std=gnu99 mlr_dsl_wrapper_main.c mlr_dsl_wrapper.c mlr_dsl_lexer.o mlr_dsl_parse.o ../lib/mlrutil.c ../lib/mlr_globals.c ../containers/sllv.c ./../dsl/mlr_dsl_ast.c -o mlr_dsl

# ----------------------------------------------------------------
ex0: ex0_wrapper.c ex0_wrapper.h ex0_parse.h ex0_lexer.o ex0_parse.o ../lib/mlrutil.c ../lib/mlrutil.h ../lib/mlr_globals.c ../lib/mlr_globals.h ./ex_ast.h \
../lib/mlrutil.c ../containers/sllv.c ./ex_ast.h ./ex_ast.c
	$(CC) -Wall $(DSLCFLAGS) -std=gnu99 ex0_wrapper.c ex0_lexer.o ex0_parse.o ../lib/mlrutil.c ../lib/mlr_globals.c ../containers/sllv.c ./ex_ast.c -o ex0

ex0_parse.o: ex0_parse.c ex0_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex0_parse.c
ex0_parse.c ex0_parse.h: ex0_parse.y lemon ./ex_ast.h ../containers/sllv.h
	./lemon -s ex0_parse.y
	mv ex0_parse.c ex0_parse.c.tmp
	sed \
			-e 's/ParseTrace/ex0_ParseTrace/g' \
			-e 's/ParseTokenName/ex0_ParseTokenName/g' \
			-e 's/lemon_parser_alloc/ex0_lemon_parser_alloc/g' \
			-e 's/lemon_parser_free/ex0_lemon_parser_free/g' \
			-e 's/lemon_parser_parse_token/ex0_lemon_parser_parse_token/g' \
			-e 's/yy_destructor/ex0_yy_destructor/g' \
		ex0_parse.c.tmp > ex0_parse.c
	rm -f ex0_parse.c.tmp

ex0_lexer.o: ex0_lexer.c ex0_lexer.h ex0_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex0_lexer.c
ex0_lexer.c ex0_lexer.h: ex0_lexer.l ./ex_ast.h
	flex --prefix=ex0_lexer_ --outfile=ex0_lexer.c --header-file=ex0_lexer.h ex0_lexer.l

# ----------------------------------------------------------------
ex1: ex1_wrapper.c ex1_wrapper.h ex1_parse.h ex1_lexer.o ex1_parse.o ../lib/mlrutil.c ../lib/mlrutil.h ../lib/mlr_globals.c ../lib/mlr_globals.h ./ex_ast.h \
../lib/mlrutil.c ../containers/sllv.c ./ex_ast.h ./ex_ast.c
	$(CC) -Wall $(DSLCFLAGS) -std=gnu99 ex1_wrapper.c ex1_lexer.o ex1_parse.o ../lib/mlrutil.c ../lib/mlr_globals.c ../containers/sllv.c ./ex_ast.c -o ex1

ex1_parse.o: ex1_parse.c ex1_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex1_parse.c
ex1_parse.c ex1_parse.h: ex1_parse.y lemon ./ex_ast.h ../containers/sllv.h
	./lemon -s ex1_parse.y
	mv ex1_parse.c ex1_parse.c.tmp
	sed \
			-e 's/ParseTrace/ex1_ParseTrace/g' \
			-e 's/ParseTokenName/ex1_ParseTokenName/g' \
			-e 's/lemon_parser_alloc/ex1_lemon_parser_alloc/g' \
			-e 's/lemon_parser_free/ex1_lemon_parser_free/g' \
			-e 's/lemon_parser_parse_token/ex1_lemon_parser_parse_token/g' \
			-e 's/yy_destructor/ex1_yy_destructor/g' \
		ex1_parse.c.tmp > ex1_parse.c
	rm -f ex1_parse.c.tmp

ex1_lexer.o: ex1_lexer.c ex1_lexer.h ex1_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex1_lexer.c
ex1_lexer.c ex1_lexer.h: ex1_lexer.l ./ex_ast.h
	flex --prefix=ex1_lexer_ --outfile=ex1_lexer.c --header-file=ex1_lexer.h ex1_lexer.l

# ----------------------------------------------------------------
ex2: ex2_wrapper.c ex2_wrapper.h ex2_parse.h ex2_lexer.o ex2_parse.o ../lib/mlrutil.c ../lib/mlrutil.h ../lib/mlr_globals.c ../lib/mlr_globals.h ./ex_ast.h \
../lib/mlrutil.c ../containers/sllv.c ./ex_ast.h ./ex_ast.c
	$(CC) -Wall $(DSLCFLAGS) -std=gnu99 ex2_wrapper.c ex2_lexer.o ex2_parse.o ../lib/mlrutil.c ../lib/mlr_globals.c ../containers/sllv.c ./ex_ast.c -o ex2

ex2_parse.o: ex2_parse.c ex2_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex2_parse.c
ex2_parse.c ex2_parse.h: ex2_parse.y lemon ./ex_ast.h ../containers/sllv.h
	./lemon -s -c ex2_parse.y
	mv ex2_parse.c ex2_parse.c.tmp
	sed \
			-e 's/ParseTrace/ex2_ParseTrace/g' \
			-e 's/ParseTokenName/ex2_ParseTokenName/g' \
			-e 's/lemon_parser_alloc/ex2_lemon_parser_alloc/g' \
			-e 's/lemon_parser_free/ex2_lemon_parser_free/g' \
			-e 's/lemon_parser_parse_token/ex2_lemon_parser_parse_token/g' \
			-e 's/yy_destructor/ex2_yy_destructor/g' \
		ex2_parse.c.tmp > ex2_parse.c
	rm -f ex2_parse.c.tmp

ex2_lexer.o: ex2_lexer.c ex2_lexer.h ex2_parse.h
	$(CC) $(DSLCFLAGS) -c -std=gnu99 ex2_lexer.c
ex2_lexer.c ex2_lexer.h: ex2_lexer.l ./ex_ast.h
	flex --prefix=ex2_lexer_ --outfile=ex2_lexer.c --header-file=ex2_lexer.h ex2_lexer.l

# ----------------------------------------------------------------
lemon: \
  lemon_assert.h \
  lemon_assert.c \
  lemon_error.h \
  lemon_error.c \
  lemon_string.h \
  lemon_string.c \
  lemon_msort.h \
  lemon_msort.c \
  lemon_set.h \
  lemon_set.c \
  lemon_memory.h \
  lemon_memory.c \
  lemon_option.h \
  lemon_option.c \
  lemon_structs.h \
  lemon_action.h \
  lemon_action.c \
  lemon_symbol.h \
  lemon_symbol.c \
  lemon_config_list.h \
  lemon_config_list.c \
  lemon_state_table.h \
  lemon_state_table.c \
  lemon_plink.h \
  lemon_plink.c \
  lemon_parse.h \
  lemon_parse.c \
  lemon_fsm.h \
  lemon_fsm.c \
  lemon_report.h \
  lemon_report.c \
  lemon_main.c
	$(CC) -o lemon lemon_assert.c lemon_error.c lemon_string.c \
		lemon_msort.c lemon_set.c lemon_memory.c lemon_option.c lemon_action.c \
		lemon_symbol.c lemon_config_list.c lemon_state_table.c lemon_plink.c \
		lemon_parse.c lemon_fsm.c lemon_report.c lemon_main.c \

# ----------------------------------------------------------------
clean:
	rm -f *.o
	rm -f mlr_dsl_parse.c mlr_dsl_parse.h mlr_dsl_parse.out
	rm -f mlr_dsl_lexer.c mlr_dsl_lexer.h
	rm -f ex0_parse.c ex0_parse.h ex0_parse.out
	rm -f ex0_lexer.c ex0_lexer.h
	rm -f ex0
	rm -f ex1_parse.c ex1_parse.h ex1_parse.out
	rm -f ex1_lexer.c ex1_lexer.h
	rm -f ex1
	rm -f ex2_parse.c ex2_parse.h ex2_parse.out
	rm -f ex2_lexer.c ex2_lexer.h
	rm -f ex2
	rm -f lemon

.always:
	@/bin/true
