// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
xorl %edx, %edx
callq 0xb473
movl 0x28(%r14), %eax
decl %eax
cmpl $0x19, %eax
ja 0xb1b8
leaq 0x266d(%rip), %rcx      # 0xd4cc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x40(%r14), %rsi
testq %rsi, %rsi
je 0xb13b
movq %rbx, %rdi
callq 0xb51a
pushq $0x2b
jmp 0xb159
movl 0x1e8(%rbx), %r15d
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x24
popq %rsi
movq %rbx, %rdi
callq 0x7117
movl 0x1e8(%rbx), %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xba1b
movq 0x40(%r14), %rsi
jmp 0xaf94
pushq $0x23
popq %rsi
movq %rbx, %rdi
callq 0x7117
leaq 0x1e8(%rbx), %r12
movq 0x1e8(%rbx), %r15
xorl %r13d, %r13d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xba1b
leaq 0x298(%rbx), %rdi
movq 0x38(%r14), %rax
movslq 0x60(%rax), %rsi
movq %r12, %rdx
callq 0xc183
movq 0x38(%r14), %rax
cmpq %r13, 0x30(%rax)
jbe 0xaf21
movq %rbx, %rdi
xorl %esi, %esi
callq 0x7117
incq %r13
jmp 0xaf08
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
pushq $0x2a
popq %rsi
movq %rbx, %rdi
callq 0x7117
movl 0x1e8(%rbx), %edx
movq %rbx, %rdi
movl %r15d, %esi
jmp 0xb068
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
movl 0x1e8(%rbx), %r15d
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x24
popq %rsi
movq %rbx, %rdi
callq 0x7117
movl 0x1e8(%rbx), %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xba1b
movq 0x50(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
movq 0x48(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
pushq $0x23
popq %rsi
movq %rbx, %rdi
callq 0x7117
movq %rbx, %rdi
movl %r15d, %esi
callq 0xba1b
movl 0x1e8(%rbx), %edx
movq %rbx, %rdi
movl %r12d, %esi
jmp 0xb068
movq %rbx, %rdi
movq %r14, %rsi
callq 0xba98
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb473
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x24
popq %rsi
movq %rbx, %rdi
callq 0x7117
movl 0x1e8(%rbx), %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xba1b
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
pushq $0x23
popq %rsi
movq %rbx, %rdi
callq 0x7117
movl 0x1e8(%rbx), %r15d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xba1b
movl 0x1e8(%rbx), %edx
movq %rbx, %rdi
movl %r12d, %esi
callq 0xba51
movq 0x48(%r14), %rsi
testq %rsi, %rsi
je 0xb05c
movq %rbx, %rdi
callq 0xae2e
movl 0x1e8(%rbx), %edx
movq %rbx, %rdi
movl %r15d, %esi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xba51
pushq $0x2e
popq %rsi
movq %rbx, %rdi
callq 0x7117
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xae2e
pushq $0x2f
jmp 0xb159
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x22
jmp 0xb159
leaq 0x38(%r14), %r15
xorl %r12d, %r12d
cmpq %r12, 0x48(%r14)
jbe 0xae68
movq %r15, %rdi
movq %r12, %rsi
callq 0xc15c
movq (%rax), %rsi
movq %rbx, %rdi
callq 0xae2e
incq %r12
jmp 0xb0b3
cmpl $0x24, 0x48(%r14)
jne 0xb1b8
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
movq 0x38(%r14), %r14
movl 0x28(%r14), %eax
cmpl $0x4, %eax
je 0xb170
cmpl $0x6, %eax
je 0xb13f
cmpl $0x5, %eax
jne 0xb1c9
movq 0x40(%r14), %rax
testq %rax, %rax
je 0xb1d2
xorl %ecx, %ecx
cmpq $0x0, (%rax)
setne %cl
leal 0x25(,%rcx,2), %esi
movq %rbx, %rdi
callq 0x7117
movq 0x40(%r14), %rax
movl 0x1c(%rax), %esi
movq %rbx, %rdi
jmp 0xb1a5
pushq $0x2a
jmp 0xb159
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x10
popq %rsi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x7117
movq 0x38(%r14), %rax
movq 0x40(%r14), %rsi
movq 0x30(%rax), %rdi
callq 0x88d3
testl %eax, %eax
js 0xb1db
movl %eax, %r15d
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xb51a
pushq $0x12
popq %rsi
movq %rbx, %rdi
callq 0x7117
movq %rbx, %rdi
movl %r15d, %esi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xba1b
leaq 0x436c(%rip), %rsi      # 0xf52b
movq %r14, %rdi
xorl %eax, %eax
callq 0x882a
leaq 0x44bb(%rip), %rsi      # 0xf68b
jmp 0xb1bf
leaq 0x444a(%rip), %rsi      # 0xf623
jmp 0xb1bf
movq 0x38(%r14), %rax
movq 0x40(%r14), %rdx
movq 0x30(%rax), %rax
movq 0x30(%rax), %rcx
leaq 0x445c(%rip), %rsi      # 0xf64e
movq %r14, %rdi
xorl %eax, %eax
callq 0x882a