List.sublist implemented and tested and implementations for take/drop first/last created

This commit is contained in:
Edwin Santos 2025-11-29 18:58:54 -05:00
parent c3b87ff8cf
commit 17a3dbcabe
5 changed files with 79 additions and 18 deletions

View file

@ -135,6 +135,35 @@ Builtin :: [].{
drop_at : List(a), U64 -> List(a)
sublist : List(a), {start : U64, len : U64} -> List(a)
take_first : List(a), U64 -> List(a)
take_first = |list, n| {
config = {start: 0, len: n}
list.sublist( config)
}
take_last : List(a), U64 -> List(a)
take_last = |list, n| {
len = List.len(list)
start = if (len < n) 0 else len - n
config = {start: start, len: len}
list.sublist( config)
}
drop_first : List(a), U64 -> List(a)
drop_first = |list, n| {
len = List.len(list)
config = {start: n, len: len}
list.sublist( config)
}
drop_last : List(a), U64 -> List(a)
drop_last = |list, n| {
len = List.len(list)
take_len = if (len < n) 0 else len - n
config = {start: 0, len: take_len}
list.sublist( config)
}
}
Bool := [False, True].{

View file

@ -163,9 +163,6 @@ pub const CommonIdents = extern struct {
// from_utf8 error payload fields (BadUtf8 record)
problem: Ident.Idx,
index: Ident.Idx,
// sublist argument payload fields
// sublist_start: Ident.Idx,
// sublist_len: Ident.Idx,
/// Insert all well-known identifiers into a CommonEnv.
/// Use this when creating a fresh ModuleEnv from scratch.
@ -231,9 +228,6 @@ pub const CommonIdents = extern struct {
// from_utf8 error payload fields (BadUtf8 record)
.problem = try common.insertIdent(gpa, Ident.for_text("problem")),
.index = try common.insertIdent(gpa, Ident.for_text("index")),
// sublist argument payload fields
// .sublist_start = try common.insertIdent(gpa, Ident.for_text("start")),
// .sublist_len = try common.insertIdent(gpa, Ident.for_text("len")),
};
}
@ -302,9 +296,6 @@ pub const CommonIdents = extern struct {
// from_utf8 error payload fields (BadUtf8 record)
.problem = common.findIdent("problem") orelse unreachable,
.index = common.findIdent("index") orelse unreachable,
// sublist argument payload fields
// .sublist_start = common.findIdent("start") orelse unreachable,
// .sublist_len = common.findIdent("len") orelse unreachable,
};
}
};

View file

@ -1795,10 +1795,9 @@ pub const Interpreter = struct {
// Access second argument as a record and extract its specific fields
const sublist_config = args[1].asRecord(&self.runtime_layout_store) catch unreachable;
const sublist_start_index = 0; // sublist_config.findFieldIndex(self.env.idents.sublist_start).?;
const sublist_start_stack = sublist_config.getFieldByIndex(sublist_start_index) catch unreachable;
const sublist_len_index = 1; //sublist_config.findFieldIndex(self.env.idents.sublist_len).?;
const sublist_len_stack = sublist_config.getFieldByIndex(sublist_len_index) catch unreachable;
// When fields are alphabetically sorted, 0 will be `len` and 1 will be `start`
const sublist_start_stack = sublist_config.getFieldByIndex(1) catch unreachable;
const sublist_len_stack = sublist_config.getFieldByIndex(0) catch unreachable;
const sublist_start: u64 = @intCast(sublist_start_stack.asI128());
const sublist_len: u64 = @intCast(sublist_len_stack.asI128());
std.debug.print("\nConfig Record: {{start: {d}, len: {d} }}\n", .{ sublist_start, sublist_len });

View file

@ -59,6 +59,11 @@ test "list refcount builtins - phase 12 limitation documented" {
// - "e_low_level_lambda - List.drop_at on refcounted List(Str)"
// - "e_low_level_lambda - List.drop_at on refcounted List(List(Str))"
//
// - "e_low_level_lambda - List.sublist on empty list"
// - "e_low_level_lambda - List.sublist on non-empty list"
// - "e_low_level_lambda - List.sublist start out of bounds"
// - "e_low_level_lambda - List.sublist requesting beyond end of list gives you input list"
//
// interpreter_style_test.zig:
// - "interpreter: match list pattern destructures"
// - "interpreter: match list rest binds slice"

View file

@ -830,17 +830,54 @@ test "e_low_level_lambda - List.drop_at on refcounted List(List(Str))" {
try testing.expectEqual(@as(i128, 4), elt_len_value);
}
test "e_low_level_lambda - List.sublist on non-empty list" {
test "e_low_level_lambda - List.sublist on empty list" {
const src =
\\x = List.sublist([0, 1, 2, 3, 4], {len: 10, start: 3})
\\x = List.sublist([], {start: 0, len: 10})
\\len = List.len(x)
;
const len_value = try evalModuleAndGetInt(src, 1);
try testing.expectEqual(@as(i128, 2), len_value);
try testing.expectEqual(@as(i128, 0), len_value);
}
// const elt_len_value = try evalModuleAndGetInt(src, 3);
// try testing.expectEqual(@as(i128, 4), elt_len_value);
test "e_low_level_lambda - List.sublist on non-empty list" {
const src =
\\x = List.sublist([0, 1, 2, 3, 4], {start: 1, len: 3})
\\len = List.len(x)
\\slice_start = List.get(x, 0)
\\slice_end = List.get(x, 2)
;
const len_value = try evalModuleAndGetInt(src, 1);
try testing.expectEqual(@as(i128, 3), len_value);
const head_value = try evalModuleAndGetString(src, 2, test_allocator);
defer test_allocator.free(head_value);
try testing.expectEqualStrings("Ok(1)", head_value);
const tail_value = try evalModuleAndGetString(src, 3, test_allocator);
defer test_allocator.free(tail_value);
try testing.expectEqualStrings("Ok(3)", tail_value);
}
test "e_low_level_lambda - List.sublist start out of bounds" {
const src =
\\x = List.sublist([0, 1, 2, 3, 4], {start: 100, len: 3})
\\len = List.len(x)
;
const len_value = try evalModuleAndGetInt(src, 1);
try testing.expectEqual(@as(i128, 0), len_value);
}
test "e_low_level_lambda - List.sublist requesting beyond end of list gives you input list" {
const src =
\\x = List.sublist([0, 1, 2, 3, 4], {start: 0, len: 10000})
\\len = List.len(x)
;
const len_value = try evalModuleAndGetInt(src, 1);
try testing.expectEqual(@as(i128, 5), len_value);
}
test "e_low_level_lambda - Dec.to_str returns string representation of decimal" {