Str.reserve

This commit is contained in:
Folkert 2022-07-04 14:57:20 +02:00
parent f7b8094dfb
commit ab721dd3c1
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
10 changed files with 32 additions and 0 deletions

View file

@ -157,6 +157,7 @@ comptime {
exportStrFn(str.strEqual, "equal");
exportStrFn(str.substringUnsafe, "substring_unsafe");
exportStrFn(str.getUnsafe, "get_unsafe");
exportStrFn(str.reserve, "reserve");
exportStrFn(str.strToUtf8C, "to_utf8");
exportStrFn(str.fromUtf8C, "from_utf8");
exportStrFn(str.fromUtf8RangeC, "from_utf8_range");

View file

@ -2446,3 +2446,11 @@ test "appendScalar: big 😀" {
try expect(actual.eq(expected));
}
pub fn reserve(string: RocStr, capacity: usize) callconv(.C) RocStr {
if (capacity > string.capacity()) {
return string.reallocate(capacity);
} else {
return string;
}
}

View file

@ -37,6 +37,7 @@ interface Str
splitFirst,
splitLast,
walkUtf8WithIndex,
reserve
]
imports [Bool.{ Bool }, Result.{ Result }]
@ -341,3 +342,6 @@ walkUtf8WithIndexHelp = \string, state, step, index, length ->
walkUtf8WithIndexHelp string newState step (index + 1) length
else
state
## Make sure at least some number of bytes fit in this string without reallocating
reserve : Str, Nat -> Str

View file

@ -333,6 +333,7 @@ pub const STR_TRIM: &str = "roc_builtins.str.trim";
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_GET_UNSAFE: &str = "roc_builtins.str.get_unsafe";
pub const STR_RESERVE: &str = "roc_builtins.str.reserve";
pub const DICT_HASH: &str = "roc_builtins.dict.hash";
pub const DICT_HASH_STR: &str = "roc_builtins.dict.hash_str";

View file

@ -83,6 +83,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
STR_COUNT_GRAPHEMES => str_count_graphemes,
STR_COUNT_UTF8_BYTES => str_count_bytes,
STR_SUBSTRING_UNSAFE => str_substring_unsafe,
STR_RESERVE => str_reserve,
STR_FROM_UTF8 => str_from_utf8,
STR_FROM_UTF8_RANGE => str_from_utf8_range,
STR_TO_UTF8 => str_to_utf8,
@ -1737,6 +1738,11 @@ fn str_substring_unsafe(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_3(symbol, LowLevel::StrSubstringUnsafe, var_store)
}
/// Str.reserve : Str, Nat -> Str
fn str_reserve(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_2(symbol, LowLevel::StrReserve, var_store)
}
/// Str.fromUtf8 : List U8 -> Result Str [BadUtf8 { byteIndex : Nat, problem : Utf8Problem } }]*
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bytes_var = var_store.fresh();

View file

@ -5356,6 +5356,14 @@ fn run_low_level<'a, 'ctx, 'env>(
let length = load_symbol(scope, &args[2]);
call_str_bitcode_fn(env, &[string, start, length], bitcode::STR_SUBSTRING_UNSAFE)
}
StrReserve => {
// Str.reserve : Str, Nat -> 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_RESERVE)
}
StrTrim => {
// Str.trim : Str -> Str
debug_assert_eq!(args.len(), 1);

View file

@ -277,6 +277,7 @@ impl<'a> LowLevelCall<'a> {
StrTrimRight => self.load_args_and_call_zig(backend, bitcode::STR_TRIM_RIGHT),
StrFromUtf8Range => self.load_args_and_call_zig(backend, bitcode::STR_FROM_UTF8_RANGE),
StrToUtf8 => self.load_args_and_call_zig(backend, bitcode::STR_TO_UTF8),
StrReserve => self.load_args_and_call_zig(backend, bitcode::STR_RESERVE),
StrRepeat => self.load_args_and_call_zig(backend, bitcode::STR_REPEAT),
StrTrim => self.load_args_and_call_zig(backend, bitcode::STR_TRIM),
StrSubstringUnsafe => {

View file

@ -27,6 +27,7 @@ pub enum LowLevel {
StrToScalars,
StrGetUnsafe,
StrSubstringUnsafe,
StrReserve,
ListLen,
ListWithCapacity,
ListGetUnsafe,

View file

@ -1196,6 +1196,7 @@ define_builtins! {
38 STR_SPLIT_FIRST: "splitFirst"
39 STR_SPLIT_LAST: "splitLast"
40 STR_WALK_UTF8_WITH_INDEX: "walkUtf8WithIndex"
41 STR_RESERVE: "reserve"
}
5 LIST: "List" => {
0 LIST_LIST: "List" imported // the List.List type alias

View file

@ -896,6 +896,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
ListConcat => arena.alloc_slice_copy(&[owned, owned]),
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
StrSubstringUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
StrTrim => arena.alloc_slice_copy(&[owned]),
StrTrimLeft => arena.alloc_slice_copy(&[owned]),
StrTrimRight => arena.alloc_slice_copy(&[owned]),