mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
llvm bindings
map the lowlevel op into LLVM code; it calls zig code, but the zig code does not do anything yet
This commit is contained in:
parent
2e73e47673
commit
baef33fc0c
5 changed files with 122 additions and 2 deletions
|
@ -152,6 +152,10 @@ pub fn listMapWithIndex(list: RocList, transform: Opaque, caller: Caller2, align
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn listMap2(list: RocList, transform: Opaque, caller: Caller1, alignment: usize, old_element_width: usize, new_element_width: usize) callconv(.C) RocList {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn listKeepIf(list: RocList, transform: Opaque, caller: Caller1, alignment: usize, element_width: usize, inc: Inc, dec: Dec) callconv(.C) RocList {
|
pub fn listKeepIf(list: RocList, transform: Opaque, caller: Caller1, alignment: usize, element_width: usize, inc: Inc, dec: Dec) callconv(.C) RocList {
|
||||||
if (list.bytes) |source_ptr| {
|
if (list.bytes) |source_ptr| {
|
||||||
const size = list.len();
|
const size = list.len();
|
||||||
|
|
|
@ -7,6 +7,7 @@ const list = @import("list.zig");
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
exportListFn(list.listMap, "map");
|
exportListFn(list.listMap, "map");
|
||||||
|
exportListFn(list.listMap2, "map2");
|
||||||
exportListFn(list.listMapWithIndex, "map_with_index");
|
exportListFn(list.listMapWithIndex, "map_with_index");
|
||||||
exportListFn(list.listKeepIf, "keep_if");
|
exportListFn(list.listKeepIf, "keep_if");
|
||||||
exportListFn(list.listWalk, "walk");
|
exportListFn(list.listWalk, "walk");
|
||||||
|
|
|
@ -63,6 +63,7 @@ pub const DICT_WALK: &str = "roc_builtins.dict.walk";
|
||||||
pub const SET_FROM_LIST: &str = "roc_builtins.dict.set_from_list";
|
pub const SET_FROM_LIST: &str = "roc_builtins.dict.set_from_list";
|
||||||
|
|
||||||
pub const LIST_MAP: &str = "roc_builtins.list.map";
|
pub const LIST_MAP: &str = "roc_builtins.list.map";
|
||||||
|
pub const LIST_MAP2: &str = "roc_builtins.list.map2";
|
||||||
pub const LIST_MAP_WITH_INDEX: &str = "roc_builtins.list.map_with_index";
|
pub const LIST_MAP_WITH_INDEX: &str = "roc_builtins.list.map_with_index";
|
||||||
pub const LIST_KEEP_IF: &str = "roc_builtins.list.keep_if";
|
pub const LIST_KEEP_IF: &str = "roc_builtins.list.keep_if";
|
||||||
pub const LIST_KEEP_OKS: &str = "roc_builtins.list.keep_oks";
|
pub const LIST_KEEP_OKS: &str = "roc_builtins.list.keep_oks";
|
||||||
|
|
|
@ -7,8 +7,8 @@ use crate::llvm::build_hash::generic_hash;
|
||||||
use crate::llvm::build_list::{
|
use crate::llvm::build_list::{
|
||||||
allocate_list, empty_list, empty_polymorphic_list, list_append, list_concat, list_contains,
|
allocate_list, empty_list, empty_polymorphic_list, list_append, list_concat, list_contains,
|
||||||
list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
|
list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
|
||||||
list_map_with_index, list_prepend, list_repeat, list_reverse, list_set, list_single, list_sum,
|
list_map2, list_map_with_index, list_prepend, list_repeat, list_reverse, list_set, list_single,
|
||||||
list_walk, list_walk_backwards,
|
list_sum, list_walk, list_walk_backwards,
|
||||||
};
|
};
|
||||||
use crate::llvm::build_str::{
|
use crate::llvm::build_str::{
|
||||||
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
|
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
|
||||||
|
@ -3719,6 +3719,33 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
_ => unreachable!("invalid list layout"),
|
_ => unreachable!("invalid list layout"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ListMap2 => {
|
||||||
|
debug_assert_eq!(args.len(), 3);
|
||||||
|
|
||||||
|
let (list1, list1_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
|
let (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||||
|
|
||||||
|
let (func, func_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||||
|
|
||||||
|
match (list1_layout, list2_layout) {
|
||||||
|
(
|
||||||
|
Layout::Builtin(Builtin::List(_, element1_layout)),
|
||||||
|
Layout::Builtin(Builtin::List(_, element2_layout)),
|
||||||
|
) => list_map2(
|
||||||
|
env,
|
||||||
|
layout_ids,
|
||||||
|
func,
|
||||||
|
func_layout,
|
||||||
|
list1,
|
||||||
|
list2,
|
||||||
|
element1_layout,
|
||||||
|
element2_layout,
|
||||||
|
),
|
||||||
|
(Layout::Builtin(Builtin::EmptyList), _)
|
||||||
|
| (_, Layout::Builtin(Builtin::EmptyList)) => empty_list(env),
|
||||||
|
_ => unreachable!("invalid list layout"),
|
||||||
|
}
|
||||||
|
}
|
||||||
ListMapWithIndex => {
|
ListMapWithIndex => {
|
||||||
// List.map : List before, (before -> after) -> List after
|
// List.map : List before, (before -> after) -> List after
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
|
@ -1230,6 +1230,93 @@ fn list_map_generic<'a, 'ctx, 'env>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_map2<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
|
transform: BasicValueEnum<'ctx>,
|
||||||
|
transform_layout: &Layout<'a>,
|
||||||
|
list1: BasicValueEnum<'ctx>,
|
||||||
|
list2: BasicValueEnum<'ctx>,
|
||||||
|
element1_layout: &Layout<'a>,
|
||||||
|
element2_layout: &Layout<'a>,
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
let builder = env.builder;
|
||||||
|
|
||||||
|
let return_layout = match transform_layout {
|
||||||
|
Layout::FunctionPointer(_, ret) => ret,
|
||||||
|
Layout::Closure(_, _, ret) => ret,
|
||||||
|
_ => unreachable!("not a callable layout"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
let list1_i128 = complex_bitcast(
|
||||||
|
env.builder,
|
||||||
|
list1,
|
||||||
|
env.context.i128_type().into(),
|
||||||
|
"to_i128",
|
||||||
|
);
|
||||||
|
|
||||||
|
let list2_i128 = complex_bitcast(
|
||||||
|
env.builder,
|
||||||
|
list2,
|
||||||
|
env.context.i128_type().into(),
|
||||||
|
"to_i128",
|
||||||
|
);
|
||||||
|
|
||||||
|
let transform_ptr = builder.build_alloca(transform.get_type(), "transform_ptr");
|
||||||
|
env.builder.build_store(transform_ptr, transform);
|
||||||
|
|
||||||
|
let argument_layouts = [element1_layout.clone(), element2_layout.clone()];
|
||||||
|
let stepper_caller =
|
||||||
|
build_transform_caller(env, layout_ids, transform_layout, &argument_layouts)
|
||||||
|
.as_global_value()
|
||||||
|
.as_pointer_value();
|
||||||
|
|
||||||
|
let a_width = env
|
||||||
|
.ptr_int()
|
||||||
|
.const_int(element1_layout.stack_size(env.ptr_bytes) as u64, false);
|
||||||
|
|
||||||
|
let b_width = env
|
||||||
|
.ptr_int()
|
||||||
|
.const_int(element2_layout.stack_size(env.ptr_bytes) as u64, false);
|
||||||
|
|
||||||
|
let c_width = env
|
||||||
|
.ptr_int()
|
||||||
|
.const_int(return_layout.stack_size(env.ptr_bytes) as u64, false);
|
||||||
|
|
||||||
|
let alignment = return_layout.alignment_bytes(env.ptr_bytes);
|
||||||
|
let alignment_iv = env.ptr_int().const_int(alignment as u64, false);
|
||||||
|
|
||||||
|
let dec_a = build_dec_wrapper(env, layout_ids, element1_layout);
|
||||||
|
let dec_b = build_dec_wrapper(env, layout_ids, element2_layout);
|
||||||
|
|
||||||
|
let output = call_bitcode_fn(
|
||||||
|
env,
|
||||||
|
&[
|
||||||
|
list1_i128,
|
||||||
|
list2_i128,
|
||||||
|
env.builder
|
||||||
|
.build_bitcast(transform_ptr, u8_ptr, "to_opaque"),
|
||||||
|
stepper_caller.into(),
|
||||||
|
alignment_iv.into(),
|
||||||
|
a_width.into(),
|
||||||
|
b_width.into(),
|
||||||
|
c_width.into(),
|
||||||
|
dec_a.as_global_value().as_pointer_value().into(),
|
||||||
|
dec_b.as_global_value().as_pointer_value().into(),
|
||||||
|
],
|
||||||
|
bitcode::LIST_MAP2,
|
||||||
|
);
|
||||||
|
|
||||||
|
complex_bitcast(
|
||||||
|
env.builder,
|
||||||
|
output,
|
||||||
|
collection(env.context, env.ptr_bytes).into(),
|
||||||
|
"from_i128",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// List.concat : List elem, List elem -> List elem
|
/// List.concat : List elem, List elem -> List elem
|
||||||
pub fn list_concat<'a, 'ctx, 'env>(
|
pub fn list_concat<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue