mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge branch 'trunk' of github.com:rtfeldman/roc into pure-roc-list-walk
This commit is contained in:
commit
94181111be
37 changed files with 259 additions and 1321 deletions
|
@ -9,9 +9,9 @@ use crate::llvm::build_dict::{
|
|||
use crate::llvm::build_hash::generic_hash;
|
||||
use crate::llvm::build_list::{
|
||||
self, allocate_list, empty_polymorphic_list, list_append, list_concat, list_drop_at,
|
||||
list_get_unsafe, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map, list_map2,
|
||||
list_map3, list_map4, list_map_with_index, list_prepend, list_replace_unsafe, list_sort_with,
|
||||
list_sublist, list_swap, list_symbol_to_c_abi, list_to_c_abi, list_with_capacity,
|
||||
list_get_unsafe, list_len, list_map, list_map2, list_map3, list_map4, list_map_with_index,
|
||||
list_prepend, list_replace_unsafe, list_sort_with, list_sublist, list_swap,
|
||||
list_symbol_to_c_abi, list_to_c_abi, list_with_capacity,
|
||||
};
|
||||
use crate::llvm::build_str::{
|
||||
str_from_float, str_from_int, str_from_utf8, str_from_utf8_range, str_split,
|
||||
|
@ -5081,110 +5081,6 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
_ => unreachable!("invalid list layout"),
|
||||
}
|
||||
}
|
||||
ListKeepIf { xs } => {
|
||||
// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
||||
|
||||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match list_layout {
|
||||
Layout::Builtin(Builtin::List(element_layout)) => {
|
||||
let argument_layouts = &[**element_layout];
|
||||
|
||||
let roc_function_call = roc_function_call(
|
||||
env,
|
||||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
result_layout,
|
||||
);
|
||||
|
||||
list_keep_if(env, layout_ids, roc_function_call, list, element_layout)
|
||||
}
|
||||
_ => unreachable!("invalid list layout"),
|
||||
}
|
||||
}
|
||||
ListKeepOks { xs } => {
|
||||
// List.keepOks : List before, (before -> Result after *) -> List after
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
||||
|
||||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(before_layout)),
|
||||
Layout::Builtin(Builtin::List(after_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[**before_layout];
|
||||
|
||||
let roc_function_call = roc_function_call(
|
||||
env,
|
||||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
result_layout,
|
||||
);
|
||||
|
||||
list_keep_oks(
|
||||
env,
|
||||
layout_ids,
|
||||
roc_function_call,
|
||||
&result_layout,
|
||||
list,
|
||||
before_layout,
|
||||
after_layout,
|
||||
)
|
||||
}
|
||||
(other1, other2) => {
|
||||
unreachable!("invalid list layouts:\n{:?}\n{:?}", other1, other2)
|
||||
}
|
||||
}
|
||||
}
|
||||
ListKeepErrs { xs } => {
|
||||
// List.keepErrs : List before, (before -> Result * after) -> List after
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
||||
|
||||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(before_layout)),
|
||||
Layout::Builtin(Builtin::List(after_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[**before_layout];
|
||||
|
||||
let roc_function_call = roc_function_call(
|
||||
env,
|
||||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
result_layout,
|
||||
);
|
||||
|
||||
list_keep_errs(
|
||||
env,
|
||||
layout_ids,
|
||||
roc_function_call,
|
||||
&result_layout,
|
||||
list,
|
||||
before_layout,
|
||||
after_layout,
|
||||
)
|
||||
}
|
||||
(other1, other2) => {
|
||||
unreachable!("invalid list layouts:\n{:?}\n{:?}", other1, other2)
|
||||
}
|
||||
}
|
||||
}
|
||||
ListSortWith { xs } => {
|
||||
// List.sortWith : List a, (a, a -> Ordering) -> List a
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
||||
|
@ -6041,8 +5937,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
set
|
||||
}
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListKeepOks
|
||||
| ListKeepErrs | ListSortWith | DictWalk => {
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListSortWith | DictWalk => {
|
||||
unreachable!("these are higher order, and are handled elsewhere")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#![allow(clippy::too_many_arguments)]
|
||||
use crate::llvm::bitcode::{
|
||||
build_dec_wrapper, build_has_tag_id, build_inc_wrapper, call_list_bitcode_fn,
|
||||
};
|
||||
use crate::llvm::bitcode::{build_dec_wrapper, call_list_bitcode_fn};
|
||||
use crate::llvm::build::{
|
||||
allocate_with_refcount_help, cast_basic_basic, Env, RocFunctionCall, Scope,
|
||||
};
|
||||
|
@ -346,162 +344,6 @@ pub fn list_len<'ctx>(
|
|||
.into_int_value()
|
||||
}
|
||||
|
||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
roc_function_call: RocFunctionCall<'ctx>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let inc_element_fn = build_inc_wrapper(env, layout_ids, element_layout);
|
||||
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, list).into(),
|
||||
roc_function_call.caller.into(),
|
||||
pass_as_opaque(env, roc_function_call.data),
|
||||
roc_function_call.inc_n_data.into(),
|
||||
roc_function_call.data_is_owned.into(),
|
||||
env.alignment_intvalue(element_layout),
|
||||
layout_width(env, element_layout),
|
||||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_KEEP_IF,
|
||||
)
|
||||
}
|
||||
|
||||
fn empty_list<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx> {
|
||||
let struct_type = super::convert::zig_list_type(env);
|
||||
|
||||
// The pointer should be null (aka zero) and the length should be zero,
|
||||
// so the whole struct should be a const_zero
|
||||
BasicValueEnum::StructValue(struct_type.const_zero())
|
||||
}
|
||||
|
||||
fn has_tag_id_helper<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
has_tag_id: FunctionValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
let u8_t = env.context.i8_type();
|
||||
let u16_t = env.context.i16_type();
|
||||
|
||||
let u8_ptr_t = u8_t.ptr_type(AddressSpace::Generic);
|
||||
|
||||
let struct_t = env
|
||||
.context
|
||||
.struct_type(&[u8_t.into(), env.ptr_int().into()], false);
|
||||
|
||||
let has_tag_id_type = struct_t
|
||||
.fn_type(&[u16_t.into(), u8_ptr_t.into()], false)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
|
||||
env.builder.build_pointer_cast(
|
||||
has_tag_id.as_global_value().as_pointer_value(),
|
||||
has_tag_id_type,
|
||||
"has_tag_id_cast",
|
||||
)
|
||||
}
|
||||
|
||||
/// List.keepOks : List before, (before -> Result after *) -> List after
|
||||
pub fn list_keep_oks<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
roc_function_call: RocFunctionCall<'ctx>,
|
||||
// Layout of the `Result after *`
|
||||
result_layout: &Layout<'a>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
before_layout: &Layout<'a>,
|
||||
after_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let dec_result_fn = build_dec_wrapper(env, layout_ids, result_layout);
|
||||
|
||||
let function = env
|
||||
.builder
|
||||
.get_insert_block()
|
||||
.unwrap()
|
||||
.get_parent()
|
||||
.unwrap();
|
||||
|
||||
let has_tag_id = match result_layout {
|
||||
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// a `Result whatever []`, so there is nothing to keep
|
||||
return empty_list(env);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, list).into(),
|
||||
roc_function_call.caller.into(),
|
||||
pass_as_opaque(env, roc_function_call.data),
|
||||
roc_function_call.inc_n_data.into(),
|
||||
roc_function_call.data_is_owned.into(),
|
||||
env.alignment_intvalue(before_layout),
|
||||
layout_width(env, before_layout),
|
||||
layout_width(env, result_layout),
|
||||
layout_width(env, after_layout),
|
||||
has_tag_id_helper(env, has_tag_id).into(),
|
||||
dec_result_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_KEEP_OKS,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.keepErrs : List before, (before -> Result * after) -> List after
|
||||
pub fn list_keep_errs<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
roc_function_call: RocFunctionCall<'ctx>,
|
||||
// Layout of the `Result * err`
|
||||
result_layout: &Layout<'a>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
before_layout: &Layout<'a>,
|
||||
after_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let dec_result_fn = build_dec_wrapper(env, layout_ids, result_layout);
|
||||
|
||||
let function = env
|
||||
.builder
|
||||
.get_insert_block()
|
||||
.unwrap()
|
||||
.get_parent()
|
||||
.unwrap();
|
||||
|
||||
let has_tag_id = match result_layout {
|
||||
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// a `Result whatever []`, so there is nothing to keep
|
||||
return empty_list(env);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, list).into(),
|
||||
roc_function_call.caller.into(),
|
||||
pass_as_opaque(env, roc_function_call.data),
|
||||
roc_function_call.inc_n_data.into(),
|
||||
roc_function_call.data_is_owned.into(),
|
||||
env.alignment_intvalue(before_layout),
|
||||
layout_width(env, before_layout),
|
||||
layout_width(env, result_layout),
|
||||
layout_width(env, after_layout),
|
||||
has_tag_id_helper(env, has_tag_id).into(),
|
||||
dec_result_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_KEEP_ERRS,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.sortWith : List a, (a, a -> Ordering) -> List a
|
||||
pub fn list_sort_with<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue