[m-rev.] for review: Add list.reverse_prepend.

Peter Wang novalazy at gmail.com
Thu Oct 15 14:27:57 AEDT 2015


reverse_prepend is the helper for non-naive reverse.
It is useful in its own right so we export it here.

library/list.m:
        Add predicate `reverse_prepend/3' and function `reverse_prepend/2'.

compiler/c_util.m:
        Delete own copy of the same predicate.

NEWS:
        Announce addition.
---
 NEWS              |  5 +++++
 compiler/c_util.m | 16 ++++------------
 library/list.m    | 20 ++++++++++++++------
 3 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/NEWS b/NEWS
index f1348a1..d84179a 100644
--- a/NEWS
+++ b/NEWS
@@ -181,6 +181,11 @@ Changes to the Mercury standard library:
 
 * The parser module passes through big_integer tokens as big_integer terms.
 
+* The following predicates and functions have been added to the list module:
+
+   - reverse_prepend/2
+   - reverse_prepend/3
+
 Changes to the Mercury compiler:
 
 * We have enabled stricter checking of non-ground final insts to reject more
diff --git a/compiler/c_util.m b/compiler/c_util.m
index 2cdc210..1e84b61 100644
--- a/compiler/c_util.m
+++ b/compiler/c_util.m
@@ -480,7 +480,7 @@ quote_one_char(Lang, Char, RevChars0, RevChars) :-
             ( if char.to_utf8(Char, CodeUnits) then
                 list.map(octal_escape_any_int, CodeUnits, EscapeCharss),
                 list.condense(EscapeCharss, EscapeChars),
-                reverse_append(EscapeChars, RevChars0, RevChars)
+                reverse_prepend(EscapeChars, RevChars0, RevChars)
             else
                 unexpected($module, $pred, "invalid Unicode code point")
             )
@@ -502,7 +502,7 @@ quote_one_char(Lang, Char, RevChars0, RevChars) :-
             Lang = literal_csharp,
             unicode_escape_any_char(Char, EscapeChars)
         ),
-        reverse_append(EscapeChars, RevChars0, RevChars)
+        reverse_prepend(EscapeChars, RevChars0, RevChars)
     ).
 
 :- pred quote_one_char_c(char::in, list(char)::in, list(char)::out) is det.
@@ -533,13 +533,13 @@ quote_one_char_c(Char, RevChars0, RevChars) :-
         ( if char.to_utf8(Char, CodeUnits) then
             list.map(octal_escape_any_int, CodeUnits, EscapeCharss),
             list.condense(EscapeCharss, EscapeChars),
-            reverse_append(EscapeChars, RevChars0, RevChars)
+            reverse_prepend(EscapeChars, RevChars0, RevChars)
         else
             unexpected($module, $pred, "invalid Unicode code point")
         )
     else
         octal_escape_any_char(Char, EscapeChars),
-        reverse_append(EscapeChars, RevChars0, RevChars)
+        reverse_prepend(EscapeChars, RevChars0, RevChars)
     ).
 
 :- pred java_escape_special_char(char::in, list(char)::out) is semidet.
@@ -578,14 +578,6 @@ is_c_source_char(Char) :-
 
 c_graphic_chars = " !\"#%&'()*+,-./:;<=>?[\\]^_{|}~".
 
-    % reverse_append(Xs, Ys, Zs) <=> Zs = list.reverse(Xs) ++ Ys.
-    %
-:- pred reverse_append(list(T)::in, list(T)::in, list(T)::out) is det.
-
-reverse_append([], L, L).
-reverse_append([X | Xs], L0, L) :-
-    reverse_append(Xs, [X | L0], L).
-
     % Convert a character to the corresponding C octal escape code.
     % XXX This assumes that the target language compiler's representation
     % of characters is the same as the Mercury compiler's.
diff --git a/library/list.m b/library/list.m
index 1b62d63..fefaf74 100644
--- a/library/list.m
+++ b/library/list.m
@@ -370,6 +370,13 @@
 
 :- func reverse(list(T)) = list(T).
 
+    % reverse_prepend(Xs, Ys, Zs):
+    %
+    % Same as `Zs = list.reverse(Xs) ++ Ys' but more efficient.
+    %
+:- pred reverse_prepend(list(T)::in, list(T)::in, list(T)::out) is det.
+:- func reverse_prepend(list(T), list(T)) = list(T).
+
     % perm(List0, List):
     %
     % True iff `List' is a permutation of `List0'.
@@ -2135,16 +2142,17 @@ list.reverse(Xs) = Ys :-
 ").
 
 list.reverse(L0::in, L::out) :-
-    list.reverse_acc(L0, [], L).
+    list.reverse_prepend(L0, [], L).
 
 list.reverse(L::out, L0::in) :-
-    list.reverse_acc(L0, [], L).
+    list.reverse_prepend(L0, [], L).
 
-:- pred list.reverse_acc(list(T)::in, list(T)::in, list(T)::out) is det.
+list.reverse_prepend(Xs, Ys) = Zs :-
+    list.reverse_prepend(Xs, Ys, Zs).
 
-list.reverse_acc([], L, L).
-list.reverse_acc([X | Xs], L0, L) :-
-    list.reverse_acc(Xs, [X | L0], L).
+list.reverse_prepend([], L, L).
+list.reverse_prepend([X | Xs], L0, L) :-
+    list.reverse_prepend(Xs, [X | L0], L).
 
 %---------------------------------------------------------------------------%
 
-- 
2.1.2




More information about the reviews mailing list