summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-11-17 21:12:08 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-11-17 21:12:08 -0800
commitdf70e45dae4adccca01441e0911d2f5e114e8e7f (patch)
treeab71125a6493e59b609eb5bc80bae30690d1baa9
parent68ca87bc780e25dea1418019161d99727225d1ce (diff)
downloadtxr-df70e45dae4adccca01441e0911d2f5e114e8e7f.tar.gz
txr-df70e45dae4adccca01441e0911d2f5e114e8e7f.tar.bz2
txr-df70e45dae4adccca01441e0911d2f5e114e8e7f.zip
Adding quote and unquote read syntax to list forms, resembling
Lisp. The difference is that splice is spelled ,* because @ already means something, and that there is only one quote operator. None of this does anything; it is only syntax. * lib.c (quote_s, qquote_s, unquote_s, splice_s): New variables. (obj_init): New variables initialized. * lib.h (quote_s, qquote_s, unquote_s, splice_s): Declared. * parser.l: Added recognition rules. * parser.y (SPLICE): New symbolic token. (list): Added new syntax for quote and splicing.
-rw-r--r--ChangeLog17
-rw-r--r--lib.c5
-rw-r--r--lib.h1
-rw-r--r--parser.l10
-rw-r--r--parser.y7
5 files changed, 38 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ecfa3d1..6035c971 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2011-11-17 Kaz Kylheku <kaz@kylheku.com>
+ Adding quote and unquote read syntax to list forms, resembling
+ Lisp. The difference is that splice is spelled ,* because @
+ already means something, and that there is only one quote operator.
+ None of this does anything; it is only syntax.
+
+ * lib.c (quote_s, qquote_s, unquote_s, splice_s): New variables.
+ (obj_init): New variables initialized.
+
+ * lib.h (quote_s, qquote_s, unquote_s, splice_s): Declared.
+
+ * parser.l: Added recognition rules.
+
+ * parser.y (SPLICE): New symbolic token.
+ (list): Added new syntax for quote and splicing.
+
+2011-11-17 Kaz Kylheku <kaz@kylheku.com>
+
* match.c (h_fun, v_fun): Bugfix! copy_list should be used for copying
the bindings, not copy_alist. Otherwise functions cannot destructively
update a binding, which is useless. We want a function not to
diff --git a/lib.c b/lib.c
index 10782cc1..7d5a8e46 100644
--- a/lib.c
+++ b/lib.c
@@ -58,6 +58,7 @@ val null, t, cons_s, str_s, chr_s, num_s, sym_s, pkg_s, fun_s, vec_s;
val stream_s, hash_s, hash_iter_s, lcons_s, lstr_s, cobj_s, cptr_s;
val var_s, expr_s, regex_s, chset_s, set_s, cset_s, wild_s, oneplus_s;
val nongreedy_s, compiled_regex_s;
+val quote_s, qquote_s, unquote_s, splice_s;
val zeroplus_s, optional_s, compl_s, compound_s, or_s, and_s, quasi_s;
val skip_s, trailer_s, block_s, next_s, freeform_s, fail_s, accept_s;
val all_s, some_s, none_s, maybe_s, cases_s, collect_s, until_s, coll_s;
@@ -2438,6 +2439,10 @@ static void obj_init(void)
regex_s = intern(lit("regex"), system_package);
nongreedy_s = intern(lit("nongreedy"), system_package);
compiled_regex_s = intern(lit("compiled-regex"), system_package);
+ quote_s = intern(lit("quote"), user_package);
+ qquote_s = intern(lit("qquote"), user_package);
+ unquote_s = intern(lit("unquote"), user_package);
+ splice_s = intern(lit("splice"), user_package);
chset_s = intern(lit("chset"), system_package);
set_s = intern(lit("set"), user_package);
cset_s = intern(lit("cset"), user_package);
diff --git a/lib.h b/lib.h
index a395b76b..5700a35c 100644
--- a/lib.h
+++ b/lib.h
@@ -243,6 +243,7 @@ extern val null, t, cons_s, str_s, chr_s, num_s, sym_s, pkg_s, fun_s, vec_s;
extern val stream_s, hash_s, hash_iter_s, lcons_s, lstr_s, cobj_s, cptr_s;
extern val var_s, expr_s, regex_s, chset_s, set_s, cset_s, wild_s, oneplus_s;
extern val nongreedy_s, compiled_regex_s;
+extern val quote_s, qquote_s, unquote_s, splice_s;
extern val zeroplus_s, optional_s, compl_s, compound_s, or_s, and_s, quasi_s;
extern val skip_s, trailer_s, block_s, next_s, freeform_s, fail_s, accept_s;
extern val all_s, some_s, none_s, maybe_s, cases_s, collect_s, until_s, coll_s;
diff --git a/parser.l b/parser.l
index 6514a39b..ccc8cf05 100644
--- a/parser.l
+++ b/parser.l
@@ -371,6 +371,16 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return yytext[0];
}
+<SPECIAL,NESTED>,[*] {
+ yylval.chr = '*';
+ return SPLICE;
+ }
+
+<SPECIAL,NESTED>[,'] {
+ yylval.chr = yytext[0];
+ return yytext[0];
+ }
+
<SPECIAL,NESTED>\}|\) {
yy_pop_state();
if (yy_top_state() == INITIAL
diff --git a/parser.y b/parser.y
index b8ee0659..e80c7756 100644
--- a/parser.y
+++ b/parser.y
@@ -71,7 +71,7 @@ static val parsed_spec;
%token <num> NUMBER
%token <chr> REGCHAR LITCHAR
-%token <chr> METAPAR
+%token <chr> METAPAR SPLICE
%type <val> spec clauses clauses_opt clause
%type <val> all_clause some_clause none_clause maybe_clause
@@ -96,7 +96,7 @@ static val parsed_spec;
%right OUTPUT REPEAT REP FIRST LAST EMPTY DEFINE
%right SPACE TEXT NUMBER
%nonassoc '[' ']' '(' ')'
-%left '-'
+%left '-' ',' '\'' SPLICE
%left '|' '/'
%left '&'
%right '~' '*' '?' '+' '%'
@@ -587,6 +587,9 @@ var_op : '*' { $$ = list(t, nao); }
list : '(' exprs ')' { $$ = rl($2, num($1)); }
| '(' ')' { $$ = nil; }
+ | ',' expr { $$ = rlcp(list(unquote_s, $2, nao), $2); }
+ | '\'' expr { $$ = rlcp(list(qquote_s, $2, nao), $2); }
+ | SPLICE expr { $$ = rlcp(list(splice_s, $2, nao), $2); }
| '(' error { $$ = nil;
yybadtoken(yychar, lit("list expression")); }
;