diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 11ee202e..9d5d759f 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -529,6 +529,8 @@ gc_mark_global_symbols(pic_state *pic) { M(sDEFINE); M(sLAMBDA); M(sIF); M(sBEGIN); M(sQUOTE); M(sSETBANG); M(sQUASIQUOTE); M(sUNQUOTE); M(sUNQUOTE_SPLICING); + M(sSYNTAX_QUOTE); M(sSYNTAX_QUASIQUOTE); M(sSYNTAX_UNQUOTE); + M(sSYNTAX_UNQUOTE_SPLICING); M(sDEFINE_MACRO); M(sIMPORT); M(sEXPORT); M(sDEFINE_LIBRARY); M(sCOND_EXPAND); M(sAND); M(sOR); M(sELSE); M(sLIBRARY); diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index c6e9595d..f2e72af8 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -98,6 +98,8 @@ typedef struct { pic_sym *sDEFINE, *sLAMBDA, *sIF, *sBEGIN, *sQUOTE, *sSETBANG; pic_sym *sQUASIQUOTE, *sUNQUOTE, *sUNQUOTE_SPLICING; + pic_sym *sSYNTAX_QUOTE, *sSYNTAX_QUASIQUOTE, *sSYNTAX_UNQUOTE; + pic_sym *sSYNTAX_UNQUOTE_SPLICING; pic_sym *sDEFINE_MACRO, *sIMPORT, *sEXPORT; pic_sym *sDEFINE_LIBRARY; pic_sym *sCOND_EXPAND, *sAND, *sOR, *sELSE, *sLIBRARY; diff --git a/extlib/benz/read.c b/extlib/benz/read.c index 8320af38..a5f45299 100644 --- a/extlib/benz/read.c +++ b/extlib/benz/read.c @@ -180,6 +180,30 @@ read_unquote(pic_state *pic, struct pic_port *port, int PIC_UNUSED(c)) return pic_list2(pic, pic_obj_value(tag), read(pic, port, next(port))); } +static pic_value +read_syntax_quote(pic_state *pic, struct pic_port *port, int PIC_UNUSED(c)) +{ + return pic_list2(pic, pic_obj_value(pic->sSYNTAX_QUOTE), read(pic, port, next(port))); +} + +static pic_value +read_syntax_quasiquote(pic_state *pic, struct pic_port *port, int PIC_UNUSED(c)) +{ + return pic_list2(pic, pic_obj_value(pic->sSYNTAX_QUASIQUOTE), read(pic, port, next(port))); +} + +static pic_value +read_syntax_unquote(pic_state *pic, struct pic_port *port, int PIC_UNUSED(c)) +{ + pic_sym *tag = pic->sSYNTAX_UNQUOTE; + + if (peek(port) == '@') { + tag = pic->sSYNTAX_UNQUOTE_SPLICING; + next(port); + } + return pic_list2(pic, pic_obj_value(tag), read(pic, port, next(port))); +} + static pic_value read_symbol(pic_state *pic, struct pic_port *port, int c) { @@ -799,6 +823,9 @@ reader_table_init(struct pic_reader *reader) reader->dispatch[';'] = read_datum_comment; reader->dispatch['t'] = read_true; reader->dispatch['f'] = read_false; + reader->dispatch['\''] = read_syntax_quote; + reader->dispatch['`'] = read_syntax_quasiquote; + reader->dispatch[','] = read_syntax_unquote; reader->dispatch['\\'] = read_char; reader->dispatch['('] = read_vector; reader->dispatch['u'] = read_undef_or_blob; diff --git a/extlib/benz/state.c b/extlib/benz/state.c index c7f965e0..65c0bcf5 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -268,6 +268,10 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf) S(sQUASIQUOTE, "quasiquote"); S(sUNQUOTE, "unquote"); S(sUNQUOTE_SPLICING, "unquote-splicing"); + S(sSYNTAX_QUOTE, "syntax-quote"); + S(sSYNTAX_QUASIQUOTE, "syntax-quasiquote"); + S(sSYNTAX_UNQUOTE, "syntax-unquote"); + S(sSYNTAX_UNQUOTE_SPLICING, "syntax-unquote-splicing"); S(sDEFINE_MACRO, "define-macro"); S(sIMPORT, "import"); S(sEXPORT, "export");