mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
str.appendScalar
This commit is contained in:
parent
ab721dd3c1
commit
9c41a4d442
10 changed files with 53 additions and 1 deletions
|
@ -158,6 +158,7 @@ comptime {
|
||||||
exportStrFn(str.substringUnsafe, "substring_unsafe");
|
exportStrFn(str.substringUnsafe, "substring_unsafe");
|
||||||
exportStrFn(str.getUnsafe, "get_unsafe");
|
exportStrFn(str.getUnsafe, "get_unsafe");
|
||||||
exportStrFn(str.reserve, "reserve");
|
exportStrFn(str.reserve, "reserve");
|
||||||
|
exportStrFn(str.appendScalar, "append_scalar");
|
||||||
exportStrFn(str.strToUtf8C, "to_utf8");
|
exportStrFn(str.strToUtf8C, "to_utf8");
|
||||||
exportStrFn(str.fromUtf8C, "from_utf8");
|
exportStrFn(str.fromUtf8C, "from_utf8");
|
||||||
exportStrFn(str.fromUtf8RangeC, "from_utf8_range");
|
exportStrFn(str.fromUtf8RangeC, "from_utf8_range");
|
||||||
|
|
|
@ -37,7 +37,8 @@ interface Str
|
||||||
splitFirst,
|
splitFirst,
|
||||||
splitLast,
|
splitLast,
|
||||||
walkUtf8WithIndex,
|
walkUtf8WithIndex,
|
||||||
reserve
|
reserve,
|
||||||
|
appendScalar,
|
||||||
]
|
]
|
||||||
imports [Bool.{ Bool }, Result.{ Result }]
|
imports [Bool.{ Bool }, Result.{ Result }]
|
||||||
|
|
||||||
|
@ -345,3 +346,17 @@ walkUtf8WithIndexHelp = \string, state, step, index, length ->
|
||||||
|
|
||||||
## Make sure at least some number of bytes fit in this string without reallocating
|
## Make sure at least some number of bytes fit in this string without reallocating
|
||||||
reserve : Str, Nat -> Str
|
reserve : Str, Nat -> Str
|
||||||
|
|
||||||
|
## is UB when the scalar is invalid
|
||||||
|
appendScalarUnsafe : Str, U32 -> Str
|
||||||
|
|
||||||
|
appendScalar : Str, U32 -> Result Str [InvalidScalar]*
|
||||||
|
appendScalar = \string, scalar ->
|
||||||
|
if isValidScalar scalar then
|
||||||
|
Ok (appendScalarUnsafe string scalar)
|
||||||
|
else
|
||||||
|
Err InvalidScalar
|
||||||
|
|
||||||
|
isValidScalar : U32 -> Bool
|
||||||
|
isValidScalar = \scalar ->
|
||||||
|
scalar <= 0xD7FF || (scalar >= 0xE000 && scalar <= 0x10FFFF)
|
||||||
|
|
|
@ -334,6 +334,7 @@ pub const STR_TRIM_LEFT: &str = "roc_builtins.str.trim_left";
|
||||||
pub const STR_TRIM_RIGHT: &str = "roc_builtins.str.trim_right";
|
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_GET_UNSAFE: &str = "roc_builtins.str.get_unsafe";
|
||||||
pub const STR_RESERVE: &str = "roc_builtins.str.reserve";
|
pub const STR_RESERVE: &str = "roc_builtins.str.reserve";
|
||||||
|
pub const STR_APPEND_SCALAR: &str = "roc_builtins.str.append_scalar";
|
||||||
|
|
||||||
pub const DICT_HASH: &str = "roc_builtins.dict.hash";
|
pub const DICT_HASH: &str = "roc_builtins.dict.hash";
|
||||||
pub const DICT_HASH_STR: &str = "roc_builtins.dict.hash_str";
|
pub const DICT_HASH_STR: &str = "roc_builtins.dict.hash_str";
|
||||||
|
|
|
@ -84,6 +84,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||||
STR_COUNT_UTF8_BYTES => str_count_bytes,
|
STR_COUNT_UTF8_BYTES => str_count_bytes,
|
||||||
STR_SUBSTRING_UNSAFE => str_substring_unsafe,
|
STR_SUBSTRING_UNSAFE => str_substring_unsafe,
|
||||||
STR_RESERVE => str_reserve,
|
STR_RESERVE => str_reserve,
|
||||||
|
STR_APPEND_SCALAR_UNSAFE => str_append_scalar_unsafe,
|
||||||
STR_FROM_UTF8 => str_from_utf8,
|
STR_FROM_UTF8 => str_from_utf8,
|
||||||
STR_FROM_UTF8_RANGE => str_from_utf8_range,
|
STR_FROM_UTF8_RANGE => str_from_utf8_range,
|
||||||
STR_TO_UTF8 => str_to_utf8,
|
STR_TO_UTF8 => str_to_utf8,
|
||||||
|
@ -1743,6 +1744,11 @@ fn str_reserve(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_2(symbol, LowLevel::StrReserve, var_store)
|
lowlevel_2(symbol, LowLevel::StrReserve, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Str.appendScalarUnsafe : Str, U32 -> Str
|
||||||
|
fn str_append_scalar_unsafe(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
lowlevel_2(symbol, LowLevel::StrAppendScalar, var_store)
|
||||||
|
}
|
||||||
|
|
||||||
/// Str.fromUtf8 : List U8 -> Result Str [BadUtf8 { byteIndex : Nat, problem : Utf8Problem } }]*
|
/// Str.fromUtf8 : List U8 -> Result Str [BadUtf8 { byteIndex : Nat, problem : Utf8Problem } }]*
|
||||||
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bytes_var = var_store.fresh();
|
let bytes_var = var_store.fresh();
|
||||||
|
|
|
@ -5364,6 +5364,14 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
let capacity = load_symbol(scope, &args[1]);
|
let capacity = load_symbol(scope, &args[1]);
|
||||||
call_str_bitcode_fn(env, &[string, capacity], bitcode::STR_RESERVE)
|
call_str_bitcode_fn(env, &[string, capacity], bitcode::STR_RESERVE)
|
||||||
}
|
}
|
||||||
|
StrAppendScalar => {
|
||||||
|
// Str.appendScalar : Str, U32 -> Str
|
||||||
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
||||||
|
let string = load_symbol(scope, &args[0]);
|
||||||
|
let capacity = load_symbol(scope, &args[1]);
|
||||||
|
call_str_bitcode_fn(env, &[string, capacity], bitcode::STR_APPEND_SCALAR)
|
||||||
|
}
|
||||||
StrTrim => {
|
StrTrim => {
|
||||||
// Str.trim : Str -> Str
|
// Str.trim : Str -> Str
|
||||||
debug_assert_eq!(args.len(), 1);
|
debug_assert_eq!(args.len(), 1);
|
||||||
|
|
|
@ -279,6 +279,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
StrToUtf8 => self.load_args_and_call_zig(backend, bitcode::STR_TO_UTF8),
|
StrToUtf8 => self.load_args_and_call_zig(backend, bitcode::STR_TO_UTF8),
|
||||||
StrReserve => self.load_args_and_call_zig(backend, bitcode::STR_RESERVE),
|
StrReserve => self.load_args_and_call_zig(backend, bitcode::STR_RESERVE),
|
||||||
StrRepeat => self.load_args_and_call_zig(backend, bitcode::STR_REPEAT),
|
StrRepeat => self.load_args_and_call_zig(backend, bitcode::STR_REPEAT),
|
||||||
|
StrAppendScalar => self.load_args_and_call_zig(backend, bitcode::STR_APPEND_SCALAR),
|
||||||
StrTrim => self.load_args_and_call_zig(backend, bitcode::STR_TRIM),
|
StrTrim => self.load_args_and_call_zig(backend, bitcode::STR_TRIM),
|
||||||
StrSubstringUnsafe => {
|
StrSubstringUnsafe => {
|
||||||
self.load_args_and_call_zig(backend, bitcode::STR_SUBSTRING_UNSAFE)
|
self.load_args_and_call_zig(backend, bitcode::STR_SUBSTRING_UNSAFE)
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub enum LowLevel {
|
||||||
StrGetUnsafe,
|
StrGetUnsafe,
|
||||||
StrSubstringUnsafe,
|
StrSubstringUnsafe,
|
||||||
StrReserve,
|
StrReserve,
|
||||||
|
StrAppendScalar,
|
||||||
ListLen,
|
ListLen,
|
||||||
ListWithCapacity,
|
ListWithCapacity,
|
||||||
ListGetUnsafe,
|
ListGetUnsafe,
|
||||||
|
@ -185,6 +186,8 @@ impl LowLevelWrapperType {
|
||||||
Symbol::STR_FROM_UTF8_RANGE => WrapperIsRequired,
|
Symbol::STR_FROM_UTF8_RANGE => WrapperIsRequired,
|
||||||
Symbol::STR_TO_UTF8 => CanBeReplacedBy(StrToUtf8),
|
Symbol::STR_TO_UTF8 => CanBeReplacedBy(StrToUtf8),
|
||||||
Symbol::STR_REPEAT => CanBeReplacedBy(StrRepeat),
|
Symbol::STR_REPEAT => CanBeReplacedBy(StrRepeat),
|
||||||
|
Symbol::STR_RESERVE => CanBeReplacedBy(StrReserve),
|
||||||
|
Symbol::STR_APPEND_SCALAR_UNSAFE => CanBeReplacedBy(StrAppendScalar),
|
||||||
Symbol::STR_TRIM => CanBeReplacedBy(StrTrim),
|
Symbol::STR_TRIM => CanBeReplacedBy(StrTrim),
|
||||||
Symbol::STR_TRIM_LEFT => CanBeReplacedBy(StrTrimLeft),
|
Symbol::STR_TRIM_LEFT => CanBeReplacedBy(StrTrimLeft),
|
||||||
Symbol::STR_TRIM_RIGHT => CanBeReplacedBy(StrTrimRight),
|
Symbol::STR_TRIM_RIGHT => CanBeReplacedBy(StrTrimRight),
|
||||||
|
|
|
@ -1197,6 +1197,8 @@ define_builtins! {
|
||||||
39 STR_SPLIT_LAST: "splitLast"
|
39 STR_SPLIT_LAST: "splitLast"
|
||||||
40 STR_WALK_UTF8_WITH_INDEX: "walkUtf8WithIndex"
|
40 STR_WALK_UTF8_WITH_INDEX: "walkUtf8WithIndex"
|
||||||
41 STR_RESERVE: "reserve"
|
41 STR_RESERVE: "reserve"
|
||||||
|
42 STR_APPEND_SCALAR_UNSAFE: "appendScalarUnsafe"
|
||||||
|
43 STR_APPEND_SCALAR: "appendScalar"
|
||||||
}
|
}
|
||||||
5 LIST: "List" => {
|
5 LIST: "List" => {
|
||||||
0 LIST_LIST: "List" imported // the List.List type alias
|
0 LIST_LIST: "List" imported // the List.List type alias
|
||||||
|
|
|
@ -897,6 +897,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
|
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||||
StrSubstringUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
StrSubstringUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
||||||
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
|
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
|
StrAppendScalar => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
StrTrim => arena.alloc_slice_copy(&[owned]),
|
StrTrim => arena.alloc_slice_copy(&[owned]),
|
||||||
StrTrimLeft => arena.alloc_slice_copy(&[owned]),
|
StrTrimLeft => arena.alloc_slice_copy(&[owned]),
|
||||||
StrTrimRight => arena.alloc_slice_copy(&[owned]),
|
StrTrimRight => arena.alloc_slice_copy(&[owned]),
|
||||||
|
|
|
@ -1744,3 +1744,17 @@ fn str_walk_utf8_with_index() {
|
||||||
RocList<(u64, u8)>
|
RocList<(u64, u8)>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
|
fn str_append_scalar() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
Str.appendScalar "abcd" 'A'
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from("abcdA"),
|
||||||
|
RocStr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue