mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-04 00:55:00 +00:00
Str.walkScalars
This commit is contained in:
parent
1de9270ecf
commit
6d7c329698
15 changed files with 109 additions and 2 deletions
|
|
@ -159,6 +159,7 @@ comptime {
|
|||
exportStrFn(str.substringUnsafe, "substring_unsafe");
|
||||
exportStrFn(str.getUnsafe, "get_unsafe");
|
||||
exportStrFn(str.reserve, "reserve");
|
||||
exportStrFn(str.getScalarUnsafe, "get_scalar_unsafe");
|
||||
exportStrFn(str.appendScalar, "append_scalar");
|
||||
exportStrFn(str.strToUtf8C, "to_utf8");
|
||||
exportStrFn(str.fromUtf8C, "from_utf8");
|
||||
|
|
|
|||
|
|
@ -2469,3 +2469,23 @@ pub fn reserve(string: RocStr, capacity: usize) callconv(.C) RocStr {
|
|||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getScalarUnsafe(string: RocStr, index: usize) callconv(.C) extern struct { bytesParsed: usize, scalar: u32 } {
|
||||
const slice = string.asSlice();
|
||||
const bytesParsed = @intCast(usize, std.unicode.utf8ByteSequenceLength(slice[index]) catch unreachable);
|
||||
const scalar = std.unicode.utf8Decode(slice[index .. index + bytesParsed]) catch unreachable;
|
||||
|
||||
return .{ .bytesParsed = bytesParsed, .scalar = @intCast(u32, scalar) };
|
||||
}
|
||||
|
||||
test "getScalarUnsafe" {
|
||||
const data_bytes = "A";
|
||||
var data = RocStr.init(data_bytes, data_bytes.len);
|
||||
|
||||
const result = getScalarUnsafe(data, 0);
|
||||
|
||||
const expected = try std.unicode.utf8Decode("A");
|
||||
|
||||
try expectEqual(result.scalar, @intCast(u32, expected));
|
||||
try expectEqual(result.bytesParsed, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ interface Str
|
|||
walkUtf8WithIndex,
|
||||
reserve,
|
||||
appendScalar,
|
||||
walkScalars,
|
||||
walkScalarsUntil,
|
||||
]
|
||||
imports [Bool.{ Bool }, Result.{ Result }]
|
||||
|
||||
|
|
@ -360,3 +362,36 @@ appendScalar = \string, scalar ->
|
|||
isValidScalar : U32 -> Bool
|
||||
isValidScalar = \scalar ->
|
||||
scalar <= 0xD7FF || (scalar >= 0xE000 && scalar <= 0x10FFFF)
|
||||
|
||||
getScalarUnsafe : Str, Nat -> { scalar : U32, bytesParsed : Nat }
|
||||
|
||||
walkScalars : Str, state, (state, U32 -> state) -> state
|
||||
walkScalars = \string, init, step ->
|
||||
walkScalarsHelp string init step 0 (Str.countUtf8Bytes string)
|
||||
|
||||
walkScalarsHelp : Str, state, (state, U32 -> state), Nat, Nat -> state
|
||||
walkScalarsHelp = \string, state, step, index, length ->
|
||||
if index < length then
|
||||
{ scalar, bytesParsed } = getScalarUnsafe string index
|
||||
newState = step state scalar
|
||||
|
||||
walkScalarsHelp string newState step (index + bytesParsed) length
|
||||
else
|
||||
state
|
||||
|
||||
walkScalarsUntil : Str, state, (state, U32 -> [Break state, Continue state]) -> state
|
||||
walkScalarsUntil = \string, init, step ->
|
||||
walkScalarsUntilHelp string init step 0 (Str.countUtf8Bytes string)
|
||||
|
||||
walkScalarsUntilHelp : Str, state, (state, U32 -> [Break state, Continue state]), Nat, Nat -> state
|
||||
walkScalarsUntilHelp = \string, state, step, index, length ->
|
||||
if index < length then
|
||||
{ scalar, bytesParsed } = getScalarUnsafe string index
|
||||
|
||||
when step state scalar is
|
||||
Continue newState ->
|
||||
walkScalarsHelp string newState step (index + bytesParsed) length
|
||||
Done newState ->
|
||||
newState
|
||||
else
|
||||
state
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ pub const STR_TRIM_RIGHT: &str = "roc_builtins.str.trim_right";
|
|||
pub const STR_GET_UNSAFE: &str = "roc_builtins.str.get_unsafe";
|
||||
pub const STR_RESERVE: &str = "roc_builtins.str.reserve";
|
||||
pub const STR_APPEND_SCALAR: &str = "roc_builtins.str.append_scalar";
|
||||
pub const STR_GET_SCALAR_UNSAFE: &str = "roc_builtins.str.get_scalar_unsafe";
|
||||
|
||||
pub const DICT_HASH: &str = "roc_builtins.dict.hash";
|
||||
pub const DICT_HASH_STR: &str = "roc_builtins.dict.hash_str";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue