mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-15 04:10:14 +03:00
remove dict/set lowlevels
This commit is contained in:
parent
79f8ae4e69
commit
8e21fdcb04
@ -733,31 +733,6 @@ fn call_spec(
|
||||
}
|
||||
|
||||
match op {
|
||||
DictWalk { xs, state } => {
|
||||
let dict = env.symbols[xs];
|
||||
let state = env.symbols[state];
|
||||
|
||||
let loop_body = |builder: &mut FuncDefBuilder, block, state| {
|
||||
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||
|
||||
let element = builder.add_bag_get(block, bag)?;
|
||||
|
||||
let key = builder.add_get_tuple_field(block, element, 0)?;
|
||||
let val = builder.add_get_tuple_field(block, element, 1)?;
|
||||
|
||||
let new_state = call_function!(builder, block, [state, key, val]);
|
||||
|
||||
Ok(new_state)
|
||||
};
|
||||
|
||||
let state_layout = argument_layouts[0];
|
||||
let state_type =
|
||||
layout_spec(builder, &state_layout, &WhenRecursive::Unreachable)?;
|
||||
let init_state = state;
|
||||
|
||||
add_loop(builder, block, state_type, init_state, loop_body)
|
||||
}
|
||||
|
||||
ListMap { xs } => {
|
||||
let list = env.symbols[xs];
|
||||
|
||||
@ -1001,7 +976,7 @@ fn lowlevel_spec(
|
||||
// just dream up a unit value
|
||||
builder.add_make_tuple(block, &[])
|
||||
}
|
||||
ListLen | DictSize => {
|
||||
ListLen => {
|
||||
// TODO should this touch the heap cell?
|
||||
// just dream up a unit value
|
||||
builder.add_make_tuple(block, &[])
|
||||
@ -1087,47 +1062,6 @@ fn lowlevel_spec(
|
||||
|
||||
builder.add_make_tuple(block, &[byte_index, string, is_ok, problem_code])
|
||||
}
|
||||
DictEmpty => match layout {
|
||||
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => {
|
||||
let key_id = layout_spec(builder, key_layout, &WhenRecursive::Unreachable)?;
|
||||
let value_id = layout_spec(builder, value_layout, &WhenRecursive::Unreachable)?;
|
||||
new_dict(builder, block, key_id, value_id)
|
||||
}
|
||||
_ => unreachable!("empty array does not have a list layout"),
|
||||
},
|
||||
DictGetUnsafe => {
|
||||
// NOTE DictGetUnsafe returns a { flag: Bool, value: v }
|
||||
// when the flag is True, the value is found and defined;
|
||||
// otherwise it is not and `Dict.get` should return `Err ...`
|
||||
|
||||
let dict = env.symbols[&arguments[0]];
|
||||
let key = env.symbols[&arguments[1]];
|
||||
|
||||
// indicate that we use the key
|
||||
builder.add_recursive_touch(block, key)?;
|
||||
|
||||
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||
let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
||||
|
||||
let _unit = builder.add_touch(block, cell)?;
|
||||
builder.add_bag_get(block, bag)
|
||||
}
|
||||
DictInsert => {
|
||||
let dict = env.symbols[&arguments[0]];
|
||||
let key = env.symbols[&arguments[1]];
|
||||
let value = env.symbols[&arguments[2]];
|
||||
|
||||
let key_value = builder.add_make_tuple(block, &[key, value])?;
|
||||
|
||||
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||
let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
||||
|
||||
let _unit = builder.add_update(block, update_mode_var, cell)?;
|
||||
|
||||
builder.add_bag_insert(block, bag, key_value)?;
|
||||
|
||||
with_new_heap_cell(builder, block, bag)
|
||||
}
|
||||
_other => {
|
||||
// println!("missing {:?}", _other);
|
||||
// TODO overly pessimstic
|
||||
@ -1512,18 +1446,10 @@ fn builtin_spec(
|
||||
use Builtin::*;
|
||||
|
||||
match builtin {
|
||||
Dict(_, _) => todo!(),
|
||||
Int(_) | Bool => builder.add_tuple_type(&[]),
|
||||
Decimal | Float(_) => builder.add_tuple_type(&[]),
|
||||
Str => str_type(builder),
|
||||
Dict(key_layout, value_layout) => {
|
||||
let value_type = layout_spec_help(builder, value_layout, when_recursive)?;
|
||||
let key_type = layout_spec_help(builder, key_layout, when_recursive)?;
|
||||
let element_type = builder.add_tuple_type(&[key_type, value_type])?;
|
||||
|
||||
let cell = builder.add_heap_cell_type();
|
||||
let bag = builder.add_bag_type(element_type)?;
|
||||
builder.add_tuple_type(&[cell, bag])
|
||||
}
|
||||
Set(key_layout) => {
|
||||
let value_type = builder.add_tuple_type(&[])?;
|
||||
let key_type = layout_spec_help(builder, key_layout, when_recursive)?;
|
||||
@ -1560,9 +1486,6 @@ fn static_list_type<TC: TypeContext>(builder: &mut TC) -> Result<TypeId> {
|
||||
const LIST_CELL_INDEX: u32 = 0;
|
||||
const LIST_BAG_INDEX: u32 = 1;
|
||||
|
||||
const DICT_CELL_INDEX: u32 = LIST_CELL_INDEX;
|
||||
const DICT_BAG_INDEX: u32 = LIST_BAG_INDEX;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const BOX_CELL_INDEX: u32 = LIST_CELL_INDEX;
|
||||
const BOX_VALUE_INDEX: u32 = LIST_BAG_INDEX;
|
||||
@ -1584,17 +1507,6 @@ fn new_list(builder: &mut FuncDefBuilder, block: BlockId, element_type: TypeId)
|
||||
with_new_heap_cell(builder, block, bag)
|
||||
}
|
||||
|
||||
fn new_dict(
|
||||
builder: &mut FuncDefBuilder,
|
||||
block: BlockId,
|
||||
key_type: TypeId,
|
||||
value_type: TypeId,
|
||||
) -> Result<ValueId> {
|
||||
let element_type = builder.add_tuple_type(&[key_type, value_type])?;
|
||||
let bag = builder.add_empty_bag(block, element_type)?;
|
||||
with_new_heap_cell(builder, block, bag)
|
||||
}
|
||||
|
||||
fn new_static_string(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
|
||||
let module = MOD_APP;
|
||||
|
||||
|
@ -58,18 +58,6 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
||||
Symbol::NUM_DIV_FRAC => Some(lowlevel_2(Symbol::NUM_DIV_FRAC, LowLevel::NumDivUnchecked, var_store)),
|
||||
Symbol::NUM_DIV_TRUNC => Some(lowlevel_2(Symbol::NUM_DIV_TRUNC, LowLevel::NumDivUnchecked, var_store)),
|
||||
|
||||
Symbol::DICT_EMPTY => Some(dict_empty(Symbol::DICT_EMPTY, var_store)),
|
||||
|
||||
Symbol::SET_UNION => Some(lowlevel_2(Symbol::SET_UNION, LowLevel::DictUnion, var_store)),
|
||||
Symbol::SET_DIFFERENCE => Some(lowlevel_2(Symbol::SET_DIFFERENCE, LowLevel::DictDifference, var_store)),
|
||||
Symbol::SET_INTERSECTION => Some(lowlevel_2(Symbol::SET_INTERSECTION, LowLevel::DictIntersection, var_store)),
|
||||
|
||||
Symbol::SET_TO_LIST => Some(lowlevel_1(Symbol::SET_TO_LIST, LowLevel::DictKeys, var_store)),
|
||||
Symbol::SET_REMOVE => Some(lowlevel_2(Symbol::SET_REMOVE, LowLevel::DictRemove, var_store)),
|
||||
Symbol::SET_INSERT => Some(set_insert(Symbol::SET_INSERT, var_store)),
|
||||
Symbol::SET_EMPTY => Some(set_empty(Symbol::SET_EMPTY, var_store)),
|
||||
Symbol::SET_SINGLE => Some(set_single(Symbol::SET_SINGLE, var_store)),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -94,7 +82,6 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
||||
LowLevel::NumToIntChecked => unreachable!(),
|
||||
LowLevel::NumToFloatChecked => unreachable!(),
|
||||
LowLevel::NumDivUnchecked => unreachable!(),
|
||||
LowLevel::DictEmpty => unreachable!(),
|
||||
|
||||
// these are used internally and not tied to a symbol
|
||||
LowLevel::Hash => unimplemented!(),
|
||||
@ -156,21 +143,6 @@ map_symbol_to_lowlevel_and_arity! {
|
||||
ListDropAt; LIST_DROP_AT; 2,
|
||||
ListSwap; LIST_SWAP; 3,
|
||||
|
||||
DictSize; DICT_LEN; 1,
|
||||
DictInsert; DICT_INSERT; 3,
|
||||
DictRemove; DICT_REMOVE; 2,
|
||||
DictContains; DICT_CONTAINS; 2,
|
||||
DictGetUnsafe; DICT_GET_LOWLEVEL; 2,
|
||||
DictKeys; DICT_KEYS; 1,
|
||||
DictValues; DICT_VALUES; 1,
|
||||
DictUnion; DICT_UNION; 2,
|
||||
DictIntersection; DICT_INTERSECTION; 2,
|
||||
DictDifference; DICT_DIFFERENCE; 2,
|
||||
DictWalk; DICT_WALK; 3,
|
||||
|
||||
SetFromList; SET_FROM_LIST; 1,
|
||||
SetToDict; SET_TO_DICT; 1,
|
||||
|
||||
NumAdd; NUM_ADD; 2,
|
||||
NumAddWrap; NUM_ADD_WRAP; 2,
|
||||
NumAddChecked; NUM_ADD_CHECKED_LOWLEVEL; 2,
|
||||
@ -563,95 +535,3 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel)
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Dict.empty : Dict * *
|
||||
fn dict_empty(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let dict_var = var_store.fresh();
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::DictEmpty,
|
||||
args: vec![],
|
||||
ret_var: dict_var,
|
||||
};
|
||||
|
||||
Def {
|
||||
annotation: None,
|
||||
expr_var: dict_var,
|
||||
loc_expr: Loc::at_zero(body),
|
||||
loc_pattern: Loc::at_zero(Pattern::Identifier(symbol)),
|
||||
pattern_vars: SendMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set.empty : Set *
|
||||
fn set_empty(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let set_var = var_store.fresh();
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::DictEmpty,
|
||||
args: vec![],
|
||||
ret_var: set_var,
|
||||
};
|
||||
|
||||
Def {
|
||||
annotation: None,
|
||||
expr_var: set_var,
|
||||
loc_expr: Loc::at_zero(body),
|
||||
loc_pattern: Loc::at_zero(Pattern::Identifier(symbol)),
|
||||
pattern_vars: SendMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set.insert : Set k, k -> Set k
|
||||
fn set_insert(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let dict_var = var_store.fresh();
|
||||
let key_var = var_store.fresh();
|
||||
let val_var = Variable::EMPTY_RECORD;
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::DictInsert,
|
||||
args: vec![
|
||||
(dict_var, Var(Symbol::ARG_1)),
|
||||
(key_var, Var(Symbol::ARG_2)),
|
||||
(val_var, EmptyRecord),
|
||||
],
|
||||
ret_var: dict_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(dict_var, Symbol::ARG_1), (key_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
dict_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Set.single : k -> Set k
|
||||
fn set_single(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let key_var = var_store.fresh();
|
||||
let set_var = var_store.fresh();
|
||||
let value_var = Variable::EMPTY_RECORD;
|
||||
|
||||
let empty = RunLowLevel {
|
||||
op: LowLevel::DictEmpty,
|
||||
args: vec![],
|
||||
ret_var: set_var,
|
||||
};
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::DictInsert,
|
||||
args: vec![
|
||||
(set_var, empty),
|
||||
(key_var, Var(Symbol::ARG_1)),
|
||||
(value_var, EmptyRecord),
|
||||
],
|
||||
ret_var: set_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(key_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
set_var,
|
||||
)
|
||||
}
|
||||
|
@ -2,10 +2,6 @@ use crate::llvm::bitcode::{
|
||||
call_bitcode_fn, call_bitcode_fn_fixing_for_convention, call_list_bitcode_fn,
|
||||
call_str_bitcode_fn, call_void_bitcode_fn,
|
||||
};
|
||||
use crate::llvm::build_dict::{
|
||||
self, dict_contains, dict_difference, dict_empty, dict_get, dict_insert, dict_intersection,
|
||||
dict_keys, dict_len, dict_remove, dict_union, dict_values, dict_walk, set_from_list,
|
||||
};
|
||||
use crate::llvm::build_hash::generic_hash;
|
||||
use crate::llvm::build_list::{
|
||||
self, allocate_list, empty_polymorphic_list, list_append_unsafe, list_concat, list_drop_at,
|
||||
@ -2265,15 +2261,6 @@ pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
|
||||
.into_pointer_value()
|
||||
}
|
||||
|
||||
macro_rules! dict_key_value_layout {
|
||||
($dict_layout:expr) => {
|
||||
match $dict_layout {
|
||||
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => (key_layout, value_layout),
|
||||
_ => unreachable!("invalid dict layout"),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! list_element_layout {
|
||||
($list_layout:expr) => {
|
||||
match $list_layout {
|
||||
@ -2824,18 +2811,10 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||
build_list::decref(env, value.into_struct_value(), alignment);
|
||||
}
|
||||
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => {
|
||||
debug_assert!(value.is_struct_value());
|
||||
let alignment = key_layout
|
||||
.alignment_bytes(env.target_info)
|
||||
.max(value_layout.alignment_bytes(env.target_info));
|
||||
|
||||
build_dict::decref(env, value.into_struct_value(), alignment);
|
||||
todo!()
|
||||
}
|
||||
Layout::Builtin(Builtin::Set(key_layout)) => {
|
||||
debug_assert!(value.is_struct_value());
|
||||
let alignment = key_layout.alignment_bytes(env.target_info);
|
||||
|
||||
build_dict::decref(env, value.into_struct_value(), alignment);
|
||||
todo!()
|
||||
}
|
||||
|
||||
_ if layout.is_refcounted() => {
|
||||
@ -5341,40 +5320,6 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||
_ => unreachable!("invalid list layout"),
|
||||
}
|
||||
}
|
||||
DictWalk { xs, state } => {
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, xs);
|
||||
let (default, default_layout) = load_symbol_and_layout(scope, state);
|
||||
|
||||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match dict_layout {
|
||||
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => {
|
||||
let argument_layouts = &[*default_layout, **key_layout, **value_layout];
|
||||
|
||||
let roc_function_call = roc_function_call(
|
||||
env,
|
||||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
result_layout,
|
||||
);
|
||||
|
||||
dict_walk(
|
||||
env,
|
||||
roc_function_call,
|
||||
dict,
|
||||
default,
|
||||
key_layout,
|
||||
value_layout,
|
||||
default_layout,
|
||||
)
|
||||
}
|
||||
_ => unreachable!("invalid dict layout"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6135,109 +6080,8 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
|
||||
generic_hash(env, layout_ids, seed.into_int_value(), value, layout).into()
|
||||
}
|
||||
DictSize => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
dict_len(env, scope, args[0])
|
||||
}
|
||||
DictEmpty => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
dict_empty(env)
|
||||
}
|
||||
DictInsert => {
|
||||
debug_assert_eq!(args.len(), 3);
|
||||
|
||||
let (dict, _) = load_symbol_and_layout(scope, &args[0]);
|
||||
let (key, key_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||
let (value, value_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
dict_insert(env, layout_ids, dict, key, key_layout, value, value_layout)
|
||||
}
|
||||
DictRemove => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let key = load_symbol(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_remove(env, layout_ids, dict, key, key_layout, value_layout)
|
||||
}
|
||||
DictContains => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let key = load_symbol(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_contains(env, layout_ids, dict, key, key_layout, value_layout)
|
||||
}
|
||||
DictGetUnsafe => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let key = load_symbol(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_get(env, layout_ids, dict, key, key_layout, value_layout)
|
||||
}
|
||||
DictKeys => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_keys(env, layout_ids, dict, key_layout, value_layout)
|
||||
}
|
||||
DictValues => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_values(env, layout_ids, dict, key_layout, value_layout)
|
||||
}
|
||||
DictUnion => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict1, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let (dict2, _) = load_symbol_and_layout(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_union(env, layout_ids, dict1, dict2, key_layout, value_layout)
|
||||
}
|
||||
DictDifference => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict1, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let (dict2, _) = load_symbol_and_layout(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_difference(env, layout_ids, dict1, dict2, key_layout, value_layout)
|
||||
}
|
||||
DictIntersection => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (dict1, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let (dict2, _) = load_symbol_and_layout(scope, &args[1]);
|
||||
|
||||
let (key_layout, value_layout) = dict_key_value_layout!(dict_layout);
|
||||
dict_intersection(env, layout_ids, dict1, dict2, key_layout, value_layout)
|
||||
}
|
||||
SetFromList => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let key_layout = list_element_layout!(list_layout);
|
||||
set_from_list(env, layout_ids, list, key_layout)
|
||||
}
|
||||
SetToDict => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (set, _set_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
set
|
||||
}
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith | DictWalk => {
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith => {
|
||||
unreachable!("these are higher order, and are handled elsewhere")
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ impl<'a> LowLevelCall<'a> {
|
||||
|
||||
ListIsUnique => self.load_args_and_call_zig(backend, bitcode::LIST_IS_UNIQUE),
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith | DictWalk => {
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith => {
|
||||
internal_error!("HigherOrder lowlevels should not be handled here")
|
||||
}
|
||||
|
||||
@ -744,12 +744,6 @@ impl<'a> LowLevelCall<'a> {
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_SWAP, 8, false);
|
||||
}
|
||||
|
||||
DictSize | DictEmpty | DictInsert | DictRemove | DictContains | DictGetUnsafe
|
||||
| DictKeys | DictValues | DictUnion | DictIntersection | DictDifference
|
||||
| SetFromList | SetToDict => {
|
||||
todo!("{:?}", self.lowlevel);
|
||||
}
|
||||
|
||||
// Num
|
||||
NumAdd => match self.ret_layout {
|
||||
Layout::Builtin(Builtin::Int(width)) => {
|
||||
@ -2082,7 +2076,6 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||
ListMap { .. } | ListMap2 { .. } | ListMap3 { .. } | ListMap4 { .. } => {
|
||||
ProcSource::HigherOrderMapper(passed_proc_index)
|
||||
}
|
||||
DictWalk { .. } => todo!("DictWalk"),
|
||||
}
|
||||
};
|
||||
let wrapper_sym = backend.create_symbol(&format!("#wrap#{:?}", fn_name));
|
||||
@ -2230,8 +2223,6 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_SORT_WITH, 9, false);
|
||||
}
|
||||
|
||||
DictWalk { .. } => todo!("{:?}", op),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,20 +46,6 @@ pub enum LowLevel {
|
||||
ListDropAt,
|
||||
ListSwap,
|
||||
ListIsUnique,
|
||||
DictSize,
|
||||
DictEmpty,
|
||||
DictInsert,
|
||||
DictRemove,
|
||||
DictContains,
|
||||
DictGetUnsafe,
|
||||
DictKeys,
|
||||
DictValues,
|
||||
DictUnion,
|
||||
DictIntersection,
|
||||
DictDifference,
|
||||
DictWalk,
|
||||
SetFromList,
|
||||
SetToDict,
|
||||
NumAdd,
|
||||
NumAddWrap,
|
||||
NumAddChecked,
|
||||
@ -126,7 +112,7 @@ pub enum LowLevel {
|
||||
|
||||
macro_rules! higher_order {
|
||||
() => {
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith | DictWalk
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith
|
||||
};
|
||||
}
|
||||
|
||||
@ -148,7 +134,6 @@ impl LowLevel {
|
||||
ListMap3 => 3,
|
||||
ListMap4 => 4,
|
||||
ListSortWith => 1,
|
||||
DictWalk => 2,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -207,7 +192,6 @@ macro_rules! map_symbol_to_lowlevel {
|
||||
LowLevel::ListMap3 => unreachable!(),
|
||||
LowLevel::ListMap4 => unreachable!(),
|
||||
LowLevel::ListSortWith => unreachable!(),
|
||||
LowLevel::DictWalk => unreachable!(),
|
||||
|
||||
// (un)boxing is handled in a custom way
|
||||
LowLevel::BoxExpr => unreachable!(),
|
||||
@ -219,7 +203,6 @@ macro_rules! map_symbol_to_lowlevel {
|
||||
LowLevel::NumToIntChecked => unreachable!(),
|
||||
LowLevel::NumToFloatChecked => unreachable!(),
|
||||
LowLevel::NumDivUnchecked => unreachable!(),
|
||||
LowLevel::DictEmpty => unreachable!(),
|
||||
|
||||
// these are used internally and not tied to a symbol
|
||||
LowLevel::Hash => unimplemented!(),
|
||||
@ -275,18 +258,6 @@ map_symbol_to_lowlevel! {
|
||||
ListSublist <= LIST_SUBLIST_LOWLEVEL,
|
||||
ListDropAt <= LIST_DROP_AT,
|
||||
ListSwap <= LIST_SWAP,
|
||||
DictSize <= DICT_LEN,
|
||||
DictInsert <= DICT_INSERT,
|
||||
DictRemove <= DICT_REMOVE,
|
||||
DictContains <= DICT_CONTAINS,
|
||||
DictGetUnsafe <= DICT_GET_LOWLEVEL,
|
||||
DictKeys <= DICT_KEYS,
|
||||
DictValues <= DICT_VALUES,
|
||||
DictUnion <= DICT_UNION,
|
||||
DictIntersection <= DICT_INTERSECTION,
|
||||
DictDifference <= DICT_DIFFERENCE,
|
||||
SetFromList <= SET_FROM_LIST,
|
||||
SetToDict <= SET_TO_DICT,
|
||||
NumAdd <= NUM_ADD,
|
||||
NumAddWrap <= NUM_ADD_WRAP,
|
||||
NumAddChecked <= NUM_ADD_CHECKED_LOWLEVEL,
|
||||
|
@ -602,17 +602,6 @@ impl<'a> BorrowInfState<'a> {
|
||||
// always own the input list
|
||||
self.own_var(*xs);
|
||||
}
|
||||
DictWalk { xs, state } => {
|
||||
// own the default value if the function wants to own it
|
||||
if !function_ps[0].borrow {
|
||||
self.own_var(*state);
|
||||
}
|
||||
|
||||
// own the data structure if the function wants to own the element
|
||||
if !function_ps[1].borrow {
|
||||
self.own_var(*xs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// own the closure environment if the function needs to own it
|
||||
@ -939,20 +928,6 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||
StrRepeat => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
StrFromInt | StrFromFloat => arena.alloc_slice_copy(&[irrelevant]),
|
||||
Hash => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
DictSize => arena.alloc_slice_copy(&[borrowed]),
|
||||
DictEmpty => &[],
|
||||
DictInsert => arena.alloc_slice_copy(&[owned, owned, owned]),
|
||||
DictRemove => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
DictContains => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
||||
DictGetUnsafe => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
||||
DictKeys | DictValues => arena.alloc_slice_copy(&[borrowed]),
|
||||
DictUnion | DictDifference | DictIntersection => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
|
||||
// borrow function argument so we don't have to worry about RC of the closure
|
||||
DictWalk => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
|
||||
|
||||
SetFromList => arena.alloc_slice_copy(&[owned]),
|
||||
SetToDict => arena.alloc_slice_copy(&[owned]),
|
||||
|
||||
ListIsUnique => arena.alloc_slice_copy(&[borrowed]),
|
||||
|
||||
|
@ -809,22 +809,6 @@ impl<'a> Context<'a> {
|
||||
|
||||
let v = create_call!(function_ps.get(2));
|
||||
|
||||
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||
}
|
||||
DictWalk { xs, state: _ } => {
|
||||
let ownerships = [
|
||||
// borrow data structure based on second argument of the folded function
|
||||
(xs, function_ps[1]),
|
||||
];
|
||||
// borrow the default based on first argument of the folded function
|
||||
// (state, function_ps[0])
|
||||
|
||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||
|
||||
let b = handle_ownerships_post!(b, ownerships);
|
||||
|
||||
let v = create_call!(function_ps.get(2));
|
||||
|
||||
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||
}
|
||||
}
|
||||
|
@ -4986,57 +4986,6 @@ pub fn with_hole<'a>(
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! walk {
|
||||
($oh:ident) => {{
|
||||
debug_assert_eq!(arg_symbols.len(), 3);
|
||||
|
||||
const LIST_INDEX: usize = 0;
|
||||
const DEFAULT_INDEX: usize = 1;
|
||||
const CLOSURE_INDEX: usize = 2;
|
||||
|
||||
let xs = arg_symbols[LIST_INDEX];
|
||||
let state = arg_symbols[DEFAULT_INDEX];
|
||||
|
||||
let stmt = match_on_closure_argument!($oh, [xs, state]);
|
||||
|
||||
// because of a hack to implement List.product and List.sum, we need to also
|
||||
// assign to symbols here. Normally the arguments to a lowlevel function are
|
||||
// all symbols anyway, but because of this hack the closure symbol can be an
|
||||
// actual closure, and the default is either the number 1 or 0
|
||||
// this can be removed when we define builtin modules as proper modules
|
||||
|
||||
let stmt = assign_to_symbol(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
args[LIST_INDEX].0,
|
||||
Loc::at_zero(args[LIST_INDEX].1.clone()),
|
||||
arg_symbols[LIST_INDEX],
|
||||
stmt,
|
||||
);
|
||||
|
||||
let stmt = assign_to_symbol(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
args[DEFAULT_INDEX].0,
|
||||
Loc::at_zero(args[DEFAULT_INDEX].1.clone()),
|
||||
arg_symbols[DEFAULT_INDEX],
|
||||
stmt,
|
||||
);
|
||||
|
||||
assign_to_symbol(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
args[CLOSURE_INDEX].0,
|
||||
Loc::at_zero(args[CLOSURE_INDEX].1.clone()),
|
||||
arg_symbols[CLOSURE_INDEX],
|
||||
stmt,
|
||||
)
|
||||
}};
|
||||
}
|
||||
|
||||
use LowLevel::*;
|
||||
match op {
|
||||
ListMap => {
|
||||
@ -5049,7 +4998,6 @@ pub fn with_hole<'a>(
|
||||
let xs = arg_symbols[0];
|
||||
match_on_closure_argument!(ListSortWith, [xs])
|
||||
}
|
||||
DictWalk => walk!(DictWalk),
|
||||
ListMap2 => {
|
||||
debug_assert_eq!(arg_symbols.len(), 3);
|
||||
|
||||
|
@ -23,10 +23,6 @@ pub enum HigherOrder {
|
||||
ListSortWith {
|
||||
xs: Symbol,
|
||||
},
|
||||
DictWalk {
|
||||
xs: Symbol,
|
||||
state: Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
impl HigherOrder {
|
||||
@ -37,7 +33,6 @@ impl HigherOrder {
|
||||
HigherOrder::ListMap3 { .. } => 3,
|
||||
HigherOrder::ListMap4 { .. } => 4,
|
||||
HigherOrder::ListSortWith { .. } => 2,
|
||||
HigherOrder::DictWalk { .. } => 2,
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +46,6 @@ impl HigherOrder {
|
||||
ListMap2 { .. } => 3,
|
||||
ListMap3 { .. } => 4,
|
||||
ListMap4 { .. } => 5,
|
||||
DictWalk { .. } => 3,
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,18 +79,6 @@ enum FirstOrder {
|
||||
ListAppend,
|
||||
ListPrepend,
|
||||
ListSwap,
|
||||
DictSize,
|
||||
DictEmpty,
|
||||
DictInsert,
|
||||
DictRemove,
|
||||
DictContains,
|
||||
DictGetUnsafe,
|
||||
DictKeys,
|
||||
DictValues,
|
||||
DictUnion,
|
||||
DictIntersection,
|
||||
DictDifference,
|
||||
SetFromList,
|
||||
NumAdd,
|
||||
NumAddWrap,
|
||||
NumAddChecked,
|
||||
|
Loading…
Reference in New Issue
Block a user