// File: luooofan[P]hblzbd_compiler/src/evaluate.cpp
// Function: ast::ArrayInitVal::Evaluate(ir::ContextInfo&, std::vector<ir::IR*, std::allocator<ir::IR*>>&)
void ArrayInitVal::Evaluate(ir::ContextInfo& ctx, std::vector<ir::IR*>& gIRList) {
  auto& symbol_item = (*ir::gScopes[ctx.scope_id_].symbol_table_.find(ctx.array_name_)).second;
  if (this->is_exp_) {
    this->value_->Evaluate(ctx, gIRList);
    if (ctx.opn_.type_ != ir::Opn::Type::Imm) {  // 语义错误 非常量表达式
      ir::SemanticError(this->line_no_, ctx.opn_.name_ + "非常量表达式");
    }

    symbol_item.initval_.push_back(ctx.opn_.imm_num_);
    ++ctx.array_offset_;
  } else {
    // 此时该结点表示一对大括号 {}
    int& offset = ctx.array_offset_;
    int& brace_num = ctx.brace_num_;

    // 根据offset和brace_num算出finaloffset
    int temp_level = 0;
    const auto& dim_total_num = ctx.dim_total_num_;
    for (int i = 0; i < dim_total_num.size(); ++i) {
      if (offset % dim_total_num[i] == 0) {
        temp_level = i;
        break;
      }
    }
    temp_level += brace_num;

    if (temp_level > dim_total_num.size()) {  // 语义错误 大括号过多
      ir::SemanticError(this->line_no_, "多余大括号");
    } else {
      int final_offset = offset + dim_total_num[temp_level - 1];
      if (!this->initval_list_.empty()) {
        ++brace_num;
        this->initval_list_[0]->Evaluate(ctx, gIRList);

        for (int i = 1; i < this->initval_list_.size(); ++i) {
          brace_num = 1;
          this->initval_list_[i]->Evaluate(ctx, gIRList);
        }
      }
      // 补0补到finaloffset
      // while (offset < final_offset) {
      //   symbol_item.initval_.push_back(0);
      //   ++offset;
      // }
      // 语义检查
      if (offset > final_offset) {  // 语义错误 初始值设定项值太多
        ir::SemanticError(this->line_no_, "初始值设定项值太多");
      }
      symbol_item.initval_.insert(symbol_item.initval_.end(), final_offset - offset, 0);
      offset = final_offset;
    }
  }
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
movq %rdx, 0x140(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x148(%rsp), %rax
movslq (%rax), %rsi
leaq 0x12da2a(%rip), %rdi    # 0x14c628
callq 0x183c0
movq %rax, %rdi
movq 0x148(%rsp), %rsi
addq $0x68, %rsi
callq 0x1f270
movq %rax, 0x130(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x10a20
movq %rax, %rcx
movq 0x58(%rsp), %rax
addq $0x20, %rcx
movq %rcx, 0x138(%rsp)
testb $0x1, 0xc(%rax)
je 0x1ed2a
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x148(%rsp), %rsi
movq 0x140(%rsp), %rdx
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x148(%rsp), %rax
cmpl $0x1, 0x8(%rax)
je 0x1eced
movq 0x58(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x4c(%rsp)
movq 0x148(%rsp), %rsi
addq $0x10, %rsi
leaq 0xdbd5c(%rip), %rdx     # 0xfa9f2
leaq 0x110(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0xc720
movl 0x4c(%rsp), %edi
movq 0x50(%rsp), %rsi
callq 0x47ce0
jmp 0x1ecb8
leaq 0x110(%rsp), %rdi
callq 0x8728
jmp 0x1eced
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x8728
jmp 0x1f150
movq 0x138(%rsp), %rdi
addq $0x38, %rdi
movq 0x148(%rsp), %rsi
addq $0x8, %rsi
addq $0x4, %rsi
callq 0x1f2a0
movq 0x148(%rsp), %rax
movl 0x88(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x88(%rax)
jmp 0x1f148
movq 0x148(%rsp), %rax
addq $0x88, %rax
movq %rax, 0xf8(%rsp)
movq 0x148(%rsp), %rax
addq $0x8c, %rax
movq %rax, 0xf0(%rsp)
movl $0x0, 0xec(%rsp)
movq 0x148(%rsp), %rax
addq $0x90, %rax
movq %rax, 0xe0(%rsp)
movl $0x0, 0xdc(%rsp)
movslq 0xdc(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x10a40
movq %rax, %rcx
movq 0x40(%rsp), %rax
cmpq %rcx, %rax
jae 0x1ee00
movq 0xf8(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x3c(%rsp)
movq 0xe0(%rsp), %rdi
movslq 0xdc(%rsp), %rsi
callq 0x1f310
movq %rax, %rcx
movl 0x3c(%rsp), %eax
cltd
idivl (%rcx)
cmpl $0x0, %edx
jne 0x1edeb
movl 0xdc(%rsp), %eax
movl %eax, 0xec(%rsp)
jmp 0x1ee00
jmp 0x1eded
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x1ed82
movq 0xf0(%rsp), %rax
movl (%rax), %eax
addl 0xec(%rsp), %eax
movl %eax, 0xec(%rsp)
movslq 0xec(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x10a40
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
jbe 0x1eef7
movq 0x58(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x24(%rsp)
leaq 0xb7(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x8680
movq 0x28(%rsp), %rdx
leaq 0xdbb98(%rip), %rsi     # 0xfaa05
leaq 0xb8(%rsp), %rdi
callq 0xc570
jmp 0x1ee7c
movl 0x24(%rsp), %edi
leaq 0xb8(%rsp), %rsi
callq 0x47ce0
jmp 0x1ee8f
leaq 0xb8(%rsp), %rdi
callq 0x8728
leaq 0xb7(%rsp), %rdi
callq 0x83c0
jmp 0x1f146
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x1eee5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x8728
leaq 0xb7(%rsp), %rdi
callq 0x83c0
jmp 0x1f150
movq 0xf8(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
movq 0xe0(%rsp), %rdi
movl 0xec(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x1f310
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl 0x20(%rsp), %eax
addl (%rcx), %eax
movl %eax, 0xb0(%rsp)
addq $0x18, %rdi
callq 0x1f330
testb $0x1, %al
jne 0x1f004
movq 0x58(%rsp), %rdi
movq 0xf0(%rsp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1f380
movq (%rax), %rdi
movq 0x148(%rsp), %rsi
movq 0x140(%rsp), %rdx
movq (%rdi), %rax
callq *0x18(%rax)
movl $0x1, 0xac(%rsp)
movq 0x58(%rsp), %rdi
movslq 0xac(%rsp), %rax
movq %rax, 0x18(%rsp)
addq $0x18, %rdi
callq 0x1f3a0
movq %rax, %rcx
movq 0x18(%rsp), %rax
cmpq %rcx, %rax
jae 0x1f002
movq 0x58(%rsp), %rdi
movq 0xf0(%rsp), %rax
movl $0x1, (%rax)
addq $0x18, %rdi
movslq 0xac(%rsp), %rsi
callq 0x1f380
movq (%rax), %rdi
movq 0x148(%rsp), %rsi
movq 0x140(%rsp), %rdx
movq (%rdi), %rax
callq *0x18(%rax)
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x1ef8a
jmp 0x1f004
movq 0xf8(%rsp), %rax
movl (%rax), %eax
cmpl 0xb0(%rsp), %eax
jle 0x1f0cc
movq 0x58(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0xc(%rsp)
leaq 0x87(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x8680
movq 0x10(%rsp), %rdx
leaq 0xdb9d0(%rip), %rsi     # 0xfaa15
leaq 0x88(%rsp), %rdi
callq 0xc570
jmp 0x1f054
movl 0xc(%rsp), %edi
leaq 0x88(%rsp), %rsi
callq 0x47ce0
jmp 0x1f067
leaq 0x88(%rsp), %rdi
callq 0x8728
leaq 0x87(%rsp), %rdi
callq 0x83c0
jmp 0x1f0cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x1f0ba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x8728
leaq 0x87(%rsp), %rdi
callq 0x83c0
jmp 0x1f150
movq 0x138(%rsp), %rax
addq $0x38, %rax
movq %rax, (%rsp)
movq 0x138(%rsp), %rdi
addq $0x38, %rdi
callq 0x1f470
movq %rax, 0x70(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x1f4a0
movq (%rsp), %rdi
movl 0xb0(%rsp), %eax
movq 0xf8(%rsp), %rcx
subl (%rcx), %eax
movslq %eax, %rdx
movl $0x0, 0x6c(%rsp)
movq 0x78(%rsp), %rsi
leaq 0x6c(%rsp), %rcx
callq 0x1f3c0
movq %rax, 0x60(%rsp)
movl 0xb0(%rsp), %ecx
movq 0xf8(%rsp), %rax
movl %ecx, (%rax)
jmp 0x1f148
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x108(%rsp), %rdi
callq 0x8670
nopl (%rax)