[m-rev.] for review: fixes for deconstruct.functor and io.write

Julien Fischer jfischer at opturion.com
Thu Jun 14 12:10:51 AEST 2018


For review by anyone.

This diff doesn't update any documentation or the NEWS file
since I have further work to do on deconstruct.functor (specifically
with character escapes and strings).

------------------------------------

Fixes for deconstruct.functor and io.write.

Fix two problems with deconstruct.functor/4 and characters.

1. Control characters were not being octal escaped as they are by
    io.write etc.

2. The higher bytes of multibyte characters were being discarded.

Note that as part of the above fix deconstruct.functor/4 will now abort if
called with a surrogate code point.

Fix problem with io.write (and related predicates) where characters were
being octal escaped even though a more specific escape character existed
(e.g. \r or \a).

runtime/mercury_ml_expand_body.h:
     Make the above fixes.

library/rtti_implementation.m:
     Conform to the above.

     Fix the escaping of single quote characters.

library/term_io.m:
     Add missing character escapes to the predicate
     mercury_escape_special_char/2.  The omission of these
     was the cause of the above problem with character escapes
     and io.write.

tests/hard_coded/deconstruct_arg.{m,exp,exp2}:
     Modify this test to use io.write rather than io.print since
     the former will insert character escapes.

     Do more thorough testing of characters.

tests/hard_coded/write.{m,exp}:
     Add more tests for escape characters.

     Add tests for infinite float values.

Julien.

diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 6ee0bfe..f0b1247 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -140,6 +140,7 @@
  :- import_module array.
  :- import_module bitmap.
  :- import_module bool.
+:- import_module char.
  :- import_module int.
  :- import_module maybe.
  :- import_module require.
@@ -2815,6 +2816,20 @@ deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
          det_dynamic_cast(Term, Char),
          ( if quote_special_escape_char(Char, EscapedChar) then
              Functor = EscapedChar
+        else if
+            Int = char.to_int(Char),
+            ( 0x0 =< Int, Int =< 0x1f
+            ; Int = 0x7f
+            )
+        then
+            string.int_to_base_string(Int, 8, OctalString0),
+            string.pad_left(OctalString0, '0', 3, OctalString),
+            Functor  = "'\\" ++ OctalString ++ "\\'"
+        else if
+            char.is_surrogate(Char)
+        then
+            unexpected($module, $pred,
+                "attempt to deconstruct surrogate code point")
          else
              Functor = string.from_char_list(['\'', Char, '\''])
          ),
@@ -3016,7 +3031,7 @@ univ_named_arg(Term, NonCanon, Name, Argument) :-
  :- pred quote_special_escape_char(character::in, string::out) is semidet.

  quote_special_escape_char('\\', "'\\\\'").
-quote_special_escape_char('\'', "'\\'").
+quote_special_escape_char('\'', "'\\''").
  quote_special_escape_char('\a', "'\\a'").
  quote_special_escape_char('\b', "'\\b'").
  quote_special_escape_char('\r', "'\\r'").
diff --git a/library/term_io.m b/library/term_io.m
index 3fee715..a818b7a 100644
--- a/library/term_io.m
+++ b/library/term_io.m
@@ -1005,12 +1005,16 @@ encode_escaped_char(Char::out, Str::in) :-
  :- mode mercury_escape_special_char(in, out) is semidet.
  :- mode mercury_escape_special_char(out, in) is semidet.

