Simplified routines for reading numbers

This commit is contained in:
jjgarcia 2005-10-28 09:42:32 +00:00
parent c4134c9013
commit 2205fb5abc
2 changed files with 38 additions and 53 deletions

View file

@ -28,6 +28,10 @@ ECL 0.9h
- In ECL, all complex types are upgraded to (COMPLEX REAL). However, parts
SUBTYPEP did not apply this.
- When reading 1/0, the reader must signal a READER-ERROR, because it is
a syntax error to have a denominator full of zeros (CLHS 2.2 end plus
2.3.2.1.2).
* Design:
- Simplified the structure of the frame stack, removing redundant fields.

View file

@ -264,6 +264,9 @@ MAYBE_NUMBER:
if ((base <= 10) && isalpha(cl_env.token->string.self[0]))
goto SYMBOL;
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp, &i, base);
if (x == Cnil)
FEreader_error("Syntax error when reading number.~%Offending string: ~S.",
in, 1, cl_env.token);
if (x != OBJNULL && length == i)
return x;
@ -341,11 +344,14 @@ parse_number(const char *s, cl_index end, cl_index *ep, int radix)
i++;
den = parse_number(s+i, end-i, ep, radix);
*ep += i;
if (num == OBJNULL || (*ep < end) ||
(!FIXNUMP(num) && type_of(num) != t_bignum))
if (den == OBJNULL || (*ep < end) ||
(!FIXNUMP(den) && type_of(den) != t_bignum))
{
return OBJNULL;
}
if (den == MAKE_FIXNUM(0)) {
return Cnil;
}
return make_ratio(num, den);
} else if (c == '.') {
radix = 10;
@ -951,45 +957,42 @@ sharp_dot_reader(cl_object in, cl_object c, cl_object d)
}
static cl_object
sharp_B_reader(cl_object in, cl_object c, cl_object d)
read_number(cl_object in, int radix, cl_object macro_char)
{
cl_index i;
cl_object x;
if (!read_constituent(in)) {
x = Cnil;
} else {
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp,
&i, radix);
if (x == OBJNULL || x == Cnil || i != cl_env.token->string.fillp) {
FEreader_error("Cannot parse the #~A readmacro.", in, 1,
macro_char);
}
if (type_of(x) == t_shortfloat ||
type_of(x) == t_longfloat) {
FEreader_error("The float ~S appeared after the #~A readmacro.",
in, 2, x, macro_char);
}
}
return x;
}
static cl_object
sharp_B_reader(cl_object in, cl_object c, cl_object d)
{
if(d != Cnil && !read_suppress)
extra_argument('B', in, d);
if (!read_constituent(in)) {
@(return Cnil);
}
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp, &i, 2);
if (x == OBJNULL || i != cl_env.token->string.fillp)
FEreader_error("Cannot parse the #B readmacro.", in, 0);
if (type_of(x) == t_shortfloat ||
type_of(x) == t_longfloat)
FEreader_error("The float ~S appeared after the #B readmacro.",
in, 1, x);
@(return x)
@(return (read_number(in, 2, CODE_CHAR('B'))))
}
static cl_object
sharp_O_reader(cl_object in, cl_object c, cl_object d)
{
cl_index i;
cl_object x;
if(d != Cnil && !read_suppress)
extra_argument('O', in, d);
if (!read_constituent(in)) {
@(return Cnil);
}
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp, &i, 8);
if (x == OBJNULL || i != cl_env.token->string.fillp)
FEreader_error("Cannot parse the #O readmacro.", in, 0);
if (type_of(x) == t_shortfloat ||
type_of(x) == t_longfloat)
FEreader_error("The float ~S appeared after the #O readmacro.",
in, 1, x);
@(return x)
@(return (read_number(in, 8, CODE_CHAR('O'))))
}
static cl_object
@ -1000,45 +1003,23 @@ sharp_X_reader(cl_object in, cl_object c, cl_object d)
if(d != Cnil && !read_suppress)
extra_argument('X', in, d);
if (!read_constituent(in)) {
@(return Cnil);
}
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp, &i, 16);
if (x == OBJNULL || i != cl_env.token->string.fillp)
FEreader_error("Cannot parse the #X readmacro.", in, 0);
if (type_of(x) == t_shortfloat ||
type_of(x) == t_longfloat)
FEreader_error("The float ~S appeared after the #X readmacro.",
in, 1, x);
@(return x)
@(return (read_number(in, 16, CODE_CHAR('X'))))
}
static cl_object
sharp_R_reader(cl_object in, cl_object c, cl_object d)
{
int radix;
cl_index i;
cl_object x;
if (read_suppress)
radix = 10;
else if (FIXNUMP(d)) {
radix = fix(d);
if (radix > 36 || radix < 2)
FEreader_error("~S is an illegal radix.", in, 1, d);
} else
} else {
FEreader_error("No radix was supplied in the #R readmacro.", in, 0);
if (!read_constituent(in)) {
@(return Cnil);
}
x = parse_number(cl_env.token->string.self, cl_env.token->string.fillp, &i, radix);
if (x == OBJNULL || i != cl_env.token->string.fillp)
FEreader_error("Cannot parse the #R readmacro.", in, 0);
if (type_of(x) == t_shortfloat ||
type_of(x) == t_longfloat)
FEreader_error("The float ~S appeared after the #R readmacro.",
in, 1, x);
@(return x)
@(return (read_number(in, radix, CODE_CHAR('R'))))
}
#define sharp_A_reader void_reader