// File: /workspace/github_c_makefile_star2_O0/goodpaul6[P]generic/script.c
// Function: compile_expr
static void compile_expr(script_t* script, expr_t* exp)
{
	compile_file_line_info(script, exp, 0);
	
	switch(exp->type)
	{
		case EXP_ATOMIC:
		{
			append_code(script, OP_ATOMIC_ENABLE);
			compile_expr(script, exp->atomx);
			append_code(script, OP_ATOMIC_DISABLE);
		} break;

		case EXP_STRUCT_DECL:
		case EXP_EXTERN:
		case EXP_EXTERN_LIST:
		case EXP_VAR:
		{
			// Do nothing for these
		} break;
		
		case EXP_BLOCK:
		{
			for(int i = 0; i < exp->block.length; ++i)
			{
				expr_t* e = vec_get_value(&exp->block, i, expr_t*);
				compile_expr(script, e);
			}
		} break;
		
		case EXP_RETURN:
		{
			if(!exp->retx.value)
				append_code(script, OP_RETURN);
			else
			{
				compile_value_expr(script, exp->retx.value);
				append_code(script, OP_RETURN_VALUE);
			}
		} break;
		
		case EXP_IF:
		{
			compile_value_expr(script, exp->ifx.cond);
			
			append_code(script, OP_GOTOZ);
			int loc = script->code.length;
			append_int(script, 0);
			
			compile_expr(script, exp->ifx.body);
			
			append_code(script, OP_GOTO);
			int exitLoc = script->code.length;
			append_int(script, 0);
			
			patch_int(script, loc, script->code.length);
			if(exp->ifx.alt)
				compile_expr(script, exp->ifx.alt);
			
			patch_int(script, exitLoc, script->code.length);
		} break;
		
		case EXP_WHILE:
		{
			int jump = script->code.length;
			compile_value_expr(script, exp->whilex.cond);
			
			append_code(script, OP_GOTOZ);
			int loc = script->code.length;
			append_int(script, 0);
			
			compile_expr(script, exp->whilex.body);
			append_code(script, OP_GOTO);
			append_int(script, jump);
			
			patch_int(script, loc, script->code.length);
		} break;

		case EXP_FOR:
		{
			compile_expr(script, exp->forx.init);
			int jump = script->code.length;
			compile_value_expr(script, exp->forx.cond);

			append_code(script, OP_GOTOZ);
			int loc = script->code.length;
			append_int(script, 0);

			compile_expr(script, exp->forx.body);
			compile_expr(script, exp->forx.step);

			append_code(script, OP_GOTO);
			append_int(script, jump);

			patch_int(script, loc, script->code.length);
		} break;
		
		case EXP_FUNC:
		{
			append_code(script, OP_GOTO);
			int loc = script->code.length;
			append_int(script, 0);
			
			vec_set(&script->function_pcs, exp->funcx.decl->index, &script->code.length);
			
			for(int i = 0; i < exp->funcx.decl->locals.length; ++i)
				append_code(script, OP_PUSH_NULL);
			
			compile_expr(script, exp->funcx.body);
			
			append_code(script, OP_RETURN);
			patch_int(script, loc, script->code.length);
		} break;
		
		case EXP_BINARY:
		{
			if(exp->binx.op != TOK_ASSIGN)
				error_exit_e(exp, "Value expression used in non-value context\n");
			
			compile_value_expr(script, exp->binx.rhs);
			compile_assign(script, exp->binx.lhs);
		} break;
		
		case EXP_CALL:
		{
			compile_call(script, exp);
			
			// NOTE: because branching
			compile_file_line_info(script, exp, 1);
		} break;
		
		case EXP_WRITE:
		{
			compile_value_expr(script, exp->write);
			append_code(script, OP_WRITE);
		} break;
		
		default:
			error_exit_e(exp, "Value expression used in non-value context\n");
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
xorl %edx, %edx
callq 0x10100
movq -0x10(%rbp), %rax
movl 0x28(%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0x19, %eax
ja 0xfd8e
movq -0x48(%rbp), %rax
leaq 0x3c72(%rip), %rcx      # 0x135f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
movl $0x2e, %esi
callq 0x9480
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl $0x2f, %esi
callq 0x9480
jmp 0xfda0
jmp 0xfda0
movl $0x0, -0x14(%rbp)
movslq -0x14(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x48(%rcx), %rax
jae 0xfa07
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
movslq -0x14(%rbp), %rsi
callq 0x11890
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xf940
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0xf9c9
jmp 0xfda0
movq -0x10(%rbp), %rax
cmpq $0x0, 0x40(%rax)
jne 0xfa27
movq -0x8(%rbp), %rdi
movl $0x2a, %esi
callq 0x9480
jmp 0xfa46
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movl $0x2b, %esi
callq 0x9480
jmp 0xfda0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movl $0x24, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, %edx
callq 0x10a30
movq -0x10(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0xfaf0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, %edx
callq 0x10a30
jmp 0xfda0
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movl $0x24, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x9480
movq -0x8(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %esi
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, %edx
callq 0x10a30
jmp 0xfda0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movl $0x24, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x9480
movq -0x8(%rbp), %rdi
movl -0x34(%rbp), %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %esi
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, %edx
callq 0x10a30
jmp 0xfda0
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x9480
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, -0x3c(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x109d0
movq -0x8(%rbp), %rdi
addq $0x298, %rdi            # imm = 0x298
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movslq 0x60(%rax), %rsi
movq -0x8(%rbp), %rdx
addq $0x1d8, %rdx            # imm = 0x1D8
addq $0x10, %rdx
callq 0x118f0
movl $0x0, -0x40(%rbp)
movslq -0x40(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x38(%rcx), %rcx
cmpq 0x30(%rcx), %rax
jae 0xfccf
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x9480
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0xfca7
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0xf940
movq -0x8(%rbp), %rdi
movl $0x2a, %esi
callq 0x9480
movq -0x8(%rbp), %rdi
movl -0x3c(%rbp), %esi
movq -0x8(%rbp), %rax
movq 0x1e8(%rax), %rax
movl %eax, %edx
callq 0x10a30
jmp 0xfda0
movq -0x10(%rbp), %rax
cmpl $0x24, 0x48(%rax)
je 0xfd28
movq -0x10(%rbp), %rdi
leaq 0x5919(%rip), %rsi      # 0x1563a
movb $0x0, %al
callq 0xba00
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x10aa0
jmp 0xfda0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x10c10
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x1, %edx
callq 0x10100
jmp 0xfda0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x101e0
movq -0x8(%rbp), %rdi
movl $0x22, %esi
callq 0x9480
jmp 0xfda0
movq -0x10(%rbp), %rdi
leaq 0x58a1(%rip), %rsi      # 0x1563a
movb $0x0, %al
callq 0xba00
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)