CC=c++
#CFLAGS=-O2
CFLAGS=-Wall -std=c++98
CINCLUDES=
CLIBS=
RM=rm -f
MAKE=make
CP=cp
STRIP=strip
NASM=nasm
NASM_FLAGS=-g -f elf
DEBUG=-g
LD=ld
OBJS=cc.o cpp.o _long_div.o _long_mul.o _ulong_div.o _ulong_mul.o
LONG_OBJS=_long_div.o _long_mul.o _ulong_div.o _ulong_mul.o

default:
	${MAKE} cpp
	${MAKE} cc
	${MAKE} driver
	${MAKE} c_code
#	${MAKE} asm
	${MAKE} math 
	${MAKE} math2 
	${MAKE} test3
	${MAKE} logic
	${MAKE} hello
	${MAKE} char
	${MAKE} short
	${MAKE} long
	${MAKE} zero
	${MAKE} pointer
	${MAKE} array 
	${MAKE} matrix
	${MAKE} cube
	${MAKE} struct 
	${MAKE} param 
	${MAKE} assign
	${MAKE} f_ptr
	${MAKE} array_struct 
	${MAKE} list 
	${MAKE} st_pass
	${MAKE} st_ass
	${MAKE} st_ret
	${MAKE} tushery
	${MAKE} const
	${MAKE} ptr_array
	${MAKE} list2

cpp:cpp.cpp
	c++ cpp.cpp -o cpp

c_code:
	rm -f ./gen_code
	${CC} -O2 ${CFLAGS} gen_code.cpp -o gen_code
	strip ./gen_code
	./gen_code
	cc -O2 c_code.c -c
	ld -shared c_code.o -o libc_code.so
	#rm -f ./gen_macro
	#${CC} -O2 ${CFLAGS} gen_macro.cpp -o gen_macro
	#strip ./gen_macro
	#./gen_macro > c_code_macro.asm
	#${CC} -O2 ${CFLAGS} extract_macro.cpp -o extract_macro
	#strip ./extract_macro
	#cat ./c_code.asm | ./extract_macro > c_code_macro2.asm
	

macros:
	c++ -O2 -Wall -std=c++98 extract_macro.cpp -o extract_macro
	strip ./extract_macro
	cat ./c_code.asm | ./extract_macro > ./c_code_macro.asm
	

debug:
	${NASM} ${NASM_FLAGS} list.asm -o list.o
	cc list.o -o list

const:const.c
	./cc ./const.c ./const.asm
	nasm -g -f elf const.asm -o const.o
	cc -g const.o -o const

test:
	nasm -g -f elf list2.asm -o list2.o
	cc -g list2.o -o list2
	./list2

test_all:
	./math
	./math2
	./logic
	./hello
	./char
	./short
	./long
	./zero
	./pointer
	./array
	./matrix
	./cube
	./struct
	./param
	./assign
	./f_ptr
	./array_struct
	./list
	./st_pass
	./st_ass
	./st_ret
	./tushery
	./const
	./ptr_array
	./list2

all:
	./driver math.c -o math
	./driver math2.c -o math2
	./driver logic.c -o logic
	./driver hello.c -o hello
	./driver test.c -o test
	./driver char.c -o char
	./driver short.c -o short
	./driver long.c -o long
	./driver zero.c -o zero
	./driver pointer.c -o pointer
	./driver array.c -o array
	./driver matrix.c -o matrix
	./driver cube.c -o cube
	./driver struct.c -o struct
	./driver param.c -o param
	./driver assign.c -o assign
	./driver f_ptr.c -o f_ptr
	./driver array_struct.c -o array_struct
	./driver st_pass.c -o st_pass
	./driver st_ass.c -o st_ass
	./driver st_ret.c -o st_ret
	./driver tushery.c -o tushery
	./driver ptr_array.c -o ptr_array
	./driver list2.c -o list2

list2:list2.c
	./cc ./list2.c ./list2.asm
	nasm -g -f elf list2.asm -o list2.o
	cc c_code.o -g list2.o -o list2

