// File: RuiDGPires[P]CrimLang/src/semantic_analiser.cpp
// Function: sc_Tracker::func_declaration(crl::Node*)
void _sc_Tracker::func_declaration(crl::Node *node){
	this->func_returns = false;
	Context::Item item;
	item.type = Context::Item::Type::FUNC;
	item.subtype = ((crl::Leaf *)node->get_child(0))->token.str;
	item.name = ((crl::Leaf *)node->get_child(1))->token.str;
	ASSERT(item.name != "_start", "_start is a reserved name");

	// Parse once to add to the args to the declaration
	int i;
	for (i = 2; node->get_child(i)->type == crl::Node::Type::ARG; i++){
		crl::Node *arg = node->get_child(i);
		std::string var_type = ((crl::Leaf *) arg->get_child(0))->token.str;

		item.args.push_back(std::pair<std::string, bool>(var_type, arg->annotation == "mut"));
	}

	node->argc = i - 2; // Store the number of arguments

	this->add(item);

	this->enter();
	// Add args to the function context
	i = 2;
	for (; node->get_child(i)->type == crl::Node::Type::ARG; i++){
		crl::Node *arg = node->get_child(i);
		Context::Item arg_item;
		arg_item.type = Context::Item::Type::VAR;
		arg_item.subtype = ((crl::Leaf *) arg->get_child(0))->token.str;
		arg_item.name = ((crl::Leaf *) arg->get_child(1))->token.str;
		arg_item._mutable = arg->annotation == "mut";
		this->add(arg_item);
	}
	this->block(node->get_child(i), item.subtype);
	
	ASSERT(func_returns, "Functions must return on all possible paths");
	this->leave();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x350, %rsp            # imm = 0x350
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movb $0x0, 0x10(%rax)
leaq -0x80(%rbp), %rdi
callq 0x6c30
movl $0x1, -0x80(%rbp)
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %esi, %esi
callq *%rax
movq %rax, -0x2b8(%rbp)
jmp 0x205ea
movq -0x2b8(%rbp), %rsi
addq $0x58, %rsi
leaq -0x58(%rbp), %rdi
callq 0x4050
jmp 0x20600
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
movl $0x1, %esi
callq *%rax
movq %rax, -0x2c8(%rbp)
jmp 0x2061b
movq -0x2c8(%rbp), %rsi
addq $0x58, %rsi
leaq -0x78(%rbp), %rdi
callq 0x4050
jmp 0x20631
leaq -0x78(%rbp), %rdi
leaq 0xb296(%rip), %rsi      # 0x2b8d2
callq 0x5390
movb %al, -0x2c9(%rbp)
jmp 0x20649
movb -0x2c9(%rbp), %al
testb $0x1, %al
jne 0x20753
jmp 0x20659
movb $0x1, -0xb2(%rbp)
movl $0x50, %edi
callq 0x4190
movq %rax, -0x2e0(%rbp)
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
callq 0x4590
movq -0x2d8(%rbp), %rdx
leaq 0xb247(%rip), %rsi      # 0x2b8d9
leaq -0xb0(%rbp), %rdi
callq 0x52e0
jmp 0x206a0
movq -0x2e0(%rbp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
leaq -0xb0(%rbp), %rcx
movl %edx, %esi
callq 0x9140
jmp 0x206bc
movq -0x2e0(%rbp), %rdi
movb $0x0, -0xb2(%rbp)
leaq 0x196af(%rip), %rsi     # 0x39d80
leaq -0x173c8(%rip), %rdx    # 0x9310
callq 0x4550
jmp 0x20c78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x20c63
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x2072b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x41e0
leaq -0xb1(%rbp), %rdi
callq 0x4360
testb $0x1, -0xb2(%rbp)
jne 0x20742
jmp 0x2074e
movq -0x2e0(%rbp), %rdi
callq 0x4230
jmp 0x20c63
movl $0x2, -0xb8(%rbp)
movq -0x10(%rbp), %rdi
movl -0xb8(%rbp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, -0x2e8(%rbp)
jmp 0x20779
movq -0x2e8(%rbp), %rax
cmpl $0x12, 0x8(%rax)
jne 0x208c0
movq -0x10(%rbp), %rdi
movl -0xb8(%rbp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, -0x2f0(%rbp)
jmp 0x207a6
movq -0x2f0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %esi, %esi
callq *%rax
movq %rax, -0x2f8(%rbp)
jmp 0x207cf
movq -0x2f8(%rbp), %rsi
addq $0x58, %rsi
leaq -0xe0(%rbp), %rdi
callq 0x4150
jmp 0x207e8
leaq -0x28(%rbp), %rax
movq %rax, -0x308(%rbp)
movq -0xc0(%rbp), %rdi
addq $0x30, %rdi
leaq 0xac4b(%rip), %rsi      # 0x2b450
callq 0x66e0
movb %al, -0x2f9(%rbp)
jmp 0x20812
movb -0x2f9(%rbp), %al
andb $0x1, %al
movb %al, -0x109(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
leaq -0x109(%rbp), %rdx
callq 0x25cc0
jmp 0x2083c
movq -0x308(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x25c90
jmp 0x20851
leaq -0x108(%rbp), %rdi
callq 0x7cd0
leaq -0xe0(%rbp), %rdi
callq 0x41e0
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0x2075d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x208af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x7cd0
leaq -0xe0(%rbp), %rdi
callq 0x41e0
jmp 0x20c63
movl -0xb8(%rbp), %ecx
addl $-0x2, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x50(%rax)
leaq -0x180(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x6d30
jmp 0x208e2
movq -0x2c0(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x20120
jmp 0x208f7
leaq -0x180(%rbp), %rdi
callq 0x6df0
movq -0x2c0(%rbp), %rdi
callq 0x20060
jmp 0x20911
movl $0x2, -0xb8(%rbp)
movq -0x10(%rbp), %rdi
movl -0xb8(%rbp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, -0x310(%rbp)
jmp 0x20937
movq -0x310(%rbp), %rax
cmpl $0x12, 0x8(%rax)
jne 0x20ade
movq -0x10(%rbp), %rdi
movl -0xb8(%rbp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, -0x318(%rbp)
jmp 0x20964
movq -0x318(%rbp), %rax
movq %rax, -0x188(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x6c30
jmp 0x20980
movl $0x3, -0x1f8(%rbp)
movq -0x188(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %esi, %esi
callq *%rax
movq %rax, -0x320(%rbp)
jmp 0x209a5
movq -0x320(%rbp), %rsi
addq $0x58, %rsi
leaq -0x1d0(%rbp), %rdi
callq 0x4050
jmp 0x209be
movq -0x188(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
movl $0x1, %esi
callq *%rax
movq %rax, -0x328(%rbp)
jmp 0x209dc
movq -0x328(%rbp), %rsi
addq $0x58, %rsi
leaq -0x1f0(%rbp), %rdi
callq 0x4050
jmp 0x209f5
movq -0x188(%rbp), %rdi
addq $0x30, %rdi
leaq 0xaa49(%rip), %rsi      # 0x2b450
callq 0x66e0
movb %al, -0x329(%rbp)
jmp 0x20a14
movb -0x329(%rbp), %al
andb $0x1, %al
movb %al, -0x1a8(%rbp)
leaq -0x268(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x6d30
jmp 0x20a37
movq -0x2c0(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x20120
jmp 0x20a4c
leaq -0x268(%rbp), %rdi
callq 0x6df0
leaq -0x1f8(%rbp), %rdi
callq 0x6df0
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0x2091b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x6df0
jmp 0x20c63
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x20acd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x6df0
leaq -0x1f8(%rbp), %rdi
callq 0x6df0
jmp 0x20c63
movq -0x10(%rbp), %rdi
movl -0xb8(%rbp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, -0x338(%rbp)
jmp 0x20afa
leaq -0x58(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x4150
jmp 0x20b0c
movq -0x338(%rbp), %rsi
movq -0x2c0(%rbp), %rdi
leaq -0x288(%rbp), %rdx
callq 0x20c80
jmp 0x20b28
leaq -0x288(%rbp), %rdi
callq 0x41e0
movq -0x2c0(%rbp), %rax
testb $0x1, 0x10(%rax)
jne 0x20c45
movb $0x1, -0x2aa(%rbp)
movl $0x50, %edi
callq 0x4190
movq %rax, -0x348(%rbp)
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0x4590
movq -0x340(%rbp), %rdx
leaq 0xad75(%rip), %rsi      # 0x2b8f3
leaq -0x2a8(%rbp), %rdi
callq 0x52e0
jmp 0x20b8c
movq -0x348(%rbp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
leaq -0x2a8(%rbp), %rcx
movl %edx, %esi
callq 0x9140
jmp 0x20ba8
movq -0x348(%rbp), %rdi
movb $0x0, -0x2aa(%rbp)
leaq 0x191c3(%rip), %rsi     # 0x39d80
leaq -0x178b4(%rip), %rdx    # 0x9310
callq 0x4550
jmp 0x20c78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x41e0
jmp 0x20c63
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x20c20
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x41e0
leaq -0x2a9(%rbp), %rdi
callq 0x4360
testb $0x1, -0x2aa(%rbp)
jne 0x20c37
jmp 0x20c43
movq -0x348(%rbp), %rdi
callq 0x4230
jmp 0x20c63
movq -0x2c0(%rbp), %rdi
callq 0x200d0
leaq -0x80(%rbp), %rdi
callq 0x6df0
addq $0x350, %rsp            # imm = 0x350
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x6df0
movq -0x88(%rbp), %rdi
callq 0x4580
nopl (%rax,%rax)