def gen_return(self, builder: 'IRBuilder', value: Value, line: int) -> None: if self.ret_reg is None: self.ret_reg = Register(builder.ret_types[-1]) builder.add(Assign(self.ret_reg, value)) builder.add(Goto(self.target))
def test_valid_goto(self) -> None: block_1 = self.basic_block([Return(value=NONE_VALUE)]) block_2 = self.basic_block([Goto(label=block_1)]) fn = FuncIR( decl=self.func_decl(name="func_1"), arg_regs=[], blocks=[block_1, block_2], ) assert_no_errors(fn)
def test_invalid_goto(self) -> None: block_1 = self.basic_block([Return(value=NONE_VALUE)]) goto = Goto(label=block_1) block_2 = self.basic_block([goto]) fn = FuncIR( decl=self.func_decl(name="func_1"), arg_regs=[], # block_1 omitted blocks=[block_2], ) assert_has_error( fn, FnError(source=goto, desc="Invalid control operation target: 1"))
def add_block(decs: Decs, incs: Incs, cache: BlockCache, blocks: List[BasicBlock], label: BasicBlock) -> BasicBlock: if not decs and not incs: return label # TODO: be able to share *partial* results if (label, decs, incs) in cache: return cache[label, decs, incs] block = BasicBlock() blocks.append(block) block.ops.extend(DecRef(reg, is_xdec=xdec) for reg, xdec in decs) block.ops.extend(IncRef(reg) for reg in incs) block.ops.append(Goto(label)) cache[label, decs, incs] = block return block
def test_pprint(self) -> None: block_1 = self.basic_block([Return(value=NONE_VALUE)]) goto = Goto(label=block_1) block_2 = self.basic_block([goto]) fn = FuncIR( decl=self.func_decl(name="func_1"), arg_regs=[], # block_1 omitted blocks=[block_2], ) errors = [(goto, "Invalid control operation target: 1")] formatted = format_func(fn, errors) assert formatted == [ "def func_1():", "L0:", " goto L1", " ERR: Invalid control operation target: 1", ]
def goto(self, target: BasicBlock) -> None: """Add goto to a basic block.""" if not self.blocks[-1].terminated: self.add(Goto(target))
def test_goto(self) -> None: self.assert_emit(Goto(BasicBlock(2)), "goto CPyL2;")
def gen_continue(self, builder: 'IRBuilder', line: int) -> None: builder.add(Goto(self.continue_block))
def gen_break(self, builder: 'IRBuilder', line: int) -> None: builder.add(Goto(self.break_block))
def test_goto_next_block(self) -> None: next_block = BasicBlock(2) self.assert_emit(Goto(next_block), "", next_block=next_block)
def create_switch_for_generator_class(builder: IRBuilder) -> None: builder.add(Goto(builder.fn_info.generator_class.switch_block)) block = BasicBlock() builder.fn_info.generator_class.continuation_blocks.append(block) builder.activate_block(block)
def goto(self, target: BasicBlock) -> None: if not self.blocks[-1].terminated: self.add(Goto(target))