// File: /workspace/github_c_makefile_star2_O3/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
subq $0x18, %rsp
movq %rsi, %r14
movq %rdi, %rbx
xorl %edx, %edx
callq 0xcc56
movl 0x28(%r14), %eax
decl %eax
cmpl $0x19, %eax
ja 0xca24
leaq 0x3103(%rip), %rcx      # 0xf50c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %rsi
movb $0x22, (%rsi)
jmp 0xc95b
movq 0x40(%r14), %rsi
testq %rsi, %rsi
je 0xc933
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %rsi
movb $0x2b, (%rsi)
jmp 0xc95b
movq 0x1e8(%rbx), %rax
movq %rax, -0x38(%rbp)
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %r12
movb $0x24, (%r12)
leaq 0x1d8(%rbx), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
movq 0x1e8(%rbx), %rax
movq %rax, -0x40(%rbp)
movl $0x0, (%r12)
xorl %r13d, %r13d
leaq -0x29(%rbp), %r12
movb -0x30(%rbp,%r13), %al
incq %r13
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
cmpq $0x4, %r13
jne 0xc497
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
leaq -0x30(%rbp), %r14
movb $0x23, (%r14)
movq %r15, %rdi
movq %r14, %rsi
callq 0xdd50
movq -0x38(%rbp), %rax
movl %eax, (%r14)
xorl %r12d, %r12d
leaq -0x29(%rbp), %r14
movb -0x30(%rbp,%r12), %al
incq %r12
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r14, %rsi
callq 0xdd50
cmpq $0x4, %r12
jne 0xc4e0
movl 0x1e8(%rbx), %eax
movl %eax, -0x30(%rbp)
movslq -0x40(%rbp), %rbx
xorl %r14d, %r14d
leaq (%r14,%rbp), %rdx
addq $-0x30, %rdx
leaq (%rbx,%r14), %rsi
movq %r15, %rdi
callq 0xdd1a
incq %r14
cmpq $0x4, %r14
jne 0xc50c
jmp 0xc96a
leaq -0x30(%rbp), %r13
movb $0x23, (%r13)
leaq 0x1d8(%rbx), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0xdd50
leaq 0x1e8(%rbx), %rax
movq %rax, -0x38(%rbp)
movq 0x1e8(%rbx), %rax
movq %rax, -0x40(%rbp)
movl $0x0, (%r13)
xorl %r12d, %r12d
leaq -0x29(%rbp), %r13
movb -0x30(%rbp,%r12), %al
incq %r12
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r13, %rsi
callq 0xdd50
cmpq $0x4, %r12
jne 0xc56e
leaq 0x298(%rbx), %rdi
movq 0x38(%r14), %rax
movslq 0x60(%rax), %rsi
movq -0x38(%rbp), %rdx
callq 0xdd1a
movq 0x38(%r14), %rax
cmpq $0x0, 0x30(%rax)
je 0xc5d0
xorl %r13d, %r13d
leaq -0x30(%rbp), %r12
movb $0x0, -0x30(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
incq %r13
movq 0x38(%r14), %rax
cmpq %r13, 0x30(%rax)
ja 0xc5b4
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
leaq -0x30(%rbp), %r14
movb $0x2a, (%r14)
movq %r15, %rdi
movq %r14, %rsi
callq 0xdd50
movl 0x1e8(%rbx), %eax
movl %eax, (%r14)
movslq -0x40(%rbp), %rbx
xorl %r14d, %r14d
leaq (%r14,%rbp), %rdx
addq $-0x30, %rdx
leaq (%rbx,%r14), %rsi
movq %r15, %rdi
callq 0xdd1a
incq %r14
cmpq $0x4, %r14
jne 0xc5ff
jmp 0xc96a
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
movq 0x1e8(%rbx), %rax
movq %rax, -0x38(%rbp)
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %r12
movb $0x24, (%r12)
leaq 0x1d8(%rbx), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
movq 0x1e8(%rbx), %rax
movq %rax, -0x40(%rbp)
movl $0x0, (%r12)
xorl %r13d, %r13d
leaq -0x29(%rbp), %r12
movb -0x30(%rbp,%r13), %al
incq %r13
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
cmpq $0x4, %r13
jne 0xc679
movq 0x50(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
movq 0x48(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
leaq -0x30(%rbp), %r14
movb $0x23, (%r14)
movq %r15, %rdi
movq %r14, %rsi
callq 0xdd50
movq -0x38(%rbp), %rax
movl %eax, (%r14)
xorl %r12d, %r12d
leaq -0x29(%rbp), %r14
movb -0x30(%rbp,%r12), %al
incq %r12
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r14, %rsi
callq 0xdd50
cmpq $0x4, %r12
jne 0xc6ce
movl 0x1e8(%rbx), %eax
movl %eax, -0x30(%rbp)
movslq -0x40(%rbp), %rbx
xorl %r14d, %r14d
leaq (%r14,%rbp), %rdx
addq $-0x30, %rdx
leaq (%rbx,%r14), %rsi
movq %r15, %rdi
callq 0xdd1a
incq %r14
cmpq $0x4, %r14
jne 0xc6fa
jmp 0xc96a
movq %rbx, %rdi
movq %r14, %rsi
callq 0xd5bc
movq %rbx, %rdi
movq %r14, %rsi
movl $0x1, %edx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xcc56
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %r12
movb $0x24, (%r12)
leaq 0x1d8(%rbx), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
movq 0x1e8(%rbx), %rax
movq %rax, -0x40(%rbp)
movl $0x0, (%r12)
xorl %r13d, %r13d
leaq -0x29(%rbp), %r12
movb -0x30(%rbp,%r13), %al
incq %r13
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
cmpq $0x4, %r13
jne 0xc786
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
leaq -0x30(%rbp), %r12
movb $0x23, (%r12)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
movq 0x1e8(%rbx), %rax
movq %rax, -0x38(%rbp)
movl $0x0, (%r12)
xorl %r13d, %r13d
leaq -0x29(%rbp), %r12
movb -0x30(%rbp,%r13), %al
incq %r13
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xdd50
cmpq $0x4, %r13
jne 0xc7dc
movl 0x1e8(%rbx), %eax
movl %eax, -0x30(%rbp)
movslq -0x40(%rbp), %r12
xorl %r13d, %r13d
leaq -0x30(,%r13), %rdx
addq %rbp, %rdx
leaq (%r12,%r13), %rsi
movq %r15, %rdi
callq 0xdd1a
incq %r13
cmpq $0x4, %r13
jne 0xc808
movq 0x48(%r14), %rsi
testq %rsi, %rsi
je 0xc839
movq %rbx, %rdi
callq 0xc3d5
movl 0x1e8(%rbx), %eax
movl %eax, -0x30(%rbp)
movslq -0x38(%rbp), %rbx
xorl %r14d, %r14d
leaq (%r14,%rbp), %rdx
addq $-0x30, %rdx
leaq (%rbx,%r14), %rsi
movq %r15, %rdi
callq 0xdd1a
incq %r14
cmpq $0x4, %r14
jne 0xc849
jmp 0xc96a
leaq -0x30(%rbp), %r15
movb $0x2e, (%r15)
leaq 0x1d8(%rbx), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0xdd50
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xc3d5
movb $0x2f, (%r15)
leaq -0x30(%rbp), %rsi
movq %r12, %rdi
jmp 0xc965
cmpq $0x0, 0x48(%r14)
je 0xc96a
leaq 0x38(%r14), %r15
xorl %r12d, %r12d
movq %r15, %rdi
movq %r12, %rsi
callq 0xdcf3
movq (%rax), %rsi
movq %rbx, %rdi
callq 0xc3d5
incq %r12
cmpq %r12, 0x48(%r14)
ja 0xc8b3
jmp 0xc96a
cmpl $0x24, 0x48(%r14)
jne 0xca24
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
movq 0x38(%r14), %r14
movl 0x28(%r14), %eax
cmpl $0x4, %eax
je 0xc979
cmpl $0x6, %eax
je 0xc93c
cmpl $0x5, %eax
jne 0xca35
movq 0x40(%r14), %rax
testq %rax, %rax
je 0xca3e
addq $0x1d8, %rbx            # imm = 0x1D8
cmpq $0x0, (%rax)
je 0xc9e3
leaq -0x30(%rbp), %rsi
movb $0x27, (%rsi)
jmp 0xc9ea
leaq -0x30(%rbp), %rsi
movb $0x2a, (%rsi)
jmp 0xc95b
movq 0x40(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %rsi
movb $0x10, (%rsi)
addq $0x1d8, %rbx            # imm = 0x1D8
movq %rbx, %rdi
callq 0xdd50
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x38(%r14), %rax
movq 0x40(%r14), %rsi
movq 0x30(%rax), %rdi
callq 0x9812
testl %eax, %eax
js 0xca47
movl %eax, %r15d
movq 0x38(%r14), %rsi
movq %rbx, %rdi
callq 0xcd65
leaq -0x30(%rbp), %r14
movb $0x12, (%r14)
addq $0x1d8, %rbx            # imm = 0x1D8
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdd50
movl %r15d, (%r14)
xorl %r15d, %r15d
leaq -0x29(%rbp), %r14
movb -0x30(%rbp,%r15), %al
incq %r15
movb %al, -0x29(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdd50
cmpq $0x4, %r15
jne 0xc9c5
jmp 0xc96a
leaq -0x30(%rbp), %rsi
movb $0x25, (%rsi)
movq %rbx, %rdi
callq 0xdd50
movq 0x40(%r14), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x30(%rbp)
xorl %r15d, %r15d
leaq -0x29(%rbp), %r14
movb -0x30(%rbp,%r15), %al
incq %r15
movb %al, -0x29(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdd50
cmpq $0x4, %r15
jne 0xca03
jmp 0xc96a
leaq 0x4af8(%rip), %rsi      # 0x11523
movq %r14, %rdi
xorl %eax, %eax
callq 0x9767
leaq 0x4c47(%rip), %rsi      # 0x11683
jmp 0xca2b
leaq 0x4bd6(%rip), %rsi      # 0x1161b
jmp 0xca2b
movq 0x38(%r14), %rax
movq 0x40(%r14), %rdx
movq 0x30(%rax), %rax
movq 0x30(%rax), %rcx
leaq 0x4be8(%rip), %rsi      # 0x11646
movq %r14, %rdi
xorl %eax, %eax
callq 0x9767