// File: /workspace/github_c_makefile_star2_O0/goodpaul6[P]generic/script.c
// Function: compile_module
static void compile_module(script_t* script, script_module_t* module)
{
	char symbol_error = 0;
	
	if(!module->compiled)
	{
		for (int pass = 0; pass <= 1; ++pass)
		{
			// NOTE: Skip first pass if there is no compile
			// time code
			if (module->compile_time_blocks.length == 0)
				pass = 1;

			check_all_tags_defined(script);
			finalize_types(script);

			int ct_start_pc = script->code.length;

			// NOTE: We must compile all referenced modules so that this 
			// module can access their code
			for (int i = 0; i < module->referenced_modules.length; ++i)
			{
				script_module_t* ref_module = vec_get(&script->modules, vec_get_value(&module->referenced_modules, i, int));

				// NOTE: This will compile its referenced modules too
				compile_module(script, ref_module);
			}

			// NOTE: Pass to resolve symbols and types
			if (pass == 1)
			{
				module->start_pc = script->code.length;

				for (int expr_index = 0; expr_index < module->expr_list.length; ++expr_index)
				{
					expr_t* node = vec_get_value(&module->expr_list, expr_index, expr_t*);

					char prev_error = g_has_error;
					resolve_symbols(script, node);
					symbol_error = prev_error ? 0 : g_has_error;
					if (!symbol_error) resolve_type_tags(script, node);
				}

				if (g_has_error) error_exit("Errors in script code. Stopping...\n");

				for (int expr_index = 0; expr_index < module->expr_list.length; ++expr_index)
				{
					expr_t* node = vec_get_value(&module->expr_list, expr_index, expr_t*);
					compile_expr(script, node);
				}

				module->end_pc = script->code.length;
			}
			
			// NOTE: The first pass is the compile-time execution pass
			
			// TODO: VERY IMPORTANT: you cannot access the code in the current
			// module in these compile-time blocks because this module is subject
			// to change during the execution of this code
			
			// Option A: I could do a thing where I look at the code in these blocks and 
			// see the symbols it references and compile the code associated
			// with them but that's very complicated and the compiler isn't set up for 
			// that
			
			// Option B: I have the compiler act differently during the first pass
			// in that it ignores missing symbols and just carries on without compiling
			// any code related to them (this could be pretty complex to do without errors
			// since it may lead to stuff like call expressions being compiled but missing
			// arguments etc; c compilers do this I believe)

			// Option C: What I'm doing now, where you can't call code in this module
			// It's just better if you create a file called "your_file_name_meta.gn"
			// and then put all the compile time functions related to this module
			// in that and you're golden (the compiler handles this just fine since
			// that code will be in a separate module and thus free from edits by this
			// code) OR you could even just label code #on_compile and it would 
			// be available to the compile time code it's super easy fam
			if (pass == 0)
			{
				module->start_pc = script->code.length;

				for (int i = 0; i < module->compile_time_blocks.length; ++i)
				{
					expr_t* exp = vec_get_value(&module->compile_time_blocks, i, expr_t*);

					char prev_error = g_has_error;
					resolve_symbols(script, exp);
					symbol_error = prev_error ? 0 : g_has_error;
					if (!symbol_error) resolve_type_tags(script, exp);

					//debug_expr(script, node);
					//printf("\n");

					if (!g_has_error)
						compile_expr(script, exp);
					else
						error_exit("Found errors in compile-time code. Stopping compilation\n");
				}

				// NOTE: Must stop after all compile time code is executed
				append_code(script, OP_HALT);

				// NOTE: Temporary end_pc for debugging
				module->end_pc = script->code.length;

				// NOTE: setup script for compile-time execution
				vec_clear(&script->stack);
				allocate_globals(script);

				printf("Executing compile-time code...\n");

				script->pc = ct_start_pc;
				while (script->pc >= 0)
					script_execute_cycle(script);

				printf("Finished compile-time execution.\n");

				// NOTE: Reset the script code so it doesn't include the compile time code
				vec_resize(&script->code, module->start_pc, NULL);
			}
		}
		module->compiled = 1;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x11(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x49(%rax)
jne 0x42ce
movl $0x0, -0x18(%rbp)
cmpl $0x1, -0x18(%rbp)
jg 0x42c6
movq -0x10(%rbp), %rax
cmpq $0x0, 0x80(%rax)
jne 0x3fc8
movl $0x1, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0xf810
movq -0x8(%rbp), %rdi
callq 0xf8d0
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movslq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x4040
movq -0x8(%rbp), %rax
addq $0x2b8, %rax            # imm = 0x2B8
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x20(%rbp), %rsi
callq 0x11890
movq -0x68(%rbp), %rdi
movslq (%rax), %rsi
callq 0x11890
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x3f80
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x3fef
cmpl $0x1, -0x18(%rbp)
jne 0x414f
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movl $0x0, -0x2c(%rbp)
movslq -0x2c(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x60(%rcx), %rax
jae 0x40e0
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
movslq -0x2c(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movb 0x1640c(%rip), %al      # 0x1a49c
movb %al, -0x39(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0xa380
movsbl -0x39(%rbp), %eax
cmpl $0x0, %eax
je 0x40b0
xorl %eax, %eax
movl %eax, -0x6c(%rbp)
jmp 0x40ba
movsbl 0x163e5(%rip), %eax     # 0x1a49c
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movb %al, -0x11(%rbp)
cmpb $0x0, -0x11(%rbp)
jne 0x40d3
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0xaa40
jmp 0x40d5
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x4064
cmpb $0x0, 0x163b5(%rip)     # 0x1a49c
je 0x40f7
leaq 0x1145e(%rip), %rdi     # 0x1554e
movb $0x0, %al
callq 0x3990
movl $0x0, -0x40(%rbp)
movslq -0x40(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x60(%rcx), %rax
jae 0x413c
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
movslq -0x40(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xf940
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x40fe
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
cmpl $0x0, -0x18(%rbp)
jne 0x42b6
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movl $0x0, -0x4c(%rbp)
movslq -0x4c(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x80(%rcx), %rax
jae 0x421f
movq -0x10(%rbp), %rdi
addq $0x70, %rdi
movslq -0x4c(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movb 0x162f6(%rip), %al      # 0x1a49c
movb %al, -0x59(%rbp)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0xa380
movsbl -0x59(%rbp), %eax
cmpl $0x0, %eax
je 0x41c6
xorl %eax, %eax
movl %eax, -0x70(%rbp)
jmp 0x41d0
movsbl 0x162cf(%rip), %eax     # 0x1a49c
movl %eax, -0x70(%rbp)
movl -0x70(%rbp), %eax
movb %al, -0x11(%rbp)
cmpb $0x0, -0x11(%rbp)
jne 0x41e9
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0xaa40
cmpb $0x0, 0x162ac(%rip)     # 0x1a49c
jne 0x4201
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0xf940
jmp 0x420f
leaq 0x1136a(%rip), %rdi     # 0x15572
movb $0x0, %al
callq 0x3990
jmp 0x4211
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x4173
movq -0x8(%rbp), %rdi
movl $0x30, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rdi
addq $0x198, %rdi            # imm = 0x198
callq 0x11da0
movq -0x8(%rbp), %rdi
callq 0x4b60
leaq 0x1134b(%rip), %rdi     # 0x155ab
movb $0x0, %al
callq 0x20c0
movl -0x1c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x11c(%rax)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x11c(%rax)
jl 0x428c
movq -0x8(%rbp), %rdi
callq 0x4c00
jmp 0x4274
leaq 0x11338(%rip), %rdi     # 0x155cb
movb $0x0, %al
callq 0x20c0
movq -0x8(%rbp), %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x11800
jmp 0x42b8
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x3fa9
movq -0x10(%rbp), %rax
movb $0x1, 0x49(%rax)
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)