// File: /workspace/github_c_makefile_star2_O0/goodpaul6[P]generic/script.c
// Function: debug_script
static void debug_script(script_t* script)
{
	printf("\n");

	if (script->pc >= 0)
		print_current_script_line(script);
	else
		printf("Finished execution.\n");

	char cmdbuf[SCRIPT_DEBUG_CMD_BUF_SIZE];

	while (1)
	{
		fgets(cmdbuf, SCRIPT_DEBUG_CMD_BUF_SIZE, stdin);

		// NOTE: empty command
		if (cmdbuf[0] == '\n')
			strcpy(cmdbuf, script->debug_env.cmd);
		else
			strcpy(script->debug_env.cmd, cmdbuf);
			
		// NOTE: Prints code in the vicinty of the error
		if (strcmp(cmdbuf, "list\n") == 0)
		{
			script_module_t* mod = get_executing_module(script);
			if (mod)
			{
				printf("distance: ");
				
				fgets(cmdbuf, SCRIPT_DEBUG_CMD_BUF_SIZE, stdin);
				cmdbuf[strcspn(cmdbuf, "\n")] = '\0';

				char* code = mod->source_code;
				int line = 1;
				int minDist = atoi(cmdbuf);

				while (code && *code)
				{
					char* line_end = strchr(code, '\n');

					int dist = (int)labs(script->cur_line - line);
					if (dist < minDist)
					{
						int n = printf("%d: ", line);
						if (dist == 0)
						{
							// NOTE: prints --> or something at the line (covering the line number)
							putchar('\r');
							n -= 2;
							while(n--) putchar('-');
							putchar('>');
						}

						printf("%.*s\n", (int)(line_end - code), code);
					}

					code = line_end ? line_end + 1 : NULL;
					++line;
				}
			}
			else
				printf("Code being executed does not belong to any modules.\n");
		}
		else if (strcmp(cmdbuf, "local\n") == 0)
		{
			script_call_record_t* record;
			if (script->call_records.length <= 0)
			{
				printf("Not inside function.\n");
				continue;
			}

			record = vec_get(&script->call_records, script->call_records.length - 1);

			printf("local name: ");
			
			fgets(cmdbuf, SCRIPT_DEBUG_CMD_BUF_SIZE, stdin);
			cmdbuf[strcspn(cmdbuf, "\n")] = '\0';

			const char* name = vec_get_value(&script->function_names, record->function.index, char*);
			
			func_decl_t* decl = reference_function(script, name);
			if (!decl)
			{
				printf("Unable to retrieve function data.\n");
				continue;
			}

			var_decl_t* local = NULL;
			for (int i = 0; i < decl->locals.length; ++i)
			{
				var_decl_t* l = vec_get_value(&decl->locals, i, var_decl_t*);
				if (strcmp(l->name, cmdbuf) == 0)
				{
					local = l;
					break;
				}
			}

			for (int i = 0; i < decl->args.length; ++i)
			{
				var_decl_t* l = vec_get_value(&decl->args, i, var_decl_t*);
				if (strcmp(l->name, cmdbuf) == 0)
				{
					local = l;
					break;
				}
			}

			if (!local)
			{
				printf("No local by that name.\n");
				continue;
			}

			printf("local offset = %d\n", local->index);
			printf("local value = ");

			script_value_t* val = vec_get_value(&script->stack, script->fp + local->index, script_value_t*);
			
			write_value(val, 1);
			printf("\n");
		}
		else if (strcmp(cmdbuf, "step\n") == 0)
		{
			script->debug_env.step_file = script->cur_file;
			script->debug_env.step_line = script->cur_line;
			script->debug_env.step = 1;
			break;
		}
		else if (strcmp(cmdbuf, "run_code\n") == 0)
		{
			printf("code: ");
			fgets(cmdbuf, SCRIPT_DEBUG_CMD_BUF_SIZE, stdin);

			// NOTE: It literally creates a module just for this code to run
			// This module automatically has access to the symbols of the other
			// modules since they're already loaded up and running hopefully
			script_parse_code(script, cmdbuf, "stdin", "debug");

			// NOTE: script_parse_code pushes a module onto the end of the array
			script_module_t* module = vec_get(&script->modules, script->modules.length - 1);

			compile_module(script, module);

			int pc = script->pc;
			script->pc = module->start_pc;

			while (script->pc >= 0 && script->pc < module->end_pc)
				script_execute_cycle(script);

			script->pc = pc;

			destroy_module(module);
			vec_pop_back(&script->modules, NULL);
		}
		else if (strcmp(cmdbuf, "stack\n") == 0)
		{
			script_call_record_t* record;
			if (script->call_records.length <= 0)
				record = NULL;
			else
				record = vec_get(&script->call_records, script->call_records.length - 1);

			func_decl_t* decl = NULL;

			if (record)
				decl = reference_function(script, vec_get_value(&script->function_names, record->function.index, char*));

			int min = script->fp;
			if (record)
				min = script->fp - record->nargs;

			for (size_t stackIndex = script->stack.length - 1; stackIndex >= min; --stackIndex)
			{
				if (decl)
				{
					for (int i = 0; i < decl->locals.length; ++i)
					{
						var_decl_t* local = vec_get_value(&decl->locals, i, var_decl_t*);
						if (local->index == stackIndex - script->fp)
						{
							printf("%s = ", local->name);
							break;
						}
					}

					for (int i = 0; i < decl->args.length; ++i)
					{
						var_decl_t* arg = vec_get_value(&decl->args, i, var_decl_t*);
						if (arg->index == stackIndex - script->fp)
						{
							printf("%s = ", arg->name);
							break;
						}
					}
				}

				write_value(vec_get_value(&script->stack, stackIndex, script_value_t*), 1);
				printf("\n");
			}
		}
		else if (strcmp(cmdbuf, "stop\n") == 0)
			break;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x8(%rbp)
leaq 0x10136(%rip), %rdi     # 0x14e3c
movb $0x0, %al
callq 0x20c0
movq -0x8(%rbp), %rax
cmpl $0x0, 0x11c(%rax)
jl 0x4d25
movq -0x8(%rbp), %rdi
callq 0x10d50
jmp 0x4d33
leaq 0x10ca7(%rip), %rdi     # 0x159d3
movb $0x0, %al
callq 0x20c0
jmp 0x4d35
leaq -0x110(%rbp), %rdi
movq 0x15295(%rip), %rax     # 0x19fd8
movq (%rax), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x2120
movsbl -0x110(%rbp), %eax
cmpl $0xa, %eax
jne 0x4d72
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x8, %rsi
callq 0x2050
jmp 0x4d86
movq -0x8(%rbp), %rdi
addq $0x8, %rdi
leaq -0x110(%rbp), %rsi
callq 0x2050
leaq -0x110(%rbp), %rdi
leaq 0x104f2(%rip), %rsi     # 0x15286
callq 0x2130
cmpl $0x0, %eax
jne 0x4fa5
movq -0x8(%rbp), %rdi
callq 0x10e50
movq %rax, -0x118(%rbp)
cmpq $0x0, -0x118(%rbp)
je 0x4f92
leaq 0x10c21(%rip), %rdi     # 0x159e8
movb $0x0, %al
callq 0x20c0
leaq -0x110(%rbp), %rdi
movq 0x151fc(%rip), %rax     # 0x19fd8
movq (%rax), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x2120
leaq -0x110(%rbp), %rdi
leaq 0x10045(%rip), %rsi     # 0x14e3c
callq 0x2110
movb $0x0, -0x110(%rbp,%rax)
movq -0x118(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x120(%rbp)
movl $0x1, -0x124(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x21f0
movl %eax, -0x128(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x120(%rbp)
movb %al, -0x1d1(%rbp)
je 0x4e5a
movq -0x120(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
setne %al
movb %al, -0x1d1(%rbp)
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0x4e69
jmp 0x4f90
movq -0x120(%rbp), %rdi
movl $0xa, %esi
callq 0x20b0
movq %rax, -0x130(%rbp)
movq -0x8(%rbp), %rax
movl 0x124(%rax), %eax
subl -0x124(%rbp), %eax
cltq
movq %rax, %rcx
negq %rcx
cmovnsq %rcx, %rax
movl %eax, -0x134(%rbp)
movl -0x134(%rbp), %eax
cmpl -0x128(%rbp), %eax
jge 0x4f45
movl -0x124(%rbp), %esi
leaq 0x10b31(%rip), %rdi     # 0x159f3
movb $0x0, %al
callq 0x20c0
movl %eax, -0x138(%rbp)
cmpl $0x0, -0x134(%rbp)
jne 0x4f1d
movl $0xd, %edi
callq 0x2040
movl -0x138(%rbp), %eax
subl $0x2, %eax
movl %eax, -0x138(%rbp)
movl -0x138(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x138(%rbp)
cmpl $0x0, %eax
je 0x4f13
movl $0x2d, %edi
callq 0x2040
jmp 0x4ef1
movl $0x3e, %edi
callq 0x2040
movq -0x130(%rbp), %rax
movq -0x120(%rbp), %rcx
subq %rcx, %rax
movl %eax, %esi
movq -0x120(%rbp), %rdx
leaq 0x10bd4(%rip), %rdi     # 0x15b12
movb $0x0, %al
callq 0x20c0
cmpq $0x0, -0x130(%rbp)
je 0x4f63
movq -0x130(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1e0(%rbp)
jmp 0x4f6e
xorl %eax, %eax
movq %rax, -0x1e0(%rbp)
jmp 0x4f6e
movq -0x1e0(%rbp), %rax
movq %rax, -0x120(%rbp)
movl -0x124(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x124(%rbp)
jmp 0x4e32
jmp 0x4fa0
leaq 0x10a5f(%rip), %rdi     # 0x159f8
movb $0x0, %al
callq 0x20c0
jmp 0x568e
leaq -0x110(%rbp), %rdi
leaq 0x10a7a(%rip), %rsi     # 0x15a2d
callq 0x2130
cmpl $0x0, %eax
jne 0x5244
movq -0x8(%rbp), %rax
cmpq $0x0, 0x140(%rax)
ja 0x4fe2
leaq 0x10a5e(%rip), %rdi     # 0x15a34
movb $0x0, %al
callq 0x20c0
jmp 0x4d35
movq -0x8(%rbp), %rdi
addq $0x130, %rdi            # imm = 0x130
movq -0x8(%rbp), %rax
movq 0x140(%rax), %rsi
subq $0x1, %rsi
callq 0x11890
movq %rax, -0x140(%rbp)
leaq 0x10a3b(%rip), %rdi     # 0x15a4a
movb $0x0, %al
callq 0x20c0
leaq -0x110(%rbp), %rdi
movq 0x14fb4(%rip), %rax     # 0x19fd8
movq (%rax), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x2120
leaq -0x110(%rbp), %rdi
leaq 0xfdfd(%rip), %rsi      # 0x14e3c
callq 0x2110
movb $0x0, -0x110(%rbp,%rax)
movq -0x8(%rbp), %rdi
addq $0x278, %rdi            # imm = 0x278
movq -0x140(%rbp), %rax
movslq 0x18(%rax), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x148(%rbp)
movq -0x8(%rbp), %rdi
movq -0x148(%rbp), %rsi
callq 0x9cb0
movq %rax, -0x150(%rbp)
cmpq $0x0, -0x150(%rbp)
jne 0x50a5
leaq 0x109be(%rip), %rdi     # 0x15a57
movb $0x0, %al
callq 0x20c0
jmp 0x4d35
movq $0x0, -0x158(%rbp)
movl $0x0, -0x15c(%rbp)
movslq -0x15c(%rbp), %rax
movq -0x150(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x512e
movq -0x150(%rbp), %rdi
addq $0x20, %rdi
movslq -0x15c(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x168(%rbp)
movq -0x168(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x110(%rbp), %rsi
callq 0x2130
cmpl $0x0, %eax
jne 0x511b
movq -0x168(%rbp), %rax
movq %rax, -0x158(%rbp)
jmp 0x512e
jmp 0x511d
movl -0x15c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x50ba
movl $0x0, -0x16c(%rbp)
movslq -0x16c(%rbp), %rax
movq -0x150(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jae 0x51ac
movq -0x150(%rbp), %rdi
addq $0x40, %rdi
movslq -0x16c(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x110(%rbp), %rsi
callq 0x2130
cmpl $0x0, %eax
jne 0x5199
movq -0x178(%rbp), %rax
movq %rax, -0x158(%rbp)
jmp 0x51ac
jmp 0x519b
movl -0x16c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x16c(%rbp)
jmp 0x5138
cmpq $0x0, -0x158(%rbp)
jne 0x51c9
leaq 0x108bd(%rip), %rdi     # 0x15a7a
movb $0x0, %al
callq 0x20c0
jmp 0x4d35
movq -0x158(%rbp), %rax
movl 0x1c(%rax), %esi
leaq 0x108b8(%rip), %rdi     # 0x15a92
movb $0x0, %al
callq 0x20c0
leaq 0x108bd(%rip), %rdi     # 0x15aa5
movb $0x0, %al
callq 0x20c0
movq -0x8(%rbp), %rdi
addq $0x198, %rdi            # imm = 0x198
movq -0x8(%rbp), %rax
movl 0x120(%rax), %eax
movq -0x158(%rbp), %rcx
addl 0x1c(%rcx), %eax
movslq %eax, %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rdi
movl $0x1, %esi
callq 0xc3e0
leaq 0xfc04(%rip), %rdi      # 0x14e3c
movb $0x0, %al
callq 0x20c0
jmp 0x568c
leaq -0x110(%rbp), %rdi
leaq 0x10862(%rip), %rsi     # 0x15ab4
callq 0x2130
cmpl $0x0, %eax
jne 0x5296
movq -0x8(%rbp), %rax
movq 0x128(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x108(%rax)
movq -0x8(%rbp), %rax
movl 0x124(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x110(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x114(%rax)
jmp 0x5693
leaq -0x110(%rbp), %rdi
leaq 0x10816(%rip), %rsi     # 0x15aba
callq 0x2130
cmpl $0x0, %eax
jne 0x53d6
leaq 0x1080b(%rip), %rdi     # 0x15ac4
movb $0x0, %al
callq 0x20c0
leaq -0x110(%rbp), %rdi
movq 0x14d0a(%rip), %rax     # 0x19fd8
movq (%rax), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x2120
movq -0x8(%rbp), %rdi
leaq -0x110(%rbp), %rsi
leaq 0x107de(%rip), %rdx     # 0x15acb
leaq 0x107dd(%rip), %rcx     # 0x15ad1
callq 0x3b00
movq -0x8(%rbp), %rdi
addq $0x2b8, %rdi            # imm = 0x2B8
movq -0x8(%rbp), %rax
movq 0x2c8(%rax), %rsi
subq $0x1, %rsi
callq 0x11890
movq %rax, -0x188(%rbp)
movq -0x8(%rbp), %rdi
movq -0x188(%rbp), %rsi
callq 0x3f80
movq -0x8(%rbp), %rax
movl 0x11c(%rax), %eax
movl %eax, -0x18c(%rbp)
movq -0x188(%rbp), %rax
movq 0x20(%rax), %rax
movl %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x11c(%rax)
movq -0x8(%rbp), %rcx
xorl %eax, %eax
cmpl $0x0, 0x11c(%rcx)
movb %al, -0x1e1(%rbp)
jl 0x538a
movq -0x8(%rbp), %rax
movslq 0x11c(%rax), %rax
movq -0x188(%rbp), %rcx
cmpq 0x28(%rcx), %rax
setb %al
movb %al, -0x1e1(%rbp)
movb -0x1e1(%rbp), %al
testb $0x1, %al
jne 0x5396
jmp 0x53a1
movq -0x8(%rbp), %rdi
callq 0x4c00
jmp 0x5356
movl -0x18c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x11c(%rax)
movq -0x188(%rbp), %rdi
callq 0x2ec0
movq -0x8(%rbp), %rdi
addq $0x2b8, %rdi            # imm = 0x2B8
xorl %eax, %eax
movl %eax, %esi
callq 0x11a00
jmp 0x5688
leaq -0x110(%rbp), %rdi
leaq 0x106f3(%rip), %rsi     # 0x15ad7
callq 0x2130
cmpl $0x0, %eax
jne 0x566a
movq -0x8(%rbp), %rax
cmpq $0x0, 0x140(%rax)
ja 0x540d
movq $0x0, -0x198(%rbp)
jmp 0x5433
movq -0x8(%rbp), %rdi
addq $0x130, %rdi            # imm = 0x130
movq -0x8(%rbp), %rax
movq 0x140(%rax), %rsi
subq $0x1, %rsi
callq 0x11890
movq %rax, -0x198(%rbp)
movq $0x0, -0x1a0(%rbp)
cmpq $0x0, -0x198(%rbp)
je 0x5484
movq -0x8(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x8(%rbp), %rdi
addq $0x278, %rdi            # imm = 0x278
movq -0x198(%rbp), %rax
movslq 0x18(%rax), %rsi
callq 0x11890
movq -0x1f0(%rbp), %rdi
movq (%rax), %rsi
callq 0x9cb0
movq %rax, -0x1a0(%rbp)
movq -0x8(%rbp), %rax
movl 0x120(%rax), %eax
movl %eax, -0x1a4(%rbp)
cmpq $0x0, -0x198(%rbp)
je 0x54b8
movq -0x8(%rbp), %rax
movl 0x120(%rax), %eax
movq -0x198(%rbp), %rcx
subl 0x10(%rcx), %eax
movl %eax, -0x1a4(%rbp)
movq -0x8(%rbp), %rax
movq 0x1a8(%rax), %rax
subq $0x1, %rax
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rax
movslq -0x1a4(%rbp), %rcx
cmpq %rcx, %rax
jb 0x5668
cmpq $0x0, -0x1a0(%rbp)
je 0x561f
movl $0x0, -0x1b4(%rbp)
movslq -0x1b4(%rbp), %rax
movq -0x1a0(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x5588
movq -0x1a0(%rbp), %rdi
addq $0x20, %rdi
movslq -0x1b4(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
movq -0x1c0(%rbp), %rax
movslq 0x1c(%rax), %rax
movq -0x1b0(%rbp), %rcx
movq -0x8(%rbp), %rdx
movslq 0x120(%rdx), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jne 0x5572
movq -0x1c0(%rbp), %rax
movq 0x10(%rax), %rsi
leaq 0x10575(%rip), %rdi     # 0x15ade
movb $0x0, %al
callq 0x20c0
jmp 0x5588
jmp 0x5574
movl -0x1b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b4(%rbp)
jmp 0x54fd
movl $0x0, -0x1c4(%rbp)
movslq -0x1c4(%rbp), %rax
movq -0x1a0(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jae 0x561d
movq -0x1a0(%rbp), %rdi
addq $0x40, %rdi
movslq -0x1c4(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x1d0(%rbp)
movq -0x1d0(%rbp), %rax
movslq 0x1c(%rax), %rax
movq -0x1b0(%rbp), %rcx
movq -0x8(%rbp), %rdx
movslq 0x120(%rdx), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jne 0x5607
movq -0x1d0(%rbp), %rax
movq 0x10(%rax), %rsi
leaq 0x104e0(%rip), %rdi     # 0x15ade
movb $0x0, %al
callq 0x20c0
jmp 0x561d
jmp 0x5609
movl -0x1c4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c4(%rbp)
jmp 0x5592
jmp 0x561f
movq -0x8(%rbp), %rdi
addq $0x198, %rdi            # imm = 0x198
movq -0x1b0(%rbp), %rsi
callq 0x11890
movq (%rax), %rdi
movl $0x1, %esi
callq 0xc3e0
leaq 0xf7f2(%rip), %rdi      # 0x14e3c
movb $0x0, %al
callq 0x20c0
movq -0x1b0(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x1b0(%rbp)
jmp 0x54ce
jmp 0x5686
leaq -0x110(%rbp), %rdi
leaq 0x1046c(%rip), %rsi     # 0x15ae4
callq 0x2130
cmpl $0x0, %eax
jne 0x5684
jmp 0x5693
jmp 0x5686
jmp 0x5688
jmp 0x568a
jmp 0x568c
jmp 0x568e
jmp 0x4d35
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
nopl (%rax)