// File: /workspace/github_c_makefile_star2_O0/Encryptr[P]O-plus-plus/opp/analysis/analysis.c
// Function: opp_analize_call
static Opp_Obj opp_analize_call(struct Opp_Analize* ctx, struct Opp_Node* node)
{
	Opp_Obj ret_type;

	ret_type = opp_analize_expr(ctx, node->call_expr.callee);

	// Immidiate func call
	if (node->call_expr.callee->type == EUNARY) {
		if (node->call_expr.callee->unary_expr.type != TIDENT)
			opp_semantics_error(ctx, node, "Expected identifier before '()' for a call expr");

		struct Opp_Bucket* bucket = env_get_item(ctx->curr_ns, 
			node->call_expr.callee->unary_expr.val.strval);

		if (bucket == NULL)
			opp_semantics_error(ctx, node, "Attempting to call undefined symbol'%s'",
				node->call_expr.callee->unary_expr.val.strval);

		node->call_expr.callee->unary_expr.bidx = bucket;

		char* fn_name = bucket->key;

		if (bucket->type == TYPE_FUNC || bucket->type == TYPE_EXTERN) {
			if (bucket->args->len != node->call_expr.args->length)
				opp_semantics_error(ctx, node, 
					"Invalid amount of args provided in function call to '%s' (expected %d)", 
					fn_name, bucket->args->len);
		}
		else if (bucket->sym_type.depth == 0)
			opp_semantics_error(ctx, node, "Calling a invalid callee '%s'", fn_name);

		for (unsigned int i = 0; i < node->call_expr.args->length; i++) 
		{
			ret_type = opp_analize_expr(ctx, node->call_expr.args->list[i]);

			if (bucket->type == TYPE_FUNC || bucket->type == TYPE_EXTERN)
				if (ret_type.depth != bucket->args->args[i].var_stmt.type.depth) 
					opp_warning(ctx, node, 
						"Invalid pointer argument provided to function call '%s'", fn_name);
		}
		return bucket->sym_type;
	}
	if (node->call_expr.args->length > 0)
		printf("ADD FN POINTER ARGS\n");

	return ret_type;
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x3770
movq %rax, 0x28(%rsp)
movq %rdx, 0x30(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
cmpl $0x5, (%rax)
jne 0x3549
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
cmpl $0x1, 0x10(%rax)
je 0x3378
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
leaq 0x105ab(%rip), %rdx     # 0x1391c
movb $0x0, %al
callq 0x2b10
movq 0x50(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x12c10
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
jne 0x33c5
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x1058e(%rip), %rdx     # 0x1394c
movb $0x0, %al
callq 0x2b10
movq 0x20(%rsp), %rcx
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq %rcx, 0x20(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x20(%rsp), %rax
cmpl $0x2, 0x8(%rax)
je 0x33fa
movq 0x20(%rsp), %rax
cmpl $0x4, 0x8(%rax)
jne 0x343f
movq 0x20(%rsp), %rax
movq 0x28(%rax), %rax
movl 0x20(%rax), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rcx), %rcx
cmpl (%rcx), %eax
je 0x343d
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x18(%rsp), %rcx
movq 0x20(%rsp), %rax
movq 0x28(%rax), %rax
movl 0x20(%rax), %r8d
leaq 0x1053e(%rip), %rdx     # 0x13974
movb $0x0, %al
callq 0x2b10
jmp 0x346c
movq 0x20(%rsp), %rax
movzwl 0x18(%rax), %eax
cmpl $0x0, %eax
jne 0x346a
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x18(%rsp), %rcx
leaq 0x10558(%rip), %rdx     # 0x139bb
movb $0x0, %al
callq 0x2b10
jmp 0x346c
movl $0x0, 0x14(%rsp)
movl 0x14(%rsp), %eax
movq 0x48(%rsp), %rcx
movq 0x18(%rcx), %rcx
cmpl (%rcx), %eax
jae 0x3530
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x3770
movq %rax, (%rsp)
movq %rdx, 0x8(%rsp)
movq (%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x20(%rsp), %rax
cmpl $0x2, 0x8(%rax)
je 0x34da
movq 0x20(%rsp), %rax
cmpl $0x4, 0x8(%rax)
jne 0x351e
movzwl 0x40(%rsp), %eax
movq 0x20(%rsp), %rcx
movq 0x28(%rcx), %rcx
movq 0x28(%rcx), %rcx
movl 0x14(%rsp), %edx
imulq $0x48, %rdx, %rdx
addq %rdx, %rcx
movzwl 0x18(%rcx), %ecx
cmpl %ecx, %eax
je 0x351c
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x18(%rsp), %rcx
leaq 0x104c4(%rip), %rdx     # 0x139d9
movb $0x0, %al
callq 0x2e80
jmp 0x351e
jmp 0x3520
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x3474
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rcx
movq %rcx, 0x58(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x60(%rsp)
jmp 0x3579
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rax
cmpl $0x0, (%rax)
jbe 0x3565
leaq 0x104b3(%rip), %rdi     # 0x13a11
movb $0x0, %al
callq 0x10c0
movq 0x38(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x58(%rsp), %rax
movq 0x60(%rsp), %rdx
addq $0x68, %rsp
retq
nopl (%rax,%rax)