2 // This file contains a slimmed down version of read_real().
3 // It does not pull in all the floating-point, complex and transcendental
10 #include "cl_rational_io.h"
17 #include "cl_spushstring.h"
19 // We read an entire token (or even more, if it begins with #C) into a
20 // buffer and then call read_rational() on the buffer.
22 class pushstring_hack : public cl_spushstring {
24 char* start_pointer (void) { return buffer; }
25 char* end_pointer (void) { return buffer+index; }
28 static cl_boolean number_char_p (char c)
30 if ((c >= '0') && (c <= '9'))
32 if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')))
35 case '+': case '-': case '.': case '/':
42 const cl_RA read_rational (cl_istream stream, const cl_read_flags& flags)
44 // One pre-allocated buffer. This reduces the allocation/free cost.
45 static pushstring_hack buffer;
48 // Skip whitespace at the beginning.
50 c = freadchar(stream);
51 if (c == cl_EOF) goto eof;
52 if ((c == ' ') || (c == '\t') || (c == '\n'))
57 // Found first non-whitespace character.
58 // Numbers cannot cross lines. We can treat EOF and '\n' the same way.
61 if (!(flags.lsyntax & lsyntax_commonlisp))
64 // Read some digits, then a letter, then a token.
66 c = freadchar(stream);
67 if (c == cl_EOF) goto eof;
69 if ((c >= '0') && (c <= '9'))
74 if (!(((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))))
77 c = freadchar(stream);
78 if (c == cl_EOF) goto eof;
80 // Read a number token.
81 if (!number_char_p(c))
85 c = freadchar(stream);
88 if (!number_char_p(c)) {
89 funreadchar(stream,c);
94 return read_rational(flags,
95 buffer.start_pointer(), buffer.end_pointer(),
99 // Handle syntax error.
100 syntax1: buffer.push(c);
101 read_number_bad_syntax(buffer.start_pointer(),buffer.end_pointer());
103 // Handle premature EOF.
104 eof: read_number_eof();