Raise an error on direct reader label self-references like #1=#1#.

Fixes issue #303.
This commit is contained in:
Alex Shinn 2016-02-01 21:39:48 +09:00
parent c6ffc27959
commit 3e9092cfcc
2 changed files with 7 additions and 4 deletions

View file

@ -275,6 +275,8 @@
(thunk (lambda () (car cell)))) (thunk (lambda () (car cell))))
(set! shared (cons (cons n thunk) shared)) (set! shared (cons (cons n thunk) shared))
(let ((x (read-one in))) (let ((x (read-one in)))
(if (hole? x)
(read-error "read error: self label reference" n))
(set-car! cell x) (set-car! cell x)
x))) x)))
((eqv? #\# (peek-char in)) ((eqv? #\# (peek-char in))

9
sexp.c
View file

@ -2871,10 +2871,8 @@ sexp sexp_read_raw (sexp ctx, sexp in, sexp *shares) {
if (tmp > if (tmp >
sexp_fx_add(sexp_vector_data(*shares)[sexp_vector_length(*shares)-1], sexp_fx_add(sexp_vector_data(*shares)[sexp_vector_length(*shares)-1],
sexp_make_fixnum(16))) { sexp_make_fixnum(16))) {
fprintf(stderr, "%d - 16 > %ld\n", c2, sexp_unbox_fixnum(sexp_vector_data(*shares)[sexp_vector_length(*shares)-1]));
res = sexp_read_error(ctx, "reader label out of order", tmp, in); res = sexp_read_error(ctx, "reader label out of order", tmp, in);
} } else {
else {
if (c2 + 1 >= sexp_vector_length(*shares)) { if (c2 + 1 >= sexp_vector_length(*shares)) {
tmp2 = sexp_make_vector(ctx, sexp_make_fixnum(sexp_vector_length(*shares)*2), SEXP_VOID); tmp2 = sexp_make_vector(ctx, sexp_make_fixnum(sexp_vector_length(*shares)*2), SEXP_VOID);
memcpy(sexp_vector_data(tmp2), sexp_vector_data(*shares), (sexp_vector_length(*shares)-1)*sizeof(sexp)); memcpy(sexp_vector_data(tmp2), sexp_vector_data(*shares), (sexp_vector_length(*shares)-1)*sizeof(sexp));
@ -2884,7 +2882,10 @@ sexp sexp_read_raw (sexp ctx, sexp in, sexp *shares) {
if (tmp > sexp_vector_data(*shares)[sexp_vector_length(*shares)-1]) if (tmp > sexp_vector_data(*shares)[sexp_vector_length(*shares)-1])
sexp_vector_data(*shares)[sexp_vector_length(*shares)-1] = tmp; sexp_vector_data(*shares)[sexp_vector_length(*shares)-1] = tmp;
res = sexp_read_raw(ctx, in, shares); res = sexp_read_raw(ctx, in, shares);
sexp_vector_data(*shares)[c2] = res; if (sexp_reader_labelp(res))
res = sexp_read_error(ctx, "self reader label reference", tmp, in);
else
sexp_vector_data(*shares)[c2] = res;
} }
} else { } else {
res = sexp_read_error(ctx, "expected # or = after #<n>", sexp_make_character(c1), in); res = sexp_read_error(ctx, "expected # or = after #<n>", sexp_make_character(c1), in);