// File: KJTang[P]SimpleCompiler/Parser.cpp
// Function: Parser::parseFuncDeclaration()
ASTNode *Parser::parseFuncDeclaration() {
    #ifdef DEBUG
    std::cout<<curToken.second<<"\tparseFuncDeclaration"<<std::endl;
    #endif
    Token type = curToken.first;
    getNextToken(); // eat function return value type
    std::string name = curToken.second;
    getNextToken(); // eat function name
    std::vector<std::pair<Token, std::string>> args;
    // if function has argument
    if (lookAheadToken(1).first != static_cast<Token>(')')) {
        do {
            getNextToken(); // eat '(' or ','
            Token varType = curToken.first;
            getNextToken(); // eat type name
            std::string varName = curToken.second;
            getNextToken(); // eat arg name
            args.push_back(std::make_pair(varType, varName));
        } while (curToken.first != static_cast<Token>(')'));
    }
    // else function has no argument
    else {
        getNextToken(); // eat '('
    }
    getNextToken(); // eat ')'
    ASTNode *block = this->parseBlock();
    return new FunctionAST(std::make_pair(type, name), args, block);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
movl 0x58(%rdi), %eax
movl %eax, -0xc(%rbp)
callq 0x10070
movq -0xe8(%rbp), %rsi
addq $0x60, %rsi
leaq -0x30(%rbp), %rdi
callq 0x3120
movq -0xe8(%rbp), %rdi
callq 0x10070
jmp 0xf9a7
leaq -0x58(%rbp), %rdi
callq 0x4d20
movq -0xe8(%rbp), %rdi
movl $0x1, %esi
callq 0x10600
movq %rax, -0xf0(%rbp)
jmp 0xf9ca
movq -0xf0(%rbp), %rax
cmpl $0x29, (%rax)
je 0xfac8
jmp 0xf9dc
movq -0xe8(%rbp), %rdi
callq 0x10070
jmp 0xf9ea
movq -0xe8(%rbp), %rdi
movl 0x58(%rdi), %eax
movl %eax, -0x5c(%rbp)
callq 0x10070
jmp 0xf9fe
movq -0xe8(%rbp), %rsi
addq $0x60, %rsi
leaq -0x80(%rbp), %rdi
callq 0x3120
jmp 0xfa14
movq -0xe8(%rbp), %rdi
callq 0x10070
jmp 0xfa22
leaq -0xa8(%rbp), %rdi
leaq -0x5c(%rbp), %rsi
leaq -0x80(%rbp), %rdx
callq 0x106d0
jmp 0xfa38
leaq -0x58(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xa910
jmp 0xfa4a
leaq -0xa8(%rbp), %rdi
callq 0x55a0
leaq -0x80(%rbp), %rdi
callq 0x34f8
movq -0xe8(%rbp), %rax
cmpl $0x29, 0x58(%rax)
jne 0xf9dc
jmp 0xfad8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xfbd6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xfbcd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xfaba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x55a0
leaq -0x80(%rbp), %rdi
callq 0x34f8
jmp 0xfbcd
movq -0xe8(%rbp), %rdi
callq 0x10070
jmp 0xfad6
jmp 0xfad8
movq -0xe8(%rbp), %rdi
callq 0x10070
jmp 0xfae6
movq -0xe8(%rbp), %rdi
callq 0xf880
movq %rax, -0xf8(%rbp)
jmp 0xfafb
movq -0xf8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl $0x58, %edi
callq 0x3290
movq %rax, -0x100(%rbp)
jmp 0xfb1c
movb $0x1, -0xd9(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xc(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x106d0
jmp 0xfb39
movq -0x100(%rbp), %rdi
movq -0xb0(%rbp), %rcx
leaq -0xd8(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0x10710
jmp 0xfb59
movb $0x0, -0xd9(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x55a0
leaq -0x58(%rbp), %rdi
callq 0x3e50
leaq -0x30(%rbp), %rdi
callq 0x34f8
movq -0x100(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xfbb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x55a0
testb $0x1, -0xd9(%rbp)
jne 0xfbbf
jmp 0xfbcb
movq -0x100(%rbp), %rdi
callq 0x3270
jmp 0xfbcd
leaq -0x58(%rbp), %rdi
callq 0x3e50
leaq -0x30(%rbp), %rdi
callq 0x34f8
movq -0x38(%rbp), %rdi
callq 0x3470
nopl (%rax,%rax)