// File: /workspace/github_cpp_makefile_star2_O2/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 0x2bc03
movq %rdi, %rbx
movl 0x28(%rdi), %eax
addl $-0x3, %eax
cmpl $0x15, %eax
ja 0x2bbfe
leaq 0x10af5(%rip), %rcx     # 0x3c4d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x2bbfe
movq 0x8(%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x2bbfe
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x25daa
movq %rax, %r15
movq 0x8(%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x25daa
movq %rax, %r14
cmpl $0xa, 0x28(%rbx)
jne 0x2bb9e
pushq $0x10
popq %rdi
callq 0x42a0
movq %rax, %r12
movq %r15, %rdi
callq 0x27c08
fstpt -0x2c(%rbp)
fldz
fstp %st(0)
movq %r14, %rdi
callq 0x27c08
fstpt 0x10(%rsp)
fldt -0x2c(%rbp)
fstpt (%rsp)
callq 0x44d0
fstpt (%rsp)
movq %r12, %rdi
callq 0x27a9a
fldz
fstp %st(0)
movq %r12, 0x18(%rbx)
jmp 0x2bc03
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x2bbfe
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x25daa
movq %rax, %r14
movl 0x28(%rbx), %eax
addl $-0xb, %eax
cmpl $0x5, %eax
ja 0x2bc03
leaq 0x10a58(%rip), %rcx     # 0x3c52c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r14, %rdi
callq 0x27fba
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2cd9a
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x2bbfe
movq 0x8(%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x2bbfe
movq (%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x25daa
movq %rax, %r12
movq 0x8(%rbx), %rdi
callq 0x247e8
movq %rax, %rdi
callq 0x25daa
movq %rax, %r14
movl 0x28(%rbx), %eax
cmpl $0x12, %eax
je 0x2bc6a
cmpl $0x11, %eax
jne 0x2bbfe
pushq $0x10
popq %rdi
callq 0x42a0
movq %rax, %r15
movq %r12, %rdi
callq 0x27c88
movl %eax, %ecx
movb $0x1, %al
testb %cl, %cl
jne 0x2bb8e
movq %r14, %rdi
callq 0x27c88
movzbl %al, %esi
movq %r15, %rdi
callq 0x27a74
jmp 0x2bc98
movq %r15, %rdi
callq 0x27fba
movl %eax, %r12d
movq %r14, %rdi
callq 0x27fba
movl %r12d, %edi
movl %eax, %esi
callq 0x27fc2
cmpl $0x5, %eax
je 0x2bbfe
movl 0x28(%rbx), %ecx
addl $-0x5, %ecx
cmpl $0x13, %ecx
ja 0x2bbfe
leaq 0x10972(%rip), %rdx     # 0x3c544
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 0x2be3e
movq (%rbx), %rax
movq %rax, 0x18(%rbx)
orq $-0x1, 0x18(%rbx)
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x42a0
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
callq 0x2796e
jmp 0x2bc98
movq %r14, %rdi
callq 0x27fba
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2cc4a
movq %r14, %rdi
callq 0x27fba
movq %rbx, %rdi
movl %eax, %esi
movq %r14, %rdx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2cd0c
pushq $0x10
popq %rdi
callq 0x42a0
movq %rax, %r15
movq %r12, %rdi
callq 0x27c88
testb %al, %al
je 0x2bc8b
movq %r14, %rdi
callq 0x27c88
jmp 0x2bc8d
xorl %eax, %eax
movzbl %al, %esi
movq %r15, %rdi
callq 0x27a74
movq %r15, 0x18(%rbx)
jmp 0x2bc03
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 0x2cb48
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 0x2c39c
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 0x2c54a
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 0x2c122
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 0x2c02a
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 0x2bf34
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 0x2c64a
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 0x2c74a
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 0x2ca46
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 0x2c8c8
leaq 0x1089c(%rip), %rsi     # 0x3c65c
leaq -0x50(%rbp), %rdi
leaq -0x21(%rbp), %rdx
callq 0x4130
pushq $0x28
popq %rdi
callq 0x4180
movq %rax, %r14
pushq $0x13
popq %rsi
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
callq 0x2b53c
leaq 0x26f82(%rip), %rsi     # 0x52d70
leaq -0x1f54d(%rip), %rdx    # 0xc8a8
movq %r14, %rdi
callq 0x44e0
jmp 0x2be01
jmp 0x2be01
movq %rax, %rbx
movq %r15, %rdi
jmp 0x2be31
movq %rax, %rbx
jmp 0x2be19
movq %rax, %rbx
movq %r14, %rdi
callq 0x4220
leaq -0x50(%rbp), %rdi
callq 0x4598
jmp 0x2be36
movq %rax, %rbx
jmp 0x2be36
fstp %st(0)
movq %rax, %rbx
movq %r12, %rdi
callq 0x4270
movq %rbx, %rdi
callq 0x4500