+mercury_escape_special_char('\a', 'a').
+mercury_escape_special_char('\b', 'b').
+mercury_escape_special_char('\r', 'r').
+mercury_escape_special_char('\f', 'f').
+mercury_escape_special_char('\t', 't').
+mercury_escape_special_char('\n', 'n').
+mercury_escape_special_char('\v', 'v').
+mercury_escape_special_char('\\', '\\').
  mercury_escape_special_char('''', '''').
  mercury_escape_special_char('"', '"').
-mercury_escape_special_char('\\', '\\').
-mercury_escape_special_char('\n', 'n').
-mercury_escape_special_char('\t', 't').
-mercury_escape_special_char('\b', 'b').

  %---------------------------------------------------------------------------%
  %---------------------------------------------------------------------------%
diff --git a/runtime/mercury_ml_expand_body.h b/runtime/mercury_ml_expand_body.h
index 6c1bf54..9e1bfee 100644
--- a/runtime/mercury_ml_expand_body.h
+++ b/runtime/mercury_ml_expand_body.h
@@ -880,10 +880,9 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
                  char        *str;

                  data_word = *data_word_ptr;
-                // XXX what should we do with other non-printable characters.
                  switch (data_word) {
                      case '\\': str_ptr = "'\\\\'"; break;
-                    case '\'': str_ptr = "'\\''"; break;
+                    case '\'': str_ptr = "'\\''";  break;
                      case '\a': str_ptr = "'\\a'";  break;
                      case '\b': str_ptr = "'\\b'";  break;
                      case '\r': str_ptr = "'\\r'";  break;
@@ -892,7 +891,28 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
                      case '\n': str_ptr = "'\\n'";  break;
                      case '\v': str_ptr = "'\\v'";  break;
                      default:
-                        sprintf(buf, "\'%c\'", (char) data_word);
+                        // Print C0 control characters and Delete in
+                        // octal.
+                        if (data_word <= 0x1f || data_word == 0x7f) {
+                            sprintf(buf, "\'\\%03o\\\'", data_word);
+                        } else if (MR_is_ascii(data_word)) {
+                            sprintf(buf, "\'%c\'", (char) data_word);
+                        } else if (MR_is_surrogate(data_word)) {
+                            // XXX Should throw an exception.
+                            MR_fatal_error(MR_STRINGIFY(EXPAND_FUNCTION_NAME)
+                                ": attempt to deconstruct surrogate code point");
+                        } else {
+                            size_t n = MR_utf8_encode(buf + 1, (MR_Char)data_word);
+                            // XXX Should throw an exception.
+                            if (n == 0) {
+                                MR_fatal_error(MR_STRINGIFY(EXPAND_FUNCTION_NAME)
+                                    ": attempt to deconstruct illegal code point");
+                            }
+                            buf[0] = '\'';
+                            buf[n + 1] = '\'';
+                            buf[n + 2] = '\0';
+
+                        }
                          str_ptr = buf;
                  }
                  MR_make_aligned_string_copy_saved_hp(str, str_ptr, NULL);
diff --git a/tests/hard_coded/deconstruct_arg.exp b/tests/hard_coded/deconstruct_arg.exp
index bb7f081..afcf08c 100644
--- a/tests/hard_coded/deconstruct_arg.exp
+++ b/tests/hard_coded/deconstruct_arg.exp
@@ -111,9 +111,9 @@ deconstruct limited deconstruct 3 of moomoo(50, "moo.")
  functor moomoo arity 2 [50, "moo."]

  deconstruct functor: 'a'/0
-deconstruct argument 0 of a doesn't exist
-deconstruct argument 1 of a doesn't exist
-deconstruct argument 2 of a doesn't exist
+deconstruct argument 0 of 'a' doesn't exist
+deconstruct argument 1 of 'a' doesn't exist
+deconstruct argument 2 of 'a' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -121,13 +121,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 'a' arity 0
  []
-deconstruct limited deconstruct 3 of a
+deconstruct limited deconstruct 3 of 'a'
  functor 'a' arity 0 []

  deconstruct functor: '\a'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\a' doesn't exist
+deconstruct argument 1 of '\a' doesn't exist
+deconstruct argument 2 of '\a' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -135,13 +135,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\a' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\a'
  functor '\a' arity 0 []

  deconstruct functor: '\b'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\b' doesn't exist
+deconstruct argument 1 of '\b' doesn't exist
+deconstruct argument 2 of '\b' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -149,13 +149,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\b' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\b'
  functor '\b' arity 0 []

  deconstruct functor: '\r'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\r' doesn't exist
+deconstruct argument 1 of '\r' doesn't exist
+deconstruct argument 2 of '\r' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -163,13 +163,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\r' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\r'
  functor '\r' arity 0 []

  deconstruct functor: '\f'/0
-deconstruct argument 0 of 
 doesn't exist
-deconstruct argument 1 of 
 doesn't exist
-deconstruct argument 2 of 
 doesn't exist
+deconstruct argument 0 of '\f' doesn't exist
+deconstruct argument 1 of '\f' doesn't exist
+deconstruct argument 2 of '\f' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -177,13 +177,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\f' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\f'
  functor '\f' arity 0 []

  deconstruct functor: '\t'/0
-deconstruct argument 0 of 	 doesn't exist
-deconstruct argument 1 of 	 doesn't exist
-deconstruct argument 2 of 	 doesn't exist
+deconstruct argument 0 of '\t' doesn't exist
+deconstruct argument 1 of '\t' doesn't exist
+deconstruct argument 2 of '\t' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -191,16 +191,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\t' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\t'
  functor '\t' arity 0 []

  deconstruct functor: '\n'/0
-deconstruct argument 0 of 
- doesn't exist
-deconstruct argument 1 of 
- doesn't exist
-deconstruct argument 2 of 
- doesn't exist
+deconstruct argument 0 of '\n' doesn't exist
+deconstruct argument 1 of '\n' doesn't exist
+deconstruct argument 2 of '\n' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -208,14 +205,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\n' arity 0
  []
-deconstruct limited deconstruct 3 of 
-
+deconstruct limited deconstruct 3 of '\n'
  functor '\n' arity 0 []

  deconstruct functor: '\v'/0
-deconstruct argument 0 of 
 doesn't exist
-deconstruct argument 1 of 
 doesn't exist
-deconstruct argument 2 of 
 doesn't exist
+deconstruct argument 0 of '\v' doesn't exist
+deconstruct argument 1 of '\v' doesn't exist
+deconstruct argument 2 of '\v' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -223,13 +219,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\v' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\v'
  functor '\v' arity 0 []

  deconstruct functor: '\\'/0
-deconstruct argument 0 of \ doesn't exist
-deconstruct argument 1 of \ doesn't exist
-deconstruct argument 2 of \ doesn't exist
+deconstruct argument 0 of '\\' doesn't exist
+deconstruct argument 1 of '\\' doesn't exist
+deconstruct argument 2 of '\\' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -237,13 +233,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\\' arity 0
  []
-deconstruct limited deconstruct 3 of \
+deconstruct limited deconstruct 3 of '\\'
  functor '\\' arity 0 []

  deconstruct functor: '\''/0
-deconstruct argument 0 of ' doesn't exist
-deconstruct argument 1 of ' doesn't exist
-deconstruct argument 2 of ' doesn't exist
+deconstruct argument 0 of '\'' doesn't exist
+deconstruct argument 1 of '\'' doesn't exist
+deconstruct argument 2 of '\'' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -251,9 +247,65 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\'' arity 0
  []
-deconstruct limited deconstruct 3 of '
+deconstruct limited deconstruct 3 of '\''
  functor '\'' arity 0 []

+deconstruct functor: '\001\'/0
+deconstruct argument 0 of '\001\' doesn't exist
+deconstruct argument 1 of '\001\' doesn't exist
+deconstruct argument 2 of '\001\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\001\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\001\'
+functor '\001\' arity 0 []
+
+deconstruct functor: '\037\'/0
+deconstruct argument 0 of '\037\' doesn't exist
+deconstruct argument 1 of '\037\' doesn't exist
+deconstruct argument 2 of '\037\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\037\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\037\'
+functor '\037\' arity 0 []
+
+deconstruct functor: '\177\'/0
+deconstruct argument 0 of '\177\' doesn't exist
+deconstruct argument 1 of '\177\' doesn't exist
+deconstruct argument 2 of '\177\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\177\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\177\'
+functor '\177\' arity 0 []
+
+deconstruct functor: 'Ω'/0
+deconstruct argument 0 of 'Ω' doesn't exist
+deconstruct argument 1 of 'Ω' doesn't exist
+deconstruct argument 2 of 'Ω' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor 'Ω' arity 0
+[]
+deconstruct limited deconstruct 3 of 'Ω'
+functor 'Ω' arity 0 []
+
  deconstruct functor: 0.12345678901234566/0
  deconstruct argument 0 of 0.12345678901234566 doesn't exist
  deconstruct argument 1 of 0.12345678901234566 doesn't exist
@@ -311,9 +363,9 @@ deconstruct limited deconstruct 3 of 4
  functor 4 arity 0 []

  deconstruct functor: 561u/0
-deconstruct argument 0 of 561 doesn't exist
-deconstruct argument 1 of 561 doesn't exist
-deconstruct argument 2 of 561 doesn't exist
+deconstruct argument 0 of 561u doesn't exist
+deconstruct argument 1 of 561u doesn't exist
+deconstruct argument 2 of 561u doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -321,13 +373,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 561u arity 0
  []
-deconstruct limited deconstruct 3 of 561
+deconstruct limited deconstruct 3 of 561u
  functor 561u arity 0 []

  deconstruct functor: 42i8/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i8 doesn't exist
+deconstruct argument 1 of 42i8 doesn't exist
+deconstruct argument 2 of 42i8 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -335,13 +387,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i8 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i8
  functor 42i8 arity 0 []

  deconstruct functor: 42u8/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42u8 doesn't exist
+deconstruct argument 1 of 42u8 doesn't exist
+deconstruct argument 2 of 42u8 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -349,13 +401,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42u8 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42u8
  functor 42u8 arity 0 []

  deconstruct functor: 42i16/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i16 doesn't exist
+deconstruct argument 1 of 42i16 doesn't exist
+deconstruct argument 2 of 42i16 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -363,13 +415,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i16 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i16
  functor 42i16 arity 0 []

  deconstruct functor: 42u16/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42u16 doesn't exist
+deconstruct argument 1 of 42u16 doesn't exist
+deconstruct argument 2 of 42u16 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -377,13 +429,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42u16 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42u16
  functor 42u16 arity 0 []

  deconstruct functor: 42i32/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i32 doesn't exist
+deconstruct argument 1 of 42i32 doesn't exist
+deconstruct argument 2 of 42i32 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -391,13 +443,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i32 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i32
  functor 42i32 arity 0 []

  deconstruct functor: 43u32/0
-deconstruct argument 0 of 43 doesn't exist
-deconstruct argument 1 of 43 doesn't exist
-deconstruct argument 2 of 43 doesn't exist
+deconstruct argument 0 of 43u32 doesn't exist
+deconstruct argument 1 of 43u32 doesn't exist
+deconstruct argument 2 of 43u32 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -405,13 +457,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 43u32 arity 0
  []
-deconstruct limited deconstruct 3 of 43
+deconstruct limited deconstruct 3 of 43u32
  functor 43u32 arity 0 []

  deconstruct functor: 66i64/0
-deconstruct argument 0 of 66 doesn't exist
-deconstruct argument 1 of 66 doesn't exist
-deconstruct argument 2 of 66 doesn't exist
+deconstruct argument 0 of 66i64 doesn't exist
+deconstruct argument 1 of 66i64 doesn't exist
+deconstruct argument 2 of 66i64 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -419,13 +471,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 66i64 arity 0
  []
-deconstruct limited deconstruct 3 of 66
+deconstruct limited deconstruct 3 of 66i64
  functor 66i64 arity 0 []

  deconstruct functor: 67u64/0
-deconstruct argument 0 of 67 doesn't exist
-deconstruct argument 1 of 67 doesn't exist
-deconstruct argument 2 of 67 doesn't exist
+deconstruct argument 0 of 67u64 doesn't exist
+deconstruct argument 1 of 67u64 doesn't exist
+deconstruct argument 2 of 67u64 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -433,13 +485,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 67u64 arity 0
  []
-deconstruct limited deconstruct 3 of 67
+deconstruct limited deconstruct 3 of 67u64
  functor 67u64 arity 0 []

  deconstruct functor: univ_cons/1
-deconstruct argument 0 of ["hi! I\'m a univ!"] is ["hi! I\'m a univ!"]
-deconstruct argument 1 of ["hi! I\'m a univ!"] doesn't exist
-deconstruct argument 2 of ["hi! I\'m a univ!"] doesn't exist
+deconstruct argument 0 of univ_cons(["hi! I\'m a univ!"]) is ["hi! I\'m a univ!"]
+deconstruct argument 1 of univ_cons(["hi! I\'m a univ!"]) doesn't exist
+deconstruct argument 2 of univ_cons(["hi! I\'m a univ!"]) doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -447,7 +499,7 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor univ_cons arity 1
  [["hi! I\'m a univ!"]]
-deconstruct limited deconstruct 3 of ["hi! I\'m a univ!"]
+deconstruct limited deconstruct 3 of univ_cons(["hi! I\'m a univ!"])
  functor univ_cons arity 1 [["hi! I\'m a univ!"]]

  deconstruct functor: set_rep/1
@@ -478,7 +530,7 @@ deconstruct deconstruct: functor newline arity 0
  deconstruct limited deconstruct 3 of '<<predicate>>'
  functor newline arity 0 []

-deconstruct functor: lambda_deconstruct_arg_m_164/1
+deconstruct functor: lambda_deconstruct_arg_m_175/1
  deconstruct argument 0 of '<<predicate>>' is [1, 2]
  deconstruct argument 1 of '<<predicate>>' doesn't exist
  deconstruct argument 2 of '<<predicate>>' doesn't exist
@@ -487,10 +539,10 @@ deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
  deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
-deconstruct deconstruct: functor lambda_deconstruct_arg_m_164 arity 1
+deconstruct deconstruct: functor lambda_deconstruct_arg_m_175 arity 1
  [[1, 2]]
  deconstruct limited deconstruct 3 of '<<predicate>>'
-functor lambda_deconstruct_arg_m_164 arity 1 [[1, 2]]
+functor lambda_deconstruct_arg_m_175 arity 1 [[1, 2]]

  deconstruct functor: p/3
  deconstruct argument 0 of '<<predicate>>' is 1
diff --git a/tests/hard_coded/deconstruct_arg.exp2 b/tests/hard_coded/deconstruct_arg.exp2
index d435242..47987d9 100644
--- a/tests/hard_coded/deconstruct_arg.exp2
+++ b/tests/hard_coded/deconstruct_arg.exp2
@@ -111,9 +111,9 @@ deconstruct limited deconstruct 3 of moomoo(50, "moo.")
  functor moomoo arity 2 [50, "moo."]

  deconstruct functor: 'a'/0
-deconstruct argument 0 of a doesn't exist
-deconstruct argument 1 of a doesn't exist
-deconstruct argument 2 of a doesn't exist
+deconstruct argument 0 of 'a' doesn't exist
+deconstruct argument 1 of 'a' doesn't exist
+deconstruct argument 2 of 'a' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -121,13 +121,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 'a' arity 0
  []
-deconstruct limited deconstruct 3 of a
+deconstruct limited deconstruct 3 of 'a'
  functor 'a' arity 0 []

  deconstruct functor: '\a'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\a' doesn't exist
+deconstruct argument 1 of '\a' doesn't exist
+deconstruct argument 2 of '\a' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -135,13 +135,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\a' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\a'
  functor '\a' arity 0 []

  deconstruct functor: '\b'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\b' doesn't exist
+deconstruct argument 1 of '\b' doesn't exist
+deconstruct argument 2 of '\b' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -149,13 +149,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\b' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\b'
  functor '\b' arity 0 []

  deconstruct functor: '\r'/0
-deconstruct argument 0 of  doesn't exist
-deconstruct argument 1 of  doesn't exist
-deconstruct argument 2 of  doesn't exist
+deconstruct argument 0 of '\r' doesn't exist
+deconstruct argument 1 of '\r' doesn't exist
+deconstruct argument 2 of '\r' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -163,13 +163,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\r' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\r'
  functor '\r' arity 0 []

  deconstruct functor: '\f'/0
-deconstruct argument 0 of 
 doesn't exist
-deconstruct argument 1 of 
 doesn't exist
-deconstruct argument 2 of 
 doesn't exist
+deconstruct argument 0 of '\f' doesn't exist
+deconstruct argument 1 of '\f' doesn't exist
+deconstruct argument 2 of '\f' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -177,13 +177,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\f' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\f'
  functor '\f' arity 0 []

  deconstruct functor: '\t'/0
-deconstruct argument 0 of 	 doesn't exist
-deconstruct argument 1 of 	 doesn't exist
-deconstruct argument 2 of 	 doesn't exist
+deconstruct argument 0 of '\t' doesn't exist
+deconstruct argument 1 of '\t' doesn't exist
+deconstruct argument 2 of '\t' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -191,16 +191,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\t' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\t'
  functor '\t' arity 0 []

  deconstruct functor: '\n'/0
-deconstruct argument 0 of 
- doesn't exist
-deconstruct argument 1 of 
- doesn't exist
-deconstruct argument 2 of 
- doesn't exist
+deconstruct argument 0 of '\n' doesn't exist
+deconstruct argument 1 of '\n' doesn't exist
+deconstruct argument 2 of '\n' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -208,14 +205,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\n' arity 0
  []
-deconstruct limited deconstruct 3 of 
-
+deconstruct limited deconstruct 3 of '\n'
  functor '\n' arity 0 []

  deconstruct functor: '\v'/0
-deconstruct argument 0 of 
 doesn't exist
-deconstruct argument 1 of 
 doesn't exist
-deconstruct argument 2 of 
 doesn't exist
+deconstruct argument 0 of '\v' doesn't exist
+deconstruct argument 1 of '\v' doesn't exist
+deconstruct argument 2 of '\v' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -223,13 +219,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\v' arity 0
  []
-deconstruct limited deconstruct 3 of 
+deconstruct limited deconstruct 3 of '\v'
  functor '\v' arity 0 []

  deconstruct functor: '\\'/0
-deconstruct argument 0 of \ doesn't exist
-deconstruct argument 1 of \ doesn't exist
-deconstruct argument 2 of \ doesn't exist
+deconstruct argument 0 of '\\' doesn't exist
+deconstruct argument 1 of '\\' doesn't exist
+deconstruct argument 2 of '\\' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -237,13 +233,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\\' arity 0
  []
-deconstruct limited deconstruct 3 of \
+deconstruct limited deconstruct 3 of '\\'
  functor '\\' arity 0 []

  deconstruct functor: '\''/0
-deconstruct argument 0 of ' doesn't exist
-deconstruct argument 1 of ' doesn't exist
-deconstruct argument 2 of ' doesn't exist
+deconstruct argument 0 of '\'' doesn't exist
+deconstruct argument 1 of '\'' doesn't exist
+deconstruct argument 2 of '\'' doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -251,9 +247,65 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor '\'' arity 0
  []
-deconstruct limited deconstruct 3 of '
+deconstruct limited deconstruct 3 of '\''
  functor '\'' arity 0 []

+deconstruct functor: '\001\'/0
+deconstruct argument 0 of '\001\' doesn't exist
+deconstruct argument 1 of '\001\' doesn't exist
+deconstruct argument 2 of '\001\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\001\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\001\'
+functor '\001\' arity 0 []
+
+deconstruct functor: '\037\'/0
+deconstruct argument 0 of '\037\' doesn't exist
+deconstruct argument 1 of '\037\' doesn't exist
+deconstruct argument 2 of '\037\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\037\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\037\'
+functor '\037\' arity 0 []
+
+deconstruct functor: '\177\'/0
+deconstruct argument 0 of '\177\' doesn't exist
+deconstruct argument 1 of '\177\' doesn't exist
+deconstruct argument 2 of '\177\' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor '\177\' arity 0
+[]
+deconstruct limited deconstruct 3 of '\177\'
+functor '\177\' arity 0 []
+
+deconstruct functor: 'Ω'/0
+deconstruct argument 0 of 'Ω' doesn't exist
+deconstruct argument 1 of 'Ω' doesn't exist
+deconstruct argument 2 of 'Ω' doesn't exist
+deconstruct argument 'moo' doesn't exist
+deconstruct argument 'mooo!' doesn't exist
+deconstruct argument 'packed1' doesn't exist
+deconstruct argument 'packed2' doesn't exist
+deconstruct argument 'packed3' doesn't exist
+deconstruct deconstruct: functor 'Ω' arity 0
+[]
+deconstruct limited deconstruct 3 of 'Ω'
+functor 'Ω' arity 0 []
+
  deconstruct functor: 0.12345678901234566/0
  deconstruct argument 0 of 0.12345678901234566 doesn't exist
  deconstruct argument 1 of 0.12345678901234566 doesn't exist
@@ -311,9 +363,9 @@ deconstruct limited deconstruct 3 of 4
  functor 4 arity 0 []

  deconstruct functor: 561u/0
-deconstruct argument 0 of 561 doesn't exist
-deconstruct argument 1 of 561 doesn't exist
-deconstruct argument 2 of 561 doesn't exist
+deconstruct argument 0 of 561u doesn't exist
+deconstruct argument 1 of 561u doesn't exist
+deconstruct argument 2 of 561u doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -321,13 +373,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 561u arity 0
  []
-deconstruct limited deconstruct 3 of 561
+deconstruct limited deconstruct 3 of 561u
  functor 561u arity 0 []

  deconstruct functor: 42i8/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i8 doesn't exist
+deconstruct argument 1 of 42i8 doesn't exist
+deconstruct argument 2 of 42i8 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -335,13 +387,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i8 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i8
  functor 42i8 arity 0 []

  deconstruct functor: 42u8/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42u8 doesn't exist
+deconstruct argument 1 of 42u8 doesn't exist
+deconstruct argument 2 of 42u8 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -349,13 +401,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42u8 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42u8
  functor 42u8 arity 0 []

  deconstruct functor: 42i16/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i16 doesn't exist
+deconstruct argument 1 of 42i16 doesn't exist
+deconstruct argument 2 of 42i16 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -363,13 +415,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i16 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i16
  functor 42i16 arity 0 []

  deconstruct functor: 42u16/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42u16 doesn't exist
+deconstruct argument 1 of 42u16 doesn't exist
+deconstruct argument 2 of 42u16 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -377,13 +429,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42u16 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42u16
  functor 42u16 arity 0 []

  deconstruct functor: 42i32/0
-deconstruct argument 0 of 42 doesn't exist
-deconstruct argument 1 of 42 doesn't exist
-deconstruct argument 2 of 42 doesn't exist
+deconstruct argument 0 of 42i32 doesn't exist
+deconstruct argument 1 of 42i32 doesn't exist
+deconstruct argument 2 of 42i32 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -391,13 +443,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 42i32 arity 0
  []
-deconstruct limited deconstruct 3 of 42
+deconstruct limited deconstruct 3 of 42i32
  functor 42i32 arity 0 []

  deconstruct functor: 43u32/0
-deconstruct argument 0 of 43 doesn't exist
-deconstruct argument 1 of 43 doesn't exist
-deconstruct argument 2 of 43 doesn't exist
+deconstruct argument 0 of 43u32 doesn't exist
+deconstruct argument 1 of 43u32 doesn't exist
+deconstruct argument 2 of 43u32 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -405,13 +457,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 43u32 arity 0
  []
-deconstruct limited deconstruct 3 of 43
+deconstruct limited deconstruct 3 of 43u32
  functor 43u32 arity 0 []

  deconstruct functor: 66i64/0
-deconstruct argument 0 of 66 doesn't exist
-deconstruct argument 1 of 66 doesn't exist
-deconstruct argument 2 of 66 doesn't exist
+deconstruct argument 0 of 66i64 doesn't exist
+deconstruct argument 1 of 66i64 doesn't exist
+deconstruct argument 2 of 66i64 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -419,13 +471,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 66i64 arity 0
  []
-deconstruct limited deconstruct 3 of 66
+deconstruct limited deconstruct 3 of 66i64
  functor 66i64 arity 0 []

  deconstruct functor: 67u64/0
-deconstruct argument 0 of 67 doesn't exist
-deconstruct argument 1 of 67 doesn't exist
-deconstruct argument 2 of 67 doesn't exist
+deconstruct argument 0 of 67u64 doesn't exist
+deconstruct argument 1 of 67u64 doesn't exist
+deconstruct argument 2 of 67u64 doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -433,13 +485,13 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor 67u64 arity 0
  []
-deconstruct limited deconstruct 3 of 67
+deconstruct limited deconstruct 3 of 67u64
  functor 67u64 arity 0 []

  deconstruct functor: univ_cons/1
-deconstruct argument 0 of ["hi! I\'m a univ!"] is ["hi! I\'m a univ!"]
-deconstruct argument 1 of ["hi! I\'m a univ!"] doesn't exist
-deconstruct argument 2 of ["hi! I\'m a univ!"] doesn't exist
+deconstruct argument 0 of univ_cons(["hi! I\'m a univ!"]) is ["hi! I\'m a univ!"]
+deconstruct argument 1 of univ_cons(["hi! I\'m a univ!"]) doesn't exist
+deconstruct argument 2 of univ_cons(["hi! I\'m a univ!"]) doesn't exist
  deconstruct argument 'moo' doesn't exist
  deconstruct argument 'mooo!' doesn't exist
  deconstruct argument 'packed1' doesn't exist
@@ -447,7 +499,7 @@ deconstruct argument 'packed2' doesn't exist
  deconstruct argument 'packed3' doesn't exist
  deconstruct deconstruct: functor univ_cons arity 1
  [["hi! I\'m a univ!"]]
-deconstruct limited deconstruct 3 of ["hi! I\'m a univ!"]
+deconstruct limited deconstruct 3 of univ_cons(["hi! I\'m a univ!"])
  functor univ_cons arity 1 [["hi! I\'m a univ!"]]

  deconstruct functor: set_rep/1
diff --git a/tests/hard_coded/deconstruct_arg.m b/tests/hard_coded/deconstruct_arg.m
index a5ce3a6..cbba19a 100644
--- a/tests/hard_coded/deconstruct_arg.m
+++ b/tests/hard_coded/deconstruct_arg.m
@@ -24,6 +24,8 @@
  :- import_module deconstruct.
  :- import_module maybe.
  :- import_module pair.
+:- import_module stream.
+:- import_module stream.string_writer.
  :- import_module univ.

  :- type enum
@@ -128,6 +130,15 @@ main(!IO) :-
      test_all('\\', !IO),
      test_all('\'', !IO),

+    % test C0 control characters
+    test_all('\1\', !IO),
+    test_all('\37\', !IO),
+    test_all('\177\', !IO),
+
+    % test a character that requires more than one byte in its
+    % UTF-8 encoding.
+    test_all('Ω', !IO),
+
      % test a float which requires 17 digits of precision
      test_all(0.12345678901234566, !IO),

@@ -216,7 +227,7 @@ test_deconstruct_functor(T, !IO) :-

  test_deconstruct_arg(T, ArgNum, !IO) :-
      io.format("deconstruct argument %d of ", [i(ArgNum)], !IO),
-    io.print(T, !IO),
+    io.write(T, !IO),
      deconstruct.arg_cc(T, ArgNum, MaybeArg),
      (
          MaybeArg = arg(Arg),
@@ -252,7 +263,7 @@ test_deconstruct_deconstruct(T, !IO) :-
      io.format("deconstruct deconstruct: functor %s arity %d\n",
          [s(Functor), i(Arity)], !IO),
      io.write_string("[", !IO),
-    io.write_list(Arguments, ", ", io.print, !IO),
+    io.write_list(Arguments, ", ", write_arg_univ, !IO),
      io.write_string("]\n", !IO).

  :- pred test_deconstruct_limited_deconstruct(T::in, int::in, io::di, io::uo)
@@ -260,18 +271,24 @@ test_deconstruct_deconstruct(T, !IO) :-

  test_deconstruct_limited_deconstruct(T, Limit, !IO) :-
      io.format("deconstruct limited deconstruct %d of ", [i(Limit)], !IO),
-    io.print(T, !IO),
+    io.write(T, !IO),
      io.nl(!IO),
      deconstruct.limited_deconstruct_cc(T, Limit, Result),
      (
          Result = yes({Functor, Arity, Arguments}),
          io.format("functor %s arity %d ", [s(Functor), i(Arity)], !IO),
          io.write_string("[", !IO),
-        io.write_list(Arguments, ", ", io.print, !IO),
+        io.write_list(Arguments, ", ", write_arg_univ, !IO),
          io.write_string("]\n", !IO)
      ;
          Result = no,
          io.write_string("failed\n", !IO)
      ).

+:- pred write_arg_univ(univ::in, io::di, io::uo) is det.
+
+write_arg_univ(Univ, !IO) :-
+    io.stdout_stream(Stdout, !IO),
+    stream.string_writer.write_univ(Stdout, Univ, !IO).
+
  %---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/write.exp b/tests/hard_coded/write.exp
index 7c02517..f9e16ef 100644
--- a/tests/hard_coded/write.exp
+++ b/tests/hard_coded/write.exp
@@ -28,11 +28,24 @@ TESTING BUILTINS
  "Hello, world\n"
  "Foo%sFoo"
  "\""
+"\a\b\f\t\n\r\v\"\\"
  'a'
  '&'
+'\a'
+'\b'
+'\f'
+'\t'
+'\n'
+'\r'
+'\v'
+'\''
+'\\'
+'\"'
  3.14159
  1.128324983e-21
  2.23954899e+23
+-infinity
+infinity
  -65
  4
  651u
diff --git a/tests/hard_coded/write.m b/tests/hard_coded/write.m
index 54d5b1b..3e9c9f0 100644
--- a/tests/hard_coded/write.m
+++ b/tests/hard_coded/write.m
@@ -12,6 +12,7 @@
  :- implementation.

  :- import_module array.
+:- import_module float.
  :- import_module int.
  :- import_module list.
  :- import_module map.
@@ -125,15 +126,29 @@ test_builtins(!IO) :-
      io.write("Hello, world\n", !IO), newline(!IO),
      io.write("Foo%sFoo", !IO), newline(!IO),
      io.write("""", !IO), newline(!IO),    % interesting - prints """ of course
+    io.write("\a\b\f\t\n\r\v\"\\", !IO), newline(!IO),

      % Test characters.
      io.write('a', !IO), newline(!IO),
      io.write('&', !IO), newline(!IO),
+    io.write('\a', !IO), newline(!IO),
+    io.write('\b', !IO), newline(!IO),
+    io.write('\f', !IO), newline(!IO),
+    io.write('\t', !IO), newline(!IO),
+    io.write('\n', !IO), newline(!IO),
+    io.write('\r', !IO), newline(!IO),
+    io.write('\v', !IO), newline(!IO),
+    io.write('\'', !IO), newline(!IO),
+    io.write(('\\') : character, !IO), newline(!IO),
+    io.write('\"', !IO), newline(!IO),

      % Test floats.
      io.write(3.14159, !IO), newline(!IO),
      io.write(11.28324983E-22, !IO), newline(!IO),
      io.write(22.3954899E22, !IO), newline(!IO),
+    NegInf : float = -float.infinity,
+    io.write(NegInf, !IO), newline(!IO),
+    io.write(float.infinity, !IO), newline(!IO),

      % Test ints.
      io.write(-65, !IO), newline(!IO),


More information about the reviews mailing list