// File: joncampbell123[P]haxcc/haxpp.cpp
// Function: parse_expr_typecast(expression&, __gnu_cxx::__normal_iterator<token*, std::vector<token, std::allocator<token>>>&, __gnu_cxx::__normal_iterator<token*, std::vector<token, std::allocator<token>>> const&, bool)
expression::node::node_t parse_expr_typecast(expression &expr,token_string::iterator &ti,const token_string::iterator &tie,const bool exprfollow=true) {
    token::token_t repl;
    auto tmpti = ti;

    if (tmpti != tie && (*tmpti).tval == token::OPEN_PARENS) {
        tmpti++;
        if (tmpti != tie && is_type_token(/*&*/repl,*tmpti)) {
            ti = tmpti;

            const expression::node::node_t opnode = expr.newnode(exprfollow ? token::TYPECAST : token::TYPESPEC);

            /* NTS: Treat LOGICAL_AND as if two ADDRESSOF so && works properly here */
            while (ti != tie && (is_type_token(/*&*/repl,*ti) || (*ti).tval == token::LOGICAL_AND)) {
                if ((*ti).tval == token::LOGICAL_AND) {
                    expr.getnode(opnode).children.push_back(expr.newnode(token::ADDRESSOF));
                    expr.getnode(opnode).children.push_back(expr.newnode(token::ADDRESSOF));
                    ti++;
                }
                else {
                    expr.getnode(opnode).children.push_back(expr.newnode(*(ti++),repl));
                }
            }

            if (ti == tie)
                throw invalid_argument("missing closing parens");
            if ((*ti).tval != token::CLOSE_PARENS)
                throw invalid_argument("missing closing parens");
            ti++;

            if (exprfollow)
                expr.getnode(opnode).children.push_back(parse_expr(expr,ti,tie));

            return opnode;
        }
    }

    return expression::node::none;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movb %cl, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x16580
testb $0x1, %al
jne 0x118cf
jmp 0x11d61
leaq -0x30(%rbp), %rdi
callq 0x16600
cmpl $0x20, (%rax)
jne 0x11d61
leaq -0x30(%rbp), %rdi
xorl %esi, %esi
callq 0x165c0
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x16580
testb $0x1, %al
jne 0x11906
jmp 0x11d5f
leaq -0x30(%rbp), %rdi
callq 0x16600
movq %rax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x11810
testb $0x1, %al
jne 0x11924
jmp 0x11d5f
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x200(%rbp)
movzbl -0x21(%rbp), %eax
andl $0x1, %eax
movl $0x8, %esi
subl %eax, %esi
leaq -0xb0(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x4170
movq -0x200(%rbp), %rdi
movq -0x1f8(%rbp), %rsi
callq 0x109f0
movq %rax, -0x1f0(%rbp)
jmp 0x11977
leaq -0xb0(%rbp), %rdi
callq 0x15bf0
movq -0x1f0(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x16580
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x201(%rbp)
jne 0x119ac
jmp 0x119f1
movq -0x18(%rbp), %rdi
callq 0x16600
movq %rax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x11810
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x202(%rbp)
jne 0x119e5
movq -0x18(%rbp), %rdi
callq 0x16600
cmpl $0x43, (%rax)
sete %al
movb %al, -0x202(%rbp)
movb -0x202(%rbp), %al
movb %al, -0x201(%rbp)
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0x11a00
jmp 0x11c10
movq -0x18(%rbp), %rdi
callq 0x16600
cmpl $0x43, (%rax)
jne 0x11b9e
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x16810
addq $0x70, %rax
movq %rax, -0x228(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq -0x140(%rbp), %rdi
movq %rdi, -0x218(%rbp)
movl $0x16, %esi
callq 0x4170
movq -0x220(%rbp), %rdi
movq -0x218(%rbp), %rsi
callq 0x109f0
movq %rax, -0x210(%rbp)
jmp 0x11a69
movq -0x228(%rbp), %rdi
movq -0x210(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0xc8(%rbp), %rsi
callq 0x169b0
jmp 0x11a8c
leaq -0x140(%rbp), %rdi
callq 0x15bf0
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x16810
addq $0x70, %rax
movq %rax, -0x248(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x240(%rbp)
leaq -0x1c0(%rbp), %rdi
movq %rdi, -0x238(%rbp)
movl $0x16, %esi
callq 0x4170
movq -0x240(%rbp), %rdi
movq -0x238(%rbp), %rsi
callq 0x109f0
movq %rax, -0x230(%rbp)
jmp 0x11aef
movq -0x248(%rbp), %rdi
movq -0x230(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x148(%rbp), %rsi
callq 0x169b0
jmp 0x11b12
leaq -0x1c0(%rbp), %rdi
callq 0x15bf0
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x165c0
movq %rax, -0x1c8(%rbp)
jmp 0x11c0b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x15bf0
jmp 0x11d76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x15bf0
jmp 0x11d76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x15bf0
jmp 0x11d76
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x16810
addq $0x70, %rax
movq %rax, -0x250(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x258(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x165c0
movq %rax, -0x1d8(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x16600
movq -0x258(%rbp), %rdi
movq %rax, %rsi
movl -0x28(%rbp), %edx
callq 0x10a50
movq -0x250(%rbp), %rdi
movq %rax, -0x1d0(%rbp)
leaq -0x1d0(%rbp), %rsi
callq 0x169b0
jmp 0x1198e
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x16970
testb $0x1, %al
jne 0x11c23
jmp 0x11c85
movl $0x10, %edi
callq 0x3130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x260(%rbp)
leaq 0x138c7(%rip), %rsi     # 0x25508
callq 0x3530
jmp 0x11c48
movq -0x260(%rbp), %rdi
movq 0x21382(%rip), %rsi     # 0x32fd8
movq 0x21363(%rip), %rdx     # 0x32fc0
callq 0x34b0
movq -0x260(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
callq 0x31f0
jmp 0x11d76
movq -0x18(%rbp), %rdi
callq 0x16600
cmpl $0x21, (%rax)
je 0x11cf5
movl $0x10, %edi
callq 0x3130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x268(%rbp)
leaq 0x13857(%rip), %rsi     # 0x25508
callq 0x3530
jmp 0x11cb8
movq -0x268(%rbp), %rdi
movq 0x21312(%rip), %rsi     # 0x32fd8
movq 0x212f3(%rip), %rdx     # 0x32fc0
callq 0x34b0
movq -0x268(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
callq 0x31f0
jmp 0x11d76
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x165c0
movq %rax, -0x1e0(%rbp)
testb $0x1, -0x21(%rbp)
je 0x11d55
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x16810
addq $0x70, %rax
movq %rax, -0x270(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0x10cd0
movq -0x270(%rbp), %rdi
movq %rax, -0x1e8(%rbp)
leaq -0x1e8(%rbp), %rsi
callq 0x169b0
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x11d69
jmp 0x11d61
movq $-0x1, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
movq -0xb8(%rbp), %rdi
callq 0x34e0
nopw %cs:(%rax,%rax)