core/irrt: Change handle_slice_indices to instead take length of object

So that all other array-like datatypes (e.g. ndarray) can also take
advantage of it.
This commit is contained in:
David Mak 2024-05-29 15:07:28 +08:00
parent 2cf79510c2
commit a176c3eb70
3 changed files with 33 additions and 17 deletions

View File

@ -2264,10 +2264,14 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let ty = ctx.get_llvm_type(generator, *ty); let ty = ctx.get_llvm_type(generator, *ty);
if let ExprKind::Slice { lower, upper, step } = &slice.node { if let ExprKind::Slice { lower, upper, step } = &slice.node {
let one = int32.const_int(1, false); let one = int32.const_int(1, false);
let Some((start, end, step)) = let Some((start, end, step)) = handle_slice_indices(
handle_slice_indices(lower, upper, step, ctx, generator, v)? else { lower,
return Ok(None) upper,
}; step,
ctx,
generator,
v.load_size(ctx, None),
)? else { return Ok(None) };
let length = calculate_len_for_slice_range( let length = calculate_len_for_slice_range(
generator, generator,
ctx, ctx,
@ -2289,10 +2293,14 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
step, step,
); );
let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret")); let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret"));
let Some(res_ind) = let Some(res_ind) = handle_slice_indices(
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)? else { &None,
return Ok(None) &None,
}; &None,
ctx,
generator,
res_array_ret.load_size(ctx, None),
)? else { return Ok(None) };
list_slice_assignment( list_slice_assignment(
generator, generator,
ctx, ctx,

View File

@ -175,12 +175,11 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
step: &Option<Box<Expr<Option<Type>>>>, step: &Option<Box<Expr<Option<Type>>>>,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
generator: &mut G, generator: &mut G,
list: ListValue<'ctx>, length: IntValue<'ctx>,
) -> Result<Option<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>)>, String> { ) -> Result<Option<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>)>, String> {
let int32 = ctx.ctx.i32_type(); let int32 = ctx.ctx.i32_type();
let zero = int32.const_zero(); let zero = int32.const_zero();
let one = int32.const_int(1, false); let one = int32.const_int(1, false);
let length = list.load_size(ctx, Some("length"));
let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32").unwrap(); let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32").unwrap();
Ok(Some(match (start, end, step) { Ok(Some(match (start, end, step) {
(s, e, None) => ( (s, e, None) => (

View File

@ -240,10 +240,14 @@ pub fn gen_assign<'ctx, G: CodeGenerator>(
.to_basic_value_enum(ctx, generator, ls.custom.unwrap())? .to_basic_value_enum(ctx, generator, ls.custom.unwrap())?
.into_pointer_value(); .into_pointer_value();
let ls = ListValue::from_ptr_val(ls, llvm_usize, None); let ls = ListValue::from_ptr_val(ls, llvm_usize, None);
let Some((start, end, step)) = let Some((start, end, step)) = handle_slice_indices(
handle_slice_indices(lower, upper, step, ctx, generator, ls)? else { lower,
return Ok(()) upper,
}; step,
ctx,
generator,
ls.load_size(ctx, None),
)? else { return Ok(()) };
let value = value let value = value
.to_basic_value_enum(ctx, generator, target.custom.unwrap())? .to_basic_value_enum(ctx, generator, target.custom.unwrap())?
.into_pointer_value(); .into_pointer_value();
@ -257,9 +261,14 @@ pub fn gen_assign<'ctx, G: CodeGenerator>(
}; };
let ty = ctx.get_llvm_type(generator, ty); let ty = ctx.get_llvm_type(generator, ty);
let Some(src_ind) = handle_slice_indices(&None, &None, &None, ctx, generator, value)? else { let Some(src_ind) = handle_slice_indices(
return Ok(()) &None,
}; &None,
&None,
ctx,
generator,
value.load_size(ctx, None),
)? else { return Ok(()) };
list_slice_assignment(generator, ctx, ty, ls, (start, end, step), value, src_ind); list_slice_assignment(generator, ctx, ty, ls, (start, end, step), value, src_ind);
} }
_ => { _ => {