]> Repositorios git - scryer-prolog.git/commitdiff
parse negative numbers properly, handle length errors and failures properly.
authorMark Thom <[email protected]>
Sun, 13 May 2018 00:23:57 +0000 (18:23 -0600)
committerMark Thom <[email protected]>
Sun, 13 May 2018 00:23:57 +0000 (18:23 -0600)
src/prolog/lib/builtins.pl
src/prolog/lib/lists.pl
src/prolog/machine/system_calls.rs
src/prolog/parser
src/tests.rs

index a8fa00a07d6e43692199b9bcaa6c5c64dc7dfe74..006fed1eefa1237a6bcf796fbd4e74154190226a 100644 (file)
@@ -3,8 +3,8 @@
 :- module(builtins, [(=)/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, arg/3, catch/3,
-       throw/1, true/0, false/0]).
+       (-)/1, (>=)/2, (=<)/2, (->)/2, (;)/2, (==)/2, (\==)/2, arg/3,
+       catch/3, throw/1, true/0, false/0, length/2]).
 
 % arithmetic operators.
 :- op(700, xfx, is).
@@ -40,6 +40,7 @@
 
 % term comparison.
 :- op(700, xfx, ==).
+:- op(700, xfx, \==).
 
 % unify.
 X = X.
@@ -96,3 +97,34 @@ arg(N, Functor, Arg) :- throw(error(type_error(integer, N), arg/3)).
 arg_(N, N,  N, Functor, Arg)     :- !, '$get_arg'(N, Functor, Arg).
 arg_(N, N,  Arity, Functor, Arg) :- '$get_arg'(N, Functor, Arg).
 arg_(N, N0, Arity, Functor, Arg) :- N0 < Arity, N1 is N0 + 1, arg_(N, N1, Arity, Functor, Arg).
+
+% length.
+
+length(Xs, N) :-
+    var(N), !,
+    '$skip_max_list'(M, -1, Xs, Xs0),
+    (  Xs0 == [] -> N = M
+    ;  var(Xs0)  -> '$length_addendum'(Xs0, N, M)).
+    % ;  throw(error(type_error(list, Xs), length/2))).
+length(Xs, N) :-
+    integer(N),
+    N >= 0, !,
+    '$skip_max_list'(M, N, Xs, Xs0),
+    (  Xs0 == [] -> N = M
+    ;  var(Xs0)  -> R is N-M, '$length_rundown'(Xs0, R)).
+    % ;  throw(error(type_error(list, Xs), length/2))).
+length(_, N) :-
+    integer(N), !,
+    throw(error(domain_error(not_less_than_zero, N), length/2)).
+length(_, N) :-
+    throw(error(type_error(integer, N), length/2)).
+
+'$length_addendum'([], N, N).
+'$length_addendum'([_|Xs], N, M) :-
+    M1 is M + 1,
+    '$length_addendum'(Xs, N, M1).
+
+'$length_rundown'([], 0) :- !.
+'$length_rundown'([_|Xs], N) :-
+    N1 is N-1,
+    '$length_rundown'(Xs, N1).
index bd3ecd5d6b8e912797e71ca2cd518651c529af95..11c0f2758c800cfa27b9946e48bab5a9b09c6b87 100644 (file)
@@ -1,5 +1,7 @@
-:- module(lists, [member/2, select/3, append/3, is_list/1, memberchk/2, reverse/2, maplist/2,
-                 maplist/3, maplist/4, maplist/5, maplist/6, maplist/7, maplist/8, maplist/9]).
+:- module(lists, [member/2, select/3, append/3, memberchk/2,
+                 reverse/2, maplist/2, maplist/3, maplist/4,
+                 maplist/5, maplist/6, maplist/7, maplist/8,
+                 maplist/9]).
 
 member(X, [X|_]).
 member(X, [_|Xs]) :- member(X, Xs).
@@ -10,10 +12,6 @@ select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
 append([], R, R).
 append([X|L], R, [X|S]) :- append(L, R, S).
 
-is_list(X) :- var(X), !, false.
-is_list([]).
-is_list([_|T]) :- is_list(T).
-
 memberchk(X, Xs) :- member(X, Xs), !.
 
 reverse(Xs, Ys) :- reverse(Xs, [], Ys).
