diff --git a/read.scm b/read.scm index 6f96f1a7..0f4d2436 100644 --- a/read.scm +++ b/read.scm @@ -747,9 +747,10 @@ (list 'quote (parse2 fp))) ((eq? token #\`) (list 'quasiquote (parse2 fp))) - ;; TODO: , - tricky, could be unquote or unquote-splicing - ;;((eq? t #\`) - ;; (list 'quasiquote (parse2 fp))) + ((eq? token #\,) + (list 'unquote (parse2 fp))) + ((eq? token (string->symbol ",@")) + (list 'unquote-splicing (parse2 fp))) ;; Other special cases? (else token)))) diff --git a/runtime.c b/runtime.c index 029254e4..105f8ad4 100644 --- a/runtime.c +++ b/runtime.c @@ -5858,6 +5858,14 @@ void _read_return_atom(void *data, object cont, port_type *p) } } +#define _read_next_char(data, cont, p) \ + if (p->mem_buf_len == 0 || p->mem_buf_len == p->buf_idx) { \ + int rv = read_from_port(p); \ + if (!rv) { \ + return_closcall1(data, cont, Cyc_EOF); \ + } \ + } + void Cyc_io_read_token(void *data, object cont, object port) { Cyc_check_port(data, port); @@ -5890,10 +5898,21 @@ void Cyc_io_read_token(void *data, object cont, object port) } else if (isspace(c)) { if (p->tok_end) _read_return_atom(data, cont, p); _read_whitespace(p); - } else if (c == '(' || c == ')' || c == '\'' || c == '`' || c == ',') { + } else if (c == '(' || c == ')' || c == '\'' || c == '`') { if (p->tok_end) _read_return_atom(data, cont, p); return_closcall1(data, cont, obj_char2obj(c)); + } else if (c == ',') { + if (p->tok_end) _read_return_atom(data, cont, p); + _read_next_char(data, cont, p); // Do another buffer read if needed + if (p->mem_buf[p->buf_idx] == '@') { + object unquote_splicing = find_or_add_symbol(",@"); + p->buf_idx++; + p->col_num++; + return_closcall1(data, cont, unquote_splicing); + } else { + return_closcall1(data, cont, obj_char2obj(c)); + } } else if (c == '"') { if (p->tok_end) _read_return_atom(data, cont, p); _read_string(data, cont, p);