mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +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
|
@ -594,69 +594,6 @@ fn build_tuple_type(
|
||||||
builder.add_tuple_type(&field_types)
|
builder.add_tuple_type(&field_types)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
enum KeepResult {
|
|
||||||
Errs = ERR_TAG_ID,
|
|
||||||
Oks = OK_TAG_ID,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KeepResult {
|
|
||||||
fn invert(&self) -> Self {
|
|
||||||
match self {
|
|
||||||
KeepResult::Errs => KeepResult::Oks,
|
|
||||||
KeepResult::Oks => KeepResult::Errs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
enum ResultRepr<'a> {
|
|
||||||
/// This is basically a `Result * whatever` or `Result [] whatever` (in keepOks, arguments flipped for keepErrs).
|
|
||||||
/// Such a `Result` gets a `Bool` layout at currently. We model the `*` or `[]` as a unit
|
|
||||||
/// (empty tuple) in morphic, otherwise we run into trouble when we need to crate a value of
|
|
||||||
/// type void
|
|
||||||
ResultStarStar,
|
|
||||||
ResultConcrete {
|
|
||||||
err: Layout<'a>,
|
|
||||||
ok: Layout<'a>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ResultRepr<'a> {
|
|
||||||
fn from_layout(layout: &Layout<'a>) -> Self {
|
|
||||||
match layout {
|
|
||||||
Layout::Union(UnionLayout::NonRecursive(tags)) => ResultRepr::ResultConcrete {
|
|
||||||
err: tags[ERR_TAG_ID as usize][0],
|
|
||||||
ok: tags[OK_TAG_ID as usize][0],
|
|
||||||
},
|
|
||||||
Layout::Builtin(Builtin::Bool) => ResultRepr::ResultStarStar,
|
|
||||||
other => unreachable!("unexpected layout: {:?}", other),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unwrap(
|
|
||||||
&self,
|
|
||||||
builder: &mut FuncDefBuilder,
|
|
||||||
block: BlockId,
|
|
||||||
err_or_ok: ValueId,
|
|
||||||
keep_tag_id: u32,
|
|
||||||
) -> Result<ValueId> {
|
|
||||||
match self {
|
|
||||||
ResultRepr::ResultConcrete { .. } => {
|
|
||||||
let unwrapped = builder.add_unwrap_union(block, err_or_ok, keep_tag_id)?;
|
|
||||||
|
|
||||||
builder.add_get_tuple_field(block, unwrapped, 0)
|
|
||||||
}
|
|
||||||
ResultRepr::ResultStarStar => {
|
|
||||||
// Void/EmptyTagUnion is represented as a unit value in morphic
|
|
||||||
// using `union {}` runs into trouble where we have to crate a value of that type
|
|
||||||
builder.add_make_tuple(block, &[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_loop(
|
fn add_loop(
|
||||||
builder: &mut FuncDefBuilder,
|
builder: &mut FuncDefBuilder,
|
||||||
block: BlockId,
|
block: BlockId,
|
||||||
|
@ -977,120 +914,6 @@ fn call_spec(
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
|
||||||
add_loop(builder, block, state_type, init_state, loop_body)
|
|
||||||
}
|
|
||||||
ListKeepIf { xs } => {
|
|
||||||
let list = env.symbols[xs];
|
|
||||||
|
|
||||||
let loop_body = |builder: &mut FuncDefBuilder, block, state| {
|
|
||||||
let bag = builder.add_get_tuple_field(block, state, LIST_BAG_INDEX)?;
|
|
||||||
let cell = builder.add_get_tuple_field(block, state, LIST_CELL_INDEX)?;
|
|
||||||
|
|
||||||
let element = builder.add_bag_get(block, bag)?;
|
|
||||||
|
|
||||||
let _ = call_function!(builder, block, [element]);
|
|
||||||
|
|
||||||
// NOTE: we assume the element is not kept
|
|
||||||
builder.add_update(block, update_mode_var, cell)?;
|
|
||||||
|
|
||||||
let removed = builder.add_bag_remove(block, bag)?;
|
|
||||||
|
|
||||||
// decrement the removed element
|
|
||||||
let removed_element = builder.add_get_tuple_field(block, removed, 1)?;
|
|
||||||
builder.add_recursive_touch(block, removed_element)?;
|
|
||||||
|
|
||||||
let new_bag = builder.add_get_tuple_field(block, removed, 0)?;
|
|
||||||
|
|
||||||
with_new_heap_cell(builder, block, new_bag)
|
|
||||||
};
|
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(&argument_layouts[0]));
|
|
||||||
let state_type =
|
|
||||||
layout_spec(builder, &state_layout, &WhenRecursive::Unreachable)?;
|
|
||||||
let init_state = list;
|
|
||||||
|
|
||||||
add_loop(builder, block, state_type, init_state, loop_body)
|
|
||||||
}
|
|
||||||
ListKeepOks { xs } | ListKeepErrs { xs } => {
|
|
||||||
let list = env.symbols[xs];
|
|
||||||
|
|
||||||
let keep_result = match op {
|
|
||||||
ListKeepOks { .. } => KeepResult::Oks,
|
|
||||||
ListKeepErrs { .. } => KeepResult::Errs,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let result_repr = ResultRepr::from_layout(return_layout);
|
|
||||||
|
|
||||||
let output_element_layout = match (keep_result, result_repr) {
|
|
||||||
(KeepResult::Errs, ResultRepr::ResultConcrete { err, .. }) => err,
|
|
||||||
(KeepResult::Oks, ResultRepr::ResultConcrete { ok, .. }) => ok,
|
|
||||||
(_, ResultRepr::ResultStarStar) => {
|
|
||||||
// we represent this case as Unit, while Void is maybe more natural
|
|
||||||
// but using Void we'd need to crate values of type Void, which is not
|
|
||||||
// possible
|
|
||||||
Layout::UNIT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let loop_body = |builder: &mut FuncDefBuilder, block, state| {
|
|
||||||
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
|
||||||
|
|
||||||
let element = builder.add_bag_get(block, bag)?;
|
|
||||||
|
|
||||||
let err_or_ok = call_function!(builder, block, [element]);
|
|
||||||
|
|
||||||
let kept_branch = builder.add_block();
|
|
||||||
let not_kept_branch = builder.add_block();
|
|
||||||
|
|
||||||
let element_kept = {
|
|
||||||
let block = kept_branch;
|
|
||||||
|
|
||||||
// a Result can be represented as a Int1
|
|
||||||
let new_element = result_repr.unwrap(
|
|
||||||
builder,
|
|
||||||
block,
|
|
||||||
err_or_ok,
|
|
||||||
keep_result as u32,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
list_append(builder, block, update_mode_var, state, new_element)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let element_not_kept = {
|
|
||||||
let block = not_kept_branch;
|
|
||||||
|
|
||||||
// a Result can be represented as a Int1
|
|
||||||
let dropped_element = result_repr.unwrap(
|
|
||||||
builder,
|
|
||||||
block,
|
|
||||||
err_or_ok,
|
|
||||||
keep_result.invert() as u32,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// decrement the element we will not keep
|
|
||||||
builder.add_recursive_touch(block, dropped_element)?;
|
|
||||||
|
|
||||||
state
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.add_choice(
|
|
||||||
block,
|
|
||||||
&[
|
|
||||||
BlockExpr(not_kept_branch, element_not_kept),
|
|
||||||
BlockExpr(kept_branch, element_kept),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let output_element_type =
|
|
||||||
layout_spec(builder, &output_element_layout, &WhenRecursive::Unreachable)?;
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(&output_element_layout));
|
|
||||||
let state_type =
|
|
||||||
layout_spec(builder, &state_layout, &WhenRecursive::Unreachable)?;
|
|
||||||
|
|
||||||
add_loop(builder, block, state_type, init_state, loop_body)
|
add_loop(builder, block, state_type, init_state, loop_body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1708,9 +1531,6 @@ fn static_list_type<TC: TypeContext>(builder: &mut TC) -> Result<TypeId> {
|
||||||
builder.add_tuple_type(&[cell, bag])
|
builder.add_tuple_type(&[cell, bag])
|
||||||
}
|
}
|
||||||
|
|
||||||
const OK_TAG_ID: u32 = 1;
|
|
||||||
const ERR_TAG_ID: u32 = 0;
|
|
||||||
|
|
||||||
const LIST_CELL_INDEX: u32 = 0;
|
const LIST_CELL_INDEX: u32 = 0;
|
||||||
const LIST_BAG_INDEX: u32 = 1;
|
const LIST_BAG_INDEX: u32 = 1;
|
||||||
|
|
||||||
|
|
|
@ -384,179 +384,6 @@ pub fn listMap4(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listKeepIf(
|
|
||||||
list: RocList,
|
|
||||||
caller: Caller1,
|
|
||||||
data: Opaque,
|
|
||||||
inc_n_data: IncN,
|
|
||||||
data_is_owned: bool,
|
|
||||||
alignment: u32,
|
|
||||||
element_width: usize,
|
|
||||||
inc: Inc,
|
|
||||||
dec: Dec,
|
|
||||||
) callconv(.C) RocList {
|
|
||||||
if (list.bytes) |source_ptr| {
|
|
||||||
const size = list.len();
|
|
||||||
var i: usize = 0;
|
|
||||||
var output = RocList.allocate(alignment, list.len(), list.len() * element_width);
|
|
||||||
const target_ptr = output.bytes orelse unreachable;
|
|
||||||
|
|
||||||
if (data_is_owned) {
|
|
||||||
inc_n_data(data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var kept: usize = 0;
|
|
||||||
while (i < size) : (i += 1) {
|
|
||||||
var keep = false;
|
|
||||||
const element = source_ptr + (i * element_width);
|
|
||||||
inc(element);
|
|
||||||
caller(data, element, @ptrCast(?[*]u8, &keep));
|
|
||||||
|
|
||||||
if (keep) {
|
|
||||||
@memcpy(target_ptr + (kept * element_width), element, element_width);
|
|
||||||
|
|
||||||
kept += 1;
|
|
||||||
} else {
|
|
||||||
dec(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kept == 0) {
|
|
||||||
// if the output is empty, deallocate the space we made for the result
|
|
||||||
utils.decref(output.bytes, size * element_width, alignment);
|
|
||||||
return RocList.empty();
|
|
||||||
} else {
|
|
||||||
output.length = kept;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return RocList.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listKeepOks(
|
|
||||||
list: RocList,
|
|
||||||
caller: Caller1,
|
|
||||||
data: Opaque,
|
|
||||||
inc_n_data: IncN,
|
|
||||||
data_is_owned: bool,
|
|
||||||
alignment: u32,
|
|
||||||
before_width: usize,
|
|
||||||
result_width: usize,
|
|
||||||
after_width: usize,
|
|
||||||
has_tag_id: HasTagId,
|
|
||||||
dec_result: Dec,
|
|
||||||
) callconv(.C) RocList {
|
|
||||||
const good_constructor: u16 = 1;
|
|
||||||
|
|
||||||
return listKeepResult(
|
|
||||||
list,
|
|
||||||
good_constructor,
|
|
||||||
caller,
|
|
||||||
data,
|
|
||||||
inc_n_data,
|
|
||||||
data_is_owned,
|
|
||||||
alignment,
|
|
||||||
before_width,
|
|
||||||
result_width,
|
|
||||||
after_width,
|
|
||||||
has_tag_id,
|
|
||||||
dec_result,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listKeepErrs(
|
|
||||||
list: RocList,
|
|
||||||
caller: Caller1,
|
|
||||||
data: Opaque,
|
|
||||||
inc_n_data: IncN,
|
|
||||||
data_is_owned: bool,
|
|
||||||
alignment: u32,
|
|
||||||
before_width: usize,
|
|
||||||
result_width: usize,
|
|
||||||
after_width: usize,
|
|
||||||
has_tag_id: HasTagId,
|
|
||||||
dec_result: Dec,
|
|
||||||
) callconv(.C) RocList {
|
|
||||||
const good_constructor: u16 = 0;
|
|
||||||
|
|
||||||
return listKeepResult(
|
|
||||||
list,
|
|
||||||
good_constructor,
|
|
||||||
caller,
|
|
||||||
data,
|
|
||||||
inc_n_data,
|
|
||||||
data_is_owned,
|
|
||||||
alignment,
|
|
||||||
before_width,
|
|
||||||
result_width,
|
|
||||||
after_width,
|
|
||||||
has_tag_id,
|
|
||||||
dec_result,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listKeepResult(
|
|
||||||
list: RocList,
|
|
||||||
good_constructor: u16,
|
|
||||||
caller: Caller1,
|
|
||||||
data: Opaque,
|
|
||||||
inc_n_data: IncN,
|
|
||||||
data_is_owned: bool,
|
|
||||||
alignment: u32,
|
|
||||||
before_width: usize,
|
|
||||||
result_width: usize,
|
|
||||||
after_width: usize,
|
|
||||||
has_tag_id: HasTagId,
|
|
||||||
dec_result: Dec,
|
|
||||||
) RocList {
|
|
||||||
if (list.bytes) |source_ptr| {
|
|
||||||
const size = list.len();
|
|
||||||
var i: usize = 0;
|
|
||||||
var output = RocList.allocate(alignment, list.len(), list.len() * after_width);
|
|
||||||
const target_ptr = output.bytes orelse unreachable;
|
|
||||||
|
|
||||||
// TODO handle alloc failing!
|
|
||||||
var temporary = utils.alloc(result_width, alignment) orelse unreachable;
|
|
||||||
|
|
||||||
if (data_is_owned) {
|
|
||||||
inc_n_data(data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var kept: usize = 0;
|
|
||||||
while (i < size) : (i += 1) {
|
|
||||||
const before_element = source_ptr + (i * before_width);
|
|
||||||
caller(data, before_element, temporary);
|
|
||||||
|
|
||||||
// a record { matched: bool, data: ?[*]u8 }
|
|
||||||
// for now, that data pointer is just the input `temporary` pointer
|
|
||||||
// this will change in the future to only return a pointer to the
|
|
||||||
// payload of the tag
|
|
||||||
const answer = has_tag_id(good_constructor, temporary);
|
|
||||||
if (answer.matched) {
|
|
||||||
const contents = (answer.data orelse unreachable);
|
|
||||||
@memcpy(target_ptr + (kept * after_width), contents, after_width);
|
|
||||||
kept += 1;
|
|
||||||
} else {
|
|
||||||
dec_result(temporary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.dealloc(temporary, alignment);
|
|
||||||
|
|
||||||
if (kept == 0) {
|
|
||||||
utils.decref(output.bytes, size * after_width, alignment);
|
|
||||||
return RocList.empty();
|
|
||||||
} else {
|
|
||||||
output.length = kept;
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return RocList.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listWithCapacity(capacity: usize, alignment: u32, element_width: usize) callconv(.C) RocList {
|
pub fn listWithCapacity(capacity: usize, alignment: u32, element_width: usize) callconv(.C) RocList {
|
||||||
var output = RocList.allocate(alignment, capacity, element_width);
|
var output = RocList.allocate(alignment, capacity, element_width);
|
||||||
output.length = 0;
|
output.length = 0;
|
||||||
|
@ -645,6 +472,7 @@ pub fn listSublist(
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return RocList.empty();
|
return RocList.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.bytes) |source_ptr| {
|
if (list.bytes) |source_ptr| {
|
||||||
const size = list.len();
|
const size = list.len();
|
||||||
|
|
||||||
|
@ -670,14 +498,20 @@ pub fn listSublist(
|
||||||
dec(element);
|
dec(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = RocList.allocate(alignment, keep_len, element_width);
|
if (start == 0 and list.isUnique()) {
|
||||||
const target_ptr = output.bytes orelse unreachable;
|
var output = list;
|
||||||
|
output.length = keep_len;
|
||||||
|
return output;
|
||||||
|
} else {
|
||||||
|
const output = RocList.allocate(alignment, keep_len, element_width);
|
||||||
|
const target_ptr = output.bytes orelse unreachable;
|
||||||
|
|
||||||
@memcpy(target_ptr, source_ptr + start * element_width, keep_len * element_width);
|
@memcpy(target_ptr, source_ptr + start * element_width, keep_len * element_width);
|
||||||
|
|
||||||
utils.decref(list.bytes, size * element_width, alignment);
|
utils.decref(list.bytes, size * element_width, alignment);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RocList.empty();
|
return RocList.empty();
|
||||||
|
|
|
@ -41,9 +41,6 @@ comptime {
|
||||||
exportListFn(list.listMap3, "map3");
|
exportListFn(list.listMap3, "map3");
|
||||||
exportListFn(list.listMap4, "map4");
|
exportListFn(list.listMap4, "map4");
|
||||||
exportListFn(list.listMapWithIndex, "map_with_index");
|
exportListFn(list.listMapWithIndex, "map_with_index");
|
||||||
exportListFn(list.listKeepIf, "keep_if");
|
|
||||||
exportListFn(list.listKeepOks, "keep_oks");
|
|
||||||
exportListFn(list.listKeepErrs, "keep_errs");
|
|
||||||
exportListFn(list.listAppend, "append");
|
exportListFn(list.listAppend, "append");
|
||||||
exportListFn(list.listPrepend, "prepend");
|
exportListFn(list.listPrepend, "prepend");
|
||||||
exportListFn(list.listWithCapacity, "with_capacity");
|
exportListFn(list.listWithCapacity, "with_capacity");
|
||||||
|
|
|
@ -477,6 +477,20 @@ all = \list, predicate ->
|
||||||
## list unaltered.
|
## list unaltered.
|
||||||
##
|
##
|
||||||
keepIf : List a, (a -> Bool) -> List a
|
keepIf : List a, (a -> Bool) -> List a
|
||||||
|
keepIf = \list, predicate ->
|
||||||
|
length = List.len list
|
||||||
|
|
||||||
|
keepIfHelp list predicate 0 0 length
|
||||||
|
|
||||||
|
keepIfHelp : List a, (a -> Bool), Nat, Nat, Nat -> List a
|
||||||
|
keepIfHelp = \list, predicate, kept, index, length ->
|
||||||
|
if index < length then
|
||||||
|
if predicate (List.getUnsafe list index) then
|
||||||
|
keepIfHelp (List.swap list kept index) predicate (kept + 1) (index + 1) length
|
||||||
|
else
|
||||||
|
keepIfHelp list predicate kept (index + 1) length
|
||||||
|
else
|
||||||
|
List.takeFirst list kept
|
||||||
|
|
||||||
## Run the given function on each element of a list, and return all the
|
## Run the given function on each element of a list, and return all the
|
||||||
## elements for which the function returned `False`.
|
## elements for which the function returned `False`.
|
||||||
|
@ -500,6 +514,13 @@ dropIf = \list, predicate ->
|
||||||
## >>>
|
## >>>
|
||||||
## >>> List.keepOks ["", "a", "bc", "", "d", "ef", ""]
|
## >>> List.keepOks ["", "a", "bc", "", "d", "ef", ""]
|
||||||
keepOks : List before, (before -> Result after *) -> List after
|
keepOks : List before, (before -> Result after *) -> List after
|
||||||
|
keepOks = \list, toResult ->
|
||||||
|
walker = \accum, element ->
|
||||||
|
when toResult element is
|
||||||
|
Ok keep -> List.append accum keep
|
||||||
|
Err _drop -> accum
|
||||||
|
|
||||||
|
List.walk list (List.withCapacity (List.len list)) walker
|
||||||
|
|
||||||
## This works like [List.map], except only the transformed values that are
|
## This works like [List.map], except only the transformed values that are
|
||||||
## wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
|
## wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
|
||||||
|
@ -510,6 +531,13 @@ keepOks : List before, (before -> Result after *) -> List after
|
||||||
## >>>
|
## >>>
|
||||||
## >>> List.keepErrs ["", "a", "bc", "", "d", "ef", ""]
|
## >>> List.keepErrs ["", "a", "bc", "", "d", "ef", ""]
|
||||||
keepErrs : List before, (before -> Result * after) -> List after
|
keepErrs : List before, (before -> Result * after) -> List after
|
||||||
|
keepErrs = \list, toResult ->
|
||||||
|
walker = \accum, element ->
|
||||||
|
when toResult element is
|
||||||
|
Ok _drop -> accum
|
||||||
|
Err keep -> List.append accum keep
|
||||||
|
|
||||||
|
List.walk list (List.withCapacity (List.len list)) walker
|
||||||
|
|
||||||
## Convert each element in the list to something new, by calling a conversion
|
## Convert each element in the list to something new, by calling a conversion
|
||||||
## function on each of them. Then return a new list of the converted values.
|
## function on each of them. Then return a new list of the converted values.
|
||||||
|
@ -630,6 +658,8 @@ dropLast = \list ->
|
||||||
## a Unique list, because [List.first] returns the first element as well -
|
## a Unique list, because [List.first] returns the first element as well -
|
||||||
## which introduces a conditional bounds check as well as a memory load.
|
## which introduces a conditional bounds check as well as a memory load.
|
||||||
takeFirst : List elem, Nat -> List elem
|
takeFirst : List elem, Nat -> List elem
|
||||||
|
takeFirst = \list, outputLength ->
|
||||||
|
List.sublist list { start: 0, len: outputLength }
|
||||||
|
|
||||||
## Returns the given number of elements from the end of the list.
|
## Returns the given number of elements from the end of the list.
|
||||||
##
|
##
|
||||||
|
@ -658,6 +688,8 @@ takeFirst : List elem, Nat -> List elem
|
||||||
## a Unique list, because [List.first] returns the first element as well -
|
## a Unique list, because [List.first] returns the first element as well -
|
||||||
## which introduces a conditional bounds check as well as a memory load.
|
## which introduces a conditional bounds check as well as a memory load.
|
||||||
takeLast : List elem, Nat -> List elem
|
takeLast : List elem, Nat -> List elem
|
||||||
|
takeLast = \list, outputLength ->
|
||||||
|
List.sublist list { start: Num.subSaturated (List.len list) outputLength, len: outputLength }
|
||||||
|
|
||||||
## Drops n elements from the beginning of the list.
|
## Drops n elements from the beginning of the list.
|
||||||
drop : List elem, Nat -> List elem
|
drop : List elem, Nat -> List elem
|
||||||
|
|
|
@ -353,9 +353,6 @@ pub const LIST_MAP2: &str = "roc_builtins.list.map2";
|
||||||
pub const LIST_MAP3: &str = "roc_builtins.list.map3";
|
pub const LIST_MAP3: &str = "roc_builtins.list.map3";
|
||||||
pub const LIST_MAP4: &str = "roc_builtins.list.map4";
|
pub const LIST_MAP4: &str = "roc_builtins.list.map4";
|
||||||
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_OKS: &str = "roc_builtins.list.keep_oks";
|
|
||||||
pub const LIST_KEEP_ERRS: &str = "roc_builtins.list.keep_errs";
|
|
||||||
pub const LIST_APPEND: &str = "roc_builtins.list.append";
|
pub const LIST_APPEND: &str = "roc_builtins.list.append";
|
||||||
pub const LIST_PREPEND: &str = "roc_builtins.list.prepend";
|
pub const LIST_PREPEND: &str = "roc_builtins.list.prepend";
|
||||||
pub const LIST_SUBLIST: &str = "roc_builtins.list.sublist";
|
pub const LIST_SUBLIST: &str = "roc_builtins.list.sublist";
|
||||||
|
|
|
@ -112,17 +112,12 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||||
LIST_MAP2 => list_map2,
|
LIST_MAP2 => list_map2,
|
||||||
LIST_MAP3 => list_map3,
|
LIST_MAP3 => list_map3,
|
||||||
LIST_MAP4 => list_map4,
|
LIST_MAP4 => list_map4,
|
||||||
LIST_TAKE_FIRST => list_take_first,
|
|
||||||
LIST_TAKE_LAST => list_take_last,
|
|
||||||
LIST_SUBLIST => list_sublist,
|
LIST_SUBLIST => list_sublist,
|
||||||
LIST_SPLIT => list_split,
|
LIST_SPLIT => list_split,
|
||||||
LIST_DROP => list_drop,
|
LIST_DROP => list_drop,
|
||||||
LIST_DROP_AT => list_drop_at,
|
LIST_DROP_AT => list_drop_at,
|
||||||
LIST_SWAP => list_swap,
|
LIST_SWAP => list_swap,
|
||||||
LIST_MAP_WITH_INDEX => list_map_with_index,
|
LIST_MAP_WITH_INDEX => list_map_with_index,
|
||||||
LIST_KEEP_IF => list_keep_if,
|
|
||||||
LIST_KEEP_OKS => list_keep_oks,
|
|
||||||
LIST_KEEP_ERRS=> list_keep_errs,
|
|
||||||
LIST_SORT_WITH => list_sort_with,
|
LIST_SORT_WITH => list_sort_with,
|
||||||
LIST_IS_UNIQUE => list_is_unique,
|
LIST_IS_UNIQUE => list_is_unique,
|
||||||
DICT_LEN => dict_len,
|
DICT_LEN => dict_len,
|
||||||
|
@ -2119,97 +2114,6 @@ fn list_swap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.takeFirst : List elem, Nat -> List elem
|
|
||||||
fn list_take_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
let list_var = var_store.fresh();
|
|
||||||
let len_var = var_store.fresh();
|
|
||||||
let zero = int::<i128>(
|
|
||||||
len_var,
|
|
||||||
Variable::NATURAL,
|
|
||||||
0,
|
|
||||||
IntBound::Exact(IntWidth::Nat),
|
|
||||||
);
|
|
||||||
|
|
||||||
let body = RunLowLevel {
|
|
||||||
op: LowLevel::ListSublist,
|
|
||||||
args: vec![
|
|
||||||
(list_var, Var(Symbol::ARG_1)),
|
|
||||||
(len_var, zero),
|
|
||||||
(len_var, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: list_var,
|
|
||||||
};
|
|
||||||
|
|
||||||
defn(
|
|
||||||
symbol,
|
|
||||||
vec![(list_var, Symbol::ARG_1), (len_var, Symbol::ARG_2)],
|
|
||||||
var_store,
|
|
||||||
body,
|
|
||||||
list_var,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.takeLast : List elem, Nat -> List elem
|
|
||||||
fn list_take_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
let list_var = var_store.fresh();
|
|
||||||
let len_var = var_store.fresh();
|
|
||||||
|
|
||||||
let zero = int::<i128>(
|
|
||||||
len_var,
|
|
||||||
Variable::NATURAL,
|
|
||||||
0,
|
|
||||||
IntBound::Exact(IntWidth::Nat),
|
|
||||||
);
|
|
||||||
let bool_var = var_store.fresh();
|
|
||||||
|
|
||||||
let get_list_len = RunLowLevel {
|
|
||||||
op: LowLevel::ListLen,
|
|
||||||
args: vec![(list_var, Var(Symbol::ARG_1))],
|
|
||||||
ret_var: len_var,
|
|
||||||
};
|
|
||||||
|
|
||||||
let get_sub = RunLowLevel {
|
|
||||||
op: LowLevel::NumSubWrap,
|
|
||||||
args: vec![
|
|
||||||
(len_var, get_list_len.clone()),
|
|
||||||
(len_var, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: len_var,
|
|
||||||
};
|
|
||||||
|
|
||||||
let get_start = If {
|
|
||||||
cond_var: bool_var,
|
|
||||||
branch_var: len_var,
|
|
||||||
branches: vec![(
|
|
||||||
no_region(RunLowLevel {
|
|
||||||
op: LowLevel::NumGt,
|
|
||||||
args: vec![(len_var, get_list_len), (len_var, Var(Symbol::ARG_2))],
|
|
||||||
ret_var: bool_var,
|
|
||||||
}),
|
|
||||||
no_region(get_sub),
|
|
||||||
)],
|
|
||||||
final_else: Box::new(no_region(zero)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let body = RunLowLevel {
|
|
||||||
op: LowLevel::ListSublist,
|
|
||||||
args: vec![
|
|
||||||
(list_var, Var(Symbol::ARG_1)),
|
|
||||||
(len_var, get_start),
|
|
||||||
(len_var, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: list_var,
|
|
||||||
};
|
|
||||||
|
|
||||||
defn(
|
|
||||||
symbol,
|
|
||||||
vec![(list_var, Symbol::ARG_1), (len_var, Symbol::ARG_2)],
|
|
||||||
var_store,
|
|
||||||
body,
|
|
||||||
list_var,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
|
/// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
|
||||||
fn list_sublist(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_sublist(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let list_var = var_store.fresh();
|
let list_var = var_store.fresh();
|
||||||
|
@ -2462,39 +2366,6 @@ fn list_prepend(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
|
||||||
fn list_keep_if(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
let list_var = var_store.fresh();
|
|
||||||
let func_var = var_store.fresh();
|
|
||||||
|
|
||||||
let body = RunLowLevel {
|
|
||||||
op: LowLevel::ListKeepIf,
|
|
||||||
args: vec![
|
|
||||||
(list_var, Var(Symbol::ARG_1)),
|
|
||||||
(func_var, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: list_var,
|
|
||||||
};
|
|
||||||
|
|
||||||
defn(
|
|
||||||
symbol,
|
|
||||||
vec![(list_var, Symbol::ARG_1), (func_var, Symbol::ARG_2)],
|
|
||||||
var_store,
|
|
||||||
body,
|
|
||||||
list_var,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.keepOks : List before, (before -> Result after *) -> List after
|
|
||||||
fn list_keep_oks(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
lowlevel_2(symbol, LowLevel::ListKeepOks, var_store)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.keepErrs: List before, (before -> Result * after) -> List after
|
|
||||||
fn list_keep_errs(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
lowlevel_2(symbol, LowLevel::ListKeepErrs, var_store)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.map : List before, (before -> after) -> List after
|
/// List.map : List before, (before -> after) -> List after
|
||||||
fn list_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_2(symbol, LowLevel::ListMap, var_store)
|
lowlevel_2(symbol, LowLevel::ListMap, var_store)
|
||||||
|
|
|
@ -9,9 +9,9 @@ use crate::llvm::build_dict::{
|
||||||
use crate::llvm::build_hash::generic_hash;
|
use crate::llvm::build_hash::generic_hash;
|
||||||
use crate::llvm::build_list::{
|
use crate::llvm::build_list::{
|
||||||
self, allocate_list, empty_polymorphic_list, list_append, list_concat, list_drop_at,
|
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_get_unsafe, list_len, list_map, list_map2, list_map3, list_map4, list_map_with_index,
|
||||||
list_map3, list_map4, list_map_with_index, list_prepend, list_replace_unsafe, list_sort_with,
|
list_prepend, list_replace_unsafe, list_sort_with, list_sublist, list_swap,
|
||||||
list_sublist, list_swap, list_symbol_to_c_abi, list_to_c_abi, list_with_capacity,
|
list_symbol_to_c_abi, list_to_c_abi, list_with_capacity,
|
||||||
};
|
};
|
||||||
use crate::llvm::build_str::{
|
use crate::llvm::build_str::{
|
||||||
str_from_float, str_from_int, str_from_utf8, str_from_utf8_range, str_split,
|
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"),
|
_ => 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 } => {
|
ListSortWith { xs } => {
|
||||||
// List.sortWith : List a, (a, a -> Ordering) -> List a
|
// List.sortWith : List a, (a, a -> Ordering) -> List a
|
||||||
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
let (list, list_layout) = load_symbol_and_layout(scope, xs);
|
||||||
|
@ -6041,8 +5937,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
|
|
||||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListKeepOks
|
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListSortWith | DictWalk => {
|
||||||
| ListKeepErrs | ListSortWith | DictWalk => {
|
|
||||||
unreachable!("these are higher order, and are handled elsewhere")
|
unreachable!("these are higher order, and are handled elsewhere")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
use crate::llvm::bitcode::{
|
use crate::llvm::bitcode::{build_dec_wrapper, call_list_bitcode_fn};
|
||||||
build_dec_wrapper, build_has_tag_id, build_inc_wrapper, call_list_bitcode_fn,
|
|
||||||
};
|
|
||||||
use crate::llvm::build::{
|
use crate::llvm::build::{
|
||||||
allocate_with_refcount_help, cast_basic_basic, Env, RocFunctionCall, Scope,
|
allocate_with_refcount_help, cast_basic_basic, Env, RocFunctionCall, Scope,
|
||||||
};
|
};
|
||||||
|
@ -346,162 +344,6 @@ pub fn list_len<'ctx>(
|
||||||
.into_int_value()
|
.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
|
/// List.sortWith : List a, (a, a -> Ordering) -> List a
|
||||||
pub fn list_sort_with<'a, 'ctx, 'env>(
|
pub fn list_sort_with<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
|
|
@ -288,8 +288,8 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
ListIsUnique => self.load_args_and_call_zig(backend, bitcode::LIST_IS_UNIQUE),
|
ListIsUnique => self.load_args_and_call_zig(backend, bitcode::LIST_IS_UNIQUE),
|
||||||
|
|
||||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf
|
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListSortWith
|
||||||
| ListKeepOks | ListKeepErrs | ListSortWith | DictWalk => {
|
| DictWalk => {
|
||||||
internal_error!("HigherOrder lowlevels should not be handled here")
|
internal_error!("HigherOrder lowlevels should not be handled here")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2017,12 +2017,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
*owns_captured_environment,
|
*owns_captured_environment,
|
||||||
),
|
),
|
||||||
|
|
||||||
ListMapWithIndex { .. }
|
ListMapWithIndex { .. } | ListSortWith { .. } | DictWalk { .. } => todo!("{:?}", op),
|
||||||
| ListKeepIf { .. }
|
|
||||||
| ListKeepOks { .. }
|
|
||||||
| ListKeepErrs { .. }
|
|
||||||
| ListSortWith { .. }
|
|
||||||
| DictWalk { .. } => todo!("{:?}", op),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,6 @@ pub enum LowLevel {
|
||||||
ListMap3,
|
ListMap3,
|
||||||
ListMap4,
|
ListMap4,
|
||||||
ListMapWithIndex,
|
ListMapWithIndex,
|
||||||
ListKeepIf,
|
|
||||||
ListKeepOks,
|
|
||||||
ListKeepErrs,
|
|
||||||
ListSortWith,
|
ListSortWith,
|
||||||
ListSublist,
|
ListSublist,
|
||||||
ListDropAt,
|
ListDropAt,
|
||||||
|
@ -127,9 +124,6 @@ macro_rules! higher_order {
|
||||||
| ListMap3
|
| ListMap3
|
||||||
| ListMap4
|
| ListMap4
|
||||||
| ListMapWithIndex
|
| ListMapWithIndex
|
||||||
| ListKeepIf
|
|
||||||
| ListKeepOks
|
|
||||||
| ListKeepErrs
|
|
||||||
| ListSortWith
|
| ListSortWith
|
||||||
| DictWalk
|
| DictWalk
|
||||||
};
|
};
|
||||||
|
@ -153,9 +147,6 @@ impl LowLevel {
|
||||||
ListMap3 => 3,
|
ListMap3 => 3,
|
||||||
ListMap4 => 4,
|
ListMap4 => 4,
|
||||||
ListMapWithIndex => 1,
|
ListMapWithIndex => 1,
|
||||||
ListKeepIf => 1,
|
|
||||||
ListKeepOks => 1,
|
|
||||||
ListKeepErrs => 1,
|
|
||||||
ListSortWith => 1,
|
ListSortWith => 1,
|
||||||
DictWalk => 2,
|
DictWalk => 2,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -220,9 +211,6 @@ impl LowLevelWrapperType {
|
||||||
Symbol::LIST_MAP3 => WrapperIsRequired,
|
Symbol::LIST_MAP3 => WrapperIsRequired,
|
||||||
Symbol::LIST_MAP4 => WrapperIsRequired,
|
Symbol::LIST_MAP4 => WrapperIsRequired,
|
||||||
Symbol::LIST_MAP_WITH_INDEX => WrapperIsRequired,
|
Symbol::LIST_MAP_WITH_INDEX => WrapperIsRequired,
|
||||||
Symbol::LIST_KEEP_IF => WrapperIsRequired,
|
|
||||||
Symbol::LIST_KEEP_OKS => WrapperIsRequired,
|
|
||||||
Symbol::LIST_KEEP_ERRS => WrapperIsRequired,
|
|
||||||
Symbol::LIST_SORT_WITH => WrapperIsRequired,
|
Symbol::LIST_SORT_WITH => WrapperIsRequired,
|
||||||
Symbol::LIST_SUBLIST => WrapperIsRequired,
|
Symbol::LIST_SUBLIST => WrapperIsRequired,
|
||||||
Symbol::LIST_DROP_AT => CanBeReplacedBy(ListDropAt),
|
Symbol::LIST_DROP_AT => CanBeReplacedBy(ListDropAt),
|
||||||
|
|
|
@ -552,10 +552,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
ListMap { xs }
|
ListMap { xs } => {
|
||||||
| ListKeepIf { xs }
|
|
||||||
| ListKeepOks { xs }
|
|
||||||
| ListKeepErrs { xs } => {
|
|
||||||
// own the list if the function wants to own the element
|
// own the list if the function wants to own the element
|
||||||
if !function_ps[0].borrow {
|
if !function_ps[0].borrow {
|
||||||
self.own_var(*xs);
|
self.own_var(*xs);
|
||||||
|
@ -907,9 +904,6 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
ListMap2 => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
|
ListMap2 => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
|
||||||
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, function, closure_data]),
|
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, function, closure_data]),
|
||||||
ListMap4 => arena.alloc_slice_copy(&[owned, owned, owned, owned, function, closure_data]),
|
ListMap4 => arena.alloc_slice_copy(&[owned, owned, owned, owned, function, closure_data]),
|
||||||
ListKeepIf | ListKeepOks | ListKeepErrs => {
|
|
||||||
arena.alloc_slice_copy(&[owned, function, closure_data])
|
|
||||||
}
|
|
||||||
ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]),
|
ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]),
|
||||||
|
|
||||||
// TODO when we have lists with capacity (if ever)
|
// TODO when we have lists with capacity (if ever)
|
||||||
|
|
|
@ -693,7 +693,7 @@ impl<'a> Context<'a> {
|
||||||
let after_arguments = &arguments[op.function_index()..];
|
let after_arguments = &arguments[op.function_index()..];
|
||||||
|
|
||||||
match *op {
|
match *op {
|
||||||
ListMap { xs } | ListKeepIf { xs } | ListKeepOks { xs } | ListKeepErrs { xs } => {
|
ListMap { xs } => {
|
||||||
let ownerships = [(xs, function_ps[0])];
|
let ownerships = [(xs, function_ps[0])];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
|
@ -5043,34 +5043,6 @@ pub fn with_hole<'a>(
|
||||||
let xs = arg_symbols[0];
|
let xs = arg_symbols[0];
|
||||||
match_on_closure_argument!(ListMapWithIndex, [xs])
|
match_on_closure_argument!(ListMapWithIndex, [xs])
|
||||||
}
|
}
|
||||||
ListKeepIf => {
|
|
||||||
debug_assert_eq!(arg_symbols.len(), 2);
|
|
||||||
let xs = arg_symbols[0];
|
|
||||||
let stmt = match_on_closure_argument!(ListKeepIf, [xs]);
|
|
||||||
|
|
||||||
// See the comment in `walk!`. We use List.keepIf to implement
|
|
||||||
// other builtins, where the closure can be an actual closure rather
|
|
||||||
// than a symbol.
|
|
||||||
assign_to_symbol(
|
|
||||||
env,
|
|
||||||
procs,
|
|
||||||
layout_cache,
|
|
||||||
args[1].0, // the closure
|
|
||||||
Loc::at_zero(args[1].1.clone()),
|
|
||||||
arg_symbols[1],
|
|
||||||
stmt,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ListKeepOks => {
|
|
||||||
debug_assert_eq!(arg_symbols.len(), 2);
|
|
||||||
let xs = arg_symbols[0];
|
|
||||||
match_on_closure_argument!(ListKeepOks, [xs])
|
|
||||||
}
|
|
||||||
ListKeepErrs => {
|
|
||||||
debug_assert_eq!(arg_symbols.len(), 2);
|
|
||||||
let xs = arg_symbols[0];
|
|
||||||
match_on_closure_argument!(ListKeepErrs, [xs])
|
|
||||||
}
|
|
||||||
ListSortWith => {
|
ListSortWith => {
|
||||||
debug_assert_eq!(arg_symbols.len(), 2);
|
debug_assert_eq!(arg_symbols.len(), 2);
|
||||||
let xs = arg_symbols[0];
|
let xs = arg_symbols[0];
|
||||||
|
|
|
@ -23,15 +23,6 @@ pub enum HigherOrder {
|
||||||
ListMapWithIndex {
|
ListMapWithIndex {
|
||||||
xs: Symbol,
|
xs: Symbol,
|
||||||
},
|
},
|
||||||
ListKeepIf {
|
|
||||||
xs: Symbol,
|
|
||||||
},
|
|
||||||
ListKeepOks {
|
|
||||||
xs: Symbol,
|
|
||||||
},
|
|
||||||
ListKeepErrs {
|
|
||||||
xs: Symbol,
|
|
||||||
},
|
|
||||||
ListSortWith {
|
ListSortWith {
|
||||||
xs: Symbol,
|
xs: Symbol,
|
||||||
},
|
},
|
||||||
|
@ -49,9 +40,6 @@ impl HigherOrder {
|
||||||
HigherOrder::ListMap3 { .. } => 3,
|
HigherOrder::ListMap3 { .. } => 3,
|
||||||
HigherOrder::ListMap4 { .. } => 4,
|
HigherOrder::ListMap4 { .. } => 4,
|
||||||
HigherOrder::ListMapWithIndex { .. } => 2,
|
HigherOrder::ListMapWithIndex { .. } => 2,
|
||||||
HigherOrder::ListKeepIf { .. } => 1,
|
|
||||||
HigherOrder::ListKeepOks { .. } => 1,
|
|
||||||
HigherOrder::ListKeepErrs { .. } => 1,
|
|
||||||
HigherOrder::ListSortWith { .. } => 2,
|
HigherOrder::ListSortWith { .. } => 2,
|
||||||
HigherOrder::DictWalk { .. } => 2,
|
HigherOrder::DictWalk { .. } => 2,
|
||||||
}
|
}
|
||||||
|
@ -63,12 +51,7 @@ impl HigherOrder {
|
||||||
use HigherOrder::*;
|
use HigherOrder::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
ListMap { .. }
|
ListMap { .. } | ListMapWithIndex { .. } | ListSortWith { .. } => 2,
|
||||||
| ListMapWithIndex { .. }
|
|
||||||
| ListSortWith { .. }
|
|
||||||
| ListKeepIf { .. }
|
|
||||||
| ListKeepOks { .. }
|
|
||||||
| ListKeepErrs { .. } => 2,
|
|
||||||
ListMap2 { .. } => 3,
|
ListMap2 { .. } => 3,
|
||||||
ListMap3 { .. } => 4,
|
ListMap3 { .. } => 4,
|
||||||
ListMap4 { .. } => 5,
|
ListMap4 { .. } => 5,
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
procedure Test.2 (Test.6, #Attr.12):
|
|
||||||
let Test.1 : U8 = StructAtIndex 0 #Attr.12;
|
|
||||||
let Test.11 : {U8} = Struct {Test.1};
|
|
||||||
ret Test.11;
|
|
||||||
|
|
||||||
procedure Test.4 (Test.5, #Attr.12):
|
|
||||||
let Test.1 : U8 = StructAtIndex 0 #Attr.12;
|
|
||||||
ret Test.1;
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
let Test.1 : U8 = 1i64;
|
|
||||||
let Test.8 : {} = Struct {};
|
|
||||||
let Test.10 : {} = Struct {};
|
|
||||||
let Test.14 : {U8} = Struct {Test.1};
|
|
||||||
let Test.9 : {U8} = CallByName Test.2 Test.10 Test.14;
|
|
||||||
let Test.7 : U8 = CallByName Test.4 Test.8 Test.9;
|
|
||||||
ret Test.7;
|
|
|
@ -1,6 +1,6 @@
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.264 : U64 = lowlevel ListLen #Attr.2;
|
let List.284 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Test.1 (Test.5):
|
procedure Test.1 (Test.5):
|
||||||
let Test.2 : I64 = 41i64;
|
let Test.2 : I64 = 41i64;
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.270 : U64 = CallByName List.6 List.74;
|
let List.290 : U64 = CallByName List.6 List.75;
|
||||||
let List.266 : Int1 = CallByName Num.22 List.75 List.270;
|
let List.286 : Int1 = CallByName Num.22 List.76 List.290;
|
||||||
if List.266 then
|
if List.286 then
|
||||||
let List.268 : {} = CallByName List.60 List.74 List.75;
|
let List.288 : {} = CallByName List.60 List.75 List.76;
|
||||||
let List.267 : [C {}, C {}] = Ok List.268;
|
let List.287 : [C {}, C {}] = Ok List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
else
|
else
|
||||||
let List.265 : {} = Struct {};
|
let List.285 : {} = Struct {};
|
||||||
let List.264 : [C {}, C {}] = Err List.265;
|
let List.284 : [C {}, C {}] = Err List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.273 : U64 = lowlevel ListLen #Attr.2;
|
let List.293 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.273;
|
ret List.293;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.272 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.292 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
procedure List.4 (#Attr.2, #Attr.3):
|
procedure List.4 (#Attr.2, #Attr.3):
|
||||||
let List.264 : List U8 = lowlevel ListAppend #Attr.2 #Attr.3;
|
let List.284 : List U8 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Test.20 (Test.22):
|
procedure Test.20 (Test.22):
|
||||||
let Test.34 : {U8} = Struct {Test.22};
|
let Test.34 : {U8} = Struct {Test.22};
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
procedure Encode.22 (Encode.93):
|
|
||||||
ret Encode.93;
|
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
|
||||||
ret Encode.93;
|
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
|
||||||
let Encode.107 : List U8 = CallByName Test.3 Encode.94 Encode.96;
|
|
||||||
ret Encode.107;
|
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
|
||||||
let Encode.114 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
|
|
||||||
ret Encode.114;
|
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
|
||||||
let Encode.104 : List U8 = Array [];
|
|
||||||
let Encode.105 : {} = CallByName Test.2 Encode.100;
|
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
|
||||||
ret Encode.103;
|
|
||||||
|
|
||||||
procedure Json.1 ():
|
|
||||||
let Json.102 : {} = Struct {};
|
|
||||||
ret Json.102;
|
|
||||||
|
|
||||||
procedure Json.17 (Json.64):
|
|
||||||
let Json.104 : {Str} = Struct {Json.64};
|
|
||||||
let Json.103 : {Str} = CallByName Encode.22 Json.104;
|
|
||||||
ret Json.103;
|
|
||||||
|
|
||||||
procedure Json.65 (Json.66, Json.105, #Attr.12):
|
|
||||||
let Json.64 : Str = StructAtIndex 0 #Attr.12;
|
|
||||||
inc Json.64;
|
|
||||||
dec #Attr.12;
|
|
||||||
let Json.114 : I32 = 34i64;
|
|
||||||
let Json.113 : U8 = CallByName Num.122 Json.114;
|
|
||||||
let Json.111 : List U8 = CallByName List.4 Json.66 Json.113;
|
|
||||||
let Json.112 : List U8 = CallByName Str.12 Json.64;
|
|
||||||
let Json.108 : List U8 = CallByName List.8 Json.111 Json.112;
|
|
||||||
let Json.110 : I32 = 34i64;
|
|
||||||
let Json.109 : U8 = CallByName Num.122 Json.110;
|
|
||||||
let Json.107 : List U8 = CallByName List.4 Json.108 Json.109;
|
|
||||||
ret Json.107;
|
|
||||||
|
|
||||||
procedure List.4 (#Attr.2, #Attr.3):
|
|
||||||
let List.141 : List U8 = lowlevel ListAppend #Attr.2 #Attr.3;
|
|
||||||
ret List.141;
|
|
||||||
|
|
||||||
procedure List.8 (#Attr.2, #Attr.3):
|
|
||||||
let List.142 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3;
|
|
||||||
ret List.142;
|
|
||||||
|
|
||||||
procedure Num.122 (#Attr.2):
|
|
||||||
let Num.272 : U8 = lowlevel NumIntCast #Attr.2;
|
|
||||||
ret Num.272;
|
|
||||||
|
|
||||||
procedure Str.12 (#Attr.2):
|
|
||||||
let Str.73 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
|
||||||
ret Str.73;
|
|
||||||
|
|
||||||
procedure Str.9 (#Attr.2):
|
|
||||||
let #Attr.3 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
|
||||||
let Str.69 : Int1 = StructAtIndex 2 #Attr.3;
|
|
||||||
if Str.69 then
|
|
||||||
let Str.71 : Str = StructAtIndex 1 #Attr.3;
|
|
||||||
inc Str.71;
|
|
||||||
dec #Attr.3;
|
|
||||||
let Str.70 : [C {U64, U8}, C Str] = Ok Str.71;
|
|
||||||
ret Str.70;
|
|
||||||
else
|
|
||||||
let Str.67 : U8 = StructAtIndex 3 #Attr.3;
|
|
||||||
let Str.68 : U64 = StructAtIndex 0 #Attr.3;
|
|
||||||
dec #Attr.3;
|
|
||||||
let Str.66 : {U64, U8} = Struct {Str.68, Str.67};
|
|
||||||
let Str.65 : [C {U64, U8}, C Str] = Err Str.66;
|
|
||||||
ret Str.65;
|
|
||||||
|
|
||||||
procedure Test.2 (Test.8):
|
|
||||||
let Test.18 : {} = Struct {};
|
|
||||||
let Test.17 : {} = CallByName Encode.22 Test.18;
|
|
||||||
ret Test.17;
|
|
||||||
|
|
||||||
procedure Test.3 (Test.4, Test.5):
|
|
||||||
let Test.21 : Str = "Hello, World!\n";
|
|
||||||
let Test.20 : {Str} = CallByName Json.17 Test.21;
|
|
||||||
let Test.19 : List U8 = CallByName Encode.23 Test.4 Test.20 Test.5;
|
|
||||||
ret Test.19;
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
let Test.15 : {} = Struct {};
|
|
||||||
let Test.16 : {} = CallByName Json.1;
|
|
||||||
let Test.14 : List U8 = CallByName Encode.25 Test.15 Test.16;
|
|
||||||
let Test.6 : [C {U64, U8}, C Str] = CallByName Str.9 Test.14;
|
|
||||||
let Test.11 : U8 = 1i64;
|
|
||||||
let Test.12 : U8 = GetTagId Test.6;
|
|
||||||
let Test.13 : Int1 = lowlevel Eq Test.11 Test.12;
|
|
||||||
if Test.13 then
|
|
||||||
let Test.7 : Str = UnionAtIndex (Id 1) (Index 0) Test.6;
|
|
||||||
inc Test.7;
|
|
||||||
dec Test.6;
|
|
||||||
ret Test.7;
|
|
||||||
else
|
|
||||||
dec Test.6;
|
|
||||||
let Test.10 : Str = "<bad>";
|
|
||||||
ret Test.10;
|
|
|
@ -1,30 +0,0 @@
|
||||||
procedure Test.4 (Test.30):
|
|
||||||
joinpoint Test.14 Test.5:
|
|
||||||
let Test.24 : Int1 = 1i64;
|
|
||||||
let Test.25 : Int1 = GetTagId Test.5;
|
|
||||||
let Test.26 : Int1 = lowlevel Eq Test.24 Test.25;
|
|
||||||
if Test.26 then
|
|
||||||
let Test.15 : Int1 = false;
|
|
||||||
ret Test.15;
|
|
||||||
else
|
|
||||||
let Test.20 : [C I64, C ] = UnionAtIndex (Id 0) (Index 0) Test.5;
|
|
||||||
let Test.21 : U8 = 1i64;
|
|
||||||
let Test.22 : U8 = GetTagId Test.20;
|
|
||||||
let Test.23 : Int1 = lowlevel Eq Test.21 Test.22;
|
|
||||||
if Test.23 then
|
|
||||||
let Test.16 : Int1 = true;
|
|
||||||
ret Test.16;
|
|
||||||
else
|
|
||||||
let Test.8 : [<rnu><null>, C [C I64, C ] *self] = UnionAtIndex (Id 0) (Index 1) Test.5;
|
|
||||||
jump Test.14 Test.8;
|
|
||||||
in
|
|
||||||
jump Test.14 Test.30;
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
let Test.29 : I64 = 3i64;
|
|
||||||
let Test.27 : [C I64, C ] = Just Test.29;
|
|
||||||
let Test.28 : [<rnu><null>, C [C I64, C ] *self] = Nil ;
|
|
||||||
let Test.13 : [<rnu><null>, C [C I64, C ] *self] = Cons Test.27 Test.28;
|
|
||||||
let Test.12 : Int1 = CallByName Test.4 Test.13;
|
|
||||||
dec Test.13;
|
|
||||||
ret Test.12;
|
|
|
@ -1,6 +1,6 @@
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.264 : U64 = lowlevel ListLen #Attr.2;
|
let List.284 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
procedure Num.19 (#Attr.2, #Attr.3):
|
||||||
let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.279 : U64 = CallByName List.6 List.74;
|
let List.299 : U64 = CallByName List.6 List.75;
|
||||||
let List.275 : Int1 = CallByName Num.22 List.75 List.279;
|
let List.295 : Int1 = CallByName Num.22 List.76 List.299;
|
||||||
if List.275 then
|
if List.295 then
|
||||||
let List.277 : I64 = CallByName List.60 List.74 List.75;
|
let List.297 : I64 = CallByName List.60 List.75 List.76;
|
||||||
let List.276 : [C {}, C I64] = Ok List.277;
|
let List.296 : [C {}, C I64] = Ok List.297;
|
||||||
ret List.276;
|
ret List.296;
|
||||||
else
|
else
|
||||||
let List.274 : {} = Struct {};
|
let List.294 : {} = Struct {};
|
||||||
let List.273 : [C {}, C I64] = Err List.274;
|
let List.293 : [C {}, C I64] = Err List.294;
|
||||||
ret List.273;
|
ret List.293;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.280 : U64 = lowlevel ListLen #Attr.2;
|
let List.300 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.280;
|
ret List.300;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.278 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.298 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.278;
|
ret List.298;
|
||||||
|
|
||||||
procedure List.9 (List.184):
|
procedure List.9 (List.202):
|
||||||
let List.271 : U64 = 0i64;
|
let List.291 : U64 = 0i64;
|
||||||
let List.264 : [C {}, C I64] = CallByName List.2 List.184 List.271;
|
let List.284 : [C {}, C I64] = CallByName List.2 List.202 List.291;
|
||||||
let List.268 : U8 = 1i64;
|
let List.288 : U8 = 1i64;
|
||||||
let List.269 : U8 = GetTagId List.264;
|
let List.289 : U8 = GetTagId List.284;
|
||||||
let List.270 : Int1 = lowlevel Eq List.268 List.269;
|
let List.290 : Int1 = lowlevel Eq List.288 List.289;
|
||||||
if List.270 then
|
if List.290 then
|
||||||
let List.185 : I64 = UnionAtIndex (Id 1) (Index 0) List.264;
|
let List.203 : I64 = UnionAtIndex (Id 1) (Index 0) List.284;
|
||||||
let List.265 : [C Int1, C I64] = Ok List.185;
|
let List.285 : [C Int1, C I64] = Ok List.203;
|
||||||
ret List.265;
|
ret List.285;
|
||||||
else
|
else
|
||||||
let List.267 : Int1 = true;
|
let List.287 : Int1 = true;
|
||||||
let List.266 : [C Int1, C I64] = Err List.267;
|
let List.286 : [C Int1, C I64] = Err List.287;
|
||||||
ret List.266;
|
ret List.286;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
|
||||||
let Num.274 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
|
||||||
ret Num.274;
|
|
||||||
|
|
||||||
procedure Test.4 (Test.6):
|
|
||||||
let Test.16 : Int1 = 1i64;
|
|
||||||
let Test.17 : Int1 = GetTagId Test.6;
|
|
||||||
let Test.18 : Int1 = lowlevel Eq Test.16 Test.17;
|
|
||||||
if Test.18 then
|
|
||||||
let Test.12 : I64 = 0i64;
|
|
||||||
ret Test.12;
|
|
||||||
else
|
|
||||||
let Test.7 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.6;
|
|
||||||
let Test.14 : I64 = 1i64;
|
|
||||||
let Test.15 : I64 = CallByName Test.4 Test.7;
|
|
||||||
let Test.13 : I64 = CallByName Num.19 Test.14 Test.15;
|
|
||||||
ret Test.13;
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
let Test.3 : [<rnu><null>, C I64 *self] = Nil ;
|
|
||||||
let Test.9 : I64 = CallByName Test.4 Test.3;
|
|
||||||
let Test.10 : I64 = CallByName Test.4 Test.3;
|
|
||||||
dec Test.3;
|
|
||||||
let Test.8 : I64 = CallByName Num.19 Test.9 Test.10;
|
|
||||||
ret Test.8;
|
|
|
@ -1,6 +1,6 @@
|
||||||
procedure List.4 (#Attr.2, #Attr.3):
|
procedure List.4 (#Attr.2, #Attr.3):
|
||||||
let List.264 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
let List.284 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.2 : List I64 = Array [1i64];
|
let Test.2 : List I64 = Array [1i64];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
procedure List.4 (#Attr.2, #Attr.3):
|
procedure List.4 (#Attr.2, #Attr.3):
|
||||||
let List.264 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
let List.284 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Test.1 (Test.2):
|
procedure Test.1 (Test.2):
|
||||||
let Test.6 : I64 = 42i64;
|
let Test.6 : I64 = 42i64;
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
procedure List.3 (List.83, List.84, List.85):
|
procedure List.3 (List.84, List.85, List.86):
|
||||||
let List.267 : {List I64, I64} = CallByName List.57 List.83 List.84 List.85;
|
let List.287 : {List I64, I64} = CallByName List.57 List.84 List.85 List.86;
|
||||||
let List.266 : List I64 = StructAtIndex 0 List.267;
|
let List.286 : List I64 = StructAtIndex 0 List.287;
|
||||||
inc List.266;
|
inc List.286;
|
||||||
dec List.267;
|
dec List.287;
|
||||||
ret List.266;
|
ret List.286;
|
||||||
|
|
||||||
procedure List.57 (List.80, List.81, List.82):
|
procedure List.57 (List.81, List.82, List.83):
|
||||||
let List.273 : U64 = CallByName List.6 List.80;
|
let List.293 : U64 = CallByName List.6 List.81;
|
||||||
let List.270 : Int1 = CallByName Num.22 List.81 List.273;
|
let List.290 : Int1 = CallByName Num.22 List.82 List.293;
|
||||||
if List.270 then
|
if List.290 then
|
||||||
let List.271 : {List I64, I64} = CallByName List.61 List.80 List.81 List.82;
|
let List.291 : {List I64, I64} = CallByName List.61 List.81 List.82 List.83;
|
||||||
ret List.271;
|
ret List.291;
|
||||||
else
|
else
|
||||||
let List.269 : {List I64, I64} = Struct {List.80, List.82};
|
let List.289 : {List I64, I64} = Struct {List.81, List.83};
|
||||||
ret List.269;
|
ret List.289;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.265 : U64 = lowlevel ListLen #Attr.2;
|
let List.285 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.265;
|
ret List.285;
|
||||||
|
|
||||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||||
let List.272 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
let List.292 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
procedure Num.19 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.270 : U64 = CallByName List.6 List.74;
|
let List.290 : U64 = CallByName List.6 List.75;
|
||||||
let List.266 : Int1 = CallByName Num.22 List.75 List.270;
|
let List.286 : Int1 = CallByName Num.22 List.76 List.290;
|
||||||
if List.266 then
|
if List.286 then
|
||||||
let List.268 : I64 = CallByName List.60 List.74 List.75;
|
let List.288 : I64 = CallByName List.60 List.75 List.76;
|
||||||
let List.267 : [C {}, C I64] = Ok List.268;
|
let List.287 : [C {}, C I64] = Ok List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
else
|
else
|
||||||
let List.265 : {} = Struct {};
|
let List.285 : {} = Struct {};
|
||||||
let List.264 : [C {}, C I64] = Err List.265;
|
let List.284 : [C {}, C I64] = Err List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.273 : U64 = lowlevel ListLen #Attr.2;
|
let List.293 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.273;
|
ret List.293;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.272 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.292 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.264 : U64 = lowlevel ListLen #Attr.2;
|
let List.284 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.265 : U64 = lowlevel ListLen #Attr.2;
|
let List.285 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.265;
|
ret List.285;
|
||||||
|
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
procedure Num.19 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.270 : U64 = CallByName List.6 List.74;
|
let List.290 : U64 = CallByName List.6 List.75;
|
||||||
let List.266 : Int1 = CallByName Num.22 List.75 List.270;
|
let List.286 : Int1 = CallByName Num.22 List.76 List.290;
|
||||||
if List.266 then
|
if List.286 then
|
||||||
let List.268 : Str = CallByName List.60 List.74 List.75;
|
let List.288 : Str = CallByName List.60 List.75 List.76;
|
||||||
let List.267 : [C {}, C Str] = Ok List.268;
|
let List.287 : [C {}, C Str] = Ok List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
else
|
else
|
||||||
let List.265 : {} = Struct {};
|
let List.285 : {} = Struct {};
|
||||||
let List.264 : [C {}, C Str] = Err List.265;
|
let List.284 : [C {}, C Str] = Err List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.5 (#Attr.2, #Attr.3):
|
procedure List.5 (#Attr.2, #Attr.3):
|
||||||
let List.272 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
let List.292 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.274 : U64 = lowlevel ListLen #Attr.2;
|
let List.294 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.274;
|
ret List.294;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.273 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.293 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.273;
|
ret List.293;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.270 : U64 = CallByName List.6 List.74;
|
let List.290 : U64 = CallByName List.6 List.75;
|
||||||
let List.266 : Int1 = CallByName Num.22 List.75 List.270;
|
let List.286 : Int1 = CallByName Num.22 List.76 List.290;
|
||||||
if List.266 then
|
if List.286 then
|
||||||
let List.268 : Str = CallByName List.60 List.74 List.75;
|
let List.288 : Str = CallByName List.60 List.75 List.76;
|
||||||
let List.267 : [C {}, C Str] = Ok List.268;
|
let List.287 : [C {}, C Str] = Ok List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
else
|
else
|
||||||
let List.265 : {} = Struct {};
|
let List.285 : {} = Struct {};
|
||||||
let List.264 : [C {}, C Str] = Err List.265;
|
let List.284 : [C {}, C Str] = Err List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.5 (#Attr.2, #Attr.3):
|
procedure List.5 (#Attr.2, #Attr.3):
|
||||||
inc #Attr.2;
|
inc #Attr.2;
|
||||||
let List.272 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
let List.292 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||||
decref #Attr.2;
|
decref #Attr.2;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.274 : U64 = lowlevel ListLen #Attr.2;
|
let List.294 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.274;
|
ret List.294;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.273 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.293 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.273;
|
ret List.293;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
procedure List.3 (List.83, List.84, List.85):
|
procedure List.3 (List.84, List.85, List.86):
|
||||||
let List.265 : {List I64, I64} = CallByName List.57 List.83 List.84 List.85;
|
let List.285 : {List I64, I64} = CallByName List.57 List.84 List.85 List.86;
|
||||||
let List.264 : List I64 = StructAtIndex 0 List.265;
|
let List.284 : List I64 = StructAtIndex 0 List.285;
|
||||||
inc List.264;
|
inc List.284;
|
||||||
dec List.265;
|
dec List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure List.57 (List.80, List.81, List.82):
|
procedure List.57 (List.81, List.82, List.83):
|
||||||
let List.271 : U64 = CallByName List.6 List.80;
|
let List.291 : U64 = CallByName List.6 List.81;
|
||||||
let List.268 : Int1 = CallByName Num.22 List.81 List.271;
|
let List.288 : Int1 = CallByName Num.22 List.82 List.291;
|
||||||
if List.268 then
|
if List.288 then
|
||||||
let List.269 : {List I64, I64} = CallByName List.61 List.80 List.81 List.82;
|
let List.289 : {List I64, I64} = CallByName List.61 List.81 List.82 List.83;
|
||||||
ret List.269;
|
ret List.289;
|
||||||
else
|
else
|
||||||
let List.267 : {List I64, I64} = Struct {List.80, List.82};
|
let List.287 : {List I64, I64} = Struct {List.81, List.83};
|
||||||
ret List.267;
|
ret List.287;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.272 : U64 = lowlevel ListLen #Attr.2;
|
let List.292 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.272;
|
ret List.292;
|
||||||
|
|
||||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||||
let List.270 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
let List.290 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||||
ret List.270;
|
ret List.290;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
procedure List.28 (#Attr.2, #Attr.3):
|
procedure List.28 (#Attr.2, #Attr.3):
|
||||||
let List.267 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
|
let List.287 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
|
||||||
let Bool.14 : Int1 = lowlevel ListIsUnique #Attr.2;
|
let Bool.14 : Int1 = lowlevel ListIsUnique #Attr.2;
|
||||||
if Bool.14 then
|
if Bool.14 then
|
||||||
ret List.267;
|
ret List.287;
|
||||||
else
|
else
|
||||||
decref #Attr.2;
|
decref #Attr.2;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
|
|
||||||
procedure List.54 (List.178):
|
procedure List.54 (List.196):
|
||||||
let List.265 : {} = Struct {};
|
let List.285 : {} = Struct {};
|
||||||
let List.264 : List I64 = CallByName List.28 List.178 List.265;
|
let List.284 : List I64 = CallByName List.28 List.196 List.285;
|
||||||
ret List.264;
|
ret List.284;
|
||||||
|
|
||||||
procedure Num.46 (#Attr.2, #Attr.3):
|
procedure Num.46 (#Attr.2, #Attr.3):
|
||||||
let Num.273 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
|
let Num.273 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
|
||||||
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
|
||||||
ret Num.273;
|
|
||||||
|
|
||||||
procedure Test.5 (Test.7, Test.8):
|
|
||||||
let Test.17 : U64 = 1i64;
|
|
||||||
ret Test.17;
|
|
||||||
|
|
||||||
procedure Test.6 (Test.7, Test.8):
|
|
||||||
let Test.14 : U64 = 1i64;
|
|
||||||
ret Test.14;
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
let Test.15 : U8 = 100i64;
|
|
||||||
let Test.16 : U32 = 100i64;
|
|
||||||
let Test.10 : U64 = CallByName Test.5 Test.15 Test.16;
|
|
||||||
let Test.12 : U32 = 100i64;
|
|
||||||
let Test.13 : U8 = 100i64;
|
|
||||||
let Test.11 : U64 = CallByName Test.6 Test.12 Test.13;
|
|
||||||
let Test.9 : U64 = CallByName Num.19 Test.10 Test.11;
|
|
||||||
ret Test.9;
|
|
|
@ -1,43 +1,43 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.284 : U64 = CallByName List.6 List.74;
|
let List.304 : U64 = CallByName List.6 List.75;
|
||||||
let List.280 : Int1 = CallByName Num.22 List.75 List.284;
|
let List.300 : Int1 = CallByName Num.22 List.76 List.304;
|
||||||
if List.280 then
|
if List.300 then
|
||||||
let List.282 : I64 = CallByName List.60 List.74 List.75;
|
let List.302 : I64 = CallByName List.60 List.75 List.76;
|
||||||
let List.281 : [C {}, C I64] = Ok List.282;
|
let List.301 : [C {}, C I64] = Ok List.302;
|
||||||
ret List.281;
|
ret List.301;
|
||||||
else
|
else
|
||||||
let List.279 : {} = Struct {};
|
let List.299 : {} = Struct {};
|
||||||
let List.278 : [C {}, C I64] = Err List.279;
|
let List.298 : [C {}, C I64] = Err List.299;
|
||||||
ret List.278;
|
ret List.298;
|
||||||
|
|
||||||
procedure List.3 (List.83, List.84, List.85):
|
procedure List.3 (List.84, List.85, List.86):
|
||||||
let List.268 : {List I64, I64} = CallByName List.57 List.83 List.84 List.85;
|
let List.288 : {List I64, I64} = CallByName List.57 List.84 List.85 List.86;
|
||||||
let List.267 : List I64 = StructAtIndex 0 List.268;
|
let List.287 : List I64 = StructAtIndex 0 List.288;
|
||||||
inc List.267;
|
inc List.287;
|
||||||
dec List.268;
|
dec List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
|
|
||||||
procedure List.57 (List.80, List.81, List.82):
|
procedure List.57 (List.81, List.82, List.83):
|
||||||
let List.290 : U64 = CallByName List.6 List.80;
|
let List.310 : U64 = CallByName List.6 List.81;
|
||||||
let List.287 : Int1 = CallByName Num.22 List.81 List.290;
|
let List.307 : Int1 = CallByName Num.22 List.82 List.310;
|
||||||
if List.287 then
|
if List.307 then
|
||||||
let List.288 : {List I64, I64} = CallByName List.61 List.80 List.81 List.82;
|
let List.308 : {List I64, I64} = CallByName List.61 List.81 List.82 List.83;
|
||||||
ret List.288;
|
ret List.308;
|
||||||
else
|
else
|
||||||
let List.286 : {List I64, I64} = Struct {List.80, List.82};
|
let List.306 : {List I64, I64} = Struct {List.81, List.83};
|
||||||
ret List.286;
|
ret List.306;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.291 : U64 = lowlevel ListLen #Attr.2;
|
let List.311 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.291;
|
ret List.311;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.292 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.312 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.292;
|
ret List.312;
|
||||||
|
|
||||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||||
let List.289 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
let List.309 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||||
ret List.289;
|
ret List.309;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
procedure List.2 (List.74, List.75):
|
procedure List.2 (List.75, List.76):
|
||||||
let List.284 : U64 = CallByName List.6 List.74;
|
let List.304 : U64 = CallByName List.6 List.75;
|
||||||
let List.280 : Int1 = CallByName Num.22 List.75 List.284;
|
let List.300 : Int1 = CallByName Num.22 List.76 List.304;
|
||||||
if List.280 then
|
if List.300 then
|
||||||
let List.282 : I64 = CallByName List.60 List.74 List.75;
|
let List.302 : I64 = CallByName List.60 List.75 List.76;
|
||||||
let List.281 : [C {}, C I64] = Ok List.282;
|
let List.301 : [C {}, C I64] = Ok List.302;
|
||||||
ret List.281;
|
ret List.301;
|
||||||
else
|
else
|
||||||
let List.279 : {} = Struct {};
|
let List.299 : {} = Struct {};
|
||||||
let List.278 : [C {}, C I64] = Err List.279;
|
let List.298 : [C {}, C I64] = Err List.299;
|
||||||
ret List.278;
|
ret List.298;
|
||||||
|
|
||||||
procedure List.3 (List.83, List.84, List.85):
|
procedure List.3 (List.84, List.85, List.86):
|
||||||
let List.268 : {List I64, I64} = CallByName List.57 List.83 List.84 List.85;
|
let List.288 : {List I64, I64} = CallByName List.57 List.84 List.85 List.86;
|
||||||
let List.267 : List I64 = StructAtIndex 0 List.268;
|
let List.287 : List I64 = StructAtIndex 0 List.288;
|
||||||
inc List.267;
|
inc List.287;
|
||||||
dec List.268;
|
dec List.288;
|
||||||
ret List.267;
|
ret List.287;
|
||||||
|
|
||||||
procedure List.57 (List.80, List.81, List.82):
|
procedure List.57 (List.81, List.82, List.83):
|
||||||
let List.290 : U64 = CallByName List.6 List.80;
|
let List.310 : U64 = CallByName List.6 List.81;
|
||||||
let List.287 : Int1 = CallByName Num.22 List.81 List.290;
|
let List.307 : Int1 = CallByName Num.22 List.82 List.310;
|
||||||
if List.287 then
|
if List.307 then
|
||||||
let List.288 : {List I64, I64} = CallByName List.61 List.80 List.81 List.82;
|
let List.308 : {List I64, I64} = CallByName List.61 List.81 List.82 List.83;
|
||||||
ret List.288;
|
ret List.308;
|
||||||
else
|
else
|
||||||
let List.286 : {List I64, I64} = Struct {List.80, List.82};
|
let List.306 : {List I64, I64} = Struct {List.81, List.83};
|
||||||
ret List.286;
|
ret List.306;
|
||||||
|
|
||||||
procedure List.6 (#Attr.2):
|
procedure List.6 (#Attr.2):
|
||||||
let List.291 : U64 = lowlevel ListLen #Attr.2;
|
let List.311 : U64 = lowlevel ListLen #Attr.2;
|
||||||
ret List.291;
|
ret List.311;
|
||||||
|
|
||||||
procedure List.60 (#Attr.2, #Attr.3):
|
procedure List.60 (#Attr.2, #Attr.3):
|
||||||
let List.292 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
let List.312 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||||
ret List.292;
|
ret List.312;
|
||||||
|
|
||||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||||
let List.289 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
let List.309 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||||
ret List.289;
|
ret List.309;
|
||||||
|
|
||||||
procedure Num.22 (#Attr.2, #Attr.3):
|
procedure Num.22 (#Attr.2, #Attr.3):
|
||||||
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
procedure Num.19 (#Attr.2, #Attr.3):
|
|
||||||
let Num.274 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
|
||||||
ret Num.274;
|
|
||||||
|
|
||||||
procedure Num.21 (#Attr.2, #Attr.3):
|
|
||||||
let Num.273 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
|
|
||||||
ret Num.273;
|
|
||||||
|
|
||||||
procedure Test.1 ():
|
|
||||||
let Test.26 : I64 = 1i64;
|
|
||||||
ret Test.26;
|
|
||||||
|
|
||||||
procedure Test.2 ():
|
|
||||||
let Test.22 : I64 = 2i64;
|
|
||||||
ret Test.22;
|
|
||||||
|
|
||||||
procedure Test.3 (Test.6):
|
|
||||||
let Test.25 : I64 = CallByName Test.1;
|
|
||||||
let Test.24 : I64 = CallByName Num.19 Test.6 Test.25;
|
|
||||||
ret Test.24;
|
|
||||||
|
|
||||||
procedure Test.4 (Test.7):
|
|
||||||
let Test.21 : I64 = CallByName Test.2;
|
|
||||||
let Test.20 : I64 = CallByName Num.21 Test.7 Test.21;
|
|
||||||
ret Test.20;
|
|
||||||
|
|
||||||
procedure Test.5 (Test.8, Test.9):
|
|
||||||
joinpoint Test.15 Test.14:
|
|
||||||
ret Test.14;
|
|
||||||
in
|
|
||||||
switch Test.8:
|
|
||||||
case 0:
|
|
||||||
let Test.16 : I64 = CallByName Test.3 Test.9;
|
|
||||||
jump Test.15 Test.16;
|
|
||||||
|
|
||||||
default:
|
|
||||||
let Test.17 : I64 = CallByName Test.4 Test.9;
|
|
||||||
jump Test.15 Test.17;
|
|
||||||
|
|
||||||
|
|
||||||
procedure Test.0 ():
|
|
||||||
joinpoint Test.19 Test.12:
|
|
||||||
let Test.13 : I64 = 42i64;
|
|
||||||
let Test.11 : I64 = CallByName Test.5 Test.12 Test.13;
|
|
||||||
ret Test.11;
|
|
||||||
in
|
|
||||||
let Test.23 : Int1 = true;
|
|
||||||
if Test.23 then
|
|
||||||
let Test.3 : Int1 = false;
|
|
||||||
jump Test.19 Test.3;
|
|
||||||
else
|
|
||||||
let Test.4 : Int1 = true;
|
|
||||||
jump Test.19 Test.4;
|
|
|
@ -1,32 +0,0 @@
|
||||||
|
|
||||||
# Meeting notes
|
|
||||||
|
|
||||||
- 18/1/2022 2pm GMT
|
|
||||||
|
|
||||||
## issue 2368
|
|
||||||
|
|
||||||
- How is AST data accessible to plugins?
|
|
||||||
- How does plugin UI work (UI components, vector level, pixel-level)?
|
|
||||||
- Given a selected expression, how do we show all plugins available that can visualize this
|
|
||||||
expression or have an interactive widget to alter the expression (color picker). What does
|
|
||||||
this API look like?
|
|
||||||
- use type driven UX? https://pchiusano.github.io/2013-09-10/type-systems-and-ux-example.html
|
|
||||||
|
|
||||||
## ideas
|
|
||||||
|
|
||||||
- Several "zoom levels" in the editor should show/hide context-appropriate views/buttons/functionality:
|
|
||||||
+ zoomed out view should show type defs and function defs with folded body
|
|
||||||
+ zooming in on function should unfold/show function body
|
|
||||||
+ Traditional IDE's like ecplise can show an overwhelming amount of possible buttons/actions and views. Zoom levels can be used to prevent this excess of available options.
|
|
||||||
|
|
||||||
- There should be a single editable text field to alter AST. This could be the same text field for entering commands, pressing a certain key could switch between command/plain text input into AST. Current part of AST that is being edited is highlighted.
|
|
||||||
|
|
||||||
- Hovering over expression should show button on left sidebar that allows you to pop out a pinned view of the expression.
|
|
||||||
This pinned view could for example show all variants in a large type definition.
|
|
||||||
Hovering over a type in a place other than the definition could show all variants, this hover view should also be capable of being pinned and moved around as desired.
|
|
||||||
|
|
||||||
- UI interaction specification from which we can generate both e.g. a window with clickable buttons 'previuous' and `next` that also supports the voice commands `previuous` and `next`.
|
|
||||||
|
|
||||||
Next actions to take:
|
|
||||||
- Zeljko: draft UI interaction in figma
|
|
||||||
- Anton: draft plugin API in roc
|
|
Loading…
Add table
Add a link
Reference in a new issue