From: Mark Thom Date: Mon, 3 Sep 2018 23:21:28 +0000 (-0600) Subject: fixes to quoted X-Git-Tag: v0.8.110~399 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=4be20e48e6571d79dabb5916bd5c6e76c2cb5fb5;p=scryer-prolog.git fixes to quoted --- diff --git a/README.md b/README.md index f0307d7c..8deb3cee 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ information. The following predicates are built-in to rusty-wam. * Arithmetic support: - * `is/2` works for `(+)/2`, `(-)/{1,2}`, `(*)/2`, `(//)/2`, `(^)/2`, `(div)/2`, `(/)/2`, `(rdiv)/2`, + * `is/2` works for `(+)/2`, `(-)/{1,2}`, `(*)/2`, `(//)/2`, `(**)/2`, `(div)/2`, `(/)/2`, `(rdiv)/2`, `(xor)/2`, `(rem)/2`, `(mod)/2`, `(/\)/2`, `(\/)/2`, `(>>)/2`, `(<<)/2`, `abs/1`. * Comparison operators: `>`, `<`, `=<`, `>=`, `=:=`, `=\=`. * `(:)/2` diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index ecde8b59..72f5c562 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -122,7 +122,7 @@ impl<'a> ArithmeticEvaluator<'a> "div" => Ok(ArithmeticInstruction::FIDiv(a1, a2, t)), "rdiv" => Ok(ArithmeticInstruction::RDiv(a1, a2, t)), "*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)), - "^" => Ok(ArithmeticInstruction::Pow(a1, a2, t)), + "**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)), ">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)), "<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)), "/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)), diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 9b4689fb..06e9acf8 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -6,12 +6,14 @@ use prolog::ordered_float::OrderedFloat; use std::cell::Cell; use std::collections::{HashMap, HashSet}; +use std::iter::once; use std::rc::Rc; #[derive(Clone)] pub enum TokenOrRedirect { Atom(ClauseName), - NumberedVar(String), + Op(ClauseName), + NumberedVar(String), Redirect, Open, Close, @@ -113,16 +115,16 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool { fn print_op(ct: ClauseType, fixity: Fixity, state_stack: &mut Vec) { match fixity { Fixity::Post => { - state_stack.push(TokenOrRedirect::Atom(ct.name())); + state_stack.push(TokenOrRedirect::Op(ct.name())); state_stack.push(TokenOrRedirect::Redirect); }, Fixity::Pre => { state_stack.push(TokenOrRedirect::Redirect); - state_stack.push(TokenOrRedirect::Atom(ct.name())); + state_stack.push(TokenOrRedirect::Op(ct.name())); }, Fixity::In => { state_stack.push(TokenOrRedirect::Redirect); - state_stack.push(TokenOrRedirect::Atom(ct.name())); + state_stack.push(TokenOrRedirect::Op(ct.name())); state_stack.push(TokenOrRedirect::Redirect); } } @@ -200,8 +202,53 @@ fn reverse_heap_locs<'a>(machine_st: &'a MachineState, heap_locs: &'a HeapVarDic }).collect() } -fn non_quoted_token(c: char) -> bool { - graphic_token_char!(c) || alpha_numeric_char!(c) +fn non_quoted_graphic_token>(mut iter: Iter, c: char) -> bool { + if c == '/' { + return match iter.next() { + None => true, + Some('*') => false, // if we start with comment token, we must quote. + Some(c) => if graphic_token_char!(c) { + iter.all(|c| graphic_token_char!(c)) + } else { + false + } + } + } else if c == '.' { + return match iter.next() { + None => false, + Some(c) => if graphic_token_char!(c) { + iter.all(|c| graphic_token_char!(c)) + } else { + false + } + } + } else { + iter.all(|c| graphic_token_char!(c)) + } +} + +fn non_quoted_token>(mut iter: Iter) -> bool { + if let Some(c) = iter.next() { + if small_letter_char!(c) { + iter.all(|c| alpha_numeric_char!(c)) + } else if graphic_token_char!(c) { + non_quoted_graphic_token(iter, c) + } else if semicolon_char!(c) { + iter.next().is_none() + } else if cut_char!(c) { + iter.next().is_none() + } else if solo_char!(c) { + !iter.next().is_none() + } else if c == '[' { + (iter.next() == Some(']') && iter.next().is_none()) + } else if c == '{' { + (iter.next() == Some('}') && iter.next().is_none()) + } else { + false + } + } else { + false + } } impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> @@ -277,11 +324,11 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> }) } - fn print_atom(&mut self, atom: &ClauseName) { + fn print_atom(&mut self, atom: &ClauseName, is_op: bool) { match atom.as_str() { "" => self.outputter.append("''"), ";" | "!" => self.outputter.append(atom.as_str()), - s => if s.chars().all(non_quoted_token) { + s => if is_op || non_quoted_token(s.chars()) { self.outputter.append(atom.as_str()); } else { self.outputter.push_char('\''); @@ -311,8 +358,8 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> fn print_constant(&mut self, c: Constant) { match c { Constant::Atom(ref atom) => - self.print_atom(atom), - Constant::Char(c) if non_quoted_token(c) => + self.print_atom(atom, false), + Constant::Char(c) if non_quoted_token(once(c)) => self.print_char(c), Constant::Char(c) => { self.outputter.push_char('\''); @@ -408,7 +455,9 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> if let Some(loc_data) = self.state_stack.pop() { match loc_data { TokenOrRedirect::Atom(atom) => - self.print_atom(&atom), + self.print_atom(&atom, false), + TokenOrRedirect::Op(atom) => + self.print_atom(&atom, true), TokenOrRedirect::NumberedVar(num_var) => self.outputter.append(num_var.as_str()), TokenOrRedirect::Redirect => diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 5e209bbe..7cf42ee1 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -1,6 +1,6 @@ :- op(400, yfx, /). -:- module(builtins, [(=)/2, (+)/2, (^)/2, (*)/2, (-)/2, (/)/2, (/\)/2, +:- module(builtins, [(=)/2, (+)/2, (**)/2, (*)/2, (-)/2, (/)/2, (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, (==)/2, @@ -19,7 +19,7 @@ :- op(500, yfx, +). :- op(500, yfx, -). :- op(400, yfx, *). -:- op(200, xfy, ^). +:- op(200, xfy, **). :- op(500, yfx, /\). :- op(500, yfx, \/). :- op(500, yfx, xor). diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 111c4495..b0f8a579 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -481,7 +481,7 @@ impl MachineState { "-" => interms.push(a1 - a2), "*" => interms.push(a1 * a2), "/" => interms.push(self.div(a1, a2)?), - "^" => interms.push(self.pow(a1, a2)?), + "**" => interms.push(self.pow(a1, a2)?), "rdiv" => { let r1 = self.get_rational(&ArithmeticTerm::Number(a1), &caller)?; let r2 = self.get_rational(&ArithmeticTerm::Number(a2), &caller)?; @@ -593,7 +593,7 @@ impl MachineState { match n1.pow(n2) { Ok(result) => Ok(result), Err(_) => { - let stub = MachineError::functor_stub(clause_name!("^"), 2); + let stub = MachineError::functor_stub(clause_name!("**"), 2); Err(self.error_form(MachineError::evaluation_error(EvalError::NoRoots), stub)) } diff --git a/src/prolog/parser b/src/prolog/parser index ba996251..48814651 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit ba9962514adf528d973babe09c7ebdaeec3eb24c +Subproject commit 48814651b857b2fd55149320f1ea71d0571b442e diff --git a/src/tests.rs b/src/tests.rs index 5f162562..b59abfa7 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1027,66 +1027,66 @@ fn test_queries_on_arithmetic() submit(&mut wam, ":- op(900, xfx, ~)."); submit(&mut wam, "X ~ Y :- abs(X - Y) =< 1 rdiv 10000."); - assert_prolog_success!(&mut wam, "?- X is 3 ^ 3.", + assert_prolog_success!(&mut wam, "?- X is 3 ** 3.", [["X = 27"]]); - assert_prolog_success!(&mut wam, "?- X is 3 ^ 0.", + assert_prolog_success!(&mut wam, "?- X is 3 ** 0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- X is 3 ^ -0.", + assert_prolog_success!(&mut wam, "?- X is 3 ** -0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- X is 3 ^ 1.", + assert_prolog_success!(&mut wam, "?- X is 3 ** 1.", [["X = 3"]]); - assert_prolog_success!(&mut wam, "?- X is 3 ^ -3.", + assert_prolog_success!(&mut wam, "?- X is 3 ** -3.", [["X = 1/27"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ 3.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** 3.", [["X = -27"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ 3.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** 3.", [["X = -27"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ 0.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** 0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ -0.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** -0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ 1.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** 1.", [["X = -3"]]); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ -3.", + assert_prolog_success!(&mut wam, "?- X is (-3) ** -3.", [["X = -1/27"]]); - assert_prolog_success!(&mut wam, "?- X is (1 rdiv 27) ^ -3, X ~ 19683."); - assert_prolog_success!(&mut wam, "?- X is (-1 rdiv 27) ^ -3, X ~ -19683."); + assert_prolog_success!(&mut wam, "?- X is (1 rdiv 27) ** -3, X ~ 19683."); + assert_prolog_success!(&mut wam, "?- X is (-1 rdiv 27) ** -3, X ~ -19683."); - assert_prolog_success!(&mut wam, "?- X is 0.0 ^ 0.", + assert_prolog_success!(&mut wam, "?- X is 0.0 ** 0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is 0.0 ^ -2342, error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is 0.0 ** -2342, error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- X is 0.0 ^ 2342.", + assert_prolog_success!(&mut wam, "?- X is 0.0 ** 2342.", [["X = 0"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is (-3) ^ (1 rdiv 2), error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is (-3/2) ^ (1 rdiv 2), error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ^ (1 rdiv 4), error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ^ (-1 rdiv 4), error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is 0 ^ (-5 rdiv 4), error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).", [["E = evaluation_error(no_roots)"]]); - assert_prolog_success!(&mut wam, "?- X is 3 ^ (1 rdiv 3), Y is X ^ 3, Y ~ 3."); - assert_prolog_success!(&mut wam, "?- X is (-3) ^ (1 rdiv 3), Y is X ^ 3, Y ~ -3."); - assert_prolog_failure!(&mut wam, "?- X is (-5) ^ (1 rdiv 3), Y is X ^ 3, Y ~ -3."); - assert_prolog_failure!(&mut wam, "?- X is 5 ^ (1 rdiv 3), Y is X ^ 3, Y ~ 3."); - assert_prolog_failure!(&mut wam, "?- X is (1 rdiv 3) ^ 0.5, Y is X ^ 2, X ~ Y."); - assert_prolog_success!(&mut wam, "?- X is (1 rdiv 3) ^ 0.5, Y is X ^ 2, 1 rdiv 3 ~ Y."); + assert_prolog_success!(&mut wam, "?- X is 3 ** (1 rdiv 3), Y is X ** 3, Y ~ 3."); + assert_prolog_success!(&mut wam, "?- X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); + assert_prolog_failure!(&mut wam, "?- X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); + assert_prolog_failure!(&mut wam, "?- X is 5 ** (1 rdiv 3), Y is X ** 3, Y ~ 3."); + assert_prolog_failure!(&mut wam, "?- X is (1 rdiv 3) ** 0.5, Y is X ** 2, X ~ Y."); + assert_prolog_success!(&mut wam, "?- X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y."); - assert_prolog_success!(&mut wam, "?- X is (-5) ^ (-1 rdiv 3), Y is X ^ 3, Y ~ -1 rdiv 5."); - assert_prolog_failure!(&mut wam, "?- X is (-5) ^ (-1 rdiv 3), Y is X ^ 3, Y ~ 1 rdiv 5."); + assert_prolog_success!(&mut wam, "?- X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5."); + assert_prolog_failure!(&mut wam, "?- X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5."); - assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ^ 5.", + assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ** 5.", [["X = 0"]]); - assert_prolog_success!(&mut wam, "?- X is (-0 rdiv 5) ^ 5.", + assert_prolog_success!(&mut wam, "?- X is (-0 rdiv 5) ** 5.", [["X = 0"]]); - assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ^ 0.", + assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ** 0.", [["X = 1"]]); - assert_prolog_success!(&mut wam, "?- catch(_ is (0 rdiv 0) ^ 5, error(E, _), true).", + assert_prolog_success!(&mut wam, "?- catch(_ is (0 rdiv 0) ** 5, error(E, _), true).", [["E = evaluation_error(zero_divisor)"]]); }