mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Merge remote-tracking branch 'origin/trunk' into add-builtin-num-aliases
This commit is contained in:
commit
c789885499
29 changed files with 864 additions and 254 deletions
|
@ -1,7 +1,7 @@
|
||||||
interface Defaults
|
interface Defaults
|
||||||
exposes []
|
exposes []
|
||||||
imports [
|
imports [
|
||||||
Map.{ Map },
|
Dict.{ Dict },
|
||||||
Set.{ Set },
|
Set.{ Set },
|
||||||
Num.{ Num, Int, Float }
|
Num.{ Num, Int, Float }
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
interface Map2
|
interface Dict2
|
||||||
exposes [ isEmpty, map ]
|
exposes [ isEmpty, map ]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
isEmpty : Map * * -> Bool
|
isEmpty : Dict * * -> Bool
|
||||||
|
|
||||||
## Convert each key and value in the #Map to something new, by calling a conversion
|
## Convert each key and value in the #Dict to something new, by calling a conversion
|
||||||
## function on each of them. Then return a new #Map of the converted keys and values.
|
## function on each of them. Then return a new #Map of the converted keys and values.
|
||||||
##
|
##
|
||||||
## >>> Map.map {{ 3.14 => "pi", 1.0 => "one" }} \{ key, value } -> { key:
|
## >>> Dict.map {{ 3.14 => "pi", 1.0 => "one" }} \{ key, value } -> { key:
|
||||||
##
|
##
|
||||||
## >>> Map.map {[ "", "a", "bc" ]} Str.isEmpty
|
## >>> Dict.map {[ "", "a", "bc" ]} Str.isEmpty
|
||||||
##
|
##
|
||||||
## `map` functions like this are common in Roc, and they all work similarly.
|
## `map` functions like this are common in Roc, and they all work similarly.
|
||||||
## See for example #Result.map, #List.map, and #Set.map.
|
## See for example #Result.map, #List.map, and #Set.map.
|
|
@ -3,7 +3,7 @@ use roc_module::ident::TagName;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::Region;
|
use roc_region::all::Region;
|
||||||
use roc_types::builtin_aliases::{
|
use roc_types::builtin_aliases::{
|
||||||
bool_type, float_type, int_type, list_type, map_type, num_type, ordering_type, result_type,
|
bool_type, dict_type, float_type, int_type, list_type, num_type, ordering_type, result_type,
|
||||||
set_type, str_type,
|
set_type, str_type,
|
||||||
};
|
};
|
||||||
use roc_types::solved_types::SolvedType;
|
use roc_types::solved_types::SolvedType;
|
||||||
|
@ -30,7 +30,7 @@ pub fn standard_stdlib() -> StdLib {
|
||||||
applies: vec![
|
applies: vec![
|
||||||
Symbol::LIST_LIST,
|
Symbol::LIST_LIST,
|
||||||
Symbol::SET_SET,
|
Symbol::SET_SET,
|
||||||
Symbol::MAP_MAP,
|
Symbol::DICT_DICT,
|
||||||
Symbol::STR_STR,
|
Symbol::STR_STR,
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -614,39 +614,43 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
top_level_function(vec![list_type(flex(TVAR1))], Box::new(bool_type())),
|
top_level_function(vec![list_type(flex(TVAR1))], Box::new(bool_type())),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Map module
|
// Dict module
|
||||||
|
|
||||||
// empty : Map k v
|
// empty : Dict k v
|
||||||
add_type(Symbol::MAP_EMPTY, map_type(flex(TVAR1), flex(TVAR2)));
|
add_type(Symbol::DICT_EMPTY, dict_type(flex(TVAR1), flex(TVAR2)));
|
||||||
|
|
||||||
// singleton : k, v -> Map k v
|
// singleton : k, v -> Dict k v
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::MAP_SINGLETON,
|
Symbol::DICT_SINGLETON,
|
||||||
top_level_function(
|
top_level_function(
|
||||||
vec![flex(TVAR1), flex(TVAR2)],
|
vec![flex(TVAR1), flex(TVAR2)],
|
||||||
Box::new(map_type(flex(TVAR1), flex(TVAR2))),
|
Box::new(dict_type(flex(TVAR1), flex(TVAR2))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// get : Map k v, k -> Result v [ KeyNotFound ]*
|
// get : Dict k v, k -> Result v [ KeyNotFound ]*
|
||||||
let key_not_found = SolvedType::TagUnion(
|
let key_not_found = SolvedType::TagUnion(
|
||||||
vec![(TagName::Global("KeyNotFound".into()), vec![])],
|
vec![(TagName::Global("KeyNotFound".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
);
|
);
|
||||||
|
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::MAP_GET,
|
Symbol::DICT_GET,
|
||||||
top_level_function(
|
top_level_function(
|
||||||
vec![map_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)],
|
vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)],
|
||||||
Box::new(result_type(flex(TVAR2), key_not_found)),
|
Box::new(result_type(flex(TVAR2), key_not_found)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::MAP_INSERT,
|
Symbol::DICT_INSERT,
|
||||||
top_level_function(
|
top_level_function(
|
||||||
vec![map_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1), flex(TVAR2)],
|
vec![
|
||||||
Box::new(map_type(flex(TVAR1), flex(TVAR2))),
|
dict_type(flex(TVAR1), flex(TVAR2)),
|
||||||
|
flex(TVAR1),
|
||||||
|
flex(TVAR2),
|
||||||
|
],
|
||||||
|
Box::new(dict_type(flex(TVAR1), flex(TVAR2))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub fn uniq_stdlib() -> StdLib {
|
||||||
Symbol::ATTR_ATTR,
|
Symbol::ATTR_ATTR,
|
||||||
Symbol::LIST_LIST,
|
Symbol::LIST_LIST,
|
||||||
Symbol::SET_SET,
|
Symbol::SET_SET,
|
||||||
Symbol::MAP_MAP,
|
Symbol::DICT_DICT,
|
||||||
Symbol::STR_STR,
|
Symbol::STR_STR,
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -831,18 +831,18 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Map module
|
// Dict module
|
||||||
|
|
||||||
// empty : Attr * (Map k v)
|
// empty : Attr * (Dict k v)
|
||||||
add_type(Symbol::MAP_EMPTY, {
|
add_type(Symbol::DICT_EMPTY, {
|
||||||
let_tvars! { star, k , v };
|
let_tvars! { star, k , v };
|
||||||
map_type(star, k, v)
|
dict_type(star, k, v)
|
||||||
});
|
});
|
||||||
|
|
||||||
// singleton : k, v -> Attr * (Map k v)
|
// singleton : k, v -> Attr * (Dict k v)
|
||||||
add_type(Symbol::MAP_SINGLETON, {
|
add_type(Symbol::DICT_SINGLETON, {
|
||||||
let_tvars! { star, k , v };
|
let_tvars! { star, k , v };
|
||||||
unique_function(vec![flex(k), flex(v)], map_type(star, k, v))
|
unique_function(vec![flex(k), flex(v)], dict_type(star, k, v))
|
||||||
});
|
});
|
||||||
|
|
||||||
let key_not_found = SolvedType::Apply(
|
let key_not_found = SolvedType::Apply(
|
||||||
|
@ -856,10 +856,10 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
// get : Attr (* | u) (Map (Attr * key) (Attr u val))
|
// get : Attr (* | u) (Dict (Attr * key) (Attr u val))
|
||||||
// , Attr * key
|
// , Attr * key
|
||||||
// -> Attr * (Result (Attr u val) [ KeyNotFound ]*)
|
// -> Attr * (Result (Attr u val) [ KeyNotFound ]*)
|
||||||
add_type(Symbol::MAP_GET, {
|
add_type(Symbol::DICT_GET, {
|
||||||
let_tvars! { u, key, val, star1, star2, star3, star4 };
|
let_tvars! { u, key, val, star1, star2, star3, star4 };
|
||||||
|
|
||||||
unique_function(
|
unique_function(
|
||||||
|
@ -869,7 +869,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
vec![
|
vec![
|
||||||
container(star1, vec![u]),
|
container(star1, vec![u]),
|
||||||
SolvedType::Apply(
|
SolvedType::Apply(
|
||||||
Symbol::MAP_MAP,
|
Symbol::DICT_DICT,
|
||||||
vec![attr_type(star2, key), attr_type(u, val)],
|
vec![attr_type(star2, key), attr_type(u, val)],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -889,11 +889,11 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// insert : Attr * (Map key value)
|
// insert : Attr * (Dict key value)
|
||||||
// , key
|
// , key
|
||||||
// , value
|
// , value
|
||||||
// , Attr * (Map key value)
|
// , Attr * (Dict key value)
|
||||||
add_type(Symbol::MAP_INSERT, {
|
add_type(Symbol::DICT_INSERT, {
|
||||||
let_tvars! { star1, star2, key, value };
|
let_tvars! { star1, star2, key, value };
|
||||||
|
|
||||||
unique_function(
|
unique_function(
|
||||||
|
@ -902,7 +902,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Symbol::ATTR_ATTR,
|
Symbol::ATTR_ATTR,
|
||||||
vec![
|
vec![
|
||||||
flex(star1),
|
flex(star1),
|
||||||
SolvedType::Apply(Symbol::MAP_MAP, vec![flex(key), flex(value)]),
|
SolvedType::Apply(Symbol::DICT_DICT, vec![flex(key), flex(value)]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
flex(key),
|
flex(key),
|
||||||
|
@ -912,7 +912,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Symbol::ATTR_ATTR,
|
Symbol::ATTR_ATTR,
|
||||||
vec![
|
vec![
|
||||||
flex(star2),
|
flex(star2),
|
||||||
SolvedType::Apply(Symbol::MAP_MAP, vec![flex(key), flex(value)]),
|
SolvedType::Apply(Symbol::DICT_DICT, vec![flex(key), flex(value)]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1267,12 +1267,12 @@ fn set_type(u: VarId, a: VarId) -> SolvedType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn map_type(u: VarId, key: VarId, value: VarId) -> SolvedType {
|
fn dict_type(u: VarId, key: VarId, value: VarId) -> SolvedType {
|
||||||
SolvedType::Apply(
|
SolvedType::Apply(
|
||||||
Symbol::ATTR_ATTR,
|
Symbol::ATTR_ATTR,
|
||||||
vec![
|
vec![
|
||||||
flex(u),
|
flex(u),
|
||||||
SolvedType::Apply(Symbol::MAP_MAP, vec![flex(key), flex(value)]),
|
SolvedType::Apply(Symbol::DICT_DICT, vec![flex(key), flex(value)]),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,17 +477,16 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
} else {
|
} else {
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let len_u64 = str_literal.len() as u64;
|
let number_of_chars = str_literal.len() as u64;
|
||||||
let elem_bytes = CHAR_LAYOUT.stack_size(env.ptr_bytes) as u64;
|
|
||||||
let ptr_bytes = env.ptr_bytes;
|
let ptr_bytes = env.ptr_bytes;
|
||||||
|
|
||||||
let populate_str = |ptr| {
|
let populate_str = |ptr| {
|
||||||
// Copy the elements from the list literal into the array
|
// Copy the elements from the list literal into the array
|
||||||
for (index, char) in str_literal.as_bytes().iter().enumerate() {
|
for (index, character) in str_literal.as_bytes().iter().enumerate() {
|
||||||
let val = env
|
let val = env
|
||||||
.context
|
.context
|
||||||
.i8_type()
|
.i8_type()
|
||||||
.const_int(*char as u64, false)
|
.const_int(*character as u64, false)
|
||||||
.as_basic_value_enum();
|
.as_basic_value_enum();
|
||||||
let index_val = ctx.i64_type().const_int(index as u64, false);
|
let index_val = ctx.i64_type().const_int(index as u64, false);
|
||||||
let elem_ptr =
|
let elem_ptr =
|
||||||
|
@ -554,14 +553,14 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
"small_str_array",
|
"small_str_array",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let bytes_len = elem_bytes * len_u64;
|
let number_of_elements = env.ptr_int().const_int(number_of_chars, false);
|
||||||
let len_type = env.ptr_int();
|
|
||||||
let len = len_type.const_int(bytes_len, false);
|
|
||||||
|
|
||||||
// NOTE we rely on CHAR_LAYOUT turning into a `i8`
|
// NOTE we rely on CHAR_LAYOUT turning into a `i8`
|
||||||
let ptr = allocate_list(env, InPlace::Clone, &CHAR_LAYOUT, len);
|
let ptr = allocate_list(env, InPlace::Clone, &CHAR_LAYOUT, number_of_elements);
|
||||||
let struct_type = collection(ctx, ptr_bytes);
|
let struct_type = collection(ctx, ptr_bytes);
|
||||||
|
|
||||||
|
populate_str(ptr);
|
||||||
|
|
||||||
let mut struct_val;
|
let mut struct_val;
|
||||||
|
|
||||||
// Store the pointer
|
// Store the pointer
|
||||||
|
@ -576,11 +575,14 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
// Store the length
|
// Store the length
|
||||||
struct_val = builder
|
struct_val = builder
|
||||||
.build_insert_value(struct_val, len, Builtin::WRAPPER_LEN, "insert_len")
|
.build_insert_value(
|
||||||
|
struct_val,
|
||||||
|
number_of_elements,
|
||||||
|
Builtin::WRAPPER_LEN,
|
||||||
|
"insert_len",
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
populate_str(ptr);
|
|
||||||
|
|
||||||
builder.build_bitcast(
|
builder.build_bitcast(
|
||||||
struct_val.into_struct_value(),
|
struct_val.into_struct_value(),
|
||||||
collection(ctx, ptr_bytes),
|
collection(ctx, ptr_bytes),
|
||||||
|
@ -2170,15 +2172,24 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
for (name, layout) in aliases {
|
for (name, layout) in aliases {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Closure(arguments, closure, result) => {
|
Layout::Closure(arguments, closure, result) => {
|
||||||
|
// define closure size and return value size, e.g.
|
||||||
|
//
|
||||||
|
// * roc__mainForHost_1_Update_size() -> i64
|
||||||
|
// * roc__mainForHost_1_Update_result_size() -> i64
|
||||||
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
||||||
}
|
}
|
||||||
Layout::FunctionPointer(_arguments, _result) => {
|
Layout::FunctionPointer(arguments, result) => {
|
||||||
// TODO should this be considered a closure of size 0?
|
// define function size (equal to pointer size) and return value size, e.g.
|
||||||
// or do we let the host call it directly?
|
//
|
||||||
// then we have no RocCallResult wrapping though
|
// * roc__mainForHost_1_Update_size() -> i64
|
||||||
|
// * roc__mainForHost_1_Update_result_size() -> i64
|
||||||
|
build_function_caller(env, &fn_name, *name, arguments, result)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// TODO
|
// for anything else we only define the size symbol, e.g.
|
||||||
|
//
|
||||||
|
// * roc__mainForHost_1_Model_size() -> i64
|
||||||
|
build_host_exposed_alias_size(env, &fn_name, *name, layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2298,23 +2309,187 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let closure_data = builder.build_load(closure_data_ptr, "load_closure_data");
|
let closure_data = builder.build_load(closure_data_ptr, "load_closure_data");
|
||||||
|
|
||||||
let mut arguments = parameters;
|
let mut parameters = parameters;
|
||||||
arguments.push(closure_data);
|
parameters.push(closure_data);
|
||||||
|
|
||||||
let result = invoke_and_catch(env, function_value, function_ptr, &arguments, result_type);
|
let call_result = invoke_and_catch(env, function_value, function_ptr, ¶meters, result_type);
|
||||||
|
|
||||||
builder.build_store(output, result);
|
builder.build_store(output, call_result);
|
||||||
|
|
||||||
builder.build_return(None);
|
builder.build_return(None);
|
||||||
|
|
||||||
// STEP 3: build a {} -> u64 function that gives the size of the return type
|
// STEP 3: build a {} -> u64 function that gives the size of the return type
|
||||||
let size_function_type = env.context.i64_type().fn_type(&[], false);
|
build_host_exposed_alias_size_help(
|
||||||
let size_function_name: String = format!(
|
env,
|
||||||
"roc_{}_{}_size",
|
def_name,
|
||||||
|
alias_symbol,
|
||||||
|
Some("result"),
|
||||||
|
roc_call_result_type.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// STEP 4: build a {} -> u64 function that gives the size of the closure
|
||||||
|
let layout = Layout::Closure(arguments, closure.clone(), result);
|
||||||
|
build_host_exposed_alias_size(env, def_name, alias_symbol, &layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
|
def_name: &str,
|
||||||
|
alias_symbol: Symbol,
|
||||||
|
arguments: &[Layout<'a>],
|
||||||
|
result: &Layout<'a>,
|
||||||
|
) {
|
||||||
|
use inkwell::types::BasicType;
|
||||||
|
|
||||||
|
let arena = env.arena;
|
||||||
|
let context = &env.context;
|
||||||
|
let builder = env.builder;
|
||||||
|
|
||||||
|
// STEP 1: build function header
|
||||||
|
|
||||||
|
// e.g. `roc__main_1_Fx_caller`
|
||||||
|
let function_name = format!(
|
||||||
|
"roc_{}_{}_caller",
|
||||||
def_name,
|
def_name,
|
||||||
alias_symbol.ident_string(&env.interns)
|
alias_symbol.ident_string(&env.interns)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
||||||
|
|
||||||
|
for layout in arguments {
|
||||||
|
argument_types.push(basic_type_from_layout(
|
||||||
|
arena,
|
||||||
|
context,
|
||||||
|
layout,
|
||||||
|
env.ptr_bytes,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_pointer_type = {
|
||||||
|
let mut args = Vec::new_in(env.arena);
|
||||||
|
args.extend(arguments.iter().cloned());
|
||||||
|
|
||||||
|
// pretend the closure layout is empty
|
||||||
|
args.push(Layout::Struct(&[]));
|
||||||
|
|
||||||
|
let function_layout = Layout::FunctionPointer(&args, result);
|
||||||
|
|
||||||
|
// this is already a (function) pointer type
|
||||||
|
basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes)
|
||||||
|
};
|
||||||
|
argument_types.push(function_pointer_type);
|
||||||
|
|
||||||
|
let closure_argument_type = {
|
||||||
|
let basic_type =
|
||||||
|
basic_type_from_layout(arena, context, &Layout::Struct(&[]), env.ptr_bytes);
|
||||||
|
|
||||||
|
basic_type.ptr_type(AddressSpace::Generic)
|
||||||
|
};
|
||||||
|
argument_types.push(closure_argument_type.into());
|
||||||
|
|
||||||
|
let result_type = basic_type_from_layout(arena, context, result, env.ptr_bytes);
|
||||||
|
|
||||||
|
let roc_call_result_type =
|
||||||
|
context.struct_type(&[context.i64_type().into(), result_type], false);
|
||||||
|
|
||||||
|
let output_type = { roc_call_result_type.ptr_type(AddressSpace::Generic) };
|
||||||
|
argument_types.push(output_type.into());
|
||||||
|
|
||||||
|
let function_type = context.void_type().fn_type(&argument_types, false);
|
||||||
|
|
||||||
|
let function_value = env.module.add_function(
|
||||||
|
function_name.as_str(),
|
||||||
|
function_type,
|
||||||
|
Some(Linkage::External),
|
||||||
|
);
|
||||||
|
|
||||||
|
function_value.set_call_conventions(C_CALL_CONV);
|
||||||
|
|
||||||
|
// STEP 2: build function body
|
||||||
|
|
||||||
|
let entry = context.append_basic_block(function_value, "entry");
|
||||||
|
|
||||||
|
builder.position_at_end(entry);
|
||||||
|
|
||||||
|
let mut parameters = function_value.get_params();
|
||||||
|
let output = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
let _closure_data_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
let function_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
|
||||||
|
// let closure_data = context.struct_type(&[], false).const_zero().into();
|
||||||
|
|
||||||
|
let actual_function_type = basic_type_from_layout(
|
||||||
|
arena,
|
||||||
|
context,
|
||||||
|
&Layout::FunctionPointer(arguments, result),
|
||||||
|
env.ptr_bytes,
|
||||||
|
);
|
||||||
|
|
||||||
|
let function_ptr = builder
|
||||||
|
.build_bitcast(function_ptr, actual_function_type, "cast")
|
||||||
|
.into_pointer_value();
|
||||||
|
|
||||||
|
let call_result = invoke_and_catch(env, function_value, function_ptr, ¶meters, result_type);
|
||||||
|
|
||||||
|
builder.build_store(output, call_result);
|
||||||
|
|
||||||
|
builder.build_return(None);
|
||||||
|
|
||||||
|
// STEP 3: build a {} -> u64 function that gives the size of the return type
|
||||||
|
build_host_exposed_alias_size_help(
|
||||||
|
env,
|
||||||
|
def_name,
|
||||||
|
alias_symbol,
|
||||||
|
Some("result"),
|
||||||
|
roc_call_result_type.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// STEP 4: build a {} -> u64 function that gives the size of the function
|
||||||
|
let layout = Layout::FunctionPointer(arguments, result);
|
||||||
|
build_host_exposed_alias_size(env, def_name, alias_symbol, &layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_host_exposed_alias_size<'a, 'ctx, 'env>(
|
||||||
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
|
def_name: &str,
|
||||||
|
alias_symbol: Symbol,
|
||||||
|
layout: &Layout<'a>,
|
||||||
|
) {
|
||||||
|
build_host_exposed_alias_size_help(
|
||||||
|
env,
|
||||||
|
def_name,
|
||||||
|
alias_symbol,
|
||||||
|
None,
|
||||||
|
basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_host_exposed_alias_size_help<'a, 'ctx, 'env>(
|
||||||
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
|
def_name: &str,
|
||||||
|
alias_symbol: Symbol,
|
||||||
|
opt_label: Option<&str>,
|
||||||
|
basic_type: BasicTypeEnum<'ctx>,
|
||||||
|
) {
|
||||||
|
let builder = env.builder;
|
||||||
|
let context = env.context;
|
||||||
|
|
||||||
|
let size_function_type = env.context.i64_type().fn_type(&[], false);
|
||||||
|
let size_function_name: String = if let Some(label) = opt_label {
|
||||||
|
format!(
|
||||||
|
"roc_{}_{}_{}_size",
|
||||||
|
def_name,
|
||||||
|
alias_symbol.ident_string(&env.interns),
|
||||||
|
label
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"roc_{}_{}_size",
|
||||||
|
def_name,
|
||||||
|
alias_symbol.ident_string(&env.interns)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let size_function = env.module.add_function(
|
let size_function = env.module.add_function(
|
||||||
size_function_name.as_str(),
|
size_function_name.as_str(),
|
||||||
size_function_type,
|
size_function_type,
|
||||||
|
@ -2325,7 +2500,8 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
builder.position_at_end(entry);
|
builder.position_at_end(entry);
|
||||||
|
|
||||||
let size: BasicValueEnum = roc_call_result_type.size_of().unwrap().into();
|
use inkwell::types::BasicType;
|
||||||
|
let size: BasicValueEnum = basic_type.size_of().unwrap().into();
|
||||||
builder.build_return(Some(&size));
|
builder.build_return(Some(&size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2067,7 +2067,7 @@ pub fn allocate_list<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
inplace: InPlace,
|
inplace: InPlace,
|
||||||
elem_layout: &Layout<'a>,
|
elem_layout: &Layout<'a>,
|
||||||
length: IntValue<'ctx>,
|
number_of_elements: IntValue<'ctx>,
|
||||||
) -> PointerValue<'ctx> {
|
) -> PointerValue<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
@ -2075,10 +2075,11 @@ pub fn allocate_list<'a, 'ctx, 'env>(
|
||||||
let len_type = env.ptr_int();
|
let len_type = env.ptr_int();
|
||||||
let elem_bytes = elem_layout.stack_size(env.ptr_bytes) as u64;
|
let elem_bytes = elem_layout.stack_size(env.ptr_bytes) as u64;
|
||||||
let bytes_per_element = len_type.const_int(elem_bytes, false);
|
let bytes_per_element = len_type.const_int(elem_bytes, false);
|
||||||
let number_of_data_bytes = builder.build_int_mul(bytes_per_element, length, "data_length");
|
let number_of_data_bytes =
|
||||||
|
builder.build_int_mul(bytes_per_element, number_of_elements, "data_length");
|
||||||
|
|
||||||
let rc1 = match inplace {
|
let rc1 = match inplace {
|
||||||
InPlace::InPlace => length,
|
InPlace::InPlace => number_of_elements,
|
||||||
InPlace::Clone => {
|
InPlace::Clone => {
|
||||||
// the refcount of a new list is initially 1
|
// the refcount of a new list is initially 1
|
||||||
// we assume that the list is indeed used (dead variables are eliminated)
|
// we assume that the list is indeed used (dead variables are eliminated)
|
||||||
|
|
|
@ -158,7 +158,7 @@ pub fn basic_type_from_layout<'ctx>(
|
||||||
Float64 => context.f64_type().as_basic_type_enum(),
|
Float64 => context.f64_type().as_basic_type_enum(),
|
||||||
Float32 => context.f32_type().as_basic_type_enum(),
|
Float32 => context.f32_type().as_basic_type_enum(),
|
||||||
Float16 => context.f16_type().as_basic_type_enum(),
|
Float16 => context.f16_type().as_basic_type_enum(),
|
||||||
Map(_, _) | EmptyMap => panic!("TODO layout_to_basic_type for Builtin::Map"),
|
Dict(_, _) | EmptyDict => panic!("TODO layout_to_basic_type for Builtin::Dict"),
|
||||||
Set(_) | EmptySet => panic!("TODO layout_to_basic_type for Builtin::Set"),
|
Set(_) | EmptySet => panic!("TODO layout_to_basic_type for Builtin::Set"),
|
||||||
List(_, _) | Str | EmptyStr => collection(context, ptr_bytes).into(),
|
List(_, _) | Str | EmptyStr => collection(context, ptr_bytes).into(),
|
||||||
EmptyList => BasicTypeEnum::StructType(collection(context, ptr_bytes)),
|
EmptyList => BasicTypeEnum::StructType(collection(context, ptr_bytes)),
|
||||||
|
|
|
@ -59,12 +59,9 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
// pointer to usize
|
// pointer to usize
|
||||||
let refcount_type = ptr_int(env.context, env.ptr_bytes);
|
let refcount_type = ptr_int(env.context, env.ptr_bytes);
|
||||||
|
let refcount_ptr_type = refcount_type.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
let ptr_as_usize_ptr = cast_basic_basic(
|
let ptr_as_usize_ptr = cast_basic_basic(builder, data_ptr.into(), refcount_ptr_type.into())
|
||||||
builder,
|
|
||||||
data_ptr.into(),
|
|
||||||
refcount_type.ptr_type(AddressSpace::Generic).into(),
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
|
||||||
// get a pointer to index -1
|
// get a pointer to index -1
|
||||||
|
@ -400,7 +397,7 @@ fn decrement_refcount_builtin<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
Map(key_layout, value_layout) => {
|
Dict(key_layout, value_layout) => {
|
||||||
if key_layout.contains_refcounted() || value_layout.contains_refcounted() {
|
if key_layout.contains_refcounted() || value_layout.contains_refcounted() {
|
||||||
// TODO decrement all values
|
// TODO decrement all values
|
||||||
}
|
}
|
||||||
|
@ -431,6 +428,24 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>(
|
||||||
RecursiveUnion(tags) => {
|
RecursiveUnion(tags) => {
|
||||||
build_inc_union(env, layout_ids, tags, value);
|
build_inc_union(env, layout_ids, tags, value);
|
||||||
}
|
}
|
||||||
|
Closure(_, closure_layout, _) => {
|
||||||
|
if closure_layout.contains_refcounted() {
|
||||||
|
let wrapper_struct = value.into_struct_value();
|
||||||
|
|
||||||
|
let field_ptr = env
|
||||||
|
.builder
|
||||||
|
.build_extract_value(wrapper_struct, 1, "increment_closure_data")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
increment_refcount_layout(
|
||||||
|
env,
|
||||||
|
parent,
|
||||||
|
layout_ids,
|
||||||
|
field_ptr,
|
||||||
|
&closure_layout.as_block_of_memory_layout(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,7 +498,7 @@ fn increment_refcount_builtin<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
Map(key_layout, value_layout) => {
|
Dict(key_layout, value_layout) => {
|
||||||
if key_layout.contains_refcounted() || value_layout.contains_refcounted() {
|
if key_layout.contains_refcounted() || value_layout.contains_refcounted() {
|
||||||
// TODO decrement all values
|
// TODO decrement all values
|
||||||
}
|
}
|
||||||
|
|
|
@ -1206,11 +1206,11 @@ mod gen_primitives {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
||||||
|
|
||||||
Key k : Num k
|
Key k : Num k
|
||||||
|
|
||||||
insert : Key k, v, Dict (Key k) v -> Dict (Key k) v
|
insert : Key k, v, RedBlackTree (Key k) v -> RedBlackTree (Key k) v
|
||||||
insert = \key, value, dict ->
|
insert = \key, value, dict ->
|
||||||
when insertHelp key value dict is
|
when insertHelp key value dict is
|
||||||
Node Red k v l r ->
|
Node Red k v l r ->
|
||||||
|
@ -1219,7 +1219,7 @@ mod gen_primitives {
|
||||||
x ->
|
x ->
|
||||||
x
|
x
|
||||||
|
|
||||||
insertHelp : (Key k), v, Dict (Key k) v -> Dict (Key k) v
|
insertHelp : (Key k), v, RedBlackTree (Key k) v -> RedBlackTree (Key k) v
|
||||||
insertHelp = \key, value, dict ->
|
insertHelp = \key, value, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Empty ->
|
Empty ->
|
||||||
|
@ -1238,7 +1238,7 @@ mod gen_primitives {
|
||||||
GT ->
|
GT ->
|
||||||
balance nColor nKey nValue nLeft (insertHelp key value nRight)
|
balance nColor nKey nValue nLeft (insertHelp key value nRight)
|
||||||
|
|
||||||
balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rV rLeft rRight ->
|
Node Red rK rV rLeft rRight ->
|
||||||
|
@ -1267,7 +1267,7 @@ mod gen_primitives {
|
||||||
_ ->
|
_ ->
|
||||||
Node color key value left right
|
Node color key value left right
|
||||||
|
|
||||||
main : Dict I64 {}
|
main : RedBlackTree I64 {}
|
||||||
main =
|
main =
|
||||||
insert 0 {} Empty
|
insert 0 {} Empty
|
||||||
"#
|
"#
|
||||||
|
@ -1288,9 +1288,9 @@ mod gen_primitives {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k : [ Node NodeColor k (Dict k) (Dict k), Empty ]
|
RedBlackTree k : [ Node NodeColor k (RedBlackTree k) (RedBlackTree k), Empty ]
|
||||||
|
|
||||||
# balance : NodeColor, k, Dict k, Dict k -> Dict k
|
# balance : NodeColor, k, RedBlackTree k, RedBlackTree k -> RedBlackTree k
|
||||||
balance = \color, key, left, right ->
|
balance = \color, key, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rLeft rRight ->
|
Node Red rK rLeft rRight ->
|
||||||
|
@ -1308,7 +1308,7 @@ mod gen_primitives {
|
||||||
_ ->
|
_ ->
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
main : Dict I64
|
main : RedBlackTree I64
|
||||||
main =
|
main =
|
||||||
balance Red 0 Empty Empty
|
balance Red 0 Empty Empty
|
||||||
"#
|
"#
|
||||||
|
@ -1325,13 +1325,13 @@ mod gen_primitives {
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k) (Dict k), Empty ]
|
RedBlackTree k : [ Node k (RedBlackTree k) (RedBlackTree k), Empty ]
|
||||||
|
|
||||||
balance : k, Dict k -> Dict k
|
balance : k, RedBlackTree k -> RedBlackTree k
|
||||||
balance = \key, left ->
|
balance = \key, left ->
|
||||||
Node key left Empty
|
Node key left Empty
|
||||||
|
|
||||||
main : Dict I64
|
main : RedBlackTree I64
|
||||||
main =
|
main =
|
||||||
balance 0 Empty
|
balance 0 Empty
|
||||||
"#
|
"#
|
||||||
|
@ -1357,9 +1357,9 @@ mod gen_primitives {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
||||||
|
|
||||||
# balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
# balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rV rLeft rRight ->
|
Node Red rK rV rLeft rRight ->
|
||||||
|
@ -1378,7 +1378,7 @@ mod gen_primitives {
|
||||||
_ ->
|
_ ->
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RedBlackTree I64 I64
|
||||||
main =
|
main =
|
||||||
balance Red 0 0 Empty Empty
|
balance Red 0 0 Empty Empty
|
||||||
"#
|
"#
|
||||||
|
@ -1397,9 +1397,9 @@ mod gen_primitives {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
||||||
|
|
||||||
balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rV rLeft rRight ->
|
Node Red rK rV rLeft rRight ->
|
||||||
|
@ -1428,7 +1428,7 @@ mod gen_primitives {
|
||||||
_ ->
|
_ ->
|
||||||
Node color key value left right
|
Node color key value left right
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RedBlackTree I64 I64
|
||||||
main =
|
main =
|
||||||
balance Red 0 0 Empty Empty
|
balance Red 0 0 Empty Empty
|
||||||
"#
|
"#
|
||||||
|
|
|
@ -8,8 +8,8 @@ interface AStar
|
||||||
Model position :
|
Model position :
|
||||||
{ evaluated : Set position
|
{ evaluated : Set position
|
||||||
, openSet : Set position
|
, openSet : Set position
|
||||||
, costs : Map.Map position F64
|
, costs : Dict.Dict position F64
|
||||||
, cameFrom : Map.Map position position
|
, cameFrom : Dict.Dict position position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ initialModel : position -> Model position
|
||||||
initialModel = \start ->
|
initialModel = \start ->
|
||||||
{ evaluated : Set.empty
|
{ evaluated : Set.empty
|
||||||
, openSet : Set.singleton start
|
, openSet : Set.singleton start
|
||||||
, costs : Map.singleton start 0.0
|
, costs : Dict.singleton start 0.0
|
||||||
, cameFrom : Map.empty
|
, cameFrom : Dict.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ cheapestOpen : (position -> F64), Model position -> Result position [ KeyNotFoun
|
||||||
cheapestOpen = \costFunction, model ->
|
cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
folder = \position, resSmallestSoFar ->
|
folder = \position, resSmallestSoFar ->
|
||||||
when Map.get model.costs position is
|
when Dict.get model.costs position is
|
||||||
Err e ->
|
Err e ->
|
||||||
Err e
|
Err e
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
reconstructPath : Map position position, position -> List position
|
reconstructPath : Dict position position, position -> List position
|
||||||
reconstructPath = \cameFrom, goal ->
|
reconstructPath = \cameFrom, goal ->
|
||||||
when Map.get cameFrom goal is
|
when Dict.get cameFrom goal is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ reconstructPath = \cameFrom, goal ->
|
||||||
|
|
||||||
updateCost : position, position, Model position -> Model position
|
updateCost : position, position, Model position -> Model position
|
||||||
updateCost = \current, neighbour, model ->
|
updateCost = \current, neighbour, model ->
|
||||||
newCameFrom = Map.insert model.cameFrom neighbour current
|
newCameFrom = Dict.insert model.cameFrom neighbour current
|
||||||
|
|
||||||
newCosts = Map.insert model.costs neighbour distanceTo
|
newCosts = Dict.insert model.costs neighbour distanceTo
|
||||||
|
|
||||||
distanceTo = reconstructPath newCameFrom neighbour
|
distanceTo = reconstructPath newCameFrom neighbour
|
||||||
|> List.len
|
|> List.len
|
||||||
|
@ -68,7 +68,7 @@ updateCost = \current, neighbour, model ->
|
||||||
|
|
||||||
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
||||||
|
|
||||||
when Map.get model.costs neighbour is
|
when Dict.get model.costs neighbour is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
newModel
|
newModel
|
||||||
|
|
||||||
|
|
|
@ -242,15 +242,15 @@ mod test_load {
|
||||||
"RBTree",
|
"RBTree",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface RBTree exposes [ Dict, empty ] imports []
|
interface RBTree exposes [ RedBlackTree, empty ] imports []
|
||||||
|
|
||||||
# The color of a node. Leaves are considered Black.
|
# The color of a node. Leaves are considered Black.
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
||||||
|
|
||||||
# Create an empty dictionary.
|
# Create an empty dictionary.
|
||||||
empty : Dict k v
|
empty : RedBlackTree k v
|
||||||
empty =
|
empty =
|
||||||
Empty
|
Empty
|
||||||
"#
|
"#
|
||||||
|
@ -265,7 +265,7 @@ mod test_load {
|
||||||
imports [ RBTree ]
|
imports [ RBTree ]
|
||||||
provides [ main ] to blah
|
provides [ main ] to blah
|
||||||
|
|
||||||
empty : RBTree.Dict I64 I64
|
empty : RBTree.RedBlackTree I64 I64
|
||||||
empty = RBTree.empty
|
empty = RBTree.empty
|
||||||
|
|
||||||
main = empty
|
main = empty
|
||||||
|
@ -424,7 +424,7 @@ mod test_load {
|
||||||
hashmap! {
|
hashmap! {
|
||||||
"findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [ KeyNotFound ]*",
|
"findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [ KeyNotFound ]*",
|
||||||
"initialModel" => "position -> Model position",
|
"initialModel" => "position -> Model position",
|
||||||
"reconstructPath" => "Map position position, position -> List position",
|
"reconstructPath" => "Dict position position, position -> List position",
|
||||||
"updateCost" => "position, position, Model position -> Model position",
|
"updateCost" => "position, position, Model position -> Model position",
|
||||||
"cheapestOpen" => "(position -> F64), Model position -> Result position [ KeyNotFound ]*",
|
"cheapestOpen" => "(position -> F64), Model position -> Result position [ KeyNotFound ]*",
|
||||||
"astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*",
|
"astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*",
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl ModuleName {
|
||||||
pub const STR: &'static str = "Str";
|
pub const STR: &'static str = "Str";
|
||||||
pub const NUM: &'static str = "Num";
|
pub const NUM: &'static str = "Num";
|
||||||
pub const LIST: &'static str = "List";
|
pub const LIST: &'static str = "List";
|
||||||
pub const MAP: &'static str = "Map";
|
pub const DICT: &'static str = "Dict";
|
||||||
pub const SET: &'static str = "Set";
|
pub const SET: &'static str = "Set";
|
||||||
pub const RESULT: &'static str = "Result";
|
pub const RESULT: &'static str = "Result";
|
||||||
|
|
||||||
|
|
|
@ -845,13 +845,13 @@ define_builtins! {
|
||||||
0 RESULT_RESULT: "Result" imported // the Result.Result type alias
|
0 RESULT_RESULT: "Result" imported // the Result.Result type alias
|
||||||
1 RESULT_MAP: "map"
|
1 RESULT_MAP: "map"
|
||||||
}
|
}
|
||||||
6 MAP: "Map" => {
|
6 DICT: "Dict" => {
|
||||||
0 MAP_MAP: "Map" imported // the Map.Map type alias
|
0 DICT_DICT: "Dict" imported // the Dict.Dict type alias
|
||||||
1 MAP_AT_MAP: "@Map" // the Map.@Map private tag
|
1 DICT_AT_DICT: "@Dict" // the Dict.@Dict private tag
|
||||||
2 MAP_EMPTY: "empty"
|
2 DICT_EMPTY: "empty"
|
||||||
3 MAP_SINGLETON: "singleton"
|
3 DICT_SINGLETON: "singleton"
|
||||||
4 MAP_GET: "get"
|
4 DICT_GET: "get"
|
||||||
5 MAP_INSERT: "insert"
|
5 DICT_INSERT: "insert"
|
||||||
}
|
}
|
||||||
7 SET: "Set" => {
|
7 SET: "Set" => {
|
||||||
0 SET_SET: "Set" imported // the Set.Set type alias
|
0 SET_SET: "Set" imported // the Set.Set type alias
|
||||||
|
|
|
@ -587,7 +587,10 @@ impl<'a> Procs<'a> {
|
||||||
let symbol = name;
|
let symbol = name;
|
||||||
|
|
||||||
// TODO should pending_procs hold a Rc<Proc>?
|
// TODO should pending_procs hold a Rc<Proc>?
|
||||||
let partial_proc = self.partial_procs.get(&symbol).unwrap().clone();
|
let partial_proc = match self.partial_procs.get(&symbol) {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => panic!("no partial_proc for {:?}", symbol),
|
||||||
|
};
|
||||||
|
|
||||||
// Mark this proc as in-progress, so if we're dealing with
|
// Mark this proc as in-progress, so if we're dealing with
|
||||||
// mutually recursive functions, we don't loop forever.
|
// mutually recursive functions, we don't loop forever.
|
||||||
|
|
|
@ -317,12 +317,12 @@ pub enum Builtin<'a> {
|
||||||
Float32,
|
Float32,
|
||||||
Float16,
|
Float16,
|
||||||
Str,
|
Str,
|
||||||
Map(&'a Layout<'a>, &'a Layout<'a>),
|
Dict(&'a Layout<'a>, &'a Layout<'a>),
|
||||||
Set(&'a Layout<'a>),
|
Set(&'a Layout<'a>),
|
||||||
List(MemoryMode, &'a Layout<'a>),
|
List(MemoryMode, &'a Layout<'a>),
|
||||||
EmptyStr,
|
EmptyStr,
|
||||||
EmptyList,
|
EmptyList,
|
||||||
EmptyMap,
|
EmptyDict,
|
||||||
EmptySet,
|
EmptySet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,8 +667,8 @@ impl<'a> Builtin<'a> {
|
||||||
|
|
||||||
/// Number of machine words in an empty one of these
|
/// Number of machine words in an empty one of these
|
||||||
pub const STR_WORDS: u32 = 2;
|
pub const STR_WORDS: u32 = 2;
|
||||||
pub const MAP_WORDS: u32 = 6;
|
pub const DICT_WORDS: u32 = 6;
|
||||||
pub const SET_WORDS: u32 = Builtin::MAP_WORDS; // Set is an alias for Map with {} for value
|
pub const SET_WORDS: u32 = Builtin::DICT_WORDS; // Set is an alias for Dict with {} for value
|
||||||
pub const LIST_WORDS: u32 = 2;
|
pub const LIST_WORDS: u32 = 2;
|
||||||
|
|
||||||
/// Layout of collection wrapper for List and Str - a struct of (pointer, length).
|
/// Layout of collection wrapper for List and Str - a struct of (pointer, length).
|
||||||
|
@ -693,7 +693,7 @@ impl<'a> Builtin<'a> {
|
||||||
Float32 => Builtin::F32_SIZE,
|
Float32 => Builtin::F32_SIZE,
|
||||||
Float16 => Builtin::F16_SIZE,
|
Float16 => Builtin::F16_SIZE,
|
||||||
Str | EmptyStr => Builtin::STR_WORDS * pointer_size,
|
Str | EmptyStr => Builtin::STR_WORDS * pointer_size,
|
||||||
Map(_, _) | EmptyMap => Builtin::MAP_WORDS * pointer_size,
|
Dict(_, _) | EmptyDict => Builtin::DICT_WORDS * pointer_size,
|
||||||
Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size,
|
Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size,
|
||||||
List(_, _) | EmptyList => Builtin::LIST_WORDS * pointer_size,
|
List(_, _) | EmptyList => Builtin::LIST_WORDS * pointer_size,
|
||||||
}
|
}
|
||||||
|
@ -718,7 +718,7 @@ impl<'a> Builtin<'a> {
|
||||||
Float32 => align_of::<f32>() as u32,
|
Float32 => align_of::<f32>() as u32,
|
||||||
Float16 => align_of::<i16>() as u32,
|
Float16 => align_of::<i16>() as u32,
|
||||||
Str | EmptyStr => pointer_size,
|
Str | EmptyStr => pointer_size,
|
||||||
Map(_, _) | EmptyMap => pointer_size,
|
Dict(_, _) | EmptyDict => pointer_size,
|
||||||
Set(_) | EmptySet => pointer_size,
|
Set(_) | EmptySet => pointer_size,
|
||||||
List(_, _) | EmptyList => pointer_size,
|
List(_, _) | EmptyList => pointer_size,
|
||||||
}
|
}
|
||||||
|
@ -729,8 +729,8 @@ impl<'a> Builtin<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
||||||
| Float16 | EmptyStr | EmptyMap | EmptyList | EmptySet => true,
|
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true,
|
||||||
Str | Map(_, _) | Set(_) | List(_, _) => false,
|
Str | Dict(_, _) | Set(_) | List(_, _) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,13 +740,13 @@ impl<'a> Builtin<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
||||||
| Float16 | EmptyStr | EmptyMap | EmptyList | EmptySet => false,
|
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false,
|
||||||
List(mode, element_layout) => match mode {
|
List(mode, element_layout) => match mode {
|
||||||
MemoryMode::Refcounted => true,
|
MemoryMode::Refcounted => true,
|
||||||
MemoryMode::Unique => element_layout.contains_refcounted(),
|
MemoryMode::Unique => element_layout.contains_refcounted(),
|
||||||
},
|
},
|
||||||
|
|
||||||
Str | Map(_, _) | Set(_) => true,
|
Str | Dict(_, _) | Set(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,14 +269,14 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.4 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.4 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.4;
|
ret Test.4;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.2 = 1i64;
|
let Test.2 = 1i64;
|
||||||
let Test.3 = 2i64;
|
let Test.3 = 2i64;
|
||||||
let Test.1 = CallByName Num.14 Test.2 Test.3;
|
let Test.1 = CallByName Num.24 Test.2 Test.3;
|
||||||
ret Test.1;
|
ret Test.1;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -291,13 +291,13 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.36 (#Attr.2):
|
procedure Num.46 (#Attr.2):
|
||||||
let Test.3 = lowlevel NumRound #Attr.2;
|
let Test.3 = lowlevel NumRound #Attr.2;
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.2 = 3.6f64;
|
let Test.2 = 3.6f64;
|
||||||
let Test.1 = CallByName Num.36 Test.2;
|
let Test.1 = CallByName Num.46 Test.2;
|
||||||
ret Test.1;
|
ret Test.1;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -314,7 +314,7 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.32 (#Attr.2, #Attr.3):
|
procedure Num.42 (#Attr.2, #Attr.3):
|
||||||
let Test.17 = 0i64;
|
let Test.17 = 0i64;
|
||||||
let Test.13 = lowlevel NotEq #Attr.3 Test.17;
|
let Test.13 = lowlevel NotEq #Attr.3 Test.17;
|
||||||
if Test.13 then
|
if Test.13 then
|
||||||
|
@ -331,7 +331,7 @@ mod test_mono {
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.8 = 1000i64;
|
let Test.8 = 1000i64;
|
||||||
let Test.9 = 10i64;
|
let Test.9 = 10i64;
|
||||||
let Test.2 = CallByName Num.32 Test.8 Test.9;
|
let Test.2 = CallByName Num.42 Test.8 Test.9;
|
||||||
let Test.5 = 1i64;
|
let Test.5 = 1i64;
|
||||||
let Test.6 = Index 0 Test.2;
|
let Test.6 = Index 0 Test.2;
|
||||||
let Test.7 = lowlevel Eq Test.5 Test.6;
|
let Test.7 = lowlevel Eq Test.5 Test.6;
|
||||||
|
@ -357,14 +357,14 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.4 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.4 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.4;
|
ret Test.4;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.1 = 3i64;
|
let Test.1 = 3i64;
|
||||||
let Test.2 = 4i64;
|
let Test.2 = 4i64;
|
||||||
let Test.3 = CallByName Num.14 Test.1 Test.2;
|
let Test.3 = CallByName Num.24 Test.1 Test.2;
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -384,7 +384,7 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.5 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.5 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.5;
|
ret Test.5;
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ mod test_mono {
|
||||||
if Test.9 then
|
if Test.9 then
|
||||||
let Test.2 = Index 1 Test.1;
|
let Test.2 = Index 1 Test.1;
|
||||||
let Test.4 = 1i64;
|
let Test.4 = 1i64;
|
||||||
let Test.3 = CallByName Num.14 Test.2 Test.4;
|
let Test.3 = CallByName Num.24 Test.2 Test.4;
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
else
|
else
|
||||||
let Test.6 = 1i64;
|
let Test.6 = 1i64;
|
||||||
|
@ -480,7 +480,7 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.5 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.5 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.5;
|
ret Test.5;
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ mod test_mono {
|
||||||
let Test.2 = Struct {Test.6};
|
let Test.2 = Struct {Test.6};
|
||||||
let Test.1 = Index 0 Test.2;
|
let Test.1 = Index 0 Test.2;
|
||||||
let Test.4 = 3i64;
|
let Test.4 = 3i64;
|
||||||
let Test.3 = CallByName Num.14 Test.1 Test.4;
|
let Test.3 = CallByName Num.24 Test.1 Test.4;
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -511,7 +511,7 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.6;
|
ret Test.6;
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ mod test_mono {
|
||||||
let Test.7 = Index 1 Test.2;
|
let Test.7 = Index 1 Test.2;
|
||||||
let Test.3 = Index 1 Test.7;
|
let Test.3 = Index 1 Test.7;
|
||||||
let Test.5 = 1i64;
|
let Test.5 = 1i64;
|
||||||
let Test.4 = CallByName Num.14 Test.3 Test.5;
|
let Test.4 = CallByName Num.24 Test.3 Test.5;
|
||||||
ret Test.4;
|
ret Test.4;
|
||||||
else
|
else
|
||||||
jump Test.14;
|
jump Test.14;
|
||||||
|
@ -558,7 +558,7 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.6;
|
ret Test.6;
|
||||||
|
|
||||||
|
@ -569,7 +569,7 @@ mod test_mono {
|
||||||
joinpoint Test.11:
|
joinpoint Test.11:
|
||||||
let Test.1 = Index 0 Test.3;
|
let Test.1 = Index 0 Test.3;
|
||||||
let Test.2 = Index 1 Test.3;
|
let Test.2 = Index 1 Test.3;
|
||||||
let Test.5 = CallByName Num.14 Test.1 Test.2;
|
let Test.5 = CallByName Num.24 Test.1 Test.2;
|
||||||
ret Test.5;
|
ret Test.5;
|
||||||
in
|
in
|
||||||
let Test.9 = Index 1 Test.3;
|
let Test.9 = Index 1 Test.3;
|
||||||
|
@ -665,7 +665,7 @@ mod test_mono {
|
||||||
let Test.8 = lowlevel ListLen #Attr.2;
|
let Test.8 = lowlevel ListLen #Attr.2;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.6;
|
ret Test.6;
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ mod test_mono {
|
||||||
dec Test.1;
|
dec Test.1;
|
||||||
let Test.5 = CallByName List.7 Test.2;
|
let Test.5 = CallByName List.7 Test.2;
|
||||||
dec Test.2;
|
dec Test.2;
|
||||||
let Test.3 = CallByName Num.14 Test.4 Test.5;
|
let Test.3 = CallByName Num.24 Test.4 Test.5;
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1055,14 +1055,14 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
|
||||||
procedure Test.1 (Test.2):
|
procedure Test.1 (Test.2):
|
||||||
let Test.3 = Index 0 Test.2;
|
let Test.3 = Index 0 Test.2;
|
||||||
let Test.4 = Index 1 Test.2;
|
let Test.4 = Index 1 Test.2;
|
||||||
let Test.7 = CallByName Num.14 Test.3 Test.4;
|
let Test.7 = CallByName Num.24 Test.3 Test.4;
|
||||||
ret Test.7;
|
ret Test.7;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
|
@ -1091,14 +1091,14 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
|
||||||
procedure Test.1 (Test.2):
|
procedure Test.1 (Test.2):
|
||||||
let Test.3 = 10i64;
|
let Test.3 = 10i64;
|
||||||
let Test.4 = Index 1 Test.2;
|
let Test.4 = Index 1 Test.2;
|
||||||
let Test.7 = CallByName Num.14 Test.3 Test.4;
|
let Test.7 = CallByName Num.24 Test.3 Test.4;
|
||||||
ret Test.7;
|
ret Test.7;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
|
@ -1124,14 +1124,14 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
|
||||||
procedure Test.1 (Test.4):
|
procedure Test.1 (Test.4):
|
||||||
let Test.2 = Index 0 Test.4;
|
let Test.2 = Index 0 Test.4;
|
||||||
let Test.3 = Index 1 Test.4;
|
let Test.3 = Index 1 Test.4;
|
||||||
let Test.7 = CallByName Num.14 Test.2 Test.3;
|
let Test.7 = CallByName Num.24 Test.2 Test.3;
|
||||||
ret Test.7;
|
ret Test.7;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
|
@ -1158,14 +1158,14 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
|
||||||
procedure Test.1 (Test.4):
|
procedure Test.1 (Test.4):
|
||||||
let Test.2 = 10i64;
|
let Test.2 = 10i64;
|
||||||
let Test.3 = Index 1 Test.4;
|
let Test.3 = Index 1 Test.4;
|
||||||
let Test.7 = CallByName Num.14 Test.2 Test.3;
|
let Test.7 = CallByName Num.24 Test.2 Test.3;
|
||||||
ret Test.7;
|
ret Test.7;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
|
@ -1496,11 +1496,11 @@ mod test_mono {
|
||||||
"#,
|
"#,
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.15 (#Attr.2, #Attr.3):
|
procedure Num.25 (#Attr.2, #Attr.3):
|
||||||
let Test.14 = lowlevel NumSub #Attr.2 #Attr.3;
|
let Test.14 = lowlevel NumSub #Attr.2 #Attr.3;
|
||||||
ret Test.14;
|
ret Test.14;
|
||||||
|
|
||||||
procedure Num.16 (#Attr.2, #Attr.3):
|
procedure Num.26 (#Attr.2, #Attr.3):
|
||||||
let Test.12 = lowlevel NumMul #Attr.2 #Attr.3;
|
let Test.12 = lowlevel NumMul #Attr.2 #Attr.3;
|
||||||
ret Test.12;
|
ret Test.12;
|
||||||
|
|
||||||
|
@ -1512,8 +1512,8 @@ mod test_mono {
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
else
|
else
|
||||||
let Test.13 = 1i64;
|
let Test.13 = 1i64;
|
||||||
let Test.10 = CallByName Num.15 Test.2 Test.13;
|
let Test.10 = CallByName Num.25 Test.2 Test.13;
|
||||||
let Test.11 = CallByName Num.16 Test.2 Test.3;
|
let Test.11 = CallByName Num.26 Test.2 Test.3;
|
||||||
jump Test.7 Test.10 Test.11;
|
jump Test.7 Test.10 Test.11;
|
||||||
in
|
in
|
||||||
jump Test.7 Test.2 Test.3;
|
jump Test.7 Test.2 Test.3;
|
||||||
|
@ -1715,7 +1715,7 @@ mod test_mono {
|
||||||
let Test.9 = lowlevel ListLen #Attr.2;
|
let Test.9 = lowlevel ListLen #Attr.2;
|
||||||
ret Test.9;
|
ret Test.9;
|
||||||
|
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.7 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.7 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.7;
|
ret Test.7;
|
||||||
|
|
||||||
|
@ -1740,7 +1740,7 @@ mod test_mono {
|
||||||
let Test.8 = FunctionPointer Test.1;
|
let Test.8 = FunctionPointer Test.1;
|
||||||
let Test.6 = CallByName List.7 Test.8;
|
let Test.6 = CallByName List.7 Test.8;
|
||||||
dec Test.8;
|
dec Test.8;
|
||||||
let Test.4 = CallByName Num.14 Test.5 Test.6;
|
let Test.4 = CallByName Num.24 Test.5 Test.6;
|
||||||
ret Test.4;
|
ret Test.4;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1935,7 +1935,7 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.16 (#Attr.2, #Attr.3):
|
procedure Num.26 (#Attr.2, #Attr.3):
|
||||||
let Test.13 = lowlevel NumMul #Attr.2 #Attr.3;
|
let Test.13 = lowlevel NumMul #Attr.2 #Attr.3;
|
||||||
ret Test.13;
|
ret Test.13;
|
||||||
|
|
||||||
|
@ -1976,9 +1976,9 @@ mod test_mono {
|
||||||
let Test.22 = false;
|
let Test.22 = false;
|
||||||
let Test.15 = Struct {Test.21, Test.22};
|
let Test.15 = Struct {Test.21, Test.22};
|
||||||
let Test.2 = CallByName Test.1 Test.15;
|
let Test.2 = CallByName Test.1 Test.15;
|
||||||
let Test.14 = CallByName Num.16 Test.2 Test.3;
|
let Test.14 = CallByName Num.26 Test.2 Test.3;
|
||||||
let Test.12 = CallByName Num.16 Test.14 Test.4;
|
let Test.12 = CallByName Num.26 Test.14 Test.4;
|
||||||
let Test.11 = CallByName Num.16 Test.12 Test.5;
|
let Test.11 = CallByName Num.26 Test.12 Test.5;
|
||||||
ret Test.11;
|
ret Test.11;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -2002,7 +2002,7 @@ mod test_mono {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
procedure Num.14 (#Attr.2, #Attr.3):
|
procedure Num.24 (#Attr.2, #Attr.3):
|
||||||
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
let Test.6 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
ret Test.6;
|
ret Test.6;
|
||||||
|
|
||||||
|
@ -2028,7 +2028,7 @@ mod test_mono {
|
||||||
let Test.7 = Index 1 Test.2;
|
let Test.7 = Index 1 Test.2;
|
||||||
let Test.3 = Index 1 Test.7;
|
let Test.3 = Index 1 Test.7;
|
||||||
let Test.5 = 1i64;
|
let Test.5 = 1i64;
|
||||||
let Test.4 = CallByName Num.14 Test.3 Test.5;
|
let Test.4 = CallByName Num.24 Test.3 Test.5;
|
||||||
ret Test.4;
|
ret Test.4;
|
||||||
else
|
else
|
||||||
jump Test.14;
|
jump Test.14;
|
||||||
|
|
|
@ -447,9 +447,9 @@ mod test_reporting {
|
||||||
these names seem close though:
|
these names seem close though:
|
||||||
|
|
||||||
baz
|
baz
|
||||||
Map
|
|
||||||
Str
|
Str
|
||||||
main
|
main
|
||||||
|
U8
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -3534,8 +3534,8 @@ mod test_reporting {
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
Num
|
Num
|
||||||
Map
|
|
||||||
Set
|
Set
|
||||||
|
Str
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -3928,10 +3928,10 @@ mod test_reporting {
|
||||||
# The color of a node. Leaves are considered Black.
|
# The color of a node. Leaves are considered Black.
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RBTree k v : [ Node NodeColor k v (RBTree k v) (RBTree k v), Empty ]
|
||||||
|
|
||||||
# Create an empty dictionary.
|
# Create an empty dictionary.
|
||||||
empty : Dict k v
|
empty : RBTree k v
|
||||||
empty =
|
empty =
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
|
|
|
@ -3102,10 +3102,10 @@ mod solve_expr {
|
||||||
infer_eq_without_problem(
|
infer_eq_without_problem(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Map.insert
|
Dict.insert
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Map a b, a, b -> Map a b",
|
"Dict a b, a, b -> Dict a b",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3186,9 +3186,9 @@ mod solve_expr {
|
||||||
infer_eq_without_problem(
|
infer_eq_without_problem(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
reconstructPath : Map position position, position -> List position
|
reconstructPath : Dict position position, position -> List position
|
||||||
reconstructPath = \cameFrom, goal ->
|
reconstructPath = \cameFrom, goal ->
|
||||||
when Map.get cameFrom goal is
|
when Dict.get cameFrom goal is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -3198,7 +3198,7 @@ mod solve_expr {
|
||||||
reconstructPath
|
reconstructPath
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Map position position, position -> List position",
|
"Dict position position, position -> List position",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3695,22 +3695,22 @@ mod solve_expr {
|
||||||
# The color of a node. Leaves are considered Black.
|
# The color of a node. Leaves are considered Black.
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RBTree k v : [ Node NodeColor k v (RBTree k v) (RBTree k v), Empty ]
|
||||||
|
|
||||||
# Create an empty dictionary.
|
# Create an empty dictionary.
|
||||||
empty : Dict k v
|
empty : RBTree k v
|
||||||
empty =
|
empty =
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
foo : Dict I64 I64
|
foo : RBTree I64 I64
|
||||||
foo = empty
|
foo = empty
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RBTree I64 I64
|
||||||
main =
|
main =
|
||||||
foo
|
foo
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64 I64",
|
"RBTree I64 I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3725,21 +3725,21 @@ mod solve_expr {
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k), Empty ]
|
RBTree k : [ Node k (RBTree k), Empty ]
|
||||||
|
|
||||||
balance : Dict k -> Dict k
|
balance : RBTree k -> RBTree k
|
||||||
balance = \left ->
|
balance = \left ->
|
||||||
when left is
|
when left is
|
||||||
Node _ Empty -> Empty
|
Node _ Empty -> Empty
|
||||||
|
|
||||||
_ -> Empty
|
_ -> Empty
|
||||||
|
|
||||||
main : Dict {}
|
main : RBTree {}
|
||||||
main =
|
main =
|
||||||
balance Empty
|
balance Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict {}",
|
"RBTree {}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3752,9 +3752,9 @@ mod solve_expr {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RBTree k v : [ Node NodeColor k v (RBTree k v) (RBTree k v), Empty ]
|
||||||
|
|
||||||
moveRedLeft : Dict k v -> Dict k v
|
moveRedLeft : RBTree k v -> RBTree k v
|
||||||
moveRedLeft = \dict ->
|
moveRedLeft = \dict ->
|
||||||
when dict is
|
when dict is
|
||||||
# Node clr k v (Node lClr lK lV lLeft lRight) (Node rClr rK rV ((Node Red rlK rlV rlL rlR) as rLeft) rRight) ->
|
# Node clr k v (Node lClr lK lV lLeft lRight) (Node rClr rK rV ((Node Red rlK rlV rlL rlR) as rLeft) rRight) ->
|
||||||
|
@ -3790,7 +3790,7 @@ mod solve_expr {
|
||||||
_ ->
|
_ ->
|
||||||
dict
|
dict
|
||||||
|
|
||||||
balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
balance : NodeColor, k, v, RBTree k v, RBTree k v -> RBTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rV rLeft rRight ->
|
Node Red rK rV rLeft rRight ->
|
||||||
|
@ -3822,7 +3822,7 @@ mod solve_expr {
|
||||||
|
|
||||||
Key k : Num k
|
Key k : Num k
|
||||||
|
|
||||||
removeHelpEQGT : Key k, Dict (Key k) v -> Dict (Key k) v
|
removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v
|
||||||
removeHelpEQGT = \targetKey, dict ->
|
removeHelpEQGT = \targetKey, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Node color key value left right ->
|
Node color key value left right ->
|
||||||
|
@ -3839,7 +3839,7 @@ mod solve_expr {
|
||||||
Empty ->
|
Empty ->
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
getMin : Dict k v -> Dict k v
|
getMin : RBTree k v -> RBTree k v
|
||||||
getMin = \dict ->
|
getMin = \dict ->
|
||||||
when dict is
|
when dict is
|
||||||
# Node _ _ _ ((Node _ _ _ _ _) as left) _ ->
|
# Node _ _ _ ((Node _ _ _ _ _) as left) _ ->
|
||||||
|
@ -3852,7 +3852,7 @@ mod solve_expr {
|
||||||
dict
|
dict
|
||||||
|
|
||||||
|
|
||||||
moveRedRight : Dict k v -> Dict k v
|
moveRedRight : RBTree k v -> RBTree k v
|
||||||
moveRedRight = \dict ->
|
moveRedRight = \dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Node clr k v (Node lClr lK lV (Node Red llK llV llLeft llRight) lRight) (Node rClr rK rV rLeft rRight) ->
|
Node clr k v (Node lClr lK lV (Node Red llK llV llLeft llRight) lRight) (Node rClr rK rV rLeft rRight) ->
|
||||||
|
@ -3885,7 +3885,7 @@ mod solve_expr {
|
||||||
dict
|
dict
|
||||||
|
|
||||||
|
|
||||||
removeHelpPrepEQGT : Key k, Dict (Key k) v, NodeColor, (Key k), v, Dict (Key k) v, Dict (Key k) v -> Dict (Key k) v
|
removeHelpPrepEQGT : Key k, RBTree (Key k) v, NodeColor, (Key k), v, RBTree (Key k) v, RBTree (Key k) v -> RBTree (Key k) v
|
||||||
removeHelpPrepEQGT = \_, dict, color, key, value, left, right ->
|
removeHelpPrepEQGT = \_, dict, color, key, value, left, right ->
|
||||||
when left is
|
when left is
|
||||||
Node Red lK lV lLeft lRight ->
|
Node Red lK lV lLeft lRight ->
|
||||||
|
@ -3908,7 +3908,7 @@ mod solve_expr {
|
||||||
dict
|
dict
|
||||||
|
|
||||||
|
|
||||||
removeMin : Dict k v -> Dict k v
|
removeMin : RBTree k v -> RBTree k v
|
||||||
removeMin = \dict ->
|
removeMin = \dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Node color key value left right ->
|
Node color key value left right ->
|
||||||
|
@ -3936,7 +3936,7 @@ mod solve_expr {
|
||||||
_ ->
|
_ ->
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
removeHelp : Key k, Dict (Key k) v -> Dict (Key k) v
|
removeHelp : Key k, RBTree (Key k) v -> RBTree (Key k) v
|
||||||
removeHelp = \targetKey, dict ->
|
removeHelp = \targetKey, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Empty ->
|
Empty ->
|
||||||
|
@ -3964,12 +3964,12 @@ mod solve_expr {
|
||||||
removeHelpEQGT targetKey (removeHelpPrepEQGT targetKey dict color key value left right)
|
removeHelpEQGT targetKey (removeHelpPrepEQGT targetKey dict color key value left right)
|
||||||
|
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RBTree I64 I64
|
||||||
main =
|
main =
|
||||||
removeHelp 1 Empty
|
removeHelp 1 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64 I64",
|
"RBTree I64 I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3980,9 +3980,9 @@ mod solve_expr {
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k) (Dict k), Empty ]
|
RBTree k : [ Node k (RBTree k) (RBTree k), Empty ]
|
||||||
|
|
||||||
removeHelp : Num k, Dict (Num k) -> Dict (Num k)
|
removeHelp : Num k, RBTree (Num k) -> RBTree (Num k)
|
||||||
removeHelp = \targetKey, dict ->
|
removeHelp = \targetKey, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Empty ->
|
Empty ->
|
||||||
|
@ -4004,12 +4004,12 @@ mod solve_expr {
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
|
|
||||||
main : Dict I64
|
main : RBTree I64
|
||||||
main =
|
main =
|
||||||
removeHelp 1 Empty
|
removeHelp 1 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64",
|
"RBTree I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4022,9 +4022,9 @@ mod solve_expr {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RBTree k v : [ Node NodeColor k v (RBTree k v) (RBTree k v), Empty ]
|
||||||
|
|
||||||
removeHelp : Num k, Dict (Num k) v -> Dict (Num k) v
|
removeHelp : Num k, RBTree (Num k) v -> RBTree (Num k) v
|
||||||
removeHelp = \targetKey, dict ->
|
removeHelp = \targetKey, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Empty ->
|
Empty ->
|
||||||
|
@ -4053,13 +4053,13 @@ mod solve_expr {
|
||||||
|
|
||||||
Key k : Num k
|
Key k : Num k
|
||||||
|
|
||||||
balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
balance : NodeColor, k, v, RBTree k v, RBTree k v -> RBTree k v
|
||||||
|
|
||||||
moveRedLeft : Dict k v -> Dict k v
|
moveRedLeft : RBTree k v -> RBTree k v
|
||||||
|
|
||||||
removeHelpPrepEQGT : Key k, Dict (Key k) v, NodeColor, (Key k), v, Dict (Key k) v, Dict (Key k) v -> Dict (Key k) v
|
removeHelpPrepEQGT : Key k, RBTree (Key k) v, NodeColor, (Key k), v, RBTree (Key k) v, RBTree (Key k) v -> RBTree (Key k) v
|
||||||
|
|
||||||
removeHelpEQGT : Key k, Dict (Key k) v -> Dict (Key k) v
|
removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v
|
||||||
removeHelpEQGT = \targetKey, dict ->
|
removeHelpEQGT = \targetKey, dict ->
|
||||||
when dict is
|
when dict is
|
||||||
Node color key value left right ->
|
Node color key value left right ->
|
||||||
|
@ -4076,16 +4076,16 @@ mod solve_expr {
|
||||||
Empty ->
|
Empty ->
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
getMin : Dict k v -> Dict k v
|
getMin : RBTree k v -> RBTree k v
|
||||||
|
|
||||||
removeMin : Dict k v -> Dict k v
|
removeMin : RBTree k v -> RBTree k v
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RBTree I64 I64
|
||||||
main =
|
main =
|
||||||
removeHelp 1 Empty
|
removeHelp 1 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64 I64",
|
"RBTree I64 I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4134,18 +4134,18 @@ mod solve_expr {
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k) (Dict k), Empty ]
|
RBTree k : [ Node k (RBTree k) (RBTree k), Empty ]
|
||||||
|
|
||||||
balance : k, Dict k -> Dict k
|
balance : k, RBTree k -> RBTree k
|
||||||
balance = \key, left ->
|
balance = \key, left ->
|
||||||
Node key left Empty
|
Node key left Empty
|
||||||
|
|
||||||
main : Dict I64
|
main : RBTree I64
|
||||||
main =
|
main =
|
||||||
balance 0 Empty
|
balance 0 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64",
|
"RBTree I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4156,20 +4156,20 @@ mod solve_expr {
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k) (Dict k), Empty ]
|
RBTree k : [ Node k (RBTree k) (RBTree k), Empty ]
|
||||||
|
|
||||||
node = \x,y,z -> Node x y z
|
node = \x,y,z -> Node x y z
|
||||||
|
|
||||||
balance : k, Dict k -> Dict k
|
balance : k, RBTree k -> RBTree k
|
||||||
balance = \key, left ->
|
balance = \key, left ->
|
||||||
node key left Empty
|
node key left Empty
|
||||||
|
|
||||||
main : Dict I64
|
main : RBTree I64
|
||||||
main =
|
main =
|
||||||
balance 0 Empty
|
balance 0 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64",
|
"RBTree I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4182,9 +4182,9 @@ mod solve_expr {
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [ Red, Black ]
|
||||||
|
|
||||||
Dict k v : [ Node NodeColor k v (Dict k v) (Dict k v), Empty ]
|
RBTree k v : [ Node NodeColor k v (RBTree k v) (RBTree k v), Empty ]
|
||||||
|
|
||||||
balance : NodeColor, k, v, Dict k v, Dict k v -> Dict k v
|
balance : NodeColor, k, v, RBTree k v, RBTree k v -> RBTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
when right is
|
when right is
|
||||||
Node Red rK rV rLeft rRight ->
|
Node Red rK rV rLeft rRight ->
|
||||||
|
@ -4213,12 +4213,12 @@ mod solve_expr {
|
||||||
_ ->
|
_ ->
|
||||||
Node color key value left right
|
Node color key value left right
|
||||||
|
|
||||||
main : Dict I64 I64
|
main : RBTree I64 I64
|
||||||
main =
|
main =
|
||||||
balance Red 0 0 Empty Empty
|
balance Red 0 0 Empty Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64 I64",
|
"RBTree I64 I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4230,9 +4230,9 @@ mod solve_expr {
|
||||||
r#"
|
r#"
|
||||||
app Test provides [ main ] imports []
|
app Test provides [ main ] imports []
|
||||||
|
|
||||||
Dict k : [ Node k (Dict k) (Dict k), Empty ]
|
RBTree k : [ Node k (RBTree k) (RBTree k), Empty ]
|
||||||
|
|
||||||
balance : k, Dict k -> Dict k
|
balance : k, RBTree k -> RBTree k
|
||||||
balance = \key, left ->
|
balance = \key, left ->
|
||||||
when left is
|
when left is
|
||||||
Node _ _ lRight ->
|
Node _ _ lRight ->
|
||||||
|
@ -4242,12 +4242,12 @@ mod solve_expr {
|
||||||
Empty
|
Empty
|
||||||
|
|
||||||
|
|
||||||
main : Dict I64
|
main : RBTree I64
|
||||||
main =
|
main =
|
||||||
balance 0 Empty
|
balance 0 Empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Dict I64",
|
"RBTree I64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2397,24 +2397,24 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_empty() {
|
fn map_empty() {
|
||||||
infer_eq("Map.empty", "Attr * (Map * *)");
|
infer_eq("Dict.empty", "Attr * (Dict * *)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_singelton() {
|
fn map_singelton() {
|
||||||
infer_eq("Map.singleton", "Attr * (a, b -> Attr * (Map a b))");
|
infer_eq("Dict.singleton", "Attr * (a, b -> Attr * (Dict a b))");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_get() {
|
fn map_get() {
|
||||||
infer_eq("Map.get", "Attr * (Attr (* | c) (Map (Attr * a) (Attr c b)), Attr * a -> Attr * (Result (Attr c b) (Attr * [ KeyNotFound ]*)))");
|
infer_eq("Dict.get", "Attr * (Attr (* | c) (Dict (Attr * a) (Attr c b)), Attr * a -> Attr * (Result (Attr c b) (Attr * [ KeyNotFound ]*)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_insert() {
|
fn map_insert() {
|
||||||
infer_eq(
|
infer_eq(
|
||||||
"Map.insert",
|
"Dict.insert",
|
||||||
"Attr * (Attr * (Map a b), a, b -> Attr * (Map a b))",
|
"Attr * (Attr * (Dict a b), a, b -> Attr * (Dict a b))",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2747,9 +2747,9 @@ mod solve_uniq_expr {
|
||||||
infer_eq(
|
infer_eq(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
reconstructPath : Map position position, position -> List position
|
reconstructPath : Dict position position, position -> List position
|
||||||
reconstructPath = \cameFrom, goal ->
|
reconstructPath = \cameFrom, goal ->
|
||||||
when Map.get cameFrom goal is
|
when Dict.get cameFrom goal is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -2759,7 +2759,7 @@ mod solve_uniq_expr {
|
||||||
reconstructPath
|
reconstructPath
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Attr Shared (Attr Shared (Map (Attr * position) (Attr Shared position)), Attr Shared position -> Attr * (List (Attr Shared position)))"
|
"Attr Shared (Attr Shared (Dict (Attr * position) (Attr Shared position)), Attr Shared position -> Attr * (List (Attr Shared position)))"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2772,15 +2772,15 @@ mod solve_uniq_expr {
|
||||||
r#"
|
r#"
|
||||||
Model position : { evaluated : Set position
|
Model position : { evaluated : Set position
|
||||||
, openSet : Set position
|
, openSet : Set position
|
||||||
, costs : Map.Map position F64
|
, costs : Dict.Dict position F64
|
||||||
, cameFrom : Map.Map position position
|
, cameFrom : Dict.Dict position position
|
||||||
}
|
}
|
||||||
|
|
||||||
cheapestOpen : (position -> F64), Model position -> Result position [ KeyNotFound ]*
|
cheapestOpen : (position -> F64), Model position -> Result position [ KeyNotFound ]*
|
||||||
cheapestOpen = \costFunction, model ->
|
cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
folder = \position, resSmallestSoFar ->
|
folder = \position, resSmallestSoFar ->
|
||||||
when Map.get model.costs position is
|
when Dict.get model.costs position is
|
||||||
Err e ->
|
Err e ->
|
||||||
Err e
|
Err e
|
||||||
|
|
||||||
|
@ -2815,13 +2815,13 @@ mod solve_uniq_expr {
|
||||||
r#"
|
r#"
|
||||||
Model position : { evaluated : Set position
|
Model position : { evaluated : Set position
|
||||||
, openSet : Set position
|
, openSet : Set position
|
||||||
, costs : Map.Map position F64
|
, costs : Dict.Dict position F64
|
||||||
, cameFrom : Map.Map position position
|
, cameFrom : Dict.Dict position position
|
||||||
}
|
}
|
||||||
|
|
||||||
reconstructPath : Map position position, position -> List position
|
reconstructPath : Dict position position, position -> List position
|
||||||
reconstructPath = \cameFrom, goal ->
|
reconstructPath = \cameFrom, goal ->
|
||||||
when Map.get cameFrom goal is
|
when Dict.get cameFrom goal is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -2830,9 +2830,9 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
updateCost : position, position, Model position -> Model position
|
updateCost : position, position, Model position -> Model position
|
||||||
updateCost = \current, neighbour, model ->
|
updateCost = \current, neighbour, model ->
|
||||||
newCameFrom = Map.insert model.cameFrom neighbour current
|
newCameFrom = Dict.insert model.cameFrom neighbour current
|
||||||
|
|
||||||
newCosts = Map.insert model.costs neighbour distanceTo
|
newCosts = Dict.insert model.costs neighbour distanceTo
|
||||||
|
|
||||||
distanceTo = reconstructPath newCameFrom neighbour
|
distanceTo = reconstructPath newCameFrom neighbour
|
||||||
|> List.len
|
|> List.len
|
||||||
|
@ -2840,7 +2840,7 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
||||||
|
|
||||||
when Map.get model.costs neighbour is
|
when Dict.get model.costs neighbour is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
newModel
|
newModel
|
||||||
|
|
||||||
|
@ -2867,8 +2867,8 @@ mod solve_uniq_expr {
|
||||||
r#"
|
r#"
|
||||||
Model position : { evaluated : Set position
|
Model position : { evaluated : Set position
|
||||||
, openSet : Set position
|
, openSet : Set position
|
||||||
, costs : Map.Map position F64
|
, costs : Dict.Dict position F64
|
||||||
, cameFrom : Map.Map position position
|
, cameFrom : Dict.Dict position position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2876,8 +2876,8 @@ mod solve_uniq_expr {
|
||||||
initialModel = \start ->
|
initialModel = \start ->
|
||||||
{ evaluated : Set.empty
|
{ evaluated : Set.empty
|
||||||
, openSet : Set.singleton start
|
, openSet : Set.singleton start
|
||||||
, costs : Map.singleton start 0.0
|
, costs : Dict.singleton start 0.0
|
||||||
, cameFrom : Map.empty
|
, cameFrom : Dict.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2885,7 +2885,7 @@ mod solve_uniq_expr {
|
||||||
cheapestOpen = \costFunction, model ->
|
cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
folder = \position, resSmallestSoFar ->
|
folder = \position, resSmallestSoFar ->
|
||||||
when Map.get model.costs position is
|
when Dict.get model.costs position is
|
||||||
Err e ->
|
Err e ->
|
||||||
Err e
|
Err e
|
||||||
|
|
||||||
|
@ -2906,9 +2906,9 @@ mod solve_uniq_expr {
|
||||||
|> Result.map (\x -> x.position)
|
|> Result.map (\x -> x.position)
|
||||||
|
|
||||||
|
|
||||||
reconstructPath : Map position position, position -> List position
|
reconstructPath : Dict position position, position -> List position
|
||||||
reconstructPath = \cameFrom, goal ->
|
reconstructPath = \cameFrom, goal ->
|
||||||
when Map.get cameFrom goal is
|
when Dict.get cameFrom goal is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -2918,9 +2918,9 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
updateCost : position, position, Model position -> Model position
|
updateCost : position, position, Model position -> Model position
|
||||||
updateCost = \current, neighbour, model ->
|
updateCost = \current, neighbour, model ->
|
||||||
newCameFrom = Map.insert model.cameFrom neighbour current
|
newCameFrom = Dict.insert model.cameFrom neighbour current
|
||||||
|
|
||||||
newCosts = Map.insert model.costs neighbour distanceTo
|
newCosts = Dict.insert model.costs neighbour distanceTo
|
||||||
|
|
||||||
distanceTo =
|
distanceTo =
|
||||||
reconstructPath newCameFrom neighbour
|
reconstructPath newCameFrom neighbour
|
||||||
|
@ -2929,7 +2929,7 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
newModel = { model & costs : newCosts , cameFrom : newCameFrom }
|
||||||
|
|
||||||
when Map.get model.costs neighbour is
|
when Dict.get model.costs neighbour is
|
||||||
Err KeyNotFound ->
|
Err KeyNotFound ->
|
||||||
newModel
|
newModel
|
||||||
|
|
||||||
|
|
|
@ -347,8 +347,8 @@ pub fn set_type(a: SolvedType) -> SolvedType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn map_type(key: SolvedType, value: SolvedType) -> SolvedType {
|
pub fn dict_type(key: SolvedType, value: SolvedType) -> SolvedType {
|
||||||
SolvedType::Apply(Symbol::MAP_MAP, vec![key, value])
|
SolvedType::Apply(Symbol::DICT_DICT, vec![key, value])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_private_tag(symbol: Symbol, type_arguments: Vec<SolvedType>) -> SolvedType {
|
fn single_private_tag(symbol: Symbol, type_arguments: Vec<SolvedType>) -> SolvedType {
|
||||||
|
|
|
@ -150,7 +150,7 @@ pub enum Type {
|
||||||
actual: Box<Type>,
|
actual: Box<Type>,
|
||||||
},
|
},
|
||||||
RecursiveTagUnion(Variable, Vec<(TagName, Vec<Type>)>, Box<Type>),
|
RecursiveTagUnion(Variable, Vec<(TagName, Vec<Type>)>, Box<Type>),
|
||||||
/// Applying a type to some arguments (e.g. Map.Map String Int)
|
/// Applying a type to some arguments (e.g. Dict.Dict String Int)
|
||||||
Apply(Symbol, Vec<Type>),
|
Apply(Symbol, Vec<Type>),
|
||||||
/// Boolean type used in uniqueness inference
|
/// Boolean type used in uniqueness inference
|
||||||
Boolean(boolean_algebra::Bool),
|
Boolean(boolean_algebra::Bool),
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn main() {
|
||||||
generate(
|
generate(
|
||||||
vec![
|
vec![
|
||||||
PathBuf::from(r"../compiler/builtins/docs/Bool.roc"),
|
PathBuf::from(r"../compiler/builtins/docs/Bool.roc"),
|
||||||
PathBuf::from(r"../compiler/builtins/docs/Map.roc"),
|
PathBuf::from(r"../compiler/builtins/docs/Dict.roc"),
|
||||||
// Not working
|
// Not working
|
||||||
// PathBuf::from(r"../compiler/builtins/docs/List.roc"),
|
// PathBuf::from(r"../compiler/builtins/docs/List.roc"),
|
||||||
// Not working
|
// Not working
|
||||||
|
|
7
examples/tea/Main.roc
Normal file
7
examples/tea/Main.roc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
app "effect-example"
|
||||||
|
packages { base: "platform" }
|
||||||
|
imports [base.Cmd]
|
||||||
|
provides [ main ] to base
|
||||||
|
|
||||||
|
main : I64
|
||||||
|
main = 42
|
21
examples/tea/platform/Cargo.lock
generated
Normal file
21
examples/tea/platform/Cargo.lock
generated
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "host"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"roc_std",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.81"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roc_std"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
13
examples/tea/platform/Cargo.toml
Normal file
13
examples/tea/platform/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "host"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Richard Feldman <oss@rtfeldman.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
roc_std = { path = "../../../roc_std" }
|
||||||
|
|
||||||
|
[workspace]
|
24
examples/tea/platform/Cmd.roc
Normal file
24
examples/tea/platform/Cmd.roc
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
interface Cmd
|
||||||
|
exposes [ Cmd, none, map, putLine, getLine, always, after ]
|
||||||
|
imports [ Effect ]
|
||||||
|
|
||||||
|
Cmd a : Effect.Effect a
|
||||||
|
|
||||||
|
none : Cmd {}
|
||||||
|
none = Effect.always {}
|
||||||
|
|
||||||
|
always : {} -> Cmd {}
|
||||||
|
always = \x -> Effect.always x
|
||||||
|
|
||||||
|
getLine : (Str -> msg) -> Cmd msg
|
||||||
|
getLine = \toMsg ->
|
||||||
|
Effect.map Effect.getLine toMsg
|
||||||
|
|
||||||
|
putLine : Str -> Cmd {}
|
||||||
|
putLine = \line -> Effect.putLine line
|
||||||
|
|
||||||
|
map : Cmd a, (a -> b) -> Cmd b
|
||||||
|
map = \cmd, transform -> Effect.map cmd transform
|
||||||
|
|
||||||
|
after : Cmd a, (a -> Cmd b) -> Cmd b
|
||||||
|
after = \cmd, transform -> Effect.after cmd transform
|
41
examples/tea/platform/Pkg-Config.roc
Normal file
41
examples/tea/platform/Pkg-Config.roc
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
platform folkertdev/foo
|
||||||
|
requires { main : Effect {} }
|
||||||
|
exposes []
|
||||||
|
packages {}
|
||||||
|
imports [Cmd]
|
||||||
|
provides [ mainForHost ]
|
||||||
|
effects Effect
|
||||||
|
{
|
||||||
|
putChar : I64 -> Effect {},
|
||||||
|
putLine : Str -> Effect {},
|
||||||
|
getLine : Effect Str
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mainForHost :
|
||||||
|
{
|
||||||
|
init : ({} -> { model: I64, cmd : (Cmd.Cmd [ Line Str ]) as Fx }) as Init,
|
||||||
|
update : ([ Line Str ], I64 -> { model: I64, cmd : Cmd.Cmd [ Line Str ] } ) as Update
|
||||||
|
}
|
||||||
|
mainForHost =
|
||||||
|
{
|
||||||
|
init : \{} ->
|
||||||
|
{
|
||||||
|
model: 42,
|
||||||
|
cmd:
|
||||||
|
Cmd.after (Cmd.putLine "Type a thing, and I'll say it back") \{} ->
|
||||||
|
Cmd.getLine (\l -> Line l)
|
||||||
|
},
|
||||||
|
update : \msg, model ->
|
||||||
|
when msg is
|
||||||
|
Line line ->
|
||||||
|
cmd =
|
||||||
|
Cmd.after (Cmd.putLine "You said:") \{} ->
|
||||||
|
Cmd.after (Cmd.putLine line) \{} ->
|
||||||
|
Cmd.after (Cmd.putLine "Type another thing, and I'll say it back") \{} ->
|
||||||
|
Cmd.getLine (\l -> Line l)
|
||||||
|
|
||||||
|
{ model: model + 1, cmd }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
7
examples/tea/platform/host.c
Normal file
7
examples/tea/platform/host.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int rust_main();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return rust_main();
|
||||||
|
}
|
298
examples/tea/platform/src/lib.rs
Normal file
298
examples/tea/platform/src/lib.rs
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use roc_std::alloca;
|
||||||
|
use roc_std::RocCallResult;
|
||||||
|
use roc_std::RocStr;
|
||||||
|
use std::alloc::Layout;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
type Msg = RocStr;
|
||||||
|
type Model = i64;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "roc__mainForHost_1_exposed"]
|
||||||
|
fn roc_main(output: *mut u8) -> ();
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_size"]
|
||||||
|
fn roc_main_size() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Init_caller"]
|
||||||
|
fn call_Init(function_pointer: *const u8, closure_data: *const u8, output: *mut u8) -> ();
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Init_size"]
|
||||||
|
fn size_Init() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Init_result_size"]
|
||||||
|
fn size_Init_result() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Update_caller"]
|
||||||
|
fn call_Update(
|
||||||
|
msg: Msg,
|
||||||
|
model: Model,
|
||||||
|
function_pointer: *const u8,
|
||||||
|
closure_data: *const u8,
|
||||||
|
output: *mut u8,
|
||||||
|
) -> ();
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Update_size"]
|
||||||
|
fn size_Update() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Update_result_size"]
|
||||||
|
fn size_Update_result() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Fx_caller"]
|
||||||
|
fn call_Fx(function_pointer: *const u8, closure_data: *const u8, output: *mut u8) -> ();
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Fx_size"]
|
||||||
|
fn size_Fx() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Fx_result_size"]
|
||||||
|
fn size_Fx_result() -> i64;
|
||||||
|
|
||||||
|
#[link_name = "roc__mainForHost_1_Model_size"]
|
||||||
|
fn size_Model() -> i64;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn roc_fx_putChar(foo: i64) -> () {
|
||||||
|
let character = foo as u8 as char;
|
||||||
|
print!("{}", character);
|
||||||
|
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn roc_fx_putLine(line: RocStr) -> () {
|
||||||
|
let bytes = line.as_slice();
|
||||||
|
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
||||||
|
println!("{}", string);
|
||||||
|
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn roc_fx_getLine() -> RocStr {
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
|
||||||
|
let stdin = io::stdin();
|
||||||
|
let line1 = stdin.lock().lines().next().unwrap().unwrap();
|
||||||
|
|
||||||
|
RocStr::from_slice_with_capacity(line1.as_bytes(), line1.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run_fx(function_pointer: *const u8, closure_data_ptr: *const u8) -> Msg {
|
||||||
|
let size = size_Fx_result() as usize;
|
||||||
|
|
||||||
|
alloca::with_stack_bytes(size, |buffer| {
|
||||||
|
let buffer: *mut std::ffi::c_void = buffer;
|
||||||
|
let buffer: *mut u8 = buffer as *mut u8;
|
||||||
|
|
||||||
|
call_Fx(
|
||||||
|
function_pointer,
|
||||||
|
closure_data_ptr as *const u8,
|
||||||
|
buffer as *mut u8,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = &*(buffer as *mut RocCallResult<()>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok(()) => {
|
||||||
|
let mut bytes = *(buffer.add(8) as *const (u64, u64));
|
||||||
|
let msg = std::mem::transmute::<(u64, u64), RocStr>(bytes);
|
||||||
|
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(e) => panic!("failed with {}", e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run_init(function_pointer: *const u8, closure_data_ptr: *const u8) -> (Model, Msg) {
|
||||||
|
let size = size_Init_result() as usize;
|
||||||
|
|
||||||
|
alloca::with_stack_bytes(size, |buffer| {
|
||||||
|
let buffer: *mut std::ffi::c_void = buffer;
|
||||||
|
let buffer: *mut u8 = buffer as *mut u8;
|
||||||
|
|
||||||
|
call_Init(function_pointer, 0 as *const u8, buffer as *mut u8);
|
||||||
|
|
||||||
|
// cmd < model, so the command comes first
|
||||||
|
let output = &*(buffer as *mut RocCallResult<()>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok(_) => {
|
||||||
|
let offset = 8 + size_Fx();
|
||||||
|
let model_ptr = buffer.add(offset as usize);
|
||||||
|
let model: i64 = *(model_ptr as *const i64);
|
||||||
|
|
||||||
|
let cmd_fn_ptr_ptr = buffer.add(8) as *const i64;
|
||||||
|
let cmd_fn_ptr = (*cmd_fn_ptr_ptr) as *const u8;
|
||||||
|
let cmd_closure_data_ptr = buffer.add(16);
|
||||||
|
|
||||||
|
let msg = run_fx(cmd_fn_ptr, cmd_closure_data_ptr);
|
||||||
|
|
||||||
|
(model, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(e) => panic!("failed with {}", e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run_update(
|
||||||
|
msg: RocStr,
|
||||||
|
model: Model,
|
||||||
|
function_pointer: *const u8,
|
||||||
|
closure_data_ptr: *const u8,
|
||||||
|
) -> (Model, Msg) {
|
||||||
|
let size = size_Update_result() as usize;
|
||||||
|
|
||||||
|
alloca::with_stack_bytes(size, |buffer| {
|
||||||
|
let buffer: *mut std::ffi::c_void = buffer;
|
||||||
|
let buffer: *mut u8 = buffer as *mut u8;
|
||||||
|
|
||||||
|
call_Update(
|
||||||
|
msg,
|
||||||
|
model,
|
||||||
|
function_pointer,
|
||||||
|
closure_data_ptr,
|
||||||
|
buffer as *mut u8,
|
||||||
|
);
|
||||||
|
|
||||||
|
// cmd < model, so the command comes first
|
||||||
|
let output = &*(buffer as *mut RocCallResult<()>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok(_) => {
|
||||||
|
let offset = 8 + size_Fx();
|
||||||
|
let model_ptr = buffer.add(offset as usize);
|
||||||
|
let model: i64 = *(model_ptr as *const i64);
|
||||||
|
|
||||||
|
let cmd_fn_ptr_ptr = buffer.add(8) as *const i64;
|
||||||
|
let cmd_fn_ptr = (*cmd_fn_ptr_ptr) as *const u8;
|
||||||
|
let cmd_closure_data_ptr = buffer.add(16);
|
||||||
|
|
||||||
|
let msg = run_fx(cmd_fn_ptr, cmd_closure_data_ptr);
|
||||||
|
|
||||||
|
(model, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(e) => panic!("failed with {}", e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn rust_main() -> isize {
|
||||||
|
let start_time = SystemTime::now();
|
||||||
|
|
||||||
|
let size = unsafe { roc_main_size() } as usize;
|
||||||
|
let layout = Layout::array::<u8>(size).unwrap();
|
||||||
|
let answer = unsafe {
|
||||||
|
let buffer = std::alloc::alloc(layout);
|
||||||
|
|
||||||
|
roc_main(buffer);
|
||||||
|
|
||||||
|
let output = &*(buffer as *mut RocCallResult<(*const u8, *const u8)>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok((init_fn_ptr, update_fn_ptr)) => {
|
||||||
|
// let closure_data_ptr = buffer.offset(16);
|
||||||
|
let closure_data_ptr = 0 as *const u8;
|
||||||
|
|
||||||
|
let (mut model, mut msg) =
|
||||||
|
run_init(init_fn_ptr as *const u8, closure_data_ptr as *const u8);
|
||||||
|
|
||||||
|
for _ in 0..5 {
|
||||||
|
let result = run_update(
|
||||||
|
msg,
|
||||||
|
model,
|
||||||
|
update_fn_ptr as *const u8,
|
||||||
|
closure_data_ptr as *const u8,
|
||||||
|
);
|
||||||
|
|
||||||
|
model = result.0;
|
||||||
|
msg = result.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::alloc::dealloc(buffer, layout);
|
||||||
|
|
||||||
|
model
|
||||||
|
}
|
||||||
|
Err(msg) => {
|
||||||
|
std::alloc::dealloc(buffer, layout);
|
||||||
|
|
||||||
|
panic!("Roc failed with message: {}", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let end_time = SystemTime::now();
|
||||||
|
let duration = end_time.duration_since(start_time).unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Roc closure took {:.4} ms to compute this answer: {:?}",
|
||||||
|
duration.as_secs_f64() * 1000.0,
|
||||||
|
// truncate the answer, so stdout is not swamped
|
||||||
|
answer
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exit code
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn old_rust_main() -> isize {
|
||||||
|
println!("Running Roc closure");
|
||||||
|
let start_time = SystemTime::now();
|
||||||
|
|
||||||
|
let size = unsafe { roc_main_size() } as usize;
|
||||||
|
let layout = Layout::array::<u8>(size).unwrap();
|
||||||
|
let answer = unsafe {
|
||||||
|
let buffer = std::alloc::alloc(layout);
|
||||||
|
|
||||||
|
roc_main(buffer);
|
||||||
|
|
||||||
|
let output = &*(buffer as *mut RocCallResult<()>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok(()) => {
|
||||||
|
let function_pointer = {
|
||||||
|
// this is a pointer to the location where the function pointer is stored
|
||||||
|
// we pass just the function pointer
|
||||||
|
let temp = buffer.offset(8) as *const i64;
|
||||||
|
|
||||||
|
(*temp) as *const u8
|
||||||
|
};
|
||||||
|
|
||||||
|
let closure_data_ptr = buffer.offset(16);
|
||||||
|
|
||||||
|
let result =
|
||||||
|
call_the_closure(function_pointer as *const u8, closure_data_ptr as *const u8);
|
||||||
|
|
||||||
|
std::alloc::dealloc(buffer, layout);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
Err(msg) => {
|
||||||
|
std::alloc::dealloc(buffer, layout);
|
||||||
|
|
||||||
|
panic!("Roc failed with message: {}", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let end_time = SystemTime::now();
|
||||||
|
let duration = end_time.duration_since(start_time).unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Roc closure took {:.4} ms to compute this answer: {:?}",
|
||||||
|
duration.as_secs_f64() * 1000.0,
|
||||||
|
// truncate the answer, so stdout is not swamped
|
||||||
|
answer
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exit code
|
||||||
|
0
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Add table
Add a link
Reference in a new issue