From 4e1170250c22dbc1938e60538aef9f800cf8af92 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 14 Mar 2012 14:38:51 -0700 Subject: Support quasiquoting over vectors also, and a bugfix for hash quasiquoting. We cannot use the same symbol for the literal form from the parser, and for the expanded form, because this creates a confusion when there are multiple nestings of quasiquote expansion. * eval.c (vector_lit_s, vector_list_s, hash_lit_s): New symbol variables. (hash_construct_s): Relocated here from hash.c. (expand_qquote): Part of bugfix: look for hash_lit_s instead of has_construct_s. Translate to a hash_construct_s form which is no longer recognizes as a hash literal. Implementing recognition of a quasiquote vector literal, handled similarly. (eval_init): Initialize vector_lit_s, vector_list_s, hash_list_s and hash_lit_s. Use vector_list_s when registering vector_list function. * eval.h (vector_lit_s, vector_list_s, hash_lit_s, hash_constuct_s): Declared. * hash.c (hash_construct_s): Variable removed and relocated into eval.c. (hash_init): Initialization of hash_construct_s removed. * hash.h (hash_construct_s): Declaration removed. * parser.y: (vector): Action updated to generate a (vec-lit ...) form if the object contains unquotes, otherwise generate a vector object. (hash): Generate hash-lit form, not a hash-construct form. --- ChangeLog | 35 +++++++++++++++++++++++++++++++++++ eval.c | 16 +++++++++++++--- eval.h | 3 ++- hash.c | 2 -- hash.h | 1 - parser.y | 9 ++++++--- 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index a125a84e..c449efa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2012-03-14 Kaz Kylheku + + Support quasiquoting over vectors also, and a bugfix for hash + quasiquoting. We cannot use the same symbol for the + literal form from the parser, and for the expanded form, + because this creates a confusion when there are multiple + nestings of quasiquote expansion. + + * eval.c (vector_lit_s, vector_list_s, hash_lit_s): New symbol + variables. + (hash_construct_s): Relocated here from hash.c. + (expand_qquote): Part of bugfix: look for hash_lit_s + instead of has_construct_s. Translate to a hash_construct_s + form which is no longer recognizes as a hash literal. + Implementing recognition of a quasiquote vector literal, + handled similarly. + (eval_init): Initialize vector_lit_s, vector_list_s, + hash_list_s and hash_lit_s. + Use vector_list_s when registering vector_list function. + + * eval.h (vector_lit_s, vector_list_s, hash_lit_s, + hash_constuct_s): Declared. + + * hash.c (hash_construct_s): Variable removed + and relocated into eval.c. + (hash_init): Initialization of hash_construct_s removed. + + * hash.h (hash_construct_s): Declaration removed. + + * parser.y: (vector): Action updated to generate + a (vec-lit ...) form if the object contains unquotes, + otherwise generate a vector object. + (hash): Generate hash-lit form, not a + hash-construct form. + 2012-03-14 Kaz Kylheku Allow quasi-quoting over hash table literals, diff --git a/eval.c b/eval.c index b87f23c5..483a412a 100644 --- a/eval.c +++ b/eval.c @@ -66,6 +66,8 @@ val dohash_s; val uw_protect_s, return_s, return_from_s; val list_s, append_s, apply_s, gen_s, generate_s, rest_s; val delay_s, promise_s, op_s; +val hash_lit_s, hash_construct_s; +val vector_lit_s, vector_list_s; val make_env(val vbindings, val fbindings, val up_env) { @@ -1383,10 +1385,13 @@ static val expand_qquote(val qquoted_form) } else if (sym == qquote_s) { return rlcp(expand_qquote(expand_qquote(second(qquoted_form))), qquoted_form); - } else if (sym == hash_construct_s) { + } else if (sym == hash_lit_s) { val args = expand_qquote(second(qquoted_form)); val pairs = expand_qquote(rest(rest(qquoted_form))); - return rlcp(list(sym, args, pairs, nao), qquoted_form); + return rlcp(list(hash_construct_s, args, pairs, nao), qquoted_form); + } else if (sym == vector_lit_s) { + val args = expand_qquote(second(qquoted_form)); + return rlcp(list(vector_list_s, args, nao), qquoted_form); } else { val f = car(qquoted_form); val r = cdr(qquoted_form); @@ -2073,6 +2078,11 @@ void eval_init(void) promise_s = intern(lit("promise"), system_package); op_s = intern(lit("op"), user_package); rest_s = intern(lit("rest"), user_package); + hash_lit_s = intern(lit("hash-construct"), system_package); + hash_construct_s = intern(lit("hash-construct"), user_package); + vector_lit_s = intern(lit("vector-lit"), system_package); + vector_list_s = intern(lit("vector-list"), user_package); + sethash(op_table, quote_s, cptr((mem_t *) op_quote)); sethash(op_table, qquote_s, cptr((mem_t *) op_qquote_error)); sethash(op_table, unquote_s, cptr((mem_t *) op_unquote_error)); @@ -2307,7 +2317,7 @@ void eval_init(void) reg_fun(intern(lit("vec-push"), user_package), func_n2(vec_push)); reg_fun(intern(lit("length-vec"), user_package), func_n1(length_vec)); reg_fun(intern(lit("size-vec"), user_package), func_n1(size_vec)); - reg_fun(intern(lit("vector-list"), user_package), func_n1(vector_list)); + reg_fun(vector_list_s, func_n1(vector_list)); reg_fun(intern(lit("list-vector"), user_package), func_n1(list_vector)); reg_fun(intern(lit("copy-vec"), user_package), func_n1(copy_vec)); reg_fun(intern(lit("sub-vec"), user_package), func_n3o(sub_vec, 1)); diff --git a/eval.h b/eval.h index 0ab46d98..d485e2d4 100644 --- a/eval.h +++ b/eval.h @@ -24,7 +24,8 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -extern val dwim_s; +extern val dwim_s, vector_lit_s, vector_list_s; +extern val hash_lit_s, hash_construct_s; val make_env(val fbindings, val vbindings, val up_env); val env_fbind(val env, val sym, val fun); diff --git a/hash.c b/hash.c index 713034c7..a00e3250 100644 --- a/hash.c +++ b/hash.c @@ -65,7 +65,6 @@ struct hash_iter { }; val weak_keys_k, weak_vals_k, equal_based_k; -val hash_construct_s; /* * Dynamic list built up during gc. @@ -598,5 +597,4 @@ void hash_init(void) weak_keys_k = intern(lit("weak-keys"), keyword_package); weak_vals_k = intern(lit("weak-vals"), keyword_package); equal_based_k = intern(lit("equal-based"), keyword_package); - hash_construct_s = intern(lit("hash-construct"), user_package); } diff --git a/hash.h b/hash.h index 72752f72..3796882b 100644 --- a/hash.h +++ b/hash.h @@ -25,7 +25,6 @@ */ extern val weak_keys_k, weak_vals_k, equal_based_k; -extern val hash_construct_s; val make_hash(val weak_keys, val weak_vals, val equal_based); val *gethash_l(val hash, val key, val *new_p); diff --git a/parser.y b/parser.y index a6827a9d..29e678d5 100644 --- a/parser.y +++ b/parser.y @@ -54,7 +54,6 @@ static val optimize_text(val text_form); static val unquotes_occur(val quoted_form); static val choose_quote(val quoted_form); static wchar_t char_from_name(wchar_t *name); -static val hash_from_notation(val notation); static val parsed_spec; @@ -669,11 +668,15 @@ o_var : IDENT { $$ = list(var_s, intern(string_own($1), nil), yybadtoken(yychar, lit("variable spec")); } ; -vector : '#' list { $$ = rlcp(vector_list($2), $2); } +vector : '#' list { if (unquotes_occur($2)) + $$ = rlcp(cons(vector_lit_s, + cons($2, nil)), $2); + else + $$ = rlcp(vector_list($2), $2); } ; hash : HASH_H list { if (unquotes_occur($2)) - $$ = rlcp(cons(hash_construct_s, $2), + $$ = rlcp(cons(hash_lit_s, $2), num($1)); else $$ = rlcp(hash_construct(first($2), -- cgit v1.2.3