Fix #x#i... numeric parsing (fixes issue #332).

This commit is contained in:
Alex Shinn 2016-05-15 20:27:36 +09:00
parent 046f22a33d
commit c7b9cb0879
2 changed files with 16 additions and 3 deletions

View file

@ -204,10 +204,20 @@
(read-label (cons (read-char in) res)))
((and (eqv? c #\/) (not (memv #\/ res)))
(read-label (cons (read-char in) res)))
((and (eqv? c #\@) (not (memv #\@ res)))
(read-label (cons (read-char in) res)))
(else
(list->string (reverse res))))))
(define (read-numeric-hashes res)
(if (eqv? #\# (peek-char in))
(let* ((res (cons (read-char in) res))
(c (read-char in)))
(if (memv c '(#\b #\d #\o #\x #\e #\i))
(read-numeric-hashes (cons c res))
(error "invalid numeric hash escape #" c)))
res))
(define (read-number base)
(let* ((str (read-label '()))
(let* ((str (read-label (read-numeric-hashes '())))
(n (string->number str base))
(c (peek-char in)))
(if (or (not n) (not (or (eof-object? c) (memv c delimiters))))

7
sexp.c
View file

@ -3264,8 +3264,11 @@ sexp sexp_string_to_number_op (sexp ctx, sexp self, sexp_sint_t n, sexp str, sex
|| sexp_string_data(str)[1] == '.' || sexp_string_data(str)[1] == '#')
sexp_read_char(ctx, in);
}
in = ((sexp_string_data(str)[0] == '#') || base == 10 ?
sexp_read(ctx, in) : sexp_read_number(ctx, in, base, 0));
in = ((sexp_string_data(str)[0] == '#' &&
sexp_tolower(sexp_string_data(str)[1]) != 'e' &&
sexp_tolower(sexp_string_data(str)[1]) != 'i')
|| base == 10 ? sexp_read(ctx, in) :
sexp_read_number(ctx, in, base, 0));
sexp_gc_release1(ctx);
return sexp_numberp(in) ? in : SEXP_FALSE;
}