From: Mark Thom Date: Mon, 3 Sep 2018 19:50:49 +0000 (-0600) Subject: properly handle character controls from ASCII to UTF-8, re: #48 X-Git-Tag: v0.8.110~402 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=c3cce4abd5dd74b47411aed5595dd5e867d5545f;p=scryer-prolog.git properly handle character controls from ASCII to UTF-8, re: #48 --- diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 35e3c705..3b02a245 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -143,7 +143,7 @@ impl HCValueFormatter for WriteqFormatter { // 7.10.4 match iter.machine_st.store(iter.machine_st.deref(addr)) { - Addr::Con(Constant::Number(Number::Integer(n))) => { + Addr::Con(Constant::Number(Number::Integer(ref n))) if !n.is_negative() => { iter.stack().pop(); let i = n.mod_floor(&BigInt::from(26)).to_usize().unwrap(); @@ -285,42 +285,47 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> self.outputter.append(atom.as_str()); } else { self.outputter.push_char('\''); - self.outputter.append(atom.as_str()); + + for c in atom.as_str().chars() { + self.print_char(c); + } + self.outputter.push_char('\''); } } } fn print_char(&mut self, c: char) { - if non_quoted_token(c) { - self.outputter.push_char(c); + if c == '\n' { + self.outputter.append("\\n"); + } else if c == '\r' { + self.outputter.append("\\r"); + } else if c == '\t' { + self.outputter.append("\\t"); + } else if c == '\u{0b}' { // UTF-8 vertical tab + self.outputter.append("\\v"); + } else if c == '\u{0c}' { // UTF-8 form feed + self.outputter.append("\\f"); + } else if c == '\u{08}' { // UTF-8 backspace + self.outputter.append("\\b"); + } else if c == '\u{07}' { // UTF-8 alert + self.outputter.append("\\a"); } else { - self.outputter.push_char('\''); self.outputter.push_char(c); - self.outputter.push_char('\''); } } fn print_constant(&mut self, c: Constant) { match c { Constant::Atom(ref atom) => - self.print_atom(atom), - Constant::Char(c) if c == '\n' => - self.outputter.append("'\\n'"), - Constant::Char(c) if c == '\r' => - self.outputter.append("'\\r'"), - Constant::Char(c) if c == '\t' => - self.outputter.append("'\\t'"), -// Constant::Char(c) if c == '\f' => -// self.outputter.append("\\f"), -// Constant::Char(c) if c == '\b' => -// self.outputter.append("\\b"), -// Constant::Char(c) if c == '\\a' => -// self.outputter.append("\a"), -// Constant::Char(c) if c == '\\v' => -// self.outputter.append("\\v"), - Constant::Char(c) => + self.print_atom(atom), + Constant::Char(c) if non_quoted_token(c) => self.print_char(c), + Constant::Char(c) => { + self.outputter.push_char('\''); + self.print_char(c); + self.outputter.push_char('\''); + }, Constant::EmptyList => self.outputter.append("[]"), Constant::Number(Number::Float(fl)) => diff --git a/src/prolog/parser b/src/prolog/parser index b663bce8..b23670b2 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit b663bce82dc7543c2bc01b557f7b0926ef29f07c +Subproject commit b23670b232d1f3a069c6a4a87378a399a69e8274 diff --git a/src/tests.rs b/src/tests.rs index bc5b9289..5adb8d37 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1622,7 +1622,20 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 100, R).", [["G = 2", "B = 3", "R = !", "S = 1"]]); assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 10, R).", - [["S = _1", "G = _4", "B = _14", "R = inference_limit_exceeded"]]); + [["S = _1", "G = _4", "B = _14", "R = inference_limit_exceeded"]]); + + assert_prolog_success!(&mut wam, "?- X = '\\n'.", + [["X = '\\n'"]]); + assert_prolog_success!(&mut wam, "?- X = '\\b'.", + [["X = '\\b'"]]); + assert_prolog_success!(&mut wam, "?- X = '\\v'.", + [["X = '\\v'"]]); + assert_prolog_success!(&mut wam, "?- X = '\\a'.", + [["X = '\\a'"]]); + assert_prolog_success!(&mut wam, "?- X = '\\f'.", + [["X = '\\f'"]]); + assert_prolog_success!(&mut wam, "?- X = '\\b\\r\\f\\t\\n'.", + [["X = '\\b\\r\\f\\t\\n'"]]); } #[test]