// File: /workspace/github_c_makefile_star2_O0/Encryptr[P]O-plus-plus/opp/parser/parser.c
// Function: opp_parse_func
static struct Opp_Node* opp_parse_func(struct Opp_Parser* parser, struct Opp_Type_Decl type)
{
	struct Opp_Node* func_node = opp_new_node(parser, STMT_FUNC);
	
	func_node->fn_stmt.type = type; 

	opp_next(parser->lex);

	func_node->fn_stmt.type.depth = 0;
	while (parser->lex->t.id != TIDENT) {
		func_node->fn_stmt.type.depth++;
		opp_next(parser->lex);
	}
	
	struct Opp_Node* name = opp_parse_unary(parser);
	func_node->fn_stmt.name = name;
	opp_next(parser->lex);

	if (parser->lex->t.id != TOPENP)
		opp_error(parser->lex, "Expected '(' after function identifier '%s'",
			name->unary_expr.val.strval);

	func_node->fn_stmt.args_end = false;
	func_node->fn_stmt.args = (struct Opp_Node*)
		malloc(sizeof(struct Opp_Node)*DEFAULT_LIST_SIZE);

	if (func_node->fn_stmt.args == NULL)
		INTERNAL_ERROR("Malloc fail");

	unsigned int i = 0;

	do {
		opp_next(parser->lex);
		if (parser->lex->t.id == TCLOSEP 
			|| parser->lex->t.id == FEND)
			break;

		if (i == DEFAULT_LIST_SIZE)
			opp_error(parser->lex, "Max function parameters met");
		
		if (parser->lex->t.id == TVA_ARGS) {
			assert(false);
			func_node->fn_stmt.args_end = true;
			opp_next(parser->lex);
			break;
		}

		if (parser->lex->t.id == TUNSIGNED) {
			func_node->fn_stmt.args[i].var_stmt.type.unsign = 1;
			opp_next(parser->lex);
		}

		func_node->fn_stmt.args[i].type = STMT_VAR;
		func_node->fn_stmt.args[i].debug = func_node->debug;
		struct Opp_Type_Entry* type = get_type(&parser->tree, parser->lex->t.buffer.buf);

		if (type == NULL)
			opp_error(parser->lex, "Use of undefined type '%s' in function argument #%d",
				parser->lex->t.buffer.buf, i+1);

		func_node->fn_stmt.args[i].var_stmt.type.decl = type;

		func_node->fn_stmt.args[i].var_stmt.type.depth = 0;
		opp_next(parser->lex);
		while (parser->lex->t.id != TIDENT) {
			func_node->fn_stmt.args[i].var_stmt.type.depth++;
			opp_next(parser->lex);
		}
	
		func_node->fn_stmt.args[i].var_stmt.var = opp_parse_allign(parser);

		i++;

	} while (parser->lex->t.id == TCOMMA);

	func_node->fn_stmt.len = i;

	if (parser->lex->t.id != TCLOSEP)
		opp_error(parser->lex, "Expected ')' after parameter list in function declaration");

	opp_next(parser->lex);

	if (parser->lex->t.id == TSEMICOLON)
		func_node->fn_stmt.body = NULL;
	else
		func_node->fn_stmt.body = opp_parse_statement(parser);

	return func_node;
}

// Assembly:
subq $0x38, %rsp
movq %rsi, 0x28(%rsp)
movq %rdx, 0x30(%rsp)
movq %rdi, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movl $0x16, %esi
callq 0xf950
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rsp), %rcx
movq %rcx, 0x18(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x18(%rsp), %rax
movw $0x0, 0x18(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x1, 0x30(%rax)
je 0xf564
movq 0x18(%rsp), %rax
movw 0x18(%rax), %cx
addw $0x1, %cx
movw %cx, 0x18(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
jmp 0xf536
movq 0x20(%rsp), %rdi
callq 0xf9c0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x22, 0x30(%rax)
je 0xf5bb
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rdx
leaq 0x54a9(%rip), %rsi      # 0x14a5d
movb $0x0, %al
callq 0x11370
movq 0x18(%rsp), %rax
movb $0x0, 0x34(%rax)
movl $0x240, %edi            # imm = 0x240
callq 0x1160
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x38(%rax)
movq 0x18(%rsp), %rax
cmpq $0x0, 0x38(%rax)
jne 0xf5f9
leaq 0x3a3a(%rip), %rdi      # 0x13027
leaq 0x5495(%rip), %rsi      # 0x14a89
callq 0x114a0
movl $0x0, 0xc(%rsp)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x23, 0x30(%rax)
je 0xf62a
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x40, 0x30(%rax)
jne 0xf62f
jmp 0xf7f7
cmpl $0x8, 0xc(%rsp)
jne 0xf64c
movq 0x20(%rsp), %rax
movq (%rax), %rdi
leaq 0x5453(%rip), %rsi      # 0x14a98
movb $0x0, %al
callq 0x11370
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x1c, 0x30(%rax)
jne 0xf679
leaq 0x46f6(%rip), %rdi      # 0x13d57
leaq 0x544c(%rip), %rsi      # 0x14ab4
movl $0x212, %edx            # imm = 0x212
leaq 0x5454(%rip), %rcx      # 0x14ac8
callq 0x10e0
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x3f, 0x30(%rax)
jne 0xf6ac
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movb $0x1, 0x1c(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movl $0x13, (%rax)
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rsp), %rcx
movq 0x4(%rcx), %rcx
movq %rcx, 0x4(%rax)
movq 0x20(%rsp), %rdi
addq $0x20, %rdi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq 0x38(%rax), %rsi
callq 0xed70
movq %rax, (%rsp)
cmpq $0x0, (%rsp)
jne 0xf735
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq 0x38(%rax), %rdx
movl 0xc(%rsp), %ecx
addl $0x1, %ecx
leaq 0x53e5(%rip), %rsi      # 0x14b13
movb $0x0, %al
callq 0x11370
movq (%rsp), %rcx
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %edx
imulq $0x48, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movw $0x0, 0x18(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x1, 0x30(%rax)
je 0xf7b5
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movw 0x18(%rax), %cx
addw $0x1, %cx
movw %cx, 0x18(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
jmp 0xf778
movq 0x20(%rsp), %rdi
callq 0xfad0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rax
movl 0xc(%rsp), %edx
imulq $0x48, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x20(%rax)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x24, 0x30(%rax)
je 0xf601
movl 0xc(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x30(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x23, 0x30(%rax)
je 0xf827
movq 0x20(%rsp), %rax
movq (%rax), %rdi
leaq 0x5327(%rip), %rsi      # 0x14b47
movb $0x0, %al
callq 0x11370
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x11bd0
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpl $0x2a, 0x30(%rax)
jne 0xf851
movq 0x18(%rsp), %rax
movq $0x0, 0x28(%rax)
jmp 0xf867
movq 0x20(%rsp), %rdi
callq 0xfbb0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x28(%rax)
movq 0x18(%rsp), %rax
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)