// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
cmpb $0x0, 0x49(%rsi)
jne 0x402b
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x70(%rsi), %rax
movq %rax, -0x68(%rbp)
leaq 0x2b8(%rdi), %r12
leaq 0x1d8(%rdi), %rax
movq %rax, -0x50(%rbp)
leaq 0x50(%rsi), %r13
leaq 0x198(%rdi), %rax
movq %rax, -0x60(%rbp)
xorl %eax, %eax
movq %r12, -0x38(%rbp)
movq %r13, -0x58(%rbp)
cmpq $0x0, 0x80(%rbx)
movl %eax, %ecx
movl $0x1, %eax
cmovel %eax, %ecx
movq %rcx, -0x40(%rbp)
movslq 0x124b2(%rip), %rsi     # 0x16238
movq %r12, %rdi
callq 0xdf24
cmpq $0x0, 0xa0(%rax)
je 0x3de7
movq %rax, %r13
movq %rax, %r15
addq $0x90, %r15
xorl %r12d, %r12d
movq %r15, %rdi
movq %r12, %rsi
callq 0xdf24
movq (%rax), %rax
cmpb $0x0, 0x24(%rax)
je 0x3dca
incq %r12
cmpq %r12, 0xa0(%r13)
ja 0x3da8
jmp 0x3de7
movq 0x30(%rax), %rsi
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
xorl %eax, %eax
callq 0x24d3
jmp 0x3dbc
cmpq $0x0, 0x2c8(%r14)
movq -0x38(%rbp), %r12
leaq 0x8e13(%rip), %r13      # 0xcc0d
je 0x3e27
xorl %r15d, %r15d
movq %r12, %rdi
movq %r15, %rsi
callq 0xdf24
leaq 0xb0(%rax), %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0xe4c2
incq %r15
cmpq %r15, 0x2c8(%r14)
ja 0x3dff
movl 0x1e8(%r14), %eax
movl %eax, -0x44(%rbp)
cmpq $0x0, 0x10(%rbx)
movq -0x58(%rbp), %r13
je 0x3e69
xorl %r15d, %r15d
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdf24
movslq (%rax), %rsi
movq %r12, %rdi
callq 0xdf24
movq %r14, %rdi
movq %rax, %rsi
callq 0x3d15
incq %r15
cmpq %r15, 0x10(%rbx)
ja 0x3e3f
movq -0x40(%rbp), %rcx
testl %ecx, %ecx
je 0x3f2a
cmpl $0x1, %ecx
jne 0x401c
movq 0x1e8(%r14), %rax
movq %rax, 0x20(%rbx)
cmpq $0x0, 0x60(%rbx)
je 0x3ed9
xorl %r15d, %r15d
movq %r13, %rdi
movq %r15, %rsi
callq 0xdf24
movq (%rax), %r12
movb 0x12394(%rip), %r13b    # 0x1623c
movq %r14, %rdi
movq %r12, %rsi
callq 0x8b6c
testb %r13b, %r13b
jne 0x3ec1
testb $0x1, 0x1237d(%rip)     # 0x1623c
jne 0x3ecc
movq %r14, %rdi
movq %r12, %rsi
callq 0x8f00
incq %r15
cmpq %r15, 0x60(%rbx)
movq -0x58(%rbp), %r13
ja 0x3e93
cmpb $0x0, 0x1235c(%rip)     # 0x1623c
jne 0x4048
cmpq $0x0, 0x60(%rbx)
movq -0x38(%rbp), %r12
je 0x3f13
xorl %r15d, %r15d
movq %r13, %rdi
movq %r15, %rsi
callq 0xdf24
movq (%rax), %rsi
movq %r14, %rdi
callq 0xc57a
incq %r15
cmpq %r15, 0x60(%rbx)
ja 0x3ef4
movq 0x1e8(%r14), %rax
movq %rax, 0x28(%rbx)
movq -0x40(%rbp), %rcx
testl %ecx, %ecx
jne 0x401c
movq 0x1e8(%r14), %rax
movq %rax, 0x20(%rbx)
cmpq $0x0, 0x80(%rbx)
je 0x3fa0
xorl %r15d, %r15d
movq -0x68(%rbp), %rdi
movq %r15, %rsi
callq 0xdf24
movq (%rax), %r12
movb 0x122e4(%rip), %r13b    # 0x1623c
movq %r14, %rdi
movq %r12, %rsi
callq 0x8b6c
testb %r13b, %r13b
jne 0x3f71
testb $0x1, 0x122cd(%rip)     # 0x1623c
jne 0x3f7c
movq %r14, %rdi
movq %r12, %rsi
callq 0x8f00
cmpb $0x0, 0x122b9(%rip)     # 0x1623c
jne 0x403a
movq %r14, %rdi
movq %r12, %rsi
callq 0xc57a
incq %r15
cmpq %r15, 0x80(%rbx)
ja 0x3f42
movb $0x30, -0x29(%rbp)
movq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rsi
callq 0xdf81
movq 0x1e8(%r14), %rax
movq %rax, 0x28(%rbx)
movq -0x60(%rbp), %rdi
callq 0xe1c4
movq %r14, %rdi
callq 0x4571
leaq 0xd9d7(%rip), %rdi      # 0x119ab
callq 0x2060
movl -0x44(%rbp), %eax
movl %eax, 0x11c(%r14)
testl %eax, %eax
js 0x3ff9
movq %r14, %rdi
callq 0x45f3
cmpl $0x0, 0x11c(%r14)
jns 0x3fe7
leaq 0xd9ca(%rip), %rdi      # 0x119ca
callq 0x2060
movq 0x20(%rbx), %rsi
movq -0x50(%rbp), %rdi
xorl %edx, %edx
callq 0xdec2
movq -0x38(%rbp), %r12
movq -0x40(%rbp), %rcx
leal 0x1(%rcx), %eax
testl %ecx, %ecx
jle 0x3d69
movb $0x1, 0x49(%rbx)
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd45c(%rip), %rdi      # 0x1149d
xorl %eax, %eax
callq 0x384e
leaq 0xd42a(%rip), %rdi      # 0x11479
jmp 0x4041