mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
destruct record at high level
This commit is contained in:
parent
98d2c57edf
commit
2e073d57ea
5 changed files with 42 additions and 18 deletions
|
@ -893,11 +893,10 @@ pub fn listSublist(
|
||||||
list: RocList,
|
list: RocList,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
element_width: usize,
|
element_width: usize,
|
||||||
rec: extern struct { len: usize, start: usize },
|
start: usize,
|
||||||
|
len: usize,
|
||||||
dec: Dec,
|
dec: Dec,
|
||||||
) callconv(.C) RocList {
|
) callconv(.C) RocList {
|
||||||
const start = rec.start;
|
|
||||||
const len = rec.len;
|
|
||||||
if (list.bytes) |source_ptr| {
|
if (list.bytes) |source_ptr| {
|
||||||
const size = list.len();
|
const size = list.len();
|
||||||
|
|
||||||
|
@ -922,9 +921,9 @@ pub fn listSublist(
|
||||||
utils.decref(list.bytes, size * element_width, alignment);
|
utils.decref(list.bytes, size * element_width, alignment);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
} else {
|
}
|
||||||
return RocList.empty();
|
|
||||||
}
|
return RocList.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listTakeLast(
|
pub fn listTakeLast(
|
||||||
|
|
|
@ -2070,9 +2070,32 @@ fn list_sublist(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let sym_list = Symbol::ARG_1;
|
let sym_list = Symbol::ARG_1;
|
||||||
let sym_rec = Symbol::ARG_2;
|
let sym_rec = Symbol::ARG_2;
|
||||||
|
|
||||||
|
let start_var = var_store.fresh();
|
||||||
|
let len_var = var_store.fresh();
|
||||||
|
|
||||||
|
let get_start = Access {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: var_store.fresh(),
|
||||||
|
field_var: var_store.fresh(),
|
||||||
|
loc_expr: Box::new(no_region(Var(sym_rec))),
|
||||||
|
field: "start".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let get_len = Access {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: var_store.fresh(),
|
||||||
|
field_var: var_store.fresh(),
|
||||||
|
loc_expr: Box::new(no_region(Var(sym_rec))),
|
||||||
|
field: "len".into(),
|
||||||
|
};
|
||||||
|
|
||||||
let body = RunLowLevel {
|
let body = RunLowLevel {
|
||||||
op: LowLevel::ListSublist,
|
op: LowLevel::ListSublist,
|
||||||
args: vec![(list_var, Var(sym_list)), (rec_var, Var(sym_rec))],
|
args: vec![
|
||||||
|
(list_var, Var(sym_list)),
|
||||||
|
(start_var, get_start),
|
||||||
|
(len_var, get_len),
|
||||||
|
],
|
||||||
ret_var: list_var,
|
ret_var: list_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5212,12 +5212,16 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
ListSublist => {
|
ListSublist => {
|
||||||
// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
|
// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
|
||||||
debug_assert_eq!(args.len(), 2);
|
//
|
||||||
|
// As a low-level, record is destructed
|
||||||
|
// List.sublist : List elem, start : Nat, len : Nat -> List elem
|
||||||
|
debug_assert_eq!(args.len(), 3);
|
||||||
|
|
||||||
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
let original_wrapper = list.into_struct_value();
|
let original_wrapper = list.into_struct_value();
|
||||||
|
|
||||||
let rec = load_symbol(scope, &args[1]);
|
let start = load_symbol(scope, &args[1]);
|
||||||
|
let len = load_symbol(scope, &args[2]);
|
||||||
|
|
||||||
match list_layout {
|
match list_layout {
|
||||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||||
|
@ -5225,7 +5229,8 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
original_wrapper,
|
original_wrapper,
|
||||||
rec.into_struct_value(),
|
start.into_int_value(),
|
||||||
|
len.into_int_value(),
|
||||||
element_layout,
|
element_layout,
|
||||||
),
|
),
|
||||||
_ => unreachable!("Invalid layout {:?} in List.sublist", list_layout),
|
_ => unreachable!("Invalid layout {:?} in List.sublist", list_layout),
|
||||||
|
|
|
@ -343,7 +343,8 @@ pub fn list_sublist<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
original_wrapper: StructValue<'ctx>,
|
original_wrapper: StructValue<'ctx>,
|
||||||
len_and_start: StructValue<'ctx>,
|
start: IntValue<'ctx>,
|
||||||
|
len: IntValue<'ctx>,
|
||||||
element_layout: &Layout<'a>,
|
element_layout: &Layout<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
|
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
|
||||||
|
@ -353,12 +354,8 @@ pub fn list_sublist<'a, 'ctx, 'env>(
|
||||||
pass_list_cc(env, original_wrapper.into()),
|
pass_list_cc(env, original_wrapper.into()),
|
||||||
env.alignment_intvalue(element_layout),
|
env.alignment_intvalue(element_layout),
|
||||||
layout_width(env, element_layout),
|
layout_width(env, element_layout),
|
||||||
complex_bitcast(
|
start.into(),
|
||||||
env.builder,
|
len.into(),
|
||||||
len_and_start.into(),
|
|
||||||
env.str_list_c_abi().into(),
|
|
||||||
"to_i128",
|
|
||||||
),
|
|
||||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||||
],
|
],
|
||||||
bitcode::LIST_SUBLIST,
|
bitcode::LIST_SUBLIST,
|
||||||
|
|
|
@ -968,7 +968,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
ListAppend => arena.alloc_slice_copy(&[owned, owned]),
|
ListAppend => arena.alloc_slice_copy(&[owned, owned]),
|
||||||
ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]),
|
ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
ListTakeLast => arena.alloc_slice_copy(&[owned, irrelevant]),
|
ListTakeLast => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
ListSublist => arena.alloc_slice_copy(&[owned, irrelevant]),
|
ListSublist => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
||||||
ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]),
|
ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]),
|
ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue