def __init__(self, symtable, threeAC):
        self.symtable = symtable
        self.code = threeAC.code

        self.unused_register = unused_register_list.copy()

        # 基本块
        self.basic_blocks = []
        # 接下来使用
        self.next_use = []
        # 每个基本块对应一个label名
        self.block_label = {}
        # {(startline, endline): label_name}

        # symbol 被存在哪些寄存器里
        self.symbol_register = {}
    def handle_return(self, codeline):

        line_num, _, lhs, _, _ = codeline

        print("[This line]: ", codeline)

        # 寄存器存回内存
        for op in self.symbol_register:
            reg = self.symbol_register[op]
            self.asmcode.append(self.store_mem(op, reg, self.scopeStack))
        self.symbol_register.clear()
        self.allocReg.unused_register = unused_register_list.copy()

        topDeleted = self.scopeStack.pop().lower()

        # TODO 恢复参数 (引用传递
        # : 将返回值放到v0

        if lhs == None:
            pass
        else:
            self.asmcode.append(
                'lw $v0, -%d($fp)' %
                self.symtable[topDeleted].get("_return").offset)

        # 指针
        self.asmcode.append('addi $sp, $sp, %d' %
                            (self.symtable[topDeleted].width + 76))
        self.asmcode.append('lw $fp, 72($fp)')

        #  恢复寄存器
        for index in range(8, 24):
            # SW R1, 0(R2)
            # FIXME:
            self.asmcode.append("lw $%s, %d($sp)" % (index, -12 -
                                                     (index - 8) * 4))

        # 恢复返回地址 ra
        self.asmcode.append('move $t8, $ra')

        # ra'
        self.asmcode.append('lw $ra, -8($sp)')

        # FIXME: 需要填好返回值,然后放回ra,最后返还stack上分配的内存,返回

        self.asmcode.append('jr $t8')  # 这个地方不是跳转到ra,因为ra已经恢复成跳转之后的返回地址了
    def tacToasm(self):
        for i in range(len(self.allocReg.basic_blocks)):
            start, end = self.allocReg.basic_blocks[i]
            block_code = self.code[start:end + 1]

            for codeline in block_code:
                self.asmcode.append('\n# %s' %
                                    ' '.join(str(code) for code in codeline))
                line_num, operation, lhs, op1, op2 = codeline
                if hasattr(lhs, 'reference') and lhs.reference or \
                        hasattr(op1, 'reference') and op1.reference or \
                        hasattr(op2, 'reference') and op2.reference:
                    for op in self.symbol_register:
                        reg = self.symbol_register[op]
                        self.asmcode.append(
                            self.store_mem(op, reg, self.scopeStack))
                    self.symbol_register.clear()
                    self.allocReg.unused_register = unused_register_list.copy()

                if operation in binary_list:
                    self.handle_binary(codeline)
                elif operation in ['>', '<', '>=', '<=', '=']:
                    self.handle_cmp(codeline)
                elif operation in ['BNE', 'BEQ', 'JMP']:
                    if codeline == block_code[-1]:
                        for op in self.symbol_register:
                            reg = self.symbol_register[op]
                            self.asmcode.append(
                                self.store_mem(op, reg, self.scopeStack))
                        self.handle_jmp(codeline)
                        self.symbol_register.clear()
                        self.allocReg.unused_register = unused_register_list.copy(
                        )
                    else:
                        self.handle_jmp(codeline)
                elif operation == 'LABEL':
                    self.handle_label(codeline)
                elif operation == 'CALL':
                    self.handle_call(codeline)
                elif operation == 'PARAM':
                    self.handle_params(codeline)
                elif operation == 'REFER':
                    self.handle_refers(codeline)
                elif operation == 'RETURN':
                    self.handle_return(codeline)
                elif operation == 'INPUT':
                    self.handle_input(codeline)
                elif operation in ['PRINT', 'PRINTLN']:
                    self.handle_print(codeline)
                elif operation == 'LOADREF':
                    self.handle_loadref(codeline)
                elif operation == 'STOREREF':
                    self.handle_storeref(codeline)

                if hasattr(lhs, 'reference') and lhs.reference or \
                        hasattr(op1, 'reference') and op1.reference or \
                        hasattr(op2, 'reference') and op2.reference:
                    for op in self.symbol_register:
                        reg = self.symbol_register[op]
                        self.asmcode.append(
                            self.store_mem(op, reg, self.scopeStack))
                    self.symbol_register.clear()
                    self.allocReg.unused_register = unused_register_list.copy()

            if block_code[-1][1] not in ['JMP', 'BNE', 'BEQ']:
                for op in self.symbol_register:
                    reg = self.symbol_register[op]
                    self.asmcode.append(
                        self.store_mem(op, reg, self.scopeStack))
                self.symbol_register.clear()
                self.allocReg.unused_register = unused_register_list.copy()
    def handle_call(self, codeline):

        print("[This line]: ", codeline)

        for op in self.symbol_register.keys():
            reg = self.symbol_register[op]
            self.asmcode.append(self.store_mem(op, reg, self.scopeStack))

        self.symbol_register.clear()
        self.allocReg.unused_register = unused_register_list.copy()

        self.paraCounter = 0

        # TODO: 访问链:判断两个scope之间的关系
        self.scopeStack[-1]
        print("****")
        print(codeline[4])
        print(self.scopeStack[-1])
        print('.'.join(self.scopeStack[-1].split('.')[:-1]))
        # if codeline[4] == self.scopeStack[-1]:
        #     # 访问控制 = fp
        #     pass

        if codeline[4] == '.'.join(self.scopeStack[-1].split('.')[:-1]):
            # 访问控制 = 当前活动访问控制
            # sp - 4 =
            self.asmcode.append("# = parent's")
            self.asmcode.append('lw $t8, 76($fp)')
            self.asmcode.append('sw $t8, 0($sp)')
        else:
            self.asmcode.append('# = fp')
            self.asmcode.append('sw $fp, 0($sp)')
            # 访问控制 = fp

        # 控制链
        self.asmcode.append('sw $fp, -4($sp)')

        # ra
        self.asmcode.append('sw $ra, -8($sp)')
        # sw  $ra -8($sp)

        # reg
        for index in range(8, 24):
            # SW R1, 0(R2)
            # FIXME:
            self.asmcode.append("sw $%s, %d($sp)" % (index, -12 -
                                                     (index - 8) * 4))

        # param 参数中处理

        #
        self.asmcode.append('addi $fp $sp -76')
        scope_width = self.symtable['%s.%s' %
                                    (codeline[4], codeline[3].lower())].width
        self.asmcode.append('addi $sp $sp %d' % -(scope_width + 76))

        # jal
        # self.asmcode.append("jal %s"%self.symtable[codeline[3]])
        self.asmcode.append("jal %s" % codeline[3])

        # 将返回值从 $v0 中取出
        if codeline[2]:
            block_index = self.allocReg.line_block(codeline[0])
            reg_lhs = self.handle_term(codeline[2], block_index, codeline[0])

            self.asmcode.append("move, {}, $v0".format(reg_lhs))