mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 16:51:53 +03:00
Merge pull request #3398 from rtfeldman/wasm-str-full-coverage
Wasm Str: 100% tests passing
This commit is contained in:
commit
4523e90bc7
@ -143,6 +143,7 @@ const str = @import("str.zig");
|
||||
comptime {
|
||||
exportStrFn(str.init, "init");
|
||||
exportStrFn(str.strToScalarsC, "to_scalars");
|
||||
exportStrFn(str.strSplit, "str_split");
|
||||
exportStrFn(str.strSplitInPlaceC, "str_split_in_place");
|
||||
exportStrFn(str.countSegments, "count_segments");
|
||||
exportStrFn(str.countGraphemeClusters, "count_grapheme_clusters");
|
||||
|
@ -744,6 +744,21 @@ fn strFromFloatHelp(comptime T: type, float: T) RocStr {
|
||||
}
|
||||
|
||||
// Str.split
|
||||
|
||||
// For dev backends
|
||||
pub fn strSplit(string: RocStr, delimiter: RocStr) callconv(.C) RocList {
|
||||
const segment_count = countSegments(string, delimiter);
|
||||
const list = RocList.allocate(@alignOf(RocStr), segment_count, @sizeOf(RocStr));
|
||||
|
||||
if (list.bytes) |bytes| {
|
||||
const strings = @ptrCast([*]RocStr, @alignCast(@alignOf(RocStr), bytes));
|
||||
strSplitInPlace(strings, string, delimiter);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// For LLVM backend
|
||||
pub fn strSplitInPlaceC(opt_array: ?[*]RocStr, string: RocStr, delimiter: RocStr) callconv(.C) void {
|
||||
if (opt_array) |array| {
|
||||
return @call(.{ .modifier = always_inline }, strSplitInPlace, .{ array, string, delimiter });
|
||||
@ -1537,7 +1552,7 @@ const CountAndStart = extern struct {
|
||||
start: usize,
|
||||
};
|
||||
|
||||
pub fn fromUtf8C(arg: RocList, update_mode: UpdateMode, output: *FromUtf8Result) callconv(.C) void {
|
||||
pub fn fromUtf8C(output: *FromUtf8Result, arg: RocList, update_mode: UpdateMode) callconv(.C) void {
|
||||
output.* = fromUtf8(arg, update_mode);
|
||||
}
|
||||
|
||||
@ -1592,7 +1607,7 @@ inline fn fromUtf8(arg: RocList, update_mode: UpdateMode) FromUtf8Result {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fromUtf8RangeC(arg: RocList, countAndStart: CountAndStart, output: *FromUtf8Result) callconv(.C) void {
|
||||
pub fn fromUtf8RangeC(output: *FromUtf8Result, arg: RocList, countAndStart: CountAndStart) callconv(.C) void {
|
||||
output.* = @call(.{ .modifier = always_inline }, fromUtf8Range, .{ arg, countAndStart });
|
||||
}
|
||||
|
||||
|
@ -310,6 +310,7 @@ pub const STR_INIT: &str = "roc_builtins.str.init";
|
||||
pub const STR_COUNT_SEGMENTS: &str = "roc_builtins.str.count_segments";
|
||||
pub const STR_CONCAT: &str = "roc_builtins.str.concat";
|
||||
pub const STR_JOIN_WITH: &str = "roc_builtins.str.joinWith";
|
||||
pub const STR_STR_SPLIT: &str = "roc_builtins.str.str_split";
|
||||
pub const STR_STR_SPLIT_IN_PLACE: &str = "roc_builtins.str.str_split_in_place";
|
||||
pub const STR_TO_SCALARS: &str = "roc_builtins.str.to_scalars";
|
||||
pub const STR_COUNT_GRAPEHEME_CLUSTERS: &str = "roc_builtins.str.count_grapheme_clusters";
|
||||
|
@ -1803,7 +1803,7 @@ fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
// Ok arg_2.str
|
||||
// else
|
||||
// # problem
|
||||
// Err (BadUtf8 { byteIndex: arg_2.byteIndex, problem : arg_2.problem })
|
||||
// Err (BadUtf8 arg_2.problem arg_2.byteIndex)
|
||||
|
||||
let def = crate::def::Def {
|
||||
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_2)),
|
||||
@ -1905,7 +1905,7 @@ fn str_from_utf8_range(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
// if arg_3.a then
|
||||
// Ok arg_3.str
|
||||
// else
|
||||
// Err (BadUtf8 { byteIndex: arg_3.byteIndex, problem : arg_3.problem })
|
||||
// Err (BadUtf8 arg_3.problem arg_3.byteIndex)
|
||||
|
||||
let def = crate::def::Def {
|
||||
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)),
|
||||
|
@ -168,10 +168,10 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
|
||||
call_void_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
result_ptr.into(),
|
||||
list_symbol_to_c_abi(env, scope, list).into(),
|
||||
count,
|
||||
start,
|
||||
result_ptr.into(),
|
||||
],
|
||||
bitcode::STR_FROM_UTF8_RANGE,
|
||||
);
|
||||
@ -194,9 +194,9 @@ pub fn str_from_utf8<'a, 'ctx, 'env>(
|
||||
call_void_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
result_ptr.into(),
|
||||
list_symbol_to_c_abi(env, scope, list).into(),
|
||||
pass_update_mode(env, update_mode),
|
||||
result_ptr.into(),
|
||||
],
|
||||
bitcode::STR_FROM_UTF8,
|
||||
);
|
||||
|
@ -184,7 +184,8 @@ pub fn build_app_module<'a>(
|
||||
}
|
||||
|
||||
let (module, called_preload_fns) = backend.finalize();
|
||||
let main_function_index = maybe_main_fn_index.unwrap();
|
||||
let main_function_index =
|
||||
maybe_main_fn_index.expect("The app must expose at least one value to the host");
|
||||
|
||||
(module, called_preload_fns, main_function_index)
|
||||
}
|
||||
|
@ -235,15 +235,7 @@ impl<'a> LowLevelCall<'a> {
|
||||
self.load_args_and_call_zig(backend, bitcode::STR_STARTS_WITH_SCALAR)
|
||||
}
|
||||
StrEndsWith => self.load_args_and_call_zig(backend, bitcode::STR_ENDS_WITH),
|
||||
StrSplit => {
|
||||
// LLVM implementation (build_str.rs) does the following
|
||||
// 1. Call bitcode::STR_COUNT_SEGMENTS
|
||||
// 2. Allocate a `List Str`
|
||||
// 3. Call bitcode::STR_STR_SPLIT_IN_PLACE
|
||||
// 4. Write the elements and length of the List
|
||||
// To do this here, we need full access to WasmBackend, or we could make a Zig wrapper
|
||||
todo!("{:?}", self.lowlevel);
|
||||
}
|
||||
StrSplit => self.load_args_and_call_zig(backend, bitcode::STR_STR_SPLIT),
|
||||
StrCountGraphemes => {
|
||||
self.load_args_and_call_zig(backend, bitcode::STR_COUNT_GRAPEHEME_CLUSTERS)
|
||||
}
|
||||
@ -268,10 +260,30 @@ impl<'a> LowLevelCall<'a> {
|
||||
}
|
||||
StrFromInt => self.num_to_str(backend),
|
||||
StrFromFloat => self.num_to_str(backend),
|
||||
StrFromUtf8 => self.load_args_and_call_zig(backend, bitcode::STR_FROM_UTF8),
|
||||
StrFromUtf8 => {
|
||||
/*
|
||||
Low-level op returns a struct with all the data for both Ok and Err.
|
||||
Roc AST wrapper converts this to a tag union, with app-dependent tag IDs.
|
||||
|
||||
fromUtf8C(output: *FromUtf8Result, arg: RocList, update_mode: UpdateMode) callconv(.C) void
|
||||
output: *FromUtf8Result i32
|
||||
arg: RocList i64, i32
|
||||
update_mode: UpdateMode i32
|
||||
*/
|
||||
backend.storage.load_symbols_for_call(
|
||||
backend.env.arena,
|
||||
&mut backend.code_builder,
|
||||
self.arguments,
|
||||
self.ret_symbol,
|
||||
&WasmLayout::new(&self.ret_layout),
|
||||
CallConv::Zig,
|
||||
);
|
||||
backend.code_builder.i32_const(UPDATE_MODE_IMMUTABLE);
|
||||
backend.call_host_fn_after_loading_args(bitcode::STR_FROM_UTF8, 4, false);
|
||||
}
|
||||
StrFromUtf8Range => self.load_args_and_call_zig(backend, bitcode::STR_FROM_UTF8_RANGE),
|
||||
StrTrimLeft => self.load_args_and_call_zig(backend, bitcode::STR_TRIM_LEFT),
|
||||
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),
|
||||
StrRepeat => self.load_args_and_call_zig(backend, bitcode::STR_REPEAT),
|
||||
StrTrim => self.load_args_and_call_zig(backend, bitcode::STR_TRIM),
|
||||
|
@ -25,7 +25,7 @@ fn str_split_empty_delimiter() {
|
||||
"#
|
||||
),
|
||||
1,
|
||||
i64
|
||||
usize
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
@ -41,7 +41,7 @@ fn str_split_empty_delimiter() {
|
||||
"#
|
||||
),
|
||||
3,
|
||||
i64
|
||||
usize
|
||||
);
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ fn str_split_bigger_delimiter_small_str() {
|
||||
"#
|
||||
),
|
||||
1,
|
||||
i64
|
||||
usize
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
@ -71,7 +71,7 @@ fn str_split_bigger_delimiter_small_str() {
|
||||
"#
|
||||
),
|
||||
3,
|
||||
i64
|
||||
usize
|
||||
);
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ fn str_split_small_str_big_delimiter() {
|
||||
"#
|
||||
),
|
||||
3,
|
||||
i64
|
||||
usize
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user