[m-rev.] for review: Simplify string.split implementation.
Mark Brown
mark at mercurylang.org
Wed Oct 23 20:32:09 AEDT 2019
This looks fine.
On Wed, Oct 23, 2019 at 3:03 PM Peter Wang <novalazy at gmail.com> wrote:
>
> library/string.m:
> Replace foreign code implementations with Mercury code.
> ---
> library/string.m | 109 ++++-------------------------------------------
> 1 file changed, 9 insertions(+), 100 deletions(-)
>
> diff --git a/library/string.m b/library/string.m
> index 8cc572d9c..97b005841 100644
> --- a/library/string.m
> +++ b/library/string.m
> @@ -679,8 +679,8 @@
>
> % split(String, Index, LeftSubstring, RightSubstring):
> %
> - % Split a string into two substrings, at the code unit `Index'.
> - % (If `Count' is out of the range [0, length of `String'], it is treated
> + % Split a string into two substrings at the code unit offset `Index'.
> + % (If `Index' is out of the range [0, length of `String'], it is treated
> % as if it were the nearest end-point of that range.)
> %
> :- pred split(string::in, int::in, string::out, string::out) is det.
> @@ -4138,110 +4138,19 @@ join_list_loop(Sep, [H | T]) = Sep ++ H ++ join_list_loop(Sep, T).
> ").
>
> %---------------------%
> -%
> -% For some Str and Count inputs, we may return Str as either Left or Right.
> -% Since Str has mode `in', both Left or Right must have mode 'out', not `uo'.
> -%
> -
> -:- pragma foreign_proc("C",
> - split(Str::in, Count::in, Left::out, Right::out),
> - [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
> - does_not_affect_liveness, may_not_duplicate],
> -"{
> - MR_Integer len;
> -
> - if (Count <= 0) {
> - MR_make_aligned_string(Left, """");
> - Right = Str;
> - } else {
> - len = strlen(Str);
>
> - if (Count > len) {
> - Count = len;
> - }
> -
> - MR_allocate_aligned_string_msg(Left, Count, MR_ALLOC_ID);
> - MR_memcpy(Left, Str, Count);
> - Left[Count] = '\\0';
> - // We need to make a copy to ensure that the pointer is word-aligned.
> - MR_allocate_aligned_string_msg(Right, len - Count, MR_ALLOC_ID);
> - strcpy(Right, Str + Count);
> - }
> -}").
> -:- pragma foreign_proc("C#",
> - split(Str::in, Count::in, Left::out, Right::out),
> - [will_not_call_mercury, promise_pure, thread_safe],
> -"{
> - int len;
> -
> - if (Count <= 0) {
> - Left = """";
> - Right = Str;
> - } else {
> - len = Str.Length;
> - if (Count > len) {
> - Count = len;
> - }
> - Left = Str.Substring(0, Count);
> - Right = Str.Substring(Count);
> - }
> -}").
> -:- pragma foreign_proc("Java",
> - split(Str::in, Count::in, Left::out, Right::out),
> - [will_not_call_mercury, promise_pure, thread_safe],
> -"
> - if (Count <= 0) {
> - Left = """";
> - Right = Str;
> - } else {
> - int len = Str.length();
> - if (Count > len) {
> - Count = len;
> - }
> - Left = Str.substring(0, Count);
> - Right = Str.substring(Count);
> - }
> -").
> -:- pragma foreign_proc("Erlang",
> - split(Str::in, Count::in, Left::out, Right::out),
> - [will_not_call_mercury, promise_pure, thread_safe],
> -"
> - if
> - Count =< 0 ->
> - Left = <<>>,
> - Right = Str;
> - Count > size(Str) ->
> - Left = Str,
> - Right = <<>>;
> - true ->
> - << Left:Count/binary, Right/binary >> = Str
> - end
> -").
> -
> - % XXX ILSEQ from_code_unit_list refuses to create strings containing
> - % ill-formed sequences.
> - %
> -split(Str, Count, Left, Right) :-
> - ( if Count =< 0 then
> +split(Str, Index, Left, Right) :-
> + ( if Index =< 0 then
> Left = "",
> Right = Str
> else
> - to_code_unit_list(Str, List),
> Len = length(Str),
> - ( if Count > Len then
> - Num = Len
> - else
> - Num = Count
> - ),
> - ( if
> - list.split_list(Num, List, LeftList, RightList),
> - from_code_unit_list(LeftList, LeftPrime),
> - from_code_unit_list(RightList, RightPrime)
> - then
> - Left = LeftPrime,
> - Right = RightPrime
> + ( if Index >= Len then
> + Left = Str,
> + Right = ""
> else
> - unexpected($pred, "split_list failed")
> + unsafe_between(Str, 0, Index, Left),
> + unsafe_between(Str, Index, Len, Right)
> )
> ).
>
> --
> 2.23.0
>
> _______________________________________________
> reviews mailing list
> reviews at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/reviews
More information about the reviews
mailing list