def gen_condition(self) -> None: builder = self.builder line = self.line # Add loop condition check. cmp = '<' if self.step > 0 else '>' comparison = builder.binary_op(builder.read(self.index_target, line), builder.read(self.end_target, line), cmp, line) builder.add_bool_branch(comparison, self.body_block, self.loop_exit)
def gen_condition(self) -> None: builder = self.builder line = self.line if self.reverse: # If we are iterating in reverse order, we obviously need # to check that the index is still positive. Somewhat less # obviously we still need to check against the length, # since it could shrink out from under us. comparison = builder.binary_op(builder.read(self.index_target, line), builder.add(LoadInt(0)), '>=', line) second_check = BasicBlock() builder.add_bool_branch(comparison, second_check, self.loop_exit) builder.activate_block(second_check) # For compatibility with python semantics we recalculate the length # at every iteration. len_reg = self.load_len() comparison = builder.binary_op(builder.read(self.index_target, line), len_reg, '<', line) builder.add_bool_branch(comparison, self.body_block, self.loop_exit)
def init(self, expr_reg: Value, target_type: RType, reverse: bool) -> None: builder = self.builder self.reverse = reverse # Define target to contain the expression, along with the index that will be used # for the for-loop. If we are inside of a generator function, spill these into the # environment class. self.expr_target = builder.maybe_spill(expr_reg) if not reverse: index_reg = builder.add(LoadInt(0)) else: index_reg = builder.binary_op(self.load_len(), builder.add(LoadInt(1)), '-', self.line) self.index_target = builder.maybe_spill_assignable(index_reg) self.target_type = target_type
def gen_step(self) -> None: builder = self.builder line = self.line # Increment index register. If the range is known to fit in short ints, use # short ints. if (is_short_int_rprimitive(self.start_reg.type) and is_short_int_rprimitive(self.end_reg.type)): new_val = builder.primitive_op( unsafe_short_add, [builder.read(self.index_reg, line), builder.add(LoadInt(self.step))], line) else: new_val = builder.binary_op( builder.read(self.index_reg, line), builder.add(LoadInt(self.step)), '+', line) builder.assign(self.index_reg, new_val, line) builder.assign(self.index_target, new_val, line)