mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Merge pull request #8442 from roc-lang/builtin-str-impls2
More Builtin `Str` implementations
This commit is contained in:
commit
f0310302f3
14 changed files with 736 additions and 9 deletions
|
|
@ -121,6 +121,30 @@ fn replaceStrIsEmptyWithLowLevel(env: *ModuleEnv) !std.ArrayList(CIR.Def.Idx) {
|
|||
if (env.common.findIdent("Builtin.Str.drop_suffix")) |str_drop_suffix_ident| {
|
||||
try low_level_map.put(str_drop_suffix_ident, .str_drop_suffix);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.count_utf8_bytes")) |str_count_utf8_bytes_ident| {
|
||||
try low_level_map.put(str_count_utf8_bytes_ident, .str_count_utf8_bytes);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.with_capacity")) |str_with_capacity_ident| {
|
||||
try low_level_map.put(str_with_capacity_ident, .str_with_capacity);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.reserve")) |str_reserve_ident| {
|
||||
try low_level_map.put(str_reserve_ident, .str_reserve);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.release_excess_capacity")) |str_release_excess_capacity_ident| {
|
||||
try low_level_map.put(str_release_excess_capacity_ident, .str_release_excess_capacity);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.to_utf8")) |str_to_utf8_ident| {
|
||||
try low_level_map.put(str_to_utf8_ident, .str_to_utf8);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.from_utf8_lossy")) |str_from_utf8_lossy_ident| {
|
||||
try low_level_map.put(str_from_utf8_lossy_ident, .str_from_utf8_lossy);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.split_on")) |str_split_on_ident| {
|
||||
try low_level_map.put(str_split_on_ident, .str_split_on);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.Str.join_with")) |str_join_with_ident| {
|
||||
try low_level_map.put(str_join_with_ident, .str_join_with);
|
||||
}
|
||||
if (env.common.findIdent("Builtin.List.len")) |list_len_ident| {
|
||||
try low_level_map.put(list_len_ident, .list_len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@ Builtin :: [].{
|
|||
with_prefix : Str, Str -> Str
|
||||
drop_prefix : Str, Str -> Str
|
||||
drop_suffix : Str, Str -> Str
|
||||
count_utf8_bytes : Str -> U64
|
||||
with_capacity : U64 -> Str
|
||||
reserve : Str, U64 -> Str
|
||||
release_excess_capacity : Str -> Str
|
||||
to_utf8 : Str -> List(U8)
|
||||
from_utf8_lossy : List(U8) -> Str
|
||||
split_on : Str, Str -> List(Str)
|
||||
join_with : List(Str), Str -> Str
|
||||
|
||||
is_eq : Str, Str -> Bool
|
||||
}
|
||||
|
|
|
|||
|
|
@ -443,6 +443,14 @@ pub const Expr = union(enum) {
|
|||
str_with_prefix,
|
||||
str_drop_prefix,
|
||||
str_drop_suffix,
|
||||
str_count_utf8_bytes,
|
||||
str_with_capacity,
|
||||
str_reserve,
|
||||
str_release_excess_capacity,
|
||||
str_to_utf8,
|
||||
str_from_utf8_lossy,
|
||||
str_split_on,
|
||||
str_join_with,
|
||||
|
||||
// Numeric to_str operations
|
||||
u8_to_str,
|
||||
|
|
|
|||
|
|
@ -3279,6 +3279,202 @@ pub const Interpreter = struct {
|
|||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_count_utf8_bytes => {
|
||||
// Str.count_utf8_bytes : Str -> U64
|
||||
std.debug.assert(args.len == 1);
|
||||
|
||||
const string_arg = args[0];
|
||||
std.debug.assert(string_arg.ptr != null);
|
||||
|
||||
const string: *const RocStr = @ptrCast(@alignCast(string_arg.ptr.?));
|
||||
const byte_count = builtins.str.countUtf8Bytes(string.*);
|
||||
|
||||
const result_layout = layout.Layout.int(.u64);
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
try out.setInt(@intCast(byte_count));
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_with_capacity => {
|
||||
// Str.with_capacity : U64 -> Str
|
||||
std.debug.assert(args.len == 1);
|
||||
|
||||
const capacity_arg = args[0];
|
||||
const capacity_value = try self.extractNumericValue(capacity_arg);
|
||||
const capacity: u64 = @intCast(capacity_value.int);
|
||||
|
||||
const result_str = builtins.str.withCapacityC(capacity, roc_ops);
|
||||
|
||||
const result_layout = layout.Layout.str();
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *RocStr = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_str;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_reserve => {
|
||||
// Str.reserve : Str, U64 -> Str
|
||||
std.debug.assert(args.len == 2);
|
||||
|
||||
const string_arg = args[0];
|
||||
const spare_arg = args[1];
|
||||
|
||||
std.debug.assert(string_arg.ptr != null);
|
||||
|
||||
const string: *const RocStr = @ptrCast(@alignCast(string_arg.ptr.?));
|
||||
const spare_value = try self.extractNumericValue(spare_arg);
|
||||
const spare: u64 = @intCast(spare_value.int);
|
||||
|
||||
const result_str = builtins.str.reserveC(string.*, spare, roc_ops);
|
||||
|
||||
const result_layout = string_arg.layout;
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *RocStr = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_str;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_release_excess_capacity => {
|
||||
// Str.release_excess_capacity : Str -> Str
|
||||
std.debug.assert(args.len == 1);
|
||||
|
||||
const string_arg = args[0];
|
||||
std.debug.assert(string_arg.ptr != null);
|
||||
|
||||
const string: *const RocStr = @ptrCast(@alignCast(string_arg.ptr.?));
|
||||
const result_str = builtins.str.strReleaseExcessCapacity(roc_ops, string.*);
|
||||
|
||||
const result_layout = string_arg.layout;
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *RocStr = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_str;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_to_utf8 => {
|
||||
// Str.to_utf8 : Str -> List(U8)
|
||||
std.debug.assert(args.len == 1);
|
||||
|
||||
const string_arg = args[0];
|
||||
std.debug.assert(string_arg.ptr != null);
|
||||
|
||||
const string: *const RocStr = @ptrCast(@alignCast(string_arg.ptr.?));
|
||||
const result_list = builtins.str.strToUtf8C(string.*, roc_ops);
|
||||
|
||||
const result_rt_var = return_rt_var orelse {
|
||||
self.triggerCrash("str_to_utf8 requires return type info", false, roc_ops);
|
||||
return error.Crash;
|
||||
};
|
||||
const result_layout = try self.getRuntimeLayout(result_rt_var);
|
||||
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *builtins.list.RocList = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_list;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_from_utf8_lossy => {
|
||||
// Str.from_utf8_lossy : List(U8) -> Str
|
||||
std.debug.assert(args.len == 1);
|
||||
|
||||
const list_arg = args[0];
|
||||
std.debug.assert(list_arg.ptr != null);
|
||||
|
||||
const roc_list: *const builtins.list.RocList = @ptrCast(@alignCast(list_arg.ptr.?));
|
||||
const result_str = builtins.str.fromUtf8Lossy(roc_list.*, roc_ops);
|
||||
|
||||
const result_layout = layout.Layout.str();
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *RocStr = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_str;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_split_on => {
|
||||
// Str.split_on : Str, Str -> List(Str)
|
||||
std.debug.assert(args.len == 2);
|
||||
|
||||
const string_arg = args[0];
|
||||
const delimiter_arg = args[1];
|
||||
|
||||
std.debug.assert(string_arg.ptr != null);
|
||||
std.debug.assert(delimiter_arg.ptr != null);
|
||||
|
||||
const string: *const RocStr = @ptrCast(@alignCast(string_arg.ptr.?));
|
||||
const delimiter: *const RocStr = @ptrCast(@alignCast(delimiter_arg.ptr.?));
|
||||
|
||||
const result_list = builtins.str.strSplitOn(string.*, delimiter.*, roc_ops);
|
||||
|
||||
// str_split_on has a fixed return type of List(Str).
|
||||
// Prefer the caller's return_rt_var when it matches that shape, but fall back
|
||||
// to the known layout if type information is missing or incorrect.
|
||||
const result_layout = blk: {
|
||||
const expected_idx = try self.runtime_layout_store.insertList(layout.Idx.str);
|
||||
const expected_layout = self.runtime_layout_store.getLayout(expected_idx);
|
||||
|
||||
if (return_rt_var) |rt_var| {
|
||||
const candidate = self.getRuntimeLayout(rt_var) catch expected_layout;
|
||||
if (candidate.tag == .list) {
|
||||
const elem_layout = self.runtime_layout_store.getLayout(candidate.data.list);
|
||||
if (elem_layout.tag == .scalar and elem_layout.data.scalar.tag == .str) {
|
||||
break :blk candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break :blk expected_layout;
|
||||
};
|
||||
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *builtins.list.RocList = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_list;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.str_join_with => {
|
||||
// Str.join_with : List(Str), Str -> Str
|
||||
std.debug.assert(args.len == 2);
|
||||
|
||||
const list_arg = args[0];
|
||||
const separator_arg = args[1];
|
||||
|
||||
std.debug.assert(list_arg.ptr != null);
|
||||
std.debug.assert(separator_arg.ptr != null);
|
||||
|
||||
const roc_list: *const builtins.list.RocList = @ptrCast(@alignCast(list_arg.ptr.?));
|
||||
const separator: *const RocStr = @ptrCast(@alignCast(separator_arg.ptr.?));
|
||||
|
||||
const result_str = builtins.str.strJoinWithC(roc_list.*, separator.*, roc_ops);
|
||||
|
||||
const result_layout = layout.Layout.str();
|
||||
var out = try self.pushRaw(result_layout, 0);
|
||||
out.is_initialized = false;
|
||||
|
||||
const result_ptr: *RocStr = @ptrCast(@alignCast(out.ptr.?));
|
||||
result_ptr.* = result_str;
|
||||
|
||||
out.is_initialized = true;
|
||||
return out;
|
||||
},
|
||||
.list_len => {
|
||||
// List.len : List(a) -> U64
|
||||
// Note: listLen returns usize, but List.len always returns U64.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
const std = @import("std");
|
||||
const parse = @import("parse");
|
||||
const types = @import("types");
|
||||
const base = @import("base");
|
||||
const can = @import("can");
|
||||
const check = @import("check");
|
||||
|
|
@ -1122,3 +1121,247 @@ test "e_low_level_lambda - Str.drop_suffix suffix longer than string" {
|
|||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hi\"", value);
|
||||
}
|
||||
|
||||
// count_utf8_bytes tests
|
||||
test "e_low_level_lambda - Str.count_utf8_bytes empty string" {
|
||||
const src =
|
||||
\\x = Str.count_utf8_bytes("")
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 0), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.count_utf8_bytes ASCII string" {
|
||||
const src =
|
||||
\\x = Str.count_utf8_bytes("hello")
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 5), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.count_utf8_bytes multi-byte UTF-8" {
|
||||
const src =
|
||||
\\x = Str.count_utf8_bytes("é")
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 2), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.count_utf8_bytes emoji" {
|
||||
const src =
|
||||
\\x = Str.count_utf8_bytes("🎉")
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 4), value);
|
||||
}
|
||||
|
||||
// with_capacity tests
|
||||
test "e_low_level_lambda - Str.with_capacity returns empty string" {
|
||||
const src =
|
||||
\\x = Str.with_capacity(0)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.with_capacity with capacity returns empty string" {
|
||||
const src =
|
||||
\\x = Str.with_capacity(100)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
// reserve tests
|
||||
test "e_low_level_lambda - Str.reserve preserves content" {
|
||||
const src =
|
||||
\\x = Str.reserve("hello", 100)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.reserve empty string" {
|
||||
const src =
|
||||
\\x = Str.reserve("", 50)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
// release_excess_capacity tests
|
||||
test "e_low_level_lambda - Str.release_excess_capacity preserves content" {
|
||||
const src =
|
||||
\\x = Str.release_excess_capacity("hello")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.release_excess_capacity empty string" {
|
||||
const src =
|
||||
\\x = Str.release_excess_capacity("")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
// to_utf8 tests (using List.len to verify)
|
||||
test "e_low_level_lambda - Str.to_utf8 empty string" {
|
||||
const src =
|
||||
\\x = List.len(Str.to_utf8(""))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 0), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.to_utf8 ASCII string" {
|
||||
const src =
|
||||
\\x = List.len(Str.to_utf8("hello"))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 5), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.to_utf8 multi-byte UTF-8" {
|
||||
const src =
|
||||
\\x = List.len(Str.to_utf8("é"))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 2), value);
|
||||
}
|
||||
|
||||
// from_utf8_lossy tests (roundtrip through to_utf8)
|
||||
test "e_low_level_lambda - Str.from_utf8_lossy roundtrip ASCII" {
|
||||
const src =
|
||||
\\x = Str.from_utf8_lossy(Str.to_utf8("hello"))
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.from_utf8_lossy roundtrip empty" {
|
||||
const src =
|
||||
\\x = Str.from_utf8_lossy(Str.to_utf8(""))
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.from_utf8_lossy roundtrip UTF-8" {
|
||||
const src =
|
||||
\\x = Str.from_utf8_lossy(Str.to_utf8("hello 🎉 world"))
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello 🎉 world\"", value);
|
||||
}
|
||||
|
||||
// split_on tests
|
||||
test "e_low_level_lambda - Str.split_on basic split count" {
|
||||
const src =
|
||||
\\x = List.len(Str.split_on("hello world", " "))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 2), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.split_on basic split first element" {
|
||||
const src =
|
||||
\\parts = Str.split_on("hello world", " ")
|
||||
\\first = List.first(parts)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 1, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("Ok(\"hello\")", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.split_on multiple delimiters count" {
|
||||
const src =
|
||||
\\x = List.len(Str.split_on("a,b,c,d", ","))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 4), value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.split_on multiple delimiters first element" {
|
||||
const src =
|
||||
\\parts = Str.split_on("a,b,c,d", ",")
|
||||
\\first = List.first(parts)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 1, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("Ok(\"a\")", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.split_on no match" {
|
||||
const src =
|
||||
\\parts = Str.split_on("hello", "x")
|
||||
\\first = List.first(parts)
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 1, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("Ok(\"hello\")", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.split_on empty string" {
|
||||
const src =
|
||||
\\x = List.len(Str.split_on("", ","))
|
||||
;
|
||||
const value = try evalModuleAndGetInt(src, 0);
|
||||
try testing.expectEqual(@as(i128, 1), value);
|
||||
}
|
||||
|
||||
// join_with tests
|
||||
test "e_low_level_lambda - Str.join_with basic join" {
|
||||
const src =
|
||||
\\x = Str.join_with(["hello", "world"], " ")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello world\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.join_with multiple elements" {
|
||||
const src =
|
||||
\\x = Str.join_with(["a", "b", "c", "d"], ",")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"a,b,c,d\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.join_with single element" {
|
||||
const src =
|
||||
\\x = Str.join_with(["hello"], "-")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.join_with empty list" {
|
||||
const src =
|
||||
\\x = Str.join_with([], ",")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"\"", value);
|
||||
}
|
||||
|
||||
test "e_low_level_lambda - Str.join_with roundtrip with split_on" {
|
||||
const src =
|
||||
\\x = Str.join_with(Str.split_on("hello world", " "), " ")
|
||||
;
|
||||
const value = try evalModuleAndGetString(src, 0, test_allocator);
|
||||
defer test_allocator.free(value);
|
||||
try testing.expectEqualStrings("\"hello world\"", value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,12 @@ DOES NOT EXIST - Color.md:51:75:51:85
|
|||
DOES NOT EXIST - Color.md:51:93:51:103
|
||||
DOES NOT EXIST - Color.md:68:14:68:27
|
||||
MISSING METHOD - Color.md:22:17:22:24
|
||||
MISSING METHOD - Color.md:29:17:29:24
|
||||
MISSING METHOD - Color.md:35:19:35:39
|
||||
MISSING METHOD - Color.md:36:23:36:43
|
||||
MISSING METHOD - Color.md:37:23:37:43
|
||||
MISSING METHOD - Color.md:38:23:38:43
|
||||
MISSING METHOD - Color.md:39:23:39:43
|
||||
MISSING METHOD - Color.md:40:23:40:43
|
||||
TYPE MISMATCH - Color.md:32:5:45:6
|
||||
MISSING METHOD - Color.md:62:12:62:26
|
||||
MISSING METHOD - Color.md:56:26:56:32
|
||||
|
|
@ -224,18 +229,88 @@ The value's type, which does not have a method named **to_frac**, is:
|
|||
**Hint: **For this to work, the type would need to have a method named **to_frac** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **to_utf8** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:29:17:29:24:**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:35:19:35:39:**
|
||||
```roc
|
||||
bytes = str.to_utf8()
|
||||
a.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **to_utf8**, is:
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_Str_
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **to_utf8** associated with it in the type's declaration.
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:36:23:36:43:**
|
||||
```roc
|
||||
and b.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:37:23:37:43:**
|
||||
```roc
|
||||
and c.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:38:23:38:43:**
|
||||
```roc
|
||||
and d.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:39:23:39:43:**
|
||||
```roc
|
||||
and e.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**MISSING METHOD**
|
||||
This **is_char_in_hex_range** method is being called on a value whose type doesn't have that method:
|
||||
**Color.md:40:23:40:43:**
|
||||
```roc
|
||||
and f.is_char_in_hex_range()
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
|
||||
**Hint: **For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
|
|||
25
test/snapshots/repl/str_count_utf8_bytes.md
Normal file
25
test/snapshots/repl/str_count_utf8_bytes.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.count_utf8_bytes should return the number of bytes in the string
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.count_utf8_bytes("")
|
||||
» Str.count_utf8_bytes("hello")
|
||||
» Str.count_utf8_bytes("hello world")
|
||||
» Str.count_utf8_bytes("é")
|
||||
» Str.count_utf8_bytes("🎉")
|
||||
~~~
|
||||
# OUTPUT
|
||||
0
|
||||
---
|
||||
5
|
||||
---
|
||||
11
|
||||
---
|
||||
2
|
||||
---
|
||||
4
|
||||
# PROBLEMS
|
||||
NIL
|
||||
25
test/snapshots/repl/str_from_utf8_lossy.md
Normal file
25
test/snapshots/repl/str_from_utf8_lossy.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.from_utf8_lossy should convert a list of UTF-8 bytes to a string
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.from_utf8_lossy(Str.to_utf8(""))
|
||||
» Str.from_utf8_lossy(Str.to_utf8("hello"))
|
||||
» Str.from_utf8_lossy(Str.to_utf8("hello world"))
|
||||
» Str.from_utf8_lossy(Str.to_utf8("é"))
|
||||
» Str.from_utf8_lossy(Str.to_utf8("🎉"))
|
||||
~~~
|
||||
# OUTPUT
|
||||
""
|
||||
---
|
||||
"hello"
|
||||
---
|
||||
"hello world"
|
||||
---
|
||||
"é"
|
||||
---
|
||||
"🎉"
|
||||
# PROBLEMS
|
||||
NIL
|
||||
22
test/snapshots/repl/str_join_with.md
Normal file
22
test/snapshots/repl/str_join_with.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.join_with should join strings with a separator
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.join_with(["hello", "world"], " ")
|
||||
» Str.join_with(["a", "b", "c"], ",")
|
||||
» Str.join_with(["single"], "-")
|
||||
» Str.join_with([], ",")
|
||||
~~~
|
||||
# OUTPUT
|
||||
"hello world"
|
||||
---
|
||||
"a,b,c"
|
||||
---
|
||||
"single"
|
||||
---
|
||||
""
|
||||
# PROBLEMS
|
||||
NIL
|
||||
19
test/snapshots/repl/str_release_excess_capacity.md
Normal file
19
test/snapshots/repl/str_release_excess_capacity.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.release_excess_capacity should return the same string with excess capacity released
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.release_excess_capacity("hello")
|
||||
» Str.release_excess_capacity("")
|
||||
» Str.release_excess_capacity("hello world")
|
||||
~~~
|
||||
# OUTPUT
|
||||
"hello"
|
||||
---
|
||||
""
|
||||
---
|
||||
"hello world"
|
||||
# PROBLEMS
|
||||
NIL
|
||||
19
test/snapshots/repl/str_reserve.md
Normal file
19
test/snapshots/repl/str_reserve.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.reserve should return the same string with additional capacity reserved
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.reserve("hello", 0)
|
||||
» Str.reserve("hello", 10)
|
||||
» Str.reserve("", 100)
|
||||
~~~
|
||||
# OUTPUT
|
||||
"hello"
|
||||
---
|
||||
"hello"
|
||||
---
|
||||
""
|
||||
# PROBLEMS
|
||||
NIL
|
||||
22
test/snapshots/repl/str_split_on.md
Normal file
22
test/snapshots/repl/str_split_on.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.split_on should split a string on a delimiter
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» List.len(Str.split_on("hello world", " "))
|
||||
» List.len(Str.split_on("a,b,c", ","))
|
||||
» List.len(Str.split_on("no match", "x"))
|
||||
» List.len(Str.split_on("", ","))
|
||||
~~~
|
||||
# OUTPUT
|
||||
2
|
||||
---
|
||||
3
|
||||
---
|
||||
1
|
||||
---
|
||||
1
|
||||
# PROBLEMS
|
||||
NIL
|
||||
22
test/snapshots/repl/str_to_utf8.md
Normal file
22
test/snapshots/repl/str_to_utf8.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.to_utf8 should convert a string to a list of UTF-8 bytes
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» List.len(Str.to_utf8(""))
|
||||
» List.len(Str.to_utf8("hello"))
|
||||
» List.len(Str.to_utf8("é"))
|
||||
» List.len(Str.to_utf8("🎉"))
|
||||
~~~
|
||||
# OUTPUT
|
||||
0
|
||||
---
|
||||
5
|
||||
---
|
||||
2
|
||||
---
|
||||
4
|
||||
# PROBLEMS
|
||||
NIL
|
||||
19
test/snapshots/repl/str_with_capacity.md
Normal file
19
test/snapshots/repl/str_with_capacity.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Str.with_capacity should create an empty string with preallocated capacity
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» Str.with_capacity(0)
|
||||
» Str.with_capacity(10)
|
||||
» Str.with_capacity(100)
|
||||
~~~
|
||||
# OUTPUT
|
||||
""
|
||||
---
|
||||
""
|
||||
---
|
||||
""
|
||||
# PROBLEMS
|
||||
NIL
|
||||
Loading…
Add table
Add a link
Reference in a new issue