]> Repositorios git - scryer-prolog.git/commitdiff
correct for issues #88, #89, #90, conformity test #208.
authorMark Thom <[email protected]>
Sat, 6 Apr 2019 15:46:42 +0000 (09:46 -0600)
committerMark Thom <[email protected]>
Sat, 6 Apr 2019 15:46:42 +0000 (09:46 -0600)
Cargo.toml
src/prolog/codegen.rs
src/prolog/heap_print.rs
src/prolog/lib/builtins.pl
src/prolog/lib/reif.pl
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs
src/tests.rs

index 647f3da1cb5a4bd55fdac0434cbb11353a5bd10d..352b8bbbe0ab7d402d4c916a713cfa1b0eccbc4f 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.44"
+version = "0.8.45"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
index f05e8d58b7846da868506718faba24c08d7120da..9d84e1d268008ebde05e8cccf46d0a0da5f3e45e 100644 (file)
@@ -317,6 +317,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
             &InlinedClauseType::IsAtom(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::Char(_))
+                  | &Term::Constant(_, Constant::EmptyList)
                   | &Term::Constant(_, Constant::Atom(..)) => {
                         code.push(succeed!());
                     },
index b6b93e77c49ca0a8a9b8f24990b618a43ca38294..50eafeaa463e38531f42d6fd6e71eab0803b5d6b 100644 (file)
@@ -264,7 +264,7 @@ macro_rules! push_space_if_amb {
     )
 }
 
