This commit is contained in:
Richard Feldman 2025-11-07 08:23:06 -05:00
parent 8494679513
commit 004219d4ee
No known key found for this signature in database
5 changed files with 52 additions and 2 deletions

View file

@ -149,6 +149,12 @@ fn replaceStrIsEmptyWithLowLevel(env: *ModuleEnv) !std.ArrayList(CIR.Def.Idx) {
if (env.common.findIdent("Builtin.Str.is_empty")) |str_is_empty_ident| {
try low_level_map.put(str_is_empty_ident, .str_is_empty);
}
if (env.common.findIdent("Builtin.List.len")) |list_len_ident| {
try low_level_map.put(list_len_ident, .list_len);
}
if (env.common.findIdent("Builtin.List.is_empty")) |list_is_empty_ident| {
try low_level_map.put(list_is_empty_ident, .list_is_empty);
}
if (env.common.findIdent("Builtin.Set.is_empty")) |set_is_empty_ident| {
try low_level_map.put(set_is_empty_ident, .set_is_empty);
}

View file

@ -8,10 +8,8 @@ Builtin := [].{
List := [ProvidedByCompiler].{
len : List(a) -> U64
len = |_| 0
is_empty : List(a) -> Bool
is_empty = |_| True
first : List(a) -> Try(a, [ListWasEmpty])
first = |_| Err(ListWasEmpty)

View file

@ -375,6 +375,16 @@ pub fn listIncref(list: RocList, amount: isize, elements_refcounted: bool) callc
list.incref(amount, elements_refcounted);
}
/// Get the number of elements in the list.
pub fn listLen(list: RocList) callconv(.c) usize {
return list.len();
}
/// Check if the list is empty.
pub fn listIsEmpty(list: RocList) callconv(.c) bool {
return list.isEmpty();
}
/// Decrement reference count and deallocate when no longer shared.
pub fn listDecref(
list: RocList,

View file

@ -387,6 +387,10 @@ pub const Expr = union(enum) {
// String operations
str_is_empty,
// List operations
list_len,
list_is_empty,
// Set operations
set_is_empty,

View file

@ -2119,6 +2119,38 @@ pub const Interpreter = struct {
return try self.makeSimpleBoolValue(result);
},
.list_len => {
// List.len : List(a) -> U64
// Note: listLen returns usize, but List.len always returns U64.
// We need to cast usize -> u64 for 32-bit targets (e.g. wasm32).
if (args.len != 1) return error.TypeMismatch;
const list_arg = args[0];
if (list_arg.ptr == null) return error.TypeMismatch;
const roc_list: *const builtins.list.RocList = @ptrCast(@alignCast(list_arg.ptr.?));
const len_usize = builtins.list.listLen(roc_list.*);
const len_u64: u64 = @intCast(len_usize);
const result_layout = layout.Layout.int(.u64);
var out = try self.pushRaw(result_layout, 0);
out.is_initialized = false;
out.setInt(@intCast(len_u64));
out.is_initialized = true;
return out;
},
.list_is_empty => {
// List.is_empty : List(a) -> Bool
if (args.len != 1) return error.TypeMismatch;
const list_arg = args[0];
if (list_arg.ptr == null) return error.TypeMismatch;
const roc_list: *const builtins.list.RocList = @ptrCast(@alignCast(list_arg.ptr.?));
const result = builtins.list.listIsEmpty(roc_list.*);
return try self.makeSimpleBoolValue(result);
},
.set_is_empty => {
// TODO: implement Set.is_empty
self.triggerCrash("Set.is_empty not yet implemented", false, roc_ops);