Merge branch 'trunk' of github.com:rtfeldman/roc into pure-roc-list-walk

This commit is contained in:
Brian Carroll 2022-07-02 21:40:51 +01:00
commit 94181111be
No known key found for this signature in database
GPG key ID: 9CF4E3BF9C4722C7
37 changed files with 259 additions and 1321 deletions

View file

@ -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;

View file

@ -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();

View file

@ -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");

View file

@ -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

View file

@ -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";

View file

@ -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)

View file

@ -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")
} }

View file

@ -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>,

View file

@ -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),
} }
} }

View file

@ -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),

View file

@ -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)

View file

@ -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);

View file

@ -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];

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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};

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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];

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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