mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
add Str.toBytes
This commit is contained in:
parent
bcbef5d3aa
commit
9116e9e8c9
10 changed files with 73 additions and 2 deletions
|
@ -68,6 +68,7 @@ comptime {
|
|||
exportStrFn(str.strFromFloatC, "from_float");
|
||||
exportStrFn(str.strEqual, "equal");
|
||||
exportStrFn(str.validateUtf8Bytes, "validate_utf8_bytes");
|
||||
exportStrFn(str.strToBytesC, "to_bytes");
|
||||
}
|
||||
|
||||
// Export helpers - Must be run inside a comptime
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const utils = @import("utils.zig");
|
||||
const RocList = @import("list.zig").RocList;
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
|
@ -961,6 +962,26 @@ test "RocStr.joinWith: result is big" {
|
|||
expect(roc_result.eq(result));
|
||||
}
|
||||
|
||||
// Str.toBytes
|
||||
pub fn strToBytesC(arg: RocStr) callconv(.C) RocList {
|
||||
return @call(.{ .modifier = always_inline }, strToBytes, .{ std.heap.c_allocator, arg });
|
||||
}
|
||||
|
||||
fn strToBytes(allocator: *Allocator, arg: RocStr) RocList {
|
||||
if (arg.isEmpty()) {
|
||||
return RocList.empty();
|
||||
} else if (arg.isSmallStr()) {
|
||||
const length = arg.len();
|
||||
const ptr = utils.allocateWithRefcount(allocator, @alignOf(usize), length);
|
||||
|
||||
@memcpy(ptr, arg.asU8ptr(), length);
|
||||
|
||||
return RocList{ .length = length, .bytes = ptr };
|
||||
} else {
|
||||
return RocList{ .length = arg.len(), .bytes = arg.str_bytes };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isValidUnicode(ptr: [*]u8, len: usize) callconv(.C) bool {
|
||||
const bytes: []u8 = ptr[0..len];
|
||||
return @call(.{ .modifier = always_inline }, unicode.utf8ValidateSlice, .{bytes});
|
||||
|
|
|
@ -42,6 +42,7 @@ pub const STR_FROM_INT: &str = "roc_builtins.str.from_int";
|
|||
pub const STR_FROM_FLOAT: &str = "roc_builtins.str.from_float";
|
||||
pub const STR_EQUAL: &str = "roc_builtins.str.equal";
|
||||
pub const STR_VALIDATE_UTF_BYTES: &str = "roc_builtins.str.validate_utf8_bytes";
|
||||
pub const STR_TO_BYTES: &str = "roc_builtins.str.to_bytes";
|
||||
|
||||
pub const DICT_HASH: &str = "roc_builtins.dict.hash";
|
||||
pub const DICT_HASH_STR: &str = "roc_builtins.dict.hash_str";
|
||||
|
|
|
@ -623,6 +623,12 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
|||
),
|
||||
);
|
||||
|
||||
// toBytes : Str -> List U8
|
||||
add_type(
|
||||
Symbol::STR_TO_BYTES,
|
||||
top_level_function(vec![str_type()], Box::new(list_type(u8_type()))),
|
||||
);
|
||||
|
||||
// fromFloat : Float a -> Str
|
||||
add_type(
|
||||
Symbol::STR_FROM_FLOAT,
|
||||
|
|
|
@ -62,6 +62,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
|||
STR_COUNT_GRAPHEMES => str_count_graphemes,
|
||||
STR_FROM_INT => str_from_int,
|
||||
STR_FROM_UTF8 => str_from_utf8,
|
||||
STR_TO_BYTES => str_to_bytes,
|
||||
STR_FROM_FLOAT=> str_from_float,
|
||||
LIST_LEN => list_len,
|
||||
LIST_GET => list_get,
|
||||
|
@ -196,6 +197,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
|
|||
Symbol::STR_COUNT_GRAPHEMES => str_count_graphemes,
|
||||
Symbol::STR_FROM_INT => str_from_int,
|
||||
Symbol::STR_FROM_UTF8 => str_from_utf8,
|
||||
Symbol::STR_TO_BYTES => str_to_bytes,
|
||||
Symbol::STR_FROM_FLOAT=> str_from_float,
|
||||
Symbol::LIST_LEN => list_len,
|
||||
Symbol::LIST_GET => list_get,
|
||||
|
@ -1655,6 +1657,11 @@ fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
)
|
||||
}
|
||||
|
||||
/// Str.toBytes : Str -> List U8
|
||||
fn str_to_bytes(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_1(symbol, LowLevel::StrToBytes, var_store)
|
||||
}
|
||||
|
||||
/// Str.fromFloat : Float * -> Str
|
||||
fn str_from_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let float_var = var_store.fresh();
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::llvm::build_list::{
|
|||
};
|
||||
use crate::llvm::build_str::{
|
||||
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
|
||||
str_join_with, str_number_of_bytes, str_split, str_starts_with, CHAR_LAYOUT,
|
||||
str_join_with, str_number_of_bytes, str_split, str_starts_with, str_to_bytes, CHAR_LAYOUT,
|
||||
};
|
||||
use crate::llvm::compare::{generic_eq, generic_neq};
|
||||
use crate::llvm::convert::{
|
||||
|
@ -3611,13 +3611,23 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
str_from_float(env, scope, args[0])
|
||||
}
|
||||
StrFromUtf8 => {
|
||||
// Str.fromInt : Int -> Str
|
||||
// Str.fromUtf8 : List U8 -> Result Str Utf8Problem
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let original_wrapper = load_symbol(scope, &args[0]).into_struct_value();
|
||||
|
||||
str_from_utf8(env, parent, original_wrapper)
|
||||
}
|
||||
StrToBytes => {
|
||||
// Str.fromInt : Str -> List U8
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
// this is an identity conversion
|
||||
// we just implement it here to subvert the type system
|
||||
let string = load_symbol(scope, &args[0]);
|
||||
|
||||
str_to_bytes(env, string.into_struct_value())
|
||||
}
|
||||
StrSplit => {
|
||||
// Str.split : Str, Str -> List Str
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
|
|
@ -275,6 +275,28 @@ pub fn str_from_int<'a, 'ctx, 'env>(
|
|||
zig_str_to_struct(env, zig_result).into()
|
||||
}
|
||||
|
||||
/// Str.toBytes : Str -> List U8
|
||||
pub fn str_to_bytes<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let string = complex_bitcast(
|
||||
env.builder,
|
||||
original_wrapper.into(),
|
||||
env.context.i128_type().into(),
|
||||
"to_bytes",
|
||||
);
|
||||
|
||||
let zig_result = call_bitcode_fn(env, &[string], &bitcode::STR_TO_BYTES);
|
||||
|
||||
complex_bitcast(
|
||||
env.builder,
|
||||
zig_result,
|
||||
collection(env.context, env.ptr_bytes).into(),
|
||||
"to_bytes",
|
||||
)
|
||||
}
|
||||
|
||||
/// Str.fromUtf8 : List U8 -> { a : Bool, b : Str, c : Nat, d : I8 }
|
||||
pub fn str_from_utf8<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
|
|
@ -12,6 +12,7 @@ pub enum LowLevel {
|
|||
StrCountGraphemes,
|
||||
StrFromInt,
|
||||
StrFromUtf8,
|
||||
StrToBytes,
|
||||
StrFromFloat,
|
||||
ListLen,
|
||||
ListGetUnsafe,
|
||||
|
|
|
@ -882,6 +882,7 @@ define_builtins! {
|
|||
12 STR_FROM_UTF8: "fromUtf8"
|
||||
13 STR_UT8_PROBLEM: "Utf8Problem" // the Utf8Problem type alias
|
||||
14 STR_UT8_BYTE_PROBLEM: "Utf8ByteProblem" // the Utf8ByteProblem type alias
|
||||
15 STR_TO_BYTES: "toBytes"
|
||||
}
|
||||
4 LIST: "List" => {
|
||||
0 LIST_LIST: "List" imported // the List.List type alias
|
||||
|
|
|
@ -676,6 +676,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
}
|
||||
StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
StrFromUtf8 => arena.alloc_slice_copy(&[owned]),
|
||||
StrToBytes => arena.alloc_slice_copy(&[owned]),
|
||||
StrFromInt | StrFromFloat => arena.alloc_slice_copy(&[irrelevant]),
|
||||
Hash => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
DictSize => arena.alloc_slice_copy(&[borrowed]),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue