7 #include "cl_complex_io.h"
13 #include "cl_spushstring.h"
16 // We read an entire token (or even more, if it begins with #C) into a
17 // buffer and then call read_complex() on the buffer.
19 class pushstring_hack : public cl_spushstring {
21 char* start_pointer (void) { return buffer; }
22 char* end_pointer (void) { return buffer+index; }
25 static cl_boolean number_char_p (char c)
27 if ((c >= '0') && (c <= '9'))
29 if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')))
32 case '+': case '-': case '.': case '/':
39 const cl_N read_complex (cl_istream stream, const cl_read_flags& flags)
41 // One pre-allocated buffer. This reduces the allocation/free cost.
42 static pushstring_hack buffer;
45 // Skip whitespace at the beginning.
47 c = freadchar(stream);
48 if (c == cl_EOF) goto eof;
49 if ((c == ' ') || (c == '\t') || (c == '\n'))
54 // Found first non-whitespace character.
55 // Numbers cannot cross lines. We can treat EOF and '\n' the same way.
58 if (!(flags.lsyntax & lsyntax_commonlisp))
61 // Read some digits, then a letter, then a list or token.
63 c = freadchar(stream);
64 if (c == cl_EOF) goto eof;
66 if ((c >= '0') && (c <= '9'))
71 if (!(((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))))
74 c = freadchar(stream);
75 if (c == cl_EOF) goto eof;
77 var uintL paren_level = 0;
80 if (c == '(') paren_level++;
81 else if (c == ')') paren_level--;
82 if (paren_level == 0) goto done;
83 c = freadchar(stream);
84 if ((c == cl_EOF) || (c == '\n')) goto syntax;
88 // Read a number token.
89 if (!number_char_p(c))
93 c = freadchar(stream);
96 if (!number_char_p(c)) {
97 funreadchar(stream,c);
103 return read_complex(flags,
104 buffer.start_pointer(), buffer.end_pointer(),
108 // Handle syntax error.
109 syntax1: buffer.push(c);
110 syntax: read_number_bad_syntax(buffer.start_pointer(),buffer.end_pointer());
112 // Handle premature EOF.
113 eof: read_number_eof();