// File: /workspace/github_c_makefile_star2_O0/Encryptr[P]O-plus-plus/opp/analysis/analysis.c
// Function: opp_analize_func
static void opp_analize_func(struct Opp_Analize* ctx, struct Opp_Node* fn)
{
	struct Opp_Stmt_Func* func = &fn->fn_stmt;

	struct Opp_Bucket* bucket = env_add_item(ctx->curr_ns, func->name->unary_expr.val.strval);

	if (bucket == NULL) {
		bucket = env_get_item(ctx->curr_ns, func->name->unary_expr.val.strval);

		if (bucket == NULL || bucket->predef == false)
			opp_semantics_error(ctx, fn, "Redeclaration of function '%s'", func->name->unary_expr.val.strval);
	}

	bucket->type = TYPE_FUNC;
	bucket->sym_type = func->type;
	bucket->args = &fn->fn_stmt;
	bucket->predef = false;
	// idx
	func->bidx = bucket;

	if (func->type.decl->t_type == TYPE_STRUCT)
		opp_semantics_error(ctx, fn, "Cannot return struct from function '%s'", bucket->key);

	ctx->debug.res_name = func->name->unary_expr.val.strval;

	if (func->body == NULL) {
		bucket->predef = true;
		return;
	}

	// Resets
	ctx->debug.scope = func->name->unary_expr.val.strval;
	ctx->debug.ret = false;
	ctx->debug.ret_type = func->type;

	struct Opp_Namespace* temp = ctx->curr_ns;
	ctx->curr_ns = init_namespace(temp, (void*)alloc);
	// func->scope = ctx->curr_ns;

	opp_analize_args(ctx, fn, bucket);

	if (func->body->type != STMT_BLOCK)
		opp_semantics_error(ctx, fn, "Expected block after function '%s'", 
			func->name->unary_expr.val.strval);

	for (unsigned int i = 0; i < func->body->block_stmt.len; i++)
		opp_analize_stmt(ctx, func->body->block_stmt.stmts[i]);

	if (ctx->debug.ret == 0 && bucket->sym_type.decl->t_type != TYPE_VOID)
		opp_warning(ctx, fn, "No return statement found, expected '%s', depth '%d'",
			bucket->sym_type.decl->id, bucket->sym_type.depth);

	ctx->curr_ns = temp;
	ctx->debug.scope = NULL;
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq 0x28(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x20(%rsp)
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x12a70
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
jne 0x2245
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x12c10
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
je 0x221e
movq 0x18(%rsp), %rax
movb 0x20(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x2243
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x113e9(%rip), %rdx     # 0x13625
movb $0x0, %al
callq 0x2b10
jmp 0x2245
movq 0x18(%rsp), %rax
movl $0x2, 0x8(%rax)
movq 0x18(%rsp), %rax
movq 0x20(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq 0x28(%rsp), %rcx
addq $0x10, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x28(%rax)
movq 0x18(%rsp), %rax
movb $0x0, 0x20(%rax)
movq 0x18(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x8, 0x8(%rax)
jne 0x22c1
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x18(%rsp), %rax
movq (%rax), %rcx
leaq 0x1138a(%rip), %rdx     # 0x13644
movb $0x0, %al
callq 0x2b10
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x40(%rax)
movq 0x20(%rsp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x22f1
movq 0x18(%rsp), %rax
movb $0x1, 0x20(%rax)
jmp 0x244b
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x30(%rsp), %rax
movb $0x0, 0x28(%rax)
movq 0x30(%rsp), %rax
movq 0x20(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x30(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x38(%rax)
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
leaq 0xbe4d(%rip), %rsi      # 0xe190
callq 0x12990
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x2c70
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
cmpl $0x12, (%rax)
je 0x239b
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x112d8(%rip), %rdx     # 0x1366c
movb $0x0, %al
callq 0x2b10
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x20(%rsp), %rcx
movq 0x18(%rcx), %rcx
cmpl 0x18(%rcx), %eax
jae 0x23e1
movq 0x30(%rsp), %rdi
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x2d70
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x23a3
movq 0x30(%rsp), %rax
movb 0x28(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x2430
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
cmpl $0x0, 0x8(%rax)
je 0x2430
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rcx
movq 0x18(%rsp), %rax
movzwl 0x18(%rax), %r8d
leaq 0x11266(%rip), %rdx     # 0x1368f
movb $0x0, %al
callq 0x2e80
movq 0x10(%rsp), %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x30(%rsp), %rax
movq $0x0, 0x20(%rax)
addq $0x38, %rsp
retq