mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
builtins work for List.last, any, all, contains, and working on append.
This commit is contained in:
parent
4b811d2dba
commit
8bfd2deee3
3 changed files with 198 additions and 0 deletions
|
|
@ -48,6 +48,53 @@ Builtin :: [].{
|
|||
|
||||
$state
|
||||
}
|
||||
|
||||
append : List(a), a -> List(a)
|
||||
append = |list, elt| {
|
||||
new_tail : List(a)
|
||||
new_tail = [elt]
|
||||
List.concat(list, new_tail)
|
||||
}
|
||||
|
||||
# append_if_ok : List(a), Try(a, err) -> List(a)
|
||||
# append_if_ok : |list, try| match try {
|
||||
# Ok(elt) => List.append(list, elt)
|
||||
# Err(_) => list
|
||||
# }
|
||||
|
||||
last : List(a) -> Try(a, [ListWasEmpty])
|
||||
last = |list| {
|
||||
len = List.len(list)
|
||||
if len == 0 {
|
||||
Try.Err(ListWasEmpty)
|
||||
} else {
|
||||
Try.Ok(list_get_unsafe(list, len - 1))
|
||||
}
|
||||
}
|
||||
|
||||
any : List(a), (a -> Bool) -> Bool
|
||||
# any = |list, predicate| {
|
||||
# for item in list {
|
||||
# if predicate(item) {
|
||||
# return True
|
||||
# }
|
||||
# }
|
||||
# False
|
||||
# }
|
||||
any = |list, fn| {
|
||||
List.fold(list, False, |state, item| fn(item) or state)
|
||||
}
|
||||
|
||||
all : List(a), (a -> Bool) -> Bool
|
||||
all = |list, fn| {
|
||||
List.fold(list, True, |state, item| fn(item) and state)
|
||||
}
|
||||
|
||||
contains : List(a), a -> Bool where [a.is_eq: a, a -> Bool]
|
||||
contains = |list, elt| {
|
||||
List.any(list, |x| x == elt)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Bool := [False, True].{
|
||||
|
|
|
|||
|
|
@ -957,6 +957,146 @@ test "interpreter: List.fold from Builtin using numbers" {
|
|||
try std.testing.expectEqualStrings("6", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.last on Empty List" {
|
||||
const roc_src = "List.last([])";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("Err(ListWasEmpty)", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.last on single element List" {
|
||||
const roc_src = "List.last([-1])";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("Ok(-1)", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.last on multi-item List" {
|
||||
const roc_src = "List.last([1, 2, 3, 4, 5, 6, 7, 8, 9])";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("Ok(9)", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.any True on integers" {
|
||||
const roc_src = "List.any([1, 0, 1, 0, -1], |x| x > 0)";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("True", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.any False on unsigned integers" {
|
||||
const roc_src = "List.any([9, 8, 7, 6, 5], |x| x > 10)";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("False", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.all False when some elements are False" {
|
||||
const roc_src = "List.all([9, 18, 7, 6, 15], |x| x < 10)";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("False", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: List.all True on small integers" {
|
||||
const roc_src = "List.all([9, 8, 7, 6, 5], |x| x < 10)";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
defer helpers.cleanupParseAndCanonical(std.testing.allocator, resources);
|
||||
|
||||
const imported_envs = [_]*const can.ModuleEnv{resources.builtin_module.env};
|
||||
var interp2 = try Interpreter.init(std.testing.allocator, resources.module_env, resources.builtin_types, resources.builtin_module.env, &imported_envs, &resources.checker.import_mapping);
|
||||
defer interp2.deinit();
|
||||
|
||||
var host = TestHost.init(std.testing.allocator);
|
||||
defer host.deinit();
|
||||
var ops = host.makeOps();
|
||||
|
||||
const result = try interp2.evalMinimal(resources.expr_idx, &ops);
|
||||
const rt_var = try interp2.translateTypeVar(resources.module_env, can.ModuleEnv.varFrom(resources.expr_idx));
|
||||
const rendered = try interp2.renderValueRocWithType(result, rt_var);
|
||||
defer std.testing.allocator.free(rendered);
|
||||
try std.testing.expectEqualStrings("True", rendered);
|
||||
}
|
||||
|
||||
test "interpreter: crash statement triggers crash error and message" {
|
||||
const roc_src = "{\n crash \"boom\"\n 0\n}";
|
||||
const resources = try helpers.parseAndCanonicalizeExpr(std.testing.allocator, roc_src);
|
||||
|
|
|
|||
|
|
@ -636,6 +636,17 @@ test "e_low_level_lambda - List.concat preserves order" {
|
|||
try testing.expectEqualStrings("Ok(10)", first_value);
|
||||
}
|
||||
|
||||
// test "e_low_level_lambda - List.append on empty" {
|
||||
// const src =
|
||||
// \\x = List.append([9], 11)
|
||||
// \\last = List.get(x, 2)
|
||||
// ;
|
||||
//
|
||||
// const first_value = try evalModuleAndGetString(src, 1, test_allocator);
|
||||
// defer test_allocator.free(first_value);
|
||||
// try testing.expectEqualStrings("Ok(10)", first_value);
|
||||
// }
|
||||
|
||||
test "e_low_level_lambda - List.concat with strings (refcounted elements)" {
|
||||
const src =
|
||||
\\x = List.concat(["hello", "world"], ["foo", "bar"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue