// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
cmpq $0x0, 0x18(%rdi)
jne 0x33cde
movq %rdi, %rbx
movl 0x28(%rdi), %eax
addl $-0x3, %eax
cmpl $0x15, %eax
ja 0x33cd6
leaq 0x13a89(%rip), %rcx     # 0x4753c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2b2f4
testb %al, %al
je 0x33cd6
movq 0x8(%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2b2f4
testb %al, %al
je 0x33cd6
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2cbac
movq %rax, %r15
movq 0x8(%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2cbac
movq %rax, %r14
cmpl $0xa, 0x28(%rbx)
jne 0x33c76
movl $0x10, %edi
callq 0x42e0
movq %rax, %r12
movq %r15, %rdi
callq 0x2f0d2
fstpt -0x2c(%rbp)
fldz
fstp %st(0)
movq %r14, %rdi
callq 0x2f0d2
fstpt 0x10(%rsp)
fldt -0x2c(%rbp)
fstpt (%rsp)
callq 0x4520
fstpt (%rsp)
movq %r12, %rdi
callq 0x2ef50
fldz
fstp %st(0)
movq %r12, 0x18(%rbx)
jmp 0x33cde
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2b2f4
testb %al, %al
je 0x33cd6
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2cbac
movq %rax, %r14
movl 0x28(%rbx), %eax
addl $-0xb, %eax
cmpl $0x5, %eax
ja 0x33cde
leaq 0x139ea(%rip), %rcx     # 0x47594
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r14, %rdi
callq 0x2f50a
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34fc0
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2b2f4
testb %al, %al
je 0x33cd6
movq 0x8(%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2b2f4
testb %al, %al
je 0x33cd6
movq (%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2cbac
movq %rax, %r12
movq 0x8(%rbx), %rdi
callq 0x2b006
movq %rax, %rdi
callq 0x2cbac
movq %rax, %r14
movl 0x28(%rbx), %eax
cmpl $0x12, %eax
je 0x33d47
cmpl $0x11, %eax
jne 0x33cd6
movl $0x10, %edi
callq 0x42e0
movq %rax, %r15
movq %r12, %rdi
callq 0x2f152
movl %eax, %ecx
movb $0x1, %al
testb %cl, %cl
jne 0x33c66
movq %r14, %rdi
callq 0x2f152
movzbl %al, %esi
movq %r15, %rdi
callq 0x2ef28
jmp 0x33d77
movq %r15, %rdi
callq 0x2f50a
movl %eax, %r12d
movq %r14, %rdi
callq 0x2f50a
movl %r12d, %edi
movl %eax, %esi
callq 0x2f512
cmpl $0x5, %eax
je 0x33cd6
movl 0x28(%rbx), %ecx
addl $-0x5, %ecx
cmpl $0x13, %ecx
ja 0x33cd6
leaq 0x13902(%rip), %rdx     # 0x475ac
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x33f2c
movq (%rbx), %rax
movq %rax, 0x18(%rbx)
movq $-0x1, 0x18(%rbx)
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x42e0
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
callq 0x2ee02
jmp 0x33d77
movq %r14, %rdi
callq 0x2f50a
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34e5e
movq %r14, %rdi
callq 0x2f50a
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34f2e
movl $0x10, %edi
callq 0x42e0
movq %rax, %r15
movq %r12, %rdi
callq 0x2f152
testb %al, %al
je 0x33d6a
movq %r14, %rdi
callq 0x2f152
jmp 0x33d6c
xorl %eax, %eax
movzbl %al, %esi
movq %r15, %rdi
callq 0x2ef28
movq %r15, 0x18(%rbx)
jmp 0x33cde
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34d52
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x344d6
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x346a8
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34228
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34128
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x3402a
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x347b2
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x348bc
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34c46
movq %rbx, %rdi
movl %eax, %esi
movq %r15, %rdx
movq %r14, %rcx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x34a82
leaq -0x40(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x1381d(%rip), %rsi     # 0x476c4
leaq 0x13861(%rip), %rdx     # 0x4770f
leaq -0x50(%rbp), %rdi
callq 0xf868
movl $0x28, %edi
callq 0x4190
movq %rax, %r14
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
movl $0x13, %esi
callq 0x333ee
leaq 0x26e94(%rip), %rsi     # 0x5ad70
leaq -0x25943(%rip), %rdx    # 0xe5a0
movq %r14, %rdi
callq 0x4540
jmp 0x33eef
jmp 0x33eef
movq %rax, %rbx
movq %r15, %rdi
jmp 0x33f1f
movq %rax, %rbx
jmp 0x33f07
movq %rax, %rbx
movq %r14, %rdi
callq 0x4250
movq -0x50(%rbp), %rdi
cmpq %r15, %rdi
jne 0x33f1f
jmp 0x33f24
movq %rax, %rbx
jmp 0x33f24
fstp %st(0)
movq %rax, %rbx
movq %r12, %rdi
callq 0x42b0
movq %rbx, %rdi
callq 0x4560