parse negative numbers properly, handle length errors and failures properly.
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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()));
|
||||
|
||||
|
||||
Submodule src/prolog/parser updated: 51e38dd242...7f9094eaed
Reference in New Issue
Block a user