7 #include "cln/complex_io.h"
13 #include "cl_spushstring.h"
14 #include "cln/input.h"
18 // We read an entire token (or even more, if it begins with #C) into a
19 // buffer and then call read_complex() on the buffer.
21 class pushstring_hack : public cl_spushstring {
23 char* start_pointer (void) { return buffer; }
24 char* end_pointer (void) { return buffer+index; }
27 static cl_boolean number_char_p (char c)
29 if ((c >= '0') && (c <= '9'))
31 if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')))
34 case '+': case '-': case '.': case '_': case '/':
41 const cl_N read_complex (cl_istream stream, const cl_read_flags& flags)
43 // One pre-allocated buffer. This reduces the allocation/free cost.
44 static pushstring_hack buffer;
47 // Skip whitespace at the beginning.
49 c = freadchar(stream);
50 if (c == cl_EOF) goto eof;
51 if ((c == ' ') || (c == '\t') || (c == '\n'))
56 // Found first non-whitespace character.
57 // Numbers cannot cross lines. We can treat EOF and '\n' the same way.
60 if (!(flags.lsyntax & lsyntax_commonlisp))
63 // Read some digits, then a letter, then a list or token.
65 c = freadchar(stream);
66 if (c == cl_EOF) goto eof;
68 if ((c >= '0') && (c <= '9'))
73 if (!(((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))))
76 c = freadchar(stream);
77 if (c == cl_EOF) goto eof;
79 var uintL paren_level = 0;
82 if (c == '(') paren_level++;
83 else if (c == ')') paren_level--;
84 if (paren_level == 0) goto done;
85 c = freadchar(stream);
86 if ((c == cl_EOF) || (c == '\n')) goto syntax;
90 // Read a number token.
91 if (!number_char_p(c))
95 c = freadchar(stream);
98 if (!number_char_p(c)) {
99 funreadchar(stream,c);
105 return read_complex(flags,
106 buffer.start_pointer(), buffer.end_pointer(),
110 // Handle syntax error.
111 syntax1: buffer.push(c);
112 syntax: read_number_bad_syntax(buffer.start_pointer(),buffer.end_pointer());
114 // Handle premature EOF.
115 eof: read_number_eof();