index ada82b6658756131bfee1db7395c77e1c6f487e9..ca4d24683a95070fff5aac5c8379afbdab6476c5 100644 (file)
@@ -103,10 +103,10 @@ impl MachineState {
     }
 
     pub(super) fn skip_max_list(&mut self) -> Result<(), MachineError> {
-        let max_steps = self.arith_eval_by_metacall(temp_v!(2))?;
+        let max_steps = self.store(self.deref(self[temp_v!(2)].clone()));
 
         match max_steps {
-            Number::Integer(ref max_steps)
+            Addr::Con(Constant::Number(Number::Integer(ref max_steps)))
                 if max_steps.to_isize().map(|i| i >= -1).unwrap_or(false) => {
                     let n = self.store(self.deref(self[temp_v!(1)].clone()));
 
index 51e38dd24252431432ec7deb5ad80e2fc11a5753..7f9094eaedf235ffacb7c49f098593f22957fcfc 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 51e38dd24252431432ec7deb5ad80e2fc11a5753
+Subproject commit 7f9094eaedf235ffacb7c49f098593f22957fcfc
index 81a2064f88079296391fb7d333acd3dbc47185a2..6a8ae689ae4633fb419bc860f037aad0d5ff7fe1 100644 (file)
@@ -550,7 +550,7 @@ fn test_queries_on_lists()
     assert_prolog_failure!(&mut wam, "?- p([Z, W, Y]).");
     assert_prolog_success!(&mut wam, "?- p([Z | W]).", [["Z = _0", "W = [_0]"]]);
     assert_prolog_success!(&mut wam, "?- p([Z | [Z]]).", [["Z = _0"]]);
-    assert_prolog_success!(&mut wam, "?- p([Z | [W]]).", [["Z = _2", "W = _2"]]);
+    assert_prolog_success!(&mut wam, "?- p([Z | [W]]).", [["Z = _0", "W = _0"]]);
     assert_prolog_failure!(&mut wam, "?- p([Z | []]).");
 
     submit(&mut wam, "p([Z]).");
@@ -581,7 +581,7 @@ fn test_queries_on_lists()
     assert_prolog_success!(&mut wam, "?- member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).",
                            [["X = b", "Y = c", "Z = _14"],
                             ["X = b", "Y = b", "Z = _14"],
-                            ["X = _14", "Y = x", "Z = _14"],
+                            ["X = _2", "Y = x", "Z = _2"],
                             ["X = d", "Y = f", "Z = _14"]]);
     assert_prolog_failure!(&mut wam, "?- member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).");
     assert_prolog_failure!(&mut wam, "?- member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]]).");
@@ -640,12 +640,12 @@ fn test_queries_on_conjuctive_queries() {
     submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).");
 
     assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
-                           [["Z = _10", "X = a", "Y = [f(g(x))]"],
-                            ["Z = _10", "X = a", "Y = [f(g(y))]"],
+                           [["Z = _11", "X = a", "Y = [f(g(x))]"],
+                            ["Z = _11", "X = a", "Y = [f(g(y))]"],
                             ["Z = a", "X = a", "Y = [f(g(z))]"]]);
     assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
-                           [["X = a", "Y = [f(g(x))]", "Z = _10"],
-                            ["X = a", "Y = [f(g(y))]", "Z = _10"],
+                           [["X = a", "Y = [f(g(x))]", "Z = _11"],
+                            ["X = a", "Y = [f(g(y))]", "Z = _11"],
                             ["X = a", "Y = [f(g(z))]", "Z = a"]]);
     assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, X).",
                            [["X = a", "Y = [f(g(x))]"],
@@ -670,12 +670,12 @@ fn test_queries_on_conjuctive_queries() {
                             ["Y = [f(g(z))]", "X = [f(g(x))]"],
                             ["Y = [f(g(z))]", "X = [f(g(y))]"]]);
     assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, X).",
-                           [["Y = [f(g(x))]", "X = s_0_2"],
-                            ["Y = [f(g(y))]", "X = s_0_2"],
+                           [["Y = [f(g(x))]", "X = _10"],
+                            ["Y = [f(g(y))]", "X = _10"],
                             ["Y = [f(g(z))]", "X = a"]]);
     assert_prolog_success!(&mut wam, "?- q(X, Y), p(Y, X).",
-                           [["Y = s_0_1", "X = [f(g(x))]"],
-                            ["Y = s_0_1", "X = [f(g(y))]"],
+                           [["Y = _9", "X = [f(g(x))]"],
+                            ["Y = _9", "X = [f(g(y))]"],
                             ["Y = a"    , "X = [f(g(z))]"]]);
 }