// File: /workspace/github_cpp_makefile_star2_O2/martinda3[P]Compiler/src/JVM/JVMgenerateStatement.cpp
// Function: toyc::JVMgenerateStatement::BlockStatement(toyc::ASblockState*, toyc::JVMtargetCode*)
void JVMgenerateStatement::BlockStatement(ASblockState *ThisBlock,JVMtargetCode *tc) {
      int BlockVars = ThisBlock->getNumVarDef();
      tc->add(new limit("locals",10));  // Scooping is hard
      for (int Var = 0 ; Var <  BlockVars; Var++) // not sure if needed
      {
//          ASvarDef *VarInit = JVMgenerateStatement::ASvarDefinition(dynamic_cast<ASvarDef*>(ThisBlock->getVarDef(Var)), tc);
//          AStype *step = dynamic_cast<AStype*>(VarInit->getIdentifier(Var));
//          std::cout << "  "<< step->getExpr()->getLexeme() << std::endl;
//          JVMgenUtils::gen_ISTORE(*symTable->getSym(symTable->find(step->getExpr()->getLexeme())),tc);
      }
      ASreadState *read_set;
      ASexprState *expr_set; ASifState *If_set;
      ASwriteState *write_set; ASreturnState *return_set;
      ASblockState *FunctionBlock;
      int Blocks = ThisBlock->getNumStatement();
      for(int Block = 0 ; Block < Blocks ; Block++)
      {
          enum stateType ThisStatement = ThisBlock->getStatement(Block)->getType();

          switch (ThisStatement){
              case READstate:
                  JVMgenerateProgram::gen_input_stream_store(tc);
//                  tc->add(new line(LINE_COUNTER)); LINE_COUNTER++;    //  Bookmakr
                  break;
              case WRITEstate: // Untested
//                  tc->add(new GETSTATIC(OUTPUT_FIELD_SPEC,OUTPUT_DESCRIPTOR));
//                  JVMgenUtils::gen_ASTORE(*symTable->getSym(symTable->find("System.out")),tc);
//                  JVMgenerateProgram::gen_output_stream_store(tc);
//                  tc->add(new line(LINE_COUNTER)); LINE_COUNTER++;    //  Bookmakr
                  break;
              default: // Should not happen
                  break;
          }
      }
      for (int Block = 0 ; Block < Blocks ; Block++)
      {
          enum stateType ThisStatement = ThisBlock->getStatement(Block)->getType();
          switch (ThisStatement){
              case EXPRstate:
                  expr_set = dynamic_cast<ASexprState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::ExprStatement(expr_set, tc);
                  break;
              case BREAKstate: // not done
                  break;
              case BLOCKstate:
                  FunctionBlock = dynamic_cast<ASblockState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::BlockStatement(FunctionBlock, tc);
                  break;
              case IFstate:
                  If_set = dynamic_cast<ASifState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::IfStatement(If_set, tc);
                  break;
              case NULLstate:
                  break;
              case RETURNstate:
                  return_set = dynamic_cast<ASreturnState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::ReturnStatement(return_set, tc);
                  break;
              case WHILEstate:
                  break;
              case READstate:
                  read_set = dynamic_cast<ASreadState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::ReadStatement(read_set, tc);
                  break;
              case WRITEstate:
                  write_set = dynamic_cast<ASwriteState*>(ThisBlock->getStatement(Block));
                  JVMgenerateStatement::WriteStatement(write_set, tc);
                  break;
              case NEWLINEstate:
                  tc->add(new GETSTATIC(OUTPUT_FIELD_SPEC, OUTPUT_DESCRIPTOR));
                  tc->add(new LDC(" "));
                  tc->add(new INVOKEVIRTUAL(PRINT_STRING_METHOD_SPEC));
                  break;
              case EMPTYstate:
                  break;
              default:
                  break;
          }
      }
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, 0x10(%rsp)
movq %rdi, 0x18(%rsp)
callq 0x19f42
pushq $0x58
popq %rdi
callq 0x8250
movq %rax, %r12
leaq 0x7bd4(%rip), %rsi      # 0x1e61e
leaq 0x48(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xd770
movb $0x1, %r15b
leaq 0x48(%rsp), %rsi
pushq $0xa
popq %rdx
movq %r12, %rdi
callq 0x16708
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
xorl %r15d, %r15d
movq %r12, %rsi
callq *(%rax)
leaq 0x48(%rsp), %rdi
callq 0x8478
movq 0x18(%rsp), %rdi
callq 0x19f4a
movl %eax, %ebx
testl %eax, %eax
cmovlel %r15d, %ebx
cmpl %r15d, %ebx
je 0x16ac6
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
callq 0x13288
cmpl $0x7, %eax
jne 0x16ac1
movq 0x10(%rsp), %rdi
callq 0x196d4
incl %r15d
jmp 0x16a98
movl %ebx, 0x24(%rsp)
xorl %r15d, %r15d
leaq 0x7b1c(%rip), %r12      # 0x1e5f0
leaq 0x1425d(%rip), %r13     # 0x2ad38
leaq 0xa8(%rsp), %rbp
leaq 0x88(%rsp), %r14
cmpl %r15d, 0x24(%rsp)
je 0x16d3b
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
callq 0x13288
cmpl $0x9, %eax
ja 0x16d33
movl %eax, %eax
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
movq %r13, %rsi
leaq 0x1428f(%rip), %rdx     # 0x2adc8
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x16de4
jmp 0x16d33
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
movq %r13, %rsi
leaq 0x1416c(%rip), %rdx     # 0x2acd8
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x16f4c
jmp 0x16d33
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
movq %r13, %rsi
leaq 0x16131(%rip), %rdx     # 0x2ccd0
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x16a18
jmp 0x16d33
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r13
leaq 0x28(%rsp), %rdi
leaq 0x16c19(%rip), %rsi     # 0x2d7e8
callq 0x82f0
movq %rbp, %rbx
movq %rbp, %rdi
leaq 0x16c27(%rip), %rsi     # 0x2d808
callq 0x82f0
movb $0x1, %r12b
movq %r13, %rdi
leaq 0x28(%rsp), %rsi
movq %rbx, %rdx
callq 0x14610
movq %r13, %rsi
addq $0x8, %rsi
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
xorl %r12d, %r12d
callq *(%rax)
movq %rbp, %rdi
callq 0x8478
leaq 0x28(%rsp), %rdi
callq 0x8478
pushq $0x38
popq %rdi
callq 0x8250
movq %rax, %r13
movq %r14, %rbx
movq %r14, %rdi
leaq 0x64bc(%rip), %rsi      # 0x1d0f3
leaq 0xf(%rsp), %rdx
callq 0xd770
movb $0x1, %r12b
movq %r13, %rdi
movq %rbx, %rsi
callq 0x15434
movq %r13, %rsi
addq $0x8, %rsi
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
xorl %r12d, %r12d
callq *(%rax)
movq %r14, %rdi
callq 0x8478
pushq $0x30
popq %rdi
callq 0x8250
movq %rax, %r13
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
leaq 0x16d63(%rip), %rsi     # 0x2d9e8
callq 0x82f0
movb $0x1, %r12b
movq %r13, %rdi
movq %rbx, %rsi
callq 0x15010
movq %r13, %rsi
addq $0x8, %rsi
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
xorl %r12d, %r12d
callq *(%rax)
leaq 0x68(%rsp), %rdi
callq 0x8478
leaq 0x7933(%rip), %r12      # 0x1e5f0
leaq 0x14074(%rip), %r13     # 0x2ad38
jmp 0x16d33
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
movq %r13, %rsi
leaq 0x13e80(%rip), %rdx     # 0x2ab60
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x16e1a
jmp 0x16d33
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
movq %rax, %rdi
movq %r13, %rsi
leaq 0x13e20(%rip), %rdx     # 0x2ab30
xorl %ecx, %ecx
callq 0x8290
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x16ef4
jmp 0x16d33
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x19f36
incl %r15d
jmp 0x16aeb
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x16d64
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x8478
testb %r15b, %r15b
je 0x16ddc
pushq $0x58
popq %rsi
movq %r12, %rdi
jmp 0x16dd7
movq %rax, %rbx
jmp 0x16d95
movq %rax, %rbx
jmp 0x16dae
movq %rax, %rbx
movb $0x1, %r12b
jmp 0x16dc2
movq %rax, %rbx
jmp 0x16dd1
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x8478
testb %r12b, %r12b
je 0x16ddc
pushq $0x30
jmp 0x16dd3
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x8478
testb %r12b, %r12b
je 0x16ddc
pushq $0x38
jmp 0x16dd3
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x8478
leaq 0x28(%rsp), %rdi
callq 0x8478
testb %r12b, %r12b
je 0x16ddc
pushq $0x50
popq %rsi
movq %r13, %rdi
callq 0x8260
movq %rbx, %rdi
callq 0x8400