%% -*- prolog -*-

%% June 2012, Göran Weinholt.

%% This program generates an instance of every possible R6RS Scheme
%% number syntax. It can be used to check if an implementation of
%% string->number is complete. Some notations have been commented out
%% in order to make the output more managable. Example invocation with
%% SWI-Prolog:

%% $ swipl -s every-number.pl
%% ?- forall(scheme_number(X,[]), writef("%s\n", [X])).
%% #b1010
%% #b1010/1010
%% #b+1010
%% ...

scheme_number --> num(2).
scheme_number --> num(8).
scheme_number --> num(10).
scheme_number --> num(16).

num(R) --> prefix(R), complex(R).

complex(R) --> real(R).
complex(R) --> real(R), "@", real(R).
complex(R) --> real(R), "+", ureal(R), "i".
complex(R) --> real(R), "-", ureal(R), "i".
complex(R) --> real(R), "+", naninf, "i".
complex(R) --> real(R), "-", naninf, "i".
complex(R) --> real(R), "+i".
complex(R) --> real(R), "-i".
complex(R) --> "+", ureal(R), "i".
complex(R) --> "-", ureal(R), "i".
complex(R) --> "+", naninf, "i".
complex(R) --> "-", naninf, "i".
complex(R) --> "+i".
complex(R) --> "-i".

real(R) --> sign, ureal(R).
real(R) --> "+", naninf.
real(R) --> "-", naninf.

naninf --> "nan.0".
naninf --> "inf.0".

ureal(R) --> uinteger(R).
ureal(R) --> uinteger(R), "/", uinteger(R).
ureal(R) --> decimal(R), mantissa_width.

decimal(10) --> uinteger(10), suffix.
decimal(10) --> ".", digits(10), suffix.
decimal(10) --> digits(10), ".", digits0(10), suffix.
decimal(10) --> digits(10), ".", suffix.

uinteger(2) --> "1010".
uinteger(8) --> "0755".
uinteger(10) --> "19".
uinteger(16) --> "abcd".

prefix(R) --> radix(R), exactness.
prefix(R) --> exactness, radix(R).

suffix --> "".
suffix --> exponent_marker, sign, digits(10).
exponent_marker --> "e".
%% exponent_marker --> "E".
%% exponent_marker --> "s".
%% exponent_marker --> "S".
%% exponent_marker --> "f".
%% exponent_marker --> "F".
%% exponent_marker --> "d".
%% exponent_marker --> "D".
%% exponent_marker --> "l".
%% exponent_marker --> "L".
mantissa_width --> "".
mantissa_width --> "|53".
sign --> "".
sign --> "+".
sign --> "-".
exactness --> "".
exactness --> "#i".
%% exactness --> "#I".
exactness --> "#e".
%% exactness --> "#E".
radix(2) --> "#b".
%% radix(2) --> "#B".
radix(8) --> "#o".
%% radix(8) --> "#O".
radix(10) --> "".
radix(10) --> "#d".
%% radix(10) --> "#D".
radix(16) --> "#x".
%% radix(16) --> "#X".

digits(10) --> "49".

digits0(10) --> "83".
digits0(10) --> "".
