|
219 | 219 |
|
220 | 220 | (define (%read-array-literal port rank type-char ctx) |
221 | 221 | (define line (port-current-line port)) |
222 | | - (define chars '()) ; for error message |
223 | | - (define type-tag |
224 | | - (case type-char |
225 | | - [(#\a #\A) 'a] |
226 | | - [else (error "Uniform numeric array literal isn't supported yet.")])) |
| 222 | + (define chars `(,type-char)) ; for error message |
| 223 | + (define (save-char!) |
| 224 | + (let1 ch (read-char) |
| 225 | + (unless (eof-object? ch) (push! chars ch)))) |
| 226 | + (define (prefix) (list->string (reverse chars))) |
227 | 227 | (define (err msg content) |
228 | 228 | (errorf <read-error> :port port :line line |
229 | | - (string-append msg ": #~a~a~a~@[~s~]") |
230 | | - (if (< rank 0) "" rank) type-tag |
231 | | - (list->string (reverse chars)) content)) |
| 229 | + (string-append msg ": #~a~a~@[~s~]") |
| 230 | + (if (< rank 0) "" rank) (prefix) content)) |
232 | 231 | (define (bad-prefix) |
233 | 232 | ;; We read up to the delimiter so that the subsequent read won't be |
234 | 233 | ;; tripped. |
235 | 234 | (let loop ((ch (peek-char))) |
236 | 235 | (unless (or (eof-object? ch) (#[\s\(\[\{#\"'`,] ch)) |
237 | | - (push! chars (read-char)) (loop (peek-char)))) |
| 236 | + (save-char!) (loop (peek-char)))) |
238 | 237 | (err "Invalid array literal prefix" #f)) |
| 238 | + (define (make-type-tag nbits) |
| 239 | + (string->symbol (format "~c~d" (char-down-case type-char) nbits))) |
| 240 | + (define type-class |
| 241 | + (if (#[aA] type-char) |
| 242 | + <array> |
| 243 | + (case (read-digits #f) |
| 244 | + [(8) (case type-char |
| 245 | + [(#\s #\S) <s8array>] |
| 246 | + [(#\u #\U) <u8array>] |
| 247 | + [else (bad-prefix)])] |
| 248 | + [(16) (case type-char |
| 249 | + [(#\f #\F) <f16array>] |
| 250 | + [(#\s #\S) <s16array>] |
| 251 | + [(#\u #\U) <u16array>] |
| 252 | + [else (bad-prefix)])] |
| 253 | + [(32) (case type-char |
| 254 | + ;;[(#\c #\C) <c32array>] |
| 255 | + [(#\f #\F) <f32array>] |
| 256 | + [(#\s #\S) <s32array>] |
| 257 | + [(#\u #\U) <u32array>] |
| 258 | + [else (bad-prefix)])] |
| 259 | + [(64) (case type-char |
| 260 | + ;;[(#\c #\C) <c64array>] |
| 261 | + [(#\f #\F) <f64array>] |
| 262 | + [(#\s #\S) <s64array>] |
| 263 | + [(#\u #\U) <u64array>] |
| 264 | + [else (bad-prefix)])] |
| 265 | + ;; [(128) (case type-char |
| 266 | + ;; [(#\c #\C) <c128array>] |
| 267 | + ;; [else (bad-prefix)])] |
| 268 | + [else (bad-prefix)]))) |
239 | 269 | (define (read-dimensions r) |
240 | 270 | (case (peek-char port) |
241 | 271 | [(#\() (reverse r)] |
242 | | - [(#\@) (push! chars (read-char)) (read-start r)] |
243 | | - [(#\:) (push! chars (read-char)) (read-length 0 r)] |
244 | | - [else (push! chars (read-char)) (bad-prefix)])) |
245 | | - (define (read-digits) |
246 | | - (let loop ((ch (peek-char port)) |
247 | | - (ds '())) |
| 272 | + [(#\@) (save-char!) (read-start r)] |
| 273 | + [(#\:) (save-char!) (read-length 0 r)] |
| 274 | + [else (save-char!) (bad-prefix)])) |
| 275 | + (define (read-digits allow-sign?) |
| 276 | + (let loop ([ch (peek-char port)] |
| 277 | + [ds '()]) |
248 | 278 | (cond |
249 | 279 | [(#[0-9] ch) |
250 | | - (push! chars (read-char)) |
| 280 | + (save-char!) |
251 | 281 | (loop (peek-char port) (cons ch ds))] |
252 | | - [(#[+-] ch) |
253 | | - (push! chars (read-char)) |
| 282 | + [(and allow-sign? (#[+-] ch)) |
| 283 | + (save-char!) |
254 | 284 | (if (null? ds) |
255 | 285 | (loop (peek-char port) (cons ch ds)) |
256 | 286 | (bad-prefix))] |
|
259 | 289 | (bad-prefix) |
260 | 290 | ($ string->number $ list->string $ reverse ds))]))) |
261 | 291 | (define (read-start r) |
262 | | - (let* ([n (read-digits)] |
| 292 | + (let* ([n (read-digits #t)] |
263 | 293 | [ch (peek-char port)]) |
264 | 294 | (case ch |
265 | | - [(#\:) (push! chars (read-char)) (read-length n r)] |
266 | | - [(#\@) (push! chars (read-char)) (read-start `((,n #f) ,@r))] |
| 295 | + [(#\:) (save-char!) (read-length n r)] |
| 296 | + [(#\@) (save-char!) (read-start `((,n #f) ,@r))] |
267 | 297 | [(#\() (reverse `((,n #f) ,@r))] |
268 | | - [else (push! chars (read-char)) (bad-prefix)]))) |
| 298 | + [else (save-char!) (bad-prefix)]))) |
269 | 299 | (define (read-length start r) |
270 | | - (let* ([n (read-digits)] |
| 300 | + (let* ([n (read-digits #t)] |
271 | 301 | [ch (peek-char port)]) |
272 | 302 | (case ch |
273 | | - [(#\:) (push! chars (read-char)) (read-length 0 `((,start ,n) ,@r))] |
274 | | - [(#\@) (push! chars (read-char)) (read-start `((,start ,n) ,@r))] |
| 303 | + [(#\:) (save-char!) (read-length 0 `((,start ,n) ,@r))] |
| 304 | + [(#\@) (save-char!) (read-start `((,start ,n) ,@r))] |
275 | 305 | [(#\() (reverse `((,start ,n) ,@r))] |
276 | | - [else (push! chars (read-char)) (bad-prefix)]))) |
| 306 | + [else (save-char!) (bad-prefix)]))) |
277 | 307 | (define (dim-check suggested content) ;returns #f when bad shape |
278 | 308 | (let* ([start (if (pair? suggested) (car suggested) 0)] |
279 | 309 | [actual (length content)] |
|
325 | 355 | (err "Array literal has inconsistent rank" contents)) |
326 | 356 |
|
327 | 357 | (list-fill-array! |
328 | | - (make-array-internal <array> (dim->shape dim-list)) |
| 358 | + (make-array-internal type-class (dim->shape dim-list)) |
329 | 359 | (flatten contents (- (length dim-list) 1) '())))) |
330 | 360 |
|
331 | 361 | ;;------------------------------------------------------------- |
|
0 commit comments