// File: /workspace/github_cpp_makefile_star2_O2/martinda3[P]Compiler/src/JVM/JVMgenerateExpression.cpp
// Function: toyc::JVMgenerateExpression::genExpression(toyc::ASexpression*, toyc::JVMtargetCode*)
void JVMgenerateExpression::genExpression(ASexpression *ast, JVMtargetCode *tc) {
        TCtoken *check1;
        std::string cleanup, idd;
        ASsimpleExpr *se;
        enum exprType etype = ast->getType();
        if (etype == EXPRexpr) {
            ASexpr *be = dynamic_cast<ASexpr *>(ast);

            ASoperator *temp = be->getOper();
            TCtoken *op = temp->getExpr();

            if (op->getTokenType() == DIVOP) {
                genExpression(be->getOp2(), tc);
                genExpression(be->getOp1(), tc);
            } else { genExpression(be->getOp1(), tc); }

            if (op->getTokenType() == ASSIGNOP) {
                se = dynamic_cast<ASsimpleExpr *>(be->getOp2());
                check1 = dynamic_cast<TCtoken *>(se->getExpr());
                JVMgenUtils::gen_ISTORE(*symTable->getSym(symTable->find(check1->getLexeme())), tc);
            }
            else {
                if (op->getTokenType() != DIVOP) { genExpression(be->getOp2(), tc); }
                switch (op->getTokenType()) {
                    case ADDOP:     JVMgenUtils::gen_ADDOP(*op, tc);    break;  // Untested
                    case MULOP:  /*JVMgenUtils::gen_MULOP(*op, tc);*/   break;  // Modulous
                    case MULTI:     JVMgenUtils::gen_MULOP(*op, tc);    break;  // multi
                    case DIVOP:     JVMgenUtils::gen_MULOP(*op, tc);    break;  // multi
                    case RELOP:     JVMgenUtils::gen_RELOP(*op, tc);    break;  // Untested
                    case OR:        JVMgenUtils::gen_OR(*op, tc);       break;  // Untested
                    case AND:       JVMgenUtils::gen_AND(*op, tc);      break;  // Untested
                    case ASSIGNOP:                                      break;  // Redudnat
                    default: // shouldn't happen
//                    std::cerr << "Fatal internal error #1: JVMgenerateExpression" << std::endl;
//                    exit(EXIT_FAILURE);
                        break;
                }
            }


        } else if (etype == SIMPLEexpr) {
            TCsymbol *idsym;
            ASsimpleExpr *se = dynamic_cast<ASsimpleExpr *>(ast);
            TCtoken *t = se->getExpr();
            std::string lexeme = t->getLexeme();
            if (t->getTokenType() == ID) {
                idsym = symTable->getSym(symTable->find(t->getLexeme()));
                JVMgenUtils::gen_ILOAD(*idsym, tc);
            } else if (t->getTokenType() == NUMBER) {
                JVMgenUtils::gen_ICONST(stoi(lexeme), tc);
            } else // shouldn't happen
            {
                std::cerr << "Fatal internal error #2: JVMgenerateExpression" << std::endl;
                exit(EXIT_FAILURE);
            }
        }
        else if (etype == FUNCCALLexpr) { // Semi-testsed [Writestate]
            TCsymbol *idsym;
            ASfuncCall *sexpr = dynamic_cast<ASfuncCall *>(ast);
            ASsimpleExpr *se = dynamic_cast<ASsimpleExpr *>(sexpr->getOp1());
            TCtoken *t = se->getExpr(); std::string choper;
            switch (t->getTokenType())
            {
                case NUMBER:
                    tc->add(new GETSTATIC(OUTPUT_FIELD_SPEC, OUTPUT_DESCRIPTOR));
                    tc->add(new LDC(t->getLexeme()));
                    tc->add(new INVOKEVIRTUAL(PRINT_STRING_METHOD_SPEC));
                    break;
                case ID:
                    idsym = symTable->getSym(symTable->find(t->getLexeme()));
                    tc->add(new GETSTATIC(OUTPUT_FIELD_SPEC, OUTPUT_DESCRIPTOR));
                    JVMgenUtils::gen_ILOAD(*idsym, tc);
                    tc->add(new INVOKEVIRTUAL(PRINT_INT_NEWLINE_METHOD_SPEC));
                    break;
                case STRING:
                    tc->add(new GETSTATIC(OUTPUT_FIELD_SPEC, OUTPUT_DESCRIPTOR));
                    choper = t->getLexeme().substr(1, (t->getLexeme().length() - 2)); // removes extra ""THis is the sirng""
                    tc->add(new LDC(choper));
                    tc->add(new INVOKEVIRTUAL(PRINT_STRING_METHOD_SPEC));
                    break;
                default:
                    break;
            }
        }
//        Unimplemented
//         else if (etype == MINUSexpr) {
//
//        } else if (etype == NOTexpr) {
//
//        } else if (etype == EMPTYexpr) {
//
//        }
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x448, %rsp            # imm = 0x448
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x340(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq 0x320(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %cl, (%rax)
callq 0x13d84
testl %eax, %eax
je 0x1819b
cmpl $0x4, %eax
je 0x180e6
cmpl $0x1, %eax
jne 0x18688
leaq 0x12e43(%rip), %rsi     # 0x2ae28
leaq 0x14cb4(%rip), %rdx     # 0x2cca0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8290
movq %rax, %r15
movq %rax, %rdi
callq 0x19e9c
movq %rax, %rdi
callq 0x13248
movq %rax, %r14
movq %rax, %rdi
callq 0x119f0
cmpl $0x16, %eax
jne 0x1802c
movq %r15, %rdi
callq 0x19e96
movq %rax, %rdi
movq %rbx, %rsi
callq 0x17f84
movq %r15, %rdi
callq 0x19e90
movq %rax, %rdi
movq %rbx, %rsi
callq 0x17f84
movq %r14, %rdi
callq 0x119f0
cmpl $0x15, %eax
jne 0x183ad
movq %r15, %rdi
callq 0x19e96
leaq 0x12dc9(%rip), %rsi     # 0x2ae28
leaq 0x12c42(%rip), %rdx     # 0x2aca8
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
callq 0x12e6c
leaq 0x154e9(%rip), %rcx     # 0x2d568
movq (%rcx), %r14
leaq 0x1a0(%rsp), %rdi
movq %rax, %rsi
callq 0x119f4
leaq 0x1a0(%rsp), %rsi
movq %r14, %rdi
callq 0x1bc3c
movq %r14, %rdi
movl %eax, %esi
callq 0x1bcc6
leaq 0x400(%rsp), %rdi
movq %rax, %rsi
callq 0x18a12
leaq 0x400(%rsp), %rdi
movq %rbx, %rsi
callq 0x16f90
leaq 0x400(%rsp), %rdi
callq 0x18a52
leaq 0x1a0(%rsp), %rdi
jmp 0x18683
leaq 0x12d3b(%rip), %rsi     # 0x2ae28
leaq 0x12bb4(%rip), %rdx     # 0x2aca8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
callq 0x12e6c
movq %rax, %r14
movq %rsp, %rdi
movq %rax, %rsi
callq 0x119f4
movq %r14, %rdi
callq 0x119f0
cmpl $0x18, %eax
jne 0x18380
leaq 0x1543c(%rip), %rax     # 0x2d568
movq (%rax), %r15
leaq 0x180(%rsp), %rdi
movq %r14, %rsi
callq 0x119f4
leaq 0x180(%rsp), %rsi
movq %r15, %rdi
callq 0x1bc3c
movq %r15, %rdi
movl %eax, %esi
callq 0x1bcc6
movq %rax, %r14
leaq 0x180(%rsp), %rdi
callq 0x8478
leaq 0x3b8(%rsp), %rdi
movq %r14, %rsi
callq 0x18a12
leaq 0x3b8(%rsp), %rdi
movq %rbx, %rsi
callq 0x17038
leaq 0x3b8(%rsp), %rdi
callq 0x18a52
jmp 0x18680
leaq 0x12c86(%rip), %rsi     # 0x2ae28
leaq 0x12bef(%rip), %rdx     # 0x2ad98
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
callq 0x13820
leaq 0x12c66(%rip), %rsi     # 0x2ae28
leaq 0x12adf(%rip), %rdx     # 0x2aca8
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
callq 0x12e6c
movq %rax, %r14
leaq 0x10(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq %r14, %rdi
callq 0x119f0
cmpl $0x10, %eax
je 0x1856d
cmpl $0x18, %eax
je 0x18438
cmpl $0x1a, %eax
jne 0x18680
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x155c4(%rip), %rsi     # 0x2d7e8
leaq 0xa0(%rsp), %rdi
callq 0x82f0
leaq 0x155d0(%rip), %rsi     # 0x2d808
leaq 0x80(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0xa0(%rsp), %rsi
leaq 0x80(%rsp), %rdx
movq %r15, %rdi
callq 0x14610
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
leaq 0x80(%rsp), %rdi
callq 0x8478
leaq 0xa0(%rsp), %rdi
callq 0x8478
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
callq 0x119f4
leaq 0x40(%rsp), %rdi
movq %r14, %rsi
callq 0x119f4
movq 0x48(%rsp), %rcx
addq $-0x2, %rcx
leaq 0x350(%rsp), %rdi
leaq 0x60(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x8270
movq %rsp, %rdi
leaq 0x350(%rsp), %r14
movq %r14, %rsi
callq 0x82d0
movq %r14, %rdi
callq 0x8478
leaq 0x40(%rsp), %rdi
callq 0x8478
leaq 0x60(%rsp), %rdi
callq 0x8478
pushq $0x38
popq %rdi
callq 0x8250
movq %rax, %r14
leaq 0x20(%rsp), %rdi
movq %rsp, %rsi
callq 0x82f0
movb $0x1, %bpl
leaq 0x20(%rsp), %rsi
movq %r14, %rdi
callq 0x15434
movq %r14, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
leaq 0x20(%rsp), %rdi
callq 0x8478
pushq $0x30
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x156a1(%rip), %rsi     # 0x2d9e8
leaq 0x2b0(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0x2b0(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x15010
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
jmp 0x18678
movq %r14, %rdi
callq 0x119f0
cmpl $0x10, %eax
jne 0x1878e
movq %rsp, %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x18a79
movl %eax, %edi
movq %rbx, %rsi
callq 0x17230
jmp 0x18680
movq %r14, %rdi
callq 0x119f0
cmpl $0x16, %eax
je 0x183cd
movq %r15, %rdi
callq 0x19e96
movq %rax, %rdi
movq %rbx, %rsi
callq 0x17f84
movq %r14, %rdi
callq 0x119f0
cmpl $0x12, %eax
je 0x18761
cmpl $0x29, %eax
je 0x18734
cmpl $0x16, %eax
je 0x186b0
cmpl $0x1d, %eax
je 0x18707
cmpl $0x28, %eax
je 0x186da
cmpl $0x13, %eax
jne 0x18688
leaq 0x288(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x288(%rsp), %rdi
movq %rbx, %rsi
callq 0x1738e
leaq 0x290(%rsp), %rdi
jmp 0x18683
leaq 0x15129(%rip), %rax     # 0x2d568
movq (%rax), %r15
leaq 0x100(%rsp), %rdi
movq %r14, %rsi
callq 0x119f4
leaq 0x100(%rsp), %rsi
movq %r15, %rdi
callq 0x1bc3c
movq %r15, %rdi
movl %eax, %esi
callq 0x1bcc6
movq %rax, %r15
leaq 0x100(%rsp), %rdi
callq 0x8478
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r14
leaq 0x1535a(%rip), %rsi     # 0x2d7e8
leaq 0xe0(%rsp), %rdi
callq 0x82f0
leaq 0x15366(%rip), %rsi     # 0x2d808
leaq 0xc0(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0xe0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
movq %r14, %rdi
callq 0x14610
movq %r14, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
leaq 0xc0(%rsp), %rdi
callq 0x8478
leaq 0xe0(%rsp), %rdi
callq 0x8478
leaq 0x370(%rsp), %rdi
movq %r15, %rsi
callq 0x18a12
leaq 0x370(%rsp), %rdi
movq %rbx, %rsi
callq 0x17038
leaq 0x370(%rsp), %rdi
callq 0x18a52
pushq $0x30
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x15494(%rip), %rsi     # 0x2d9c8
leaq 0x2d0(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0x2d0(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x15010
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
jmp 0x18678
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x15269(%rip), %rsi     # 0x2d7e8
leaq 0x160(%rsp), %rdi
callq 0x82f0
leaq 0x15275(%rip), %rsi     # 0x2d808
leaq 0x140(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0x160(%rsp), %rsi
leaq 0x140(%rsp), %rdx
movq %r15, %rdi
callq 0x14610
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
leaq 0x140(%rsp), %rdi
callq 0x8478
leaq 0x160(%rsp), %rdi
callq 0x8478
pushq $0x38
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x120(%rsp), %rdi
movq %r14, %rsi
callq 0x119f4
movb $0x1, %bpl
leaq 0x120(%rsp), %rsi
movq %r15, %rdi
callq 0x15434
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
leaq 0x120(%rsp), %rdi
callq 0x8478
pushq $0x30
popq %rdi
callq 0x8250
movq %rax, %r15
leaq 0x153a4(%rip), %rsi     # 0x2d9e8
leaq 0x2f0(%rsp), %rdi
callq 0x82f0
movb $0x1, %bpl
leaq 0x2f0(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x15010
movq %r15, %rsi
addq $0x8, %rsi
movq (%rbx), %rax
xorl %ebp, %ebp
movq %rbx, %rdi
callq *(%rax)
movq %r14, %rdi
callq 0x8478
movq %rsp, %rdi
callq 0x8478
leaq 0x310(%rsp), %rdi
callq 0x8478
leaq 0x330(%rsp), %rdi
callq 0x8478
addq $0x448, %rsp            # imm = 0x448
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x238(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x238(%rsp), %rdi
movq %rbx, %rsi
callq 0x17478
leaq 0x240(%rsp), %rdi
jmp 0x18683
leaq 0x1c0(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x1c0(%rsp), %rdi
movq %rbx, %rsi
callq 0x17c56
leaq 0x1c8(%rsp), %rdi
jmp 0x18683
leaq 0x260(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x260(%rsp), %rdi
movq %rbx, %rsi
callq 0x17478
leaq 0x268(%rsp), %rdi
jmp 0x18683
leaq 0x1e8(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x1e8(%rsp), %rdi
movq %rbx, %rsi
callq 0x1795e
leaq 0x1f0(%rsp), %rdi
jmp 0x18683
leaq 0x210(%rsp), %rdi
movq %r14, %rsi
callq 0x18a68
leaq 0x210(%rsp), %rdi
movq %rbx, %rsi
callq 0x1756e
leaq 0x218(%rsp), %rdi
jmp 0x18683
movq 0x1485b(%rip), %rdi     # 0x2cff0
leaq 0x5f32(%rip), %rsi      # 0x1e6ce
callq 0x8240
movq %rax, %rdi
callq 0x8130
pushq $0x1
popq %rdi
callq 0x82c0
movq %rax, %rbx
leaq 0x218(%rsp), %rdi
jmp 0x189e4
movq %rax, %rbx
leaq 0x1f0(%rsp), %rdi
jmp 0x189e4
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
jmp 0x189e4
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
jmp 0x189e4
movq %rax, %rbx
leaq 0x240(%rsp), %rdi
jmp 0x189e4
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
jmp 0x189e4
jmp 0x18815
jmp 0x18815
movq %rax, %rbx
jmp 0x188c4
movq %rax, %rbx
jmp 0x188e1
movq %rax, %rbx
leaq 0x370(%rsp), %rdi
jmp 0x18953
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x8478
jmp 0x18847
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
jmp 0x189be
movq %rax, %rbx
jmp 0x18913
jmp 0x189de
movq %rax, %rbx
movb $0x1, %bpl
jmp 0x1892a
movq %rax, %rbx
jmp 0x18940
movq %rax, %rbx
movb $0x1, %bpl
jmp 0x1896d
movq %rax, %rbx
movb $0x1, %bpl
jmp 0x18987
jmp 0x18889
movq %rax, %rbx
jmp 0x18999
movq %rax, %rbx
leaq 0x2b0(%rsp), %rdi
jmp 0x188b6
movq %rax, %rbx
leaq 0x2d0(%rsp), %rdi
jmp 0x188b6
movq %rax, %rbx
leaq 0x2f0(%rsp), %rdi
callq 0x8478
testb %bpl, %bpl
je 0x189e1
pushq $0x30
jmp 0x1899b
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x8478
testb %bpl, %bpl
je 0x189e1
pushq $0x38
jmp 0x18942
movq %rax, %rbx
leaq 0x400(%rsp), %rdi
callq 0x18a52
jmp 0x189d2
movq %rax, %rbx
leaq 0x120(%rsp), %rdi
callq 0x8478
testb %bpl, %bpl
je 0x189e1
pushq $0x38
jmp 0x1899b
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x8478
leaq 0xe0(%rsp), %rdi
callq 0x8478
testb %bpl, %bpl
je 0x189e1
pushq $0x50
popq %rsi
movq %r14, %rdi
jmp 0x1899f
movq %rax, %rbx
leaq 0x3b8(%rsp), %rdi
callq 0x18a52
jmp 0x189e1
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x8478
leaq 0xa0(%rsp), %rdi
jmp 0x1898f
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0x8478
leaq 0x160(%rsp), %rdi
callq 0x8478
testb %bpl, %bpl
je 0x189e1
pushq $0x50
popq %rsi
movq %r15, %rdi
callq 0x8260
jmp 0x189e1
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
jmp 0x189be
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
callq 0x8478
jmp 0x189e1
jmp 0x189ed
jmp 0x189ed
jmp 0x189ed
jmp 0x189ed
jmp 0x189ed
movq %rax, %rbx
leaq 0x1a0(%rsp), %rdi
jmp 0x189e4
jmp 0x189de
movq %rax, %rbx
movq %rsp, %rdi
callq 0x8478
jmp 0x189f0
jmp 0x189ed
movq %rax, %rbx
leaq 0x310(%rsp), %rdi
callq 0x8478
leaq 0x330(%rsp), %rdi
callq 0x8478
movq %rbx, %rdi
callq 0x8400