ptr_array:ptr_array.o
	./cc ./ptr_array.c ./ptr_array.asm
	nasm -g -f elf ptr_array.asm -o ptr_array.o
	cc -g c_code.o ptr_array.o -o ptr_array
	
st_pass:st_pass.c
	./cc ./st_pass.c ./st_pass.asm
	nasm -g -f elf st_pass.asm -o st_pass.o
	cc -g c_code.o st_pass.o -o st_pass

st_ass:st_ass.c
	./cc ./st_ass.c ./st_ass.asm
	nasm -g -f elf st_ass.asm -o st_ass.o
	cc -g c_code.o st_ass.o -o st_ass

st_ret:st_ret.c
	./cc ./st_ret.c ./st_ret.asm
	nasm -g -f elf st_ret.asm -o st_ret.o
	cc -g c_code.o st_ret.o -o st_ret

tushery:tushery.c
	./cc ./tushery.c ./tushery.asm
	nasm -g -f elf tushery.asm -o tushery.o
	cc -g c_code.o tushery.o -o tushery

list:list.c
	./cc ./list.c ./list.asm
	nasm -g -f elf list.asm -o list.o
	cc -g c_code.o list.o -o list

array_struct:array_struct.c
	./cc ./array_struct.c ./array_struct.asm
	nasm -g -f elf array_struct.asm -o array_struct.o
	cc c_code.o array_struct.o -o array_struct

f_ptr:f_ptr.c
	./cc ./f_ptr.c ./f_ptr.asm
	nasm -g -f elf f_ptr.asm -o f_ptr.o
	cc c_code.o f_ptr.o -o f_ptr

assign:assign.c
	./cc ./assign.c ./assign.asm
	nasm -f elf assign.asm -o assign.o
	cc c_code.o assign.o -o assign

param:param.c
	./cc ./param.c ./param.asm
	nasm -f elf param.asm -o param.o
	cc c_code.o param.o -o param

cube:cube.c
	./cc ./cube.c ./cube.asm
	nasm ${DEBUG} -f elf cube.asm -o cube.o
	cc c_code.o cube.o -o cube

matrix:matrix.c
	./cc ./matrix.c ./matrix.asm
	nasm -f elf matrix.asm -o matrix.o
	cc c_code.o matrix.o -o matrix

address_get.o:address_get.c
	cc -O2 -S address_get.c -o address_get.s
	intel2gas -g -o address_get.asm address_get.s
	nasm -f elf address_get.asm -o address_get.o

array_fun:array_fun.c
	#cc -O2 -g -Wall -std=c89 array_fun.c -o array_fun.o
	#./cc ./array_fun.c ./array_fun.asm
	#intel2gas -g -o array_fun.asm array_fun.s
	nasm -f elf array_fun.asm -o array_fun.o

pointer:pointer.c
	./cc ./pointer.c ./pointer.asm
	nasm -f elf pointer.asm -o pointer.o
	cc c_code.o pointer.o -o pointer


zero:zero.c
	./cc ./zero.c ./zero.asm
	nasm -f elf zero.asm -o zero.o
	cc c_code.o zero.o -o zero

asm:
	make gas
	make intell
	make obj

gas:
	cc -O2 -S array_fun.c -o array_fun.s
	cc -O2 -S long_mul.c -o long_mul.s
	cc -O2 -S long_div.c -o long_div.s
	cc -O2 -S ulong_div.c -o ulong_div.s
	cc -O2 -S ulong_mul.c -o ulong_mul.s

intell:
	intel2gas -g -o array_fun.asm array_fun.s
	intel2gas -g -o long_mul.asm long_mul.s
	intel2gas -g -o long_div.asm long_div.s
	intel2gas -g -o ulong_mul.asm ulong_mul.s
	intel2gas -g -o ulong_div.asm ulong_div.s

obj2:
	as array_fun.s -o array_fun.o
	as long_mul.s -o long_mul.o
	as long_div.s -o long_div.o
	as ulong_mul.s -o ulong_mul.o
	as ulong_div.s -o ulong_div.o

obj:
	nasm -g -f elf array_fun.asm -o array_fun.o
	nasm -g -f elf _long_mul.asm -o _long_mul.o
	nasm -g -f elf _long_div.asm -o _long_div.o
	nasm -g -f elf _ulong_mul.asm -o _ulong_mul.o
	nasm -g -f elf _ulong_div.asm -o _ulong_div.o

struct:struct.c
	./cc ./struct.c ./struct.asm
	nasm -f elf struct.asm -o struct.o
	cc c_code.o struct.o -o struct

array:array.c
	./cc ./array.c ./array.asm
	nasm -f elf array.asm -o array.o
	cc c_code.o array.o -o array

long:long.c
	./cc ./long.c ./long.asm
	nasm -f elf long.asm -o long.o
	cc c_code.o long.o -o long

short:short.c
	./cc ./short.c ./short.asm
	nasm -f elf short.asm -o short.o
	cc c_code.o short.o -o short

char:char.c
	./cc ./char.c ./char.asm
	nasm -f elf char.asm -o char.o
	cc c_code.o char.o -o char

driver:driver.cpp
	c++ -Wall -std=c++98 driver.cpp -o driver

float:
	nasm -f elf float_math.asm -o float_math.o
	cc c_code.o float_math.o -o float_math

mathtest:
	rm -f math_test
	nasm -f elf math_test.asm -o math_test.o
	cc c_code.o math_test.o -o math_test

math2:math2.c
	./cc ./math2.c ./math2.asm
	nasm -f elf math2.asm -o math2.o
	cc c_code.o math2.o -o math2

math:math.c
	./cc ./math.c ./math.asm
	nasm -f elf math.asm -o math.o
	cc c_code.o math.o -o math 

hello:hello.c
	./cc ./hello.c ./hello.asm
	nasm -f elf hello.asm -o hello.o
	cc -g c_code.o hello.o -o hello

logic:logic.c
	./cc ./logic.c ./logic.asm
	nasm -g -f elf logic.asm
	cc -g c_code.o logic.o -o logic

test3:test.c
	./cc ./test.c ./test.asm
	nasm -f elf test.asm -o test.o
	cc c_code.o test.o -o test3

test2.o:
	./cc ./test2.c ./test2.asm
	nasm -f elf ./test2.asm

test2:
	${CC} ${CFLAGS} ${CINCLUDES} test2.o -o test2

all33:
	${MAKE} clean
	${MAKE} default

clean:
	${RM} ./*.core
	${RM} ./cc
	${RM} ./cpp
	${RM} ./make
	${RM} ./test
	${RM} ./*.o
	${RM} ./logic
	${RM} ./float_math
	${RM} ./hello_world
	${RM} ./math
	${RM} ./math2
	${RM} ./char
	${RM} ./short
	${RM} ./long
	${RM} ./zero
	${RM} ./*.core
	${RM} ./driver
	${RM} ./pointer
	${RM} ./array
	${RM} ./matrix
	${RM} ./cube
	${RM} ./struct
	${RM} ./param
	${RM} ./assign
	${RM} ./f_ptr
	${RM} ./array_fun.o
	${RM} ./array_struct
	${RM} ./list
	${RM} ./list2
	${RM} ./st_pass
	${RM} ./st_ass
	${RM} ./st_ret
	${RM} ./tushery
	${RM} ./const

install:
	${CP} ./cc ../bin/
	${CP} ./cpp ../bin/
	${CP} ./make ../bin/

cpp.o:
	${CC} ${CFLAGS} -c ./cpp.cpp ${CINCLUDES}

cc.o:cc.cpp
	${CC} ${CFLAGS} ./cc.cpp ${CINCLUDES} -c

make.o:
	${CC} ${CFLAGS} -c ./make.cpp ${CINCLUDES}

cc:cc.cpp
	c++ -g -Wall -std=c++98 cc.cpp -o cc

make:
	c++ make.cpp -c
	${CC} ${CFLAGS} ./make.cpp -o ./make ${CINCLUDES}
	#${STRIP} ./make


