package main

import "core:fmt"
import "core:os"

main :: proc() {
	handle: os.Handle
	if len(os.args) >= 2 {
		errno: os.Errno
		handle, errno = os.open(os.args[1])
		if errno != 0 {
			fmt.printf("Error opening file\n", errno)
				return
		}
	} else {
		handle = os.stdin
	}
	defer os.close(handle)

	data, err := os.read_entire_file_from_handle(handle)
	if !err {
		fmt.printf("Error reading file\n", err)
		return
	}

	u8_arr : [dynamic]u8
	for ch in data {
		append(&u8_arr, u8(ch))
	}

	lexer := lexer_create(&u8_arr)
	parser := parser_create(lexer)

	ast := parser_parse(&parser)
	if len(g_message_list) > 0 {
		for msg in g_message_list {
			fmt.printf("%s\n", msg)
		}
		return
	}
	fmt.println("After parse:")
	node_print(ast)
	clear(&g_message_list)
	type_check(ast, nil)
	fmt.println("After type check:")
	node_print(ast)
	if len(g_message_list) > 0 {
		for msg in g_message_list {
			fmt.printf("%s\n", msg)
		}
		return
	}

	node_print(ast)

	name : string
	if handle == os.stdin {
		name = "stdin"
	} else {
		name = os.args[1]
	}
	name_dyn := [dynamic]u8{}
	for ch in transmute([]u8)name {
		append(&name_dyn, u8(ch))
	}
	module_name := parse_use_path2(name_dyn)
	module_name = main_module_name_from_filename(module_name)
	if len(module_name) == 0 {
		clear(&module_name)
		append(&module_name, 'm')
		append(&module_name, 'a')
		append(&module_name, 'i')
		append(&module_name, 'n')
	}
	ctx := LLVMContextCreate()
	defer LLVMContextDispose(ctx)
	module := LLVMModuleCreateWithNameInContext(cstring(raw_data(module_name[:])), ctx)
	defer LLVMDisposeModule(module)
	builder := LLVMCreateBuilderInContext(ctx)

	generate_llvm(ctx, module, builder, ast)

	append(&module_name, '.')
	append(&module_name, 'l')
	append(&module_name, 'l')
	LLVMPrintModuleToFile(module, cstring(raw_data(module_name[:])), nil)
}

main_module_name_from_filename :: proc(fname: [dynamic]u8) -> (module_name: [dynamic]u8) {
	temp_name := [dynamic]u8{}
	for ch in fname {
		if ch == '/' || ch == '\\' {
			clear(&temp_name)
		} else {
			append(&temp_name, ch)
		}
	}

	for ch in temp_name {
		if ch == '.' {
			break
		}
		append(&module_name, ch)
	}

	return
}