-fn continues_with_append(atom: &str, op: &str) -> bool {
+fn requires_space(atom: &str, op: &str) -> bool {
     match atom.chars().last() {
         Some(ac) => op.chars().next().map(|oc| {
             if alpha_char!(ac) {
@@ -277,6 +277,8 @@ fn continues_with_append(atom: &str, op: &str) -> bool {
                 alpha_numeric_char!(oc)
             } else if sign_char!(ac) {
                 sign_char!(oc) || decimal_digit_char!(oc)
+            } else if ac == '0' {
+                !non_quoted_token(op.chars())
             } else {
                 false
             }
@@ -382,7 +384,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
     fn ambiguity_check(&self, atom: &str) -> bool
     {
         let tail = self.outputter.range_from(self.last_item_idx ..);
-        continues_with_append(tail, atom)
+        requires_space(tail, atom)
     }
 
     // TODO: create a DirectedOp factory method. Use it here, and above.
@@ -579,11 +581,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
     }
 
     fn print_op(&mut self, atom: &str) {
-        if atom == "," {
-            self.push_char(',');
-        } else {
-            self.print_op_addendum(atom);
-        }
+        push_space_if_amb!(self, atom, {
+            if atom == "," {
+                self.push_char(',');
+            } else {
+                self.print_op_addendum(atom);
+            }
+        });
     }
 
     fn print_char(&mut self, c: char) {
index 6417ac83fe3d96f63be68a0a03dfc2c486206f76..e86e305d461b34303a3f161275ec2b72108d3e9b 100644 (file)
@@ -4,7 +4,7 @@
        (+)/2, (**)/2, (*)/2, (-)/1, (-)/2, (/)/2, (/\)/2, (\/)/2,
        (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2,
        (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2,
-       (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, (==)/2, (\==)/2,
+       (=<)/2, (',')/2, (->)/2, (;)/2, (=..)/2, (==)/2, (\==)/2,
        (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2, (\=@=)/2, (:)/2,
        abolish/1, asserta/1, assertz/1, atom_chars/2, atom_codes/2,
        atom_length/2, bagof/3, bb_b_put/2, bb_get/2, bb_put/2,
@@ -137,10 +137,10 @@ repeat :- repeat.
 ','(G1, G2) :- '$get_b_value'(B), '$call_with_default_policy'(comma_errors(G1, G2, B)).
 
 :- non_counted_backtracking comma_errors/3.
-comma_errors(G1, G2, B) :- var(G1), throw(error(instantiation_error, (,)/2)).
+comma_errors(G1, G2, B) :- var(G1), throw(error(instantiation_error, (',')/2)).
 comma_errors(G1, G2, B) :- '$call_with_default_policy'(','(G1, G2, B)).
 
-:- non_counted_backtracking (,)/3.
+:- non_counted_backtracking (',')/3.
 ','(!, CF, B) :- compound(CF),
                 '$call_with_default_policy'(CF = ','(G1, G2)),
                 '$set_cp'(B),
@@ -256,12 +256,13 @@ expand_term(Term0, Term) :- '$expand_term'(Term0, Term).
 
 % term_variables.
 
-can_be(Type, Term) :- error:can_be(Type, Term).
+% ensures List is either a variable or a proper list.
+can_be_list(List, _)  :- var(List), !.
+can_be_list(List, _)  :- '$skip_max_list'(_, -1, List, Tail), Tail == [], !.
+can_be_list(List, PI) :- throw(error(type_error(list, List), PI)).
 
 term_variables(Term, Vars) :-
-    catch(can_be(list, Vars), error(E, Ctx),
-         ( ( var(Ctx) -> Ctx = term_variables/2 ; true ),
-           throw(error(E, Ctx)) ) ),
+    can_be_list(Vars, term_variables/2),
     '$term_variables'(Term, Vars).
 
 % setup_call_cleanup.
@@ -721,10 +722,15 @@ current_predicate(Pred) :-
     '$get_next_op_db_ref'(Ref, NextRef),
     '$iterate_op_db_refs'(NextRef, Priority, Spec, Op).
 
+can_be_op_priority(Priority) :- var(Priority).
+can_be_op_priority(Priority) :- op_priority(Priority).
+
+can_be_op_specifier(Spec) :- var(Spec).
+can_be_op_specifier(Spec) :- op_specifier(Spec).
+
 current_op(Priority, Spec, Op) :-
-    (  nonvar(Op), \+ atom(Op)
-    -> throw(error(type_error(atom, Op), current_op/3))
-    ;  '$get_next_op_db_ref'(Ref, _),
+    (  can_be_op_priority(Priority), can_be_op_specifier(Spec), error:can_be(atom, Op)
+    -> '$get_next_op_db_ref'(Ref, _),
        '$iterate_op_db_refs'(Ref, Priority, Spec, Op)
     ).
 
@@ -753,7 +759,7 @@ op_specifier(OpSpec) :- atom(OpSpec),
 op_specifier(OpSpec) :- throw(error(type_error(atom, OpSpec), op/3)).
 
 valid_op(Op) :- atom(Op),
-    (  Op == (,) -> throw(error(permission_error(modify, operator, (,)), op/3)) % 8.14.3.3 j), k).
+    (  Op == (',') -> throw(error(permission_error(modify, operator, (',')), op/3)) % 8.14.3.3 j), k).
     ;  Op == {} -> throw(error(permission_error(create, operator, {}), op/3))
     ;  Op == [] -> throw(error(permission_error(create, operator, []), op/3))
     ;  true
@@ -810,24 +816,20 @@ no_var_in_list([]).
 no_var_in_list([X|Xs]) :- var(X), !, '$fail'.
 no_var_in_list([_|Xs]) :- no_var_in_list(Xs).
 
-atom_chars(Atom, List) :-
-    error:can_be(list, List),
+atom_chars(Atom, List) :-    
     (  var(Atom) ->
        (  var(List) -> throw(error(instantiation_error, atom_chars/2))
-       ;  no_var_in_list(List) -> '$atom_chars'(Atom, List)
+       ;  can_be_list(List, atom_chars/3), no_var_in_list(List) -> '$atom_chars'(Atom, List)
        )
     ;  atom(Atom) -> '$atom_chars'(Atom, List)
-    ;  Atom == [] -> '$atom_chars'(Atom, List)
     ;  throw(error(type_error(atom, Atom), atom_chars/2))
     ).
 
-atom_codes(Atom, List) :-
-    error:can_be(list, List),
+atom_codes(Atom, List) :-    
     (  var(Atom) ->
        (  var(List) -> throw(error(instantiation_error, atom_codes/2))
-       ;  no_var_in_list(List) -> '$atom_codes'(Atom, List)
+       ;  can_be_list(List, atom_codes/3), no_var_in_list(List) -> '$atom_codes'(Atom, List)
        )
     ;  atom(Atom) -> '$atom_codes'(Atom, List)
-    ;  Atom == [] -> '$atom_codes'(Atom, List)
     ;  throw(error(type_error(atom, Atom), atom_codes/2))
     ).
index d57acaf2c1c3c77bbba46cf7b0f8795c6cb70985..0e958356995c5491a297cefc0963a69735cd519d 100644 (file)
@@ -1,4 +1,4 @@
-:- module(reif, [if_/3, (=)/3, (,)/3, (;)/3, cond_t/3, dif/3,
+:- module(reif, [if_/3, (=)/3, (',')/3, (;)/3, cond_t/3, dif/3,
                 memberd_t/3, tfilter/3, tmember/2, tmember_t/3,
                 tpartition/4]).
 
index 5c79e0d050a8f9b7015af5516eabd5a208e957d7..a59e3f14730825f3d693b2f22e4338aabaf75f45 100644 (file)
@@ -1905,6 +1905,7 @@ impl MachineState {
 
                 match d {
                     Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1,
+                    Addr::Con(Constant::EmptyList) => self.p += 1,
                     _ => self.fail = true
                 };
             },
index f23bd7305d35296c4158336aa1251f6d40a8bc19..f8bbde797953ec0871333946644ca00716f3ee14 100644 (file)
@@ -362,7 +362,7 @@ impl MachineState {
                     },
                     ref addr if addr.is_ref() => {
                         let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2);
-
+                        
                         match self.try_from_list(temp_v!(2), stub.clone()) {
                             Err(e) => return Err(e),
                             Ok(addrs) => {
index f28ef5361be6664b06e693f61f67445669e0f94a..9f3a2ecacaa1d01331dae3f6223e86c6a210aa72 100644 (file)
@@ -1413,7 +1413,7 @@ fn test_queries_on_builtins()
     assert_prolog_failure!(&mut wam, "?- atom(X).");
     assert_prolog_success!(&mut wam, "?- atom(a).");
     assert_prolog_failure!(&mut wam, "?- atom(\"string\").");
-    assert_prolog_failure!(&mut wam, "?- atom([]).");
+    assert_prolog_success!(&mut wam, "?- atom([]).");
     assert_prolog_failure!(&mut wam, "?- atom(1).");
     assert_prolog_failure!(&mut wam, "?- atom(0).");
     assert_prolog_failure!(&mut wam, "?- atom(0.0).");
@@ -1750,12 +1750,12 @@ fn test_queries_on_builtins()
 
     assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
-                            ["L = [_188]", "X = _0", "Y = 1", "Z = _6"]]);
+                            ["L = [_112]", "X = _0", "Y = 1", "Z = _6"]]);
 
     submit(&mut wam, "a(1, f(_)). a(2, f(_)).");
 
     assert_prolog_success!(&mut wam, "?- bagof(X, a(X, Y), L).",
-                           [["L = [1, 2]", "X = _0", "Y = f(_154)"]]);
+                           [["L = [1, 2]", "X = _0", "Y = f(_78)"]]);
 
     assert_prolog_success!(&mut wam, "?- setof(X, (X = 1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
@@ -1767,7 +1767,7 @@ fn test_queries_on_builtins()
                             ["L = [1]", "Y = 2"]]);
     assert_prolog_success!(&mut wam, "?- setof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
-                            ["L = [_188]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]);
+                            ["L = [_112]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]);
     assert_prolog_failure!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)]).");
     assert_prolog_success!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).",
                            [["U = a", "V = a", "X = _0"]]);
@@ -1794,12 +1794,12 @@ fn test_queries_on_builtins()
     assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
                            [["S = [1, 2]", "X = _0", "Y = _5"]]);
     assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
-                           [["S = [1, _240, 2]", "X = _0", "Y = _5"]]);
+                           [["S = [1, _126, 2]", "X = _0", "Y = _5"]]);
 
     assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
                            [["S = [1, 2]", "X = _0", "Y = _5"]]);
     assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
-                           [["S = [_240, 1, 2]", "X = _0", "Y = _5"]]);
+                           [["S = [_126, 1, 2]", "X = _0", "Y = _5"]]);
     assert_prolog_success!(&mut wam, "?- setof(X, (exists(U,V) ^ member(X, [V,U,f(U),f(V)])), [a,b,f(b),f(a)]).");
 
     submit(&mut wam, ":- use_module(library(non_iso)).");