// File: acliusBackHome[P]kamaya/dist/ParseExpressionConstCalculate.cpp
// Function: ParseExpression::calculate_const()
void ParseExpression::calculate_const() {
    if (const_value) {
        return;
    }
    // 只有const_value等于0时才计算常量
    switch (expr_type) {
        //双目运算符
        case E_ADD:
        case E_SUB:
        case E_MUL:
        case E_DIV:
        case E_POW:
        case E_MOD:
            // 比较运算符

        case E_G:
        case E_GE:
        case E_EQUAL:
        case E_NE:
        case E_L:
        case E_LE: {
            if (!get_expression(child[0]).is_const() || !get_expression(child[1]).is_const()) {
                // 不是常量退出
                break;
            }
            const ParseConstant &const1 = get_expression(child[0]).get_const(),
                    &const2 = get_expression(child[1]).get_const();
            if (expr_type == E_POW) {
                // 求幂运算比较特殊 直接返回long double
                const_value = (size_t)
                        new ParseConstant(powl(const1.get_float(), const2.get_float()));
                return;
            }
            ConstValueType cal_type =
                    ParseConstant::wider_const_type(const1.get_type(), const2.get_type());
            if (cal_type == C_UNDEFINED) {
                break;
            }
            switch (expr_type) {
                case E_ADD: {
                    calculate_const_add(cal_type, const1, const2);
                    return;
                }
                case E_SUB: {
                    calculate_const_sub(cal_type, const1, const2);
                    return;
                }
                case E_MUL: {
                    calculate_const_mul(cal_type, const1, const2);
                    return;
                }
                case E_DIV: {
                    calculate_const_div(cal_type, const1, const2);
                    return;
                }
                case E_MOD: {
                    calculate_const_mod(cal_type, const1, const2);
                    return;
                }
                    // 比较运算符
                case E_G: {
                    calculate_const_g(cal_type, const1, const2);
                    return;
                }
                case E_GE: {
                    calculate_const_ge(cal_type, const1, const2);
                    return;
                }
                case E_EQUAL: {
                    calculate_const_eq(cal_type, const1, const2);
                    return;
                }
                case E_NE: {
                    calculate_const_ne(cal_type, const1, const2);
                    return;
                }
                case E_L: {
                    calculate_const_l(cal_type, const1, const2);
                    return;
                }
                case E_LE: {
                    calculate_const_le(cal_type, const1, const2);
                    return;
                }
                default:
                    break;
            }
            break;
        }
            // 单目运算符

        case E_ADR:
        case E_PTR: {
            // 还未实现的调用
            string info = "ParseExpression::calculate_const() not implemented calling address operator";
            throw ParseException(EX_NOT_IMPLEMENTED, info);
        }
        case E_NEG:
        case E_POS:
        case E_BIT_NOT:
        case E_NOT: {
            if (!get_expression(child[0]).is_const()) {
                // 不是常量退出
                break;
            }
            const ParseConstant &constant = get_expression(child[0]).get_const();
            switch (expr_type) {
                case E_NEG: {
                    calculate_const_neg(constant.get_type(), constant);
                    return;
                }
                case E_POS: {
                    const_value = (size_t)
                            new ParseConstant(constant);
                    return;
                }
                case E_BIT_NOT: {
                    calculate_const_bit_not(constant.get_type(), constant);
                    return;
                }
                case E_NOT: {
                    calculate_const_not(constant.get_type(), constant);
                    return;
                }
                default:
                    break;
            }
            return;
        }
            // 逻辑运算符
        case E_LOGIC_OR:
        case E_LOGIC_AND: {
            if (!get_expression(child[0]).is_const() || !get_expression(child[1]).is_const()) {
                // 不是常量退出
                break;
            }
            const ParseConstant &const1 = get_expression(child[0]).get_const(),
                    &const2 = get_expression(child[1]).get_const();
            switch (expr_type) {
                case E_LOGIC_OR:
                    const_value = (size_t)
                            new ParseConstant(const1.get_bool() || const2.get_bool());
                    return;
                case E_LOGIC_AND:
                    const_value = (size_t)
                            new ParseConstant(const1.get_bool() && const2.get_bool());
                    return;
                default:
                    break;
            }
            break;
        }
        case E_CONST:
            const_value = child[0];
            break;
        case E_ASSIGN:// 赋值语句肯定不是常量
        case E_UNDEFINED:
        case E_VAR:
        case E_GET_ITEM: // 能进行后缀表达式运算的都不会是常量
            // 变量或者常量, 未定义不会计算常量
            break;
    }
    const_value = (size_t) -1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, 0x18(%rax)
je 0x74b83
jmp 0x7520d
movq -0x70(%rbp), %rax
movl 0x28(%rax), %eax
movq %rax, -0x78(%rbp)
subq $0x19, %rax
ja 0x75201
movq -0x78(%rbp), %rax
leaq 0x1c9d5(%rip), %rcx     # 0x91578
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x61790
testb $0x1, %al
jne 0x74bc6
jmp 0x74bdf
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x61790
testb $0x1, %al
jne 0x74be4
jmp 0x75201
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x63e50
movq %rax, %rcx
movq -0x70(%rbp), %rax
movq %rcx, -0x10(%rbp)
movq 0x8(%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x63e50
movq %rax, %rcx
movq -0x70(%rbp), %rax
movq %rcx, -0x18(%rbp)
cmpl $0xa, 0x28(%rax)
jne 0x74cb9
movl $0x10, %edi
callq 0x4310
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
callq 0x694c0
fstpt -0x84(%rbp)
jmp 0x74c4b
movq -0x18(%rbp), %rdi
callq 0x694c0
fstpt -0x9c(%rbp)
jmp 0x74c5c
fldt -0x84(%rbp)
fldt -0x9c(%rbp)
movq %rsp, %rax
fstpt 0x10(%rax)
fstpt (%rax)
callq 0x45a0
movq -0x90(%rbp), %rdi
movq %rsp, %rax
fstpt (%rax)
callq 0x69250
jmp 0x74c88
movq -0x70(%rbp), %rax
movq -0x90(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x7520d
movq -0x90(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x42d0
jmp 0x75216
movq -0x10(%rbp), %rdi
callq 0x6a020
movl %eax, -0xa0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6a020
movl -0xa0(%rbp), %edi
movl %eax, %esi
callq 0x6a030
movl %eax, -0x28(%rbp)
cmpl $0x5, -0x28(%rbp)
jne 0x74cec
jmp 0x75201
movq -0x70(%rbp), %rax
movl 0x28(%rax), %eax
addl $-0x5, %eax
movl %eax, %ecx
movq %rcx, -0xa8(%rbp)
subl $0x13, %eax
ja 0x74e32
movq -0xa8(%rbp), %rax
leaq 0x1c8e2(%rip), %rcx     # 0x915f8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x75220
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x753e0
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x755a0
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x75760
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x75c40
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x75f90
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x76160
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x76330
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x76620
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x76910
jmp 0x7520d
movq -0x70(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x76ae0
jmp 0x7520d
jmp 0x74e34
jmp 0x75201
leaq -0x49(%rbp), %rdi
movq %rdi, -0xb0(%rbp)
callq 0x45f0
movq -0xb0(%rbp), %rdx
leaq 0x1c909(%rip), %rsi     # 0x91760
leaq -0x48(%rbp), %rdi
callq 0x4450
jmp 0x74e62
leaq -0x49(%rbp), %rdi
callq 0x4380
movl $0x28, %edi
callq 0x41c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xb8(%rbp)
movl $0x13, %esi
leaq -0x48(%rbp), %rdx
callq 0x73a90
jmp 0x74e92
movq -0xb8(%rbp), %rdi
leaq 0x50eb0(%rip), %rsi     # 0xc5d50
leaq -0x5f017(%rip), %rdx    # 0x15e90
callq 0x45b0
jmp 0x7521f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x49(%rbp), %rdi
callq 0x4380
jmp 0x75216
movq -0xb8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x4280
jmp 0x74ef1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x4688
jmp 0x75216
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x61790
testb $0x1, %al
jne 0x74f1c
jmp 0x75201
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x63e50
movq %rax, %rcx
movq -0x70(%rbp), %rax
movq %rcx, -0x58(%rbp)
movl 0x28(%rax), %eax
addl $-0xb, %eax
movl %eax, %ecx
movq %rcx, -0xc0(%rbp)
subl $0x5, %eax
ja 0x75014
movq -0xc0(%rbp), %rax
leaq 0x1c67f(%rip), %rcx     # 0x915e0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x58(%rbp), %rdi
callq 0x6a020
movq -0x70(%rbp), %rdi
movl %eax, %esi
movq -0x58(%rbp), %rdx
callq 0x76cb0
jmp 0x7520d
movl $0x10, %edi
callq 0x4310
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xc8(%rbp)
movq -0x58(%rbp), %rsi
callq 0x69010
jmp 0x74fa9
movq -0x70(%rbp), %rax
movq -0xc8(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x7520d
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x42d0
jmp 0x75216
movq -0x58(%rbp), %rdi
callq 0x6a020
movq -0x70(%rbp), %rdi
movl %eax, %esi
movq -0x58(%rbp), %rdx
callq 0x76e20
jmp 0x7520d
movq -0x58(%rbp), %rdi
callq 0x6a020
movq -0x70(%rbp), %rdi
movl %eax, %esi
movq -0x58(%rbp), %rdx
callq 0x76f30
jmp 0x7520d
jmp 0x75016
jmp 0x7520d
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x61790
testb $0x1, %al
jne 0x75035
jmp 0x7504e
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x61790
testb $0x1, %al
jne 0x75053
jmp 0x75201
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x63e50
movq %rax, %rcx
movq -0x70(%rbp), %rax
movq %rcx, -0x60(%rbp)
movq 0x8(%rax), %rdi
callq 0x60f30
movq %rax, %rdi
callq 0x63e50
movq %rax, %rcx
movq -0x70(%rbp), %rax
movq %rcx, -0x68(%rbp)
movl 0x28(%rax), %eax
movl %eax, -0xcc(%rbp)
subl $0x11, %eax
je 0x750b2
jmp 0x7509e
movl -0xcc(%rbp), %eax
subl $0x12, %eax
je 0x75153
jmp 0x751ee
movl $0x10, %edi
callq 0x4310
movq %rax, -0xd8(%rbp)
movq -0x60(%rbp), %rdi
callq 0x69590
movb %al, -0xcd(%rbp)
jmp 0x750d4
movb -0xcd(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0xd9(%rbp)
jne 0x75108
jmp 0x750e9
movq -0x68(%rbp), %rdi
callq 0x69590
movb %al, -0xda(%rbp)
jmp 0x750fa
movb -0xda(%rbp), %al
movb %al, -0xd9(%rbp)
jmp 0x75108
movq -0xd8(%rbp), %rdi
movb -0xd9(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x69200
jmp 0x75122
movq -0x70(%rbp), %rax
movq -0xd8(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x7520d
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x42d0
jmp 0x75216
movl $0x10, %edi
callq 0x4310
movq %rax, -0xe8(%rbp)
movq -0x60(%rbp), %rdi
callq 0x69590
movb %al, -0xdb(%rbp)
jmp 0x75175
movb -0xdb(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xe9(%rbp)
jne 0x7518a
jmp 0x751a9
movq -0x68(%rbp), %rdi
callq 0x69590
movb %al, -0xea(%rbp)
jmp 0x7519b
movb -0xea(%rbp), %al
movb %al, -0xe9(%rbp)
jmp 0x751a9
movq -0xe8(%rbp), %rdi
movb -0xe9(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x69200
jmp 0x751c3
movq -0x70(%rbp), %rax
movq -0xe8(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x7520d
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x42d0
jmp 0x75216
jmp 0x751f0
jmp 0x75201
movq -0x70(%rbp), %rax
movq (%rax), %rcx
movq %rcx, 0x18(%rax)
jmp 0x75201
jmp 0x75201
movq -0x70(%rbp), %rax
movq $-0x1, 0x18(%rax)
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x45e0
nop