// File: acliusBackHome[P]kamaya/dist/ParseExpression.cpp
// Function: ParseExpression::generate_expression(ExpressionType, ParseExpression const&, ParseExpression const&)
const ParseExpression &ParseExpression::generate_expression(
        ExpressionType type,
        const ParseExpression &expr1,
        const ParseExpression &expr2) {
    ParseExpression res;
    res.expr_type = type;
    res.child[0] = get_expr_id(expr1);
    res.child[1] = get_expr_id(expr2);
    switch (type) {
        case E_ADD:
        case E_SUB:
        case E_MUL:
        case E_DIV:
        case E_MOD:
        case E_POW: {
            // 如果其中一个是不可在编译期计算的表达式, 另一个是常量表达式, 则表达式返回值为不可计算表达式的类型
            if ((!expr1.is_const()) && expr2.is_const()) {
                res.ret_type_id = expr1.get_ret_type().get_id();
            } else if (!(expr2.is_const()) && expr1.is_const()) {
                res.ret_type_id = expr2.get_ret_type().get_id();
            } else {
                // 两者都是变量或者两者都是常量
                try {
                    res.ret_type_id = ParseType::convert(type, expr1.get_ret_type(), expr2.get_ret_type());
                } catch (ParseException &exc) {
                    string info = "in ParseExpression::generate_expression("
                                  "ExpressionType type, "
                                  "const ParseExpression &expr1, "
                                  "const ParseExpression &expr2)";
                    info += " expr1=" + to_string(expr1.get_id());
                    info += " expr2=" + to_string(expr2.get_id());
                    exc.push_trace(info);
                    throw exc;
                }
                if (expr1.is_const() && expr2.is_const()) {
                    res.calculate_const();
                }
            }
            // 求幂运算比较特殊(想出来C语言支持求幂运算符的要求的真是天才),
            // 返回值是long double
            if (type == E_POW) {
                ParseType ret_type(T_DOUBLE, S_LONG);
                res.ret_type_id = ret_type.get_id();
            }
            break;
        }
        case E_LOGIC_OR:
        case E_LOGIC_AND:
        case E_G:
        case E_GE:
        case E_EQUAL:
        case E_NE:
        case E_L:
        case E_LE:
            res.ret_type_id = T_BOOL;
            if (expr1.is_const() && expr2.is_const()) {
                res.calculate_const();
            }
            break;
        case E_ADR:
        case E_PTR:
        case E_NEG:
        case E_POS:
        case E_BIT_NOT:
        case E_NOT:
        case E_GET_ITEM:
        case E_UNDEFINED:
        case E_VAR:
        case E_CONST:
        case E_FUN:
        case E_ASSIGN: {
            // 错误调用该函数
            string info = "ParseExpression::generate_expression("
                          "ExpressionType type, "
                          "const ParseExpression &expr1, "
                          "const ParseExpression &expr2)";
            info += " expr1=" + to_string(expr1.get_id());
            info += " expr2=" + to_string(expr2.get_id());
            throw ParseException(EX_EXPRESSION_CAN_NOT_GENERATE, info);
        }
    }
    update(res);
    return get_expression(res.get_id());
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x61e30
movl -0x4(%rbp), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x63830
movq %rax, -0x1f0(%rbp)
jmp 0x62a57
movq -0x1f0(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
callq 0x63830
movq %rax, -0x1f8(%rbp)
jmp 0x62a74
movq -0x1f8(%rbp), %rax
movq %rax, -0x40(%rbp)
movl -0x4(%rbp), %eax
movl %eax, -0x1fc(%rbp)
subl $0x5, %eax
jb 0x62f67
jmp 0x62a93
movl -0x1fc(%rbp), %eax
addl $-0x5, %eax
subl $0x6, %eax
jb 0x62af0
jmp 0x62aa3
movl -0x1fc(%rbp), %eax
addl $-0xb, %eax
subl $0x6, %eax
jb 0x62f67
jmp 0x62ab7
movl -0x1fc(%rbp), %eax
addl $-0x11, %eax
subl $0x8, %eax
jb 0x62f13
jmp 0x62acb
movl -0x1fc(%rbp), %eax
subl $0x19, %eax
je 0x62f67
jmp 0x63187
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x631d2
movq -0x10(%rbp), %rdi
callq 0x61790
movb %al, -0x1fd(%rbp)
jmp 0x62b01
movb -0x1fd(%rbp), %al
testb $0x1, %al
jne 0x62b61
jmp 0x62b0d
movq -0x18(%rbp), %rdi
callq 0x61790
movb %al, -0x1fe(%rbp)
jmp 0x62b1e
movb -0x1fe(%rbp), %al
testb $0x1, %al
jne 0x62b2a
jmp 0x62b61
movq -0x10(%rbp), %rdi
callq 0x61800
movq %rax, -0x208(%rbp)
jmp 0x62b3c
movq -0x208(%rbp), %rdi
callq 0x56260
movq %rax, -0x210(%rbp)
jmp 0x62b51
movq -0x210(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x62ea5
movq -0x18(%rbp), %rdi
callq 0x61790
movb %al, -0x211(%rbp)
jmp 0x62b72
movb -0x211(%rbp), %al
testb $0x1, %al
jne 0x62bd2
jmp 0x62b7e
movq -0x10(%rbp), %rdi
callq 0x61790
movb %al, -0x212(%rbp)
jmp 0x62b8f
movb -0x212(%rbp), %al
testb $0x1, %al
jne 0x62b9b
jmp 0x62bd2
movq -0x18(%rbp), %rdi
callq 0x61800
movq %rax, -0x220(%rbp)
jmp 0x62bad
movq -0x220(%rbp), %rdi
callq 0x56260
movq %rax, -0x228(%rbp)
jmp 0x62bc2
movq -0x228(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x62ea3
movl -0x4(%rbp), %eax
movl %eax, -0x234(%rbp)
movq -0x10(%rbp), %rdi
callq 0x61800
movq %rax, -0x230(%rbp)
jmp 0x62bed
movq -0x18(%rbp), %rdi
callq 0x61800
movq %rax, -0x240(%rbp)
jmp 0x62bff
movq -0x240(%rbp), %rdx
movq -0x230(%rbp), %rsi
movl -0x234(%rbp), %edi
callq 0x586f0
movq %rax, -0x248(%rbp)
jmp 0x62c21
movq -0x248(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x62e5a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x631d2
movq -0x50(%rbp), %rdi
callq 0x4170
movq %rax, -0x60(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0x45f0
movq -0x250(%rbp), %rdx
leaq 0x2d782(%rip), %rsi     # 0x903fd
leaq -0x80(%rbp), %rdi
callq 0x4450
jmp 0x62c86
leaq -0x81(%rbp), %rdi
callq 0x4380
movq -0x10(%rbp), %rdi
callq 0x63810
movq %rax, -0x258(%rbp)
jmp 0x62ca4
movq -0x258(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
callq 0x15db0
jmp 0x62cb9
leaq 0x2a081(%rip), %rsi     # 0x8cd41
leaq -0xa8(%rbp), %rdi
leaq -0xc8(%rbp), %rdx
callq 0x15d60
jmp 0x62cd5
leaq -0x80(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x43f0
jmp 0x62ce7
leaq -0xa8(%rbp), %rdi
callq 0x4688
leaq -0xc8(%rbp), %rdi
callq 0x4688
movq -0x18(%rbp), %rdi
callq 0x63810
movq %rax, -0x260(%rbp)
jmp 0x62d11
movq -0x260(%rbp), %rsi
leaq -0x108(%rbp), %rdi
callq 0x15db0
jmp 0x62d26
leaq 0x2a01c(%rip), %rsi     # 0x8cd49
leaq -0xe8(%rbp), %rdi
leaq -0x108(%rbp), %rdx
callq 0x15d60
jmp 0x62d42
leaq -0x80(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x43f0
jmp 0x62d54
leaq -0xe8(%rbp), %rdi
callq 0x4688
leaq -0x108(%rbp), %rdi
callq 0x4688
movq -0x60(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x74530
jmp 0x62d7b
movl $0x28, %edi
callq 0x41c0
movq %rax, %rdi
movq %rdi, -0x268(%rbp)
movq -0x60(%rbp), %rsi
callq 0x74640
movq -0x268(%rbp), %rdi
leaq 0x62faa(%rip), %rsi     # 0xc5d50
leaq -0x4cf1d(%rip), %rdx    # 0x15e90
callq 0x45b0
jmp 0x631ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x81(%rbp), %rdi
callq 0x4380
jmp 0x62e4e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x62e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x62e05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x4688
leaq -0xc8(%rbp), %rdi
callq 0x4688
jmp 0x62e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x62e39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x4688
leaq -0x108(%rbp), %rdi
callq 0x4688
leaq -0x80(%rbp), %rdi
callq 0x4688
callq 0x4570
jmp 0x62e55
jmp 0x631d2
movq -0x10(%rbp), %rdi
callq 0x61790
movb %al, -0x269(%rbp)
jmp 0x62e6b
movb -0x269(%rbp), %al
testb $0x1, %al
jne 0x62e77
jmp 0x62ea1
movq -0x18(%rbp), %rdi
callq 0x61790
movb %al, -0x26a(%rbp)
jmp 0x62e88
movb -0x26a(%rbp), %al
testb $0x1, %al
jne 0x62e94
jmp 0x62ea1
leaq -0x48(%rbp), %rdi
callq 0x74b60
jmp 0x62e9f
jmp 0x62ea1
jmp 0x62ea3
jmp 0x62ea5
cmpl $0xa, -0x4(%rbp)
jne 0x62f0e
leaq -0x140(%rbp), %rdi
movl $0x7, %esi
movl $0x2, %edx
callq 0x55ef0
jmp 0x62ec3
leaq -0x140(%rbp), %rdi
callq 0x56260
movq %rax, -0x278(%rbp)
jmp 0x62ed8
movq -0x278(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x57350
jmp 0x62f0e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x57350
jmp 0x631d2
jmp 0x63187
movq $0x1, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x61790
movb %al, -0x279(%rbp)
jmp 0x62f2c
movb -0x279(%rbp), %al
testb $0x1, %al
jne 0x62f38
jmp 0x62f62
movq -0x18(%rbp), %rdi
callq 0x61790
movb %al, -0x27a(%rbp)
jmp 0x62f49
movb -0x27a(%rbp), %al
testb $0x1, %al
jne 0x62f55
jmp 0x62f62
leaq -0x48(%rbp), %rdi
callq 0x74b60
jmp 0x62f60
jmp 0x62f62
jmp 0x63187
leaq -0x161(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x45f0
movq -0x288(%rbp), %rdx
leaq 0x2d478(%rip), %rsi     # 0x90400
leaq -0x160(%rbp), %rdi
callq 0x4450
jmp 0x62f96
leaq -0x161(%rbp), %rdi
callq 0x4380
movq -0x10(%rbp), %rdi
callq 0x63810
movq %rax, -0x290(%rbp)
jmp 0x62fb4
movq -0x290(%rbp), %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x15db0
jmp 0x62fc9
leaq 0x29d71(%rip), %rsi     # 0x8cd41
leaq -0x188(%rbp), %rdi
leaq -0x1a8(%rbp), %rdx
callq 0x15d60
jmp 0x62fe5
leaq -0x160(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x43f0
jmp 0x62ffa
leaq -0x188(%rbp), %rdi
callq 0x4688
leaq -0x1a8(%rbp), %rdi
callq 0x4688
movq -0x18(%rbp), %rdi
callq 0x63810
movq %rax, -0x298(%rbp)
jmp 0x63024
movq -0x298(%rbp), %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x15db0
jmp 0x63039
leaq 0x29d09(%rip), %rsi     # 0x8cd49
leaq -0x1c8(%rbp), %rdi
leaq -0x1e8(%rbp), %rdx
callq 0x15d60
jmp 0x63055
leaq -0x160(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x43f0
jmp 0x6306a
leaq -0x1c8(%rbp), %rdi
callq 0x4688
leaq -0x1e8(%rbp), %rdi
callq 0x4688
movl $0x28, %edi
callq 0x41c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x2a0(%rbp)
movl $0x10, %esi
leaq -0x160(%rbp), %rdx
callq 0x73a90
jmp 0x630ac
movq -0x2a0(%rbp), %rdi
leaq 0x62c96(%rip), %rsi     # 0xc5d50
leaq -0x4d231(%rip), %rdx    # 0x15e90
callq 0x45b0
jmp 0x631ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x161(%rbp), %rdi
callq 0x4380
jmp 0x631d2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x63179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6311f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x4688
leaq -0x1a8(%rbp), %rdi
callq 0x4688
jmp 0x63179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x63153
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x4688
leaq -0x1e8(%rbp), %rdi
callq 0x4688
jmp 0x63179
movq -0x2a0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
callq 0x4280
leaq -0x160(%rbp), %rdi
callq 0x4688
jmp 0x631d2
leaq -0x48(%rbp), %rdi
callq 0x60e20
jmp 0x63192
leaq -0x48(%rbp), %rdi
callq 0x63810
movq %rax, -0x2a8(%rbp)
jmp 0x631a4
movq -0x2a8(%rbp), %rdi
callq 0x60f30
movq %rax, -0x2b0(%rbp)
jmp 0x631b9
leaq -0x48(%rbp), %rdi
callq 0x62810
movq -0x2b0(%rbp), %rax
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0x62810
movq -0x50(%rbp), %rdi
callq 0x45e0
movq %rax, %rdi
callq 0x16180
nopl (%rax)