diff options
-rw-r--r-- | match.c | 80 | ||||
-rw-r--r-- | match.h | 1 | ||||
-rw-r--r-- | parser.h | 1 | ||||
-rw-r--r-- | parser.y | 7 |
4 files changed, 76 insertions, 13 deletions
@@ -2894,27 +2894,91 @@ val match_expand_keyword_args(val args) while (consp(args)) { val sym = car(args); - if (sym == maxgap_k || sym == mingap_k || sym == gap_k || sym == times_k || - sym == mintimes_k || sym == maxtimes_k || sym == lines_k || - sym == counter_k || sym == vars_k) + val next = cdr(args); + val more = consp(next); + + if (more && + (sym == maxgap_k || sym == mingap_k || sym == gap_k || + sym == times_k || sym == mintimes_k || sym == maxtimes_k || + sym == lines_k || sym == counter_k || sym == vars_k || + sym == list_k || sym == string_k)) { - val d = cdr(args); - val form = car(d); + val form = car(next); val form_ex = if3(sym == vars_k, match_expand_vars(form), expand(form, nil)); ptail = list_collect(ptail, sym); ptail = list_collect(ptail, form_ex); - args = cdr(d); - } else { + args = cdr(next); + } else if (more && + (sym == tlist_k)) { + ptail = list_collect(ptail, sym); + ptail = list_collect(ptail, expand_meta(car(next), nil)); + args = cdr(next); + } else if (more && + (sym == var_k)) { ptail = list_collect(ptail, sym); - args = cdr(args); + ptail = list_collect(ptail, car(next)); + args = cdr(next); + } else { + ptail = list_collect(ptail, expand(sym, nil)); + args = next; } } return out; } +val match_expand_elem(val elem) +{ + if (atom(elem)) { + return elem; + } else { + val sym = car(elem); + val args = cdr(elem); + + if (opt_compat && opt_compat < 166) { + goto out; + } else if (sym == skip_s || sym == fuzz_s || sym == load_s || + sym == close_s) + { + val args_ex = expand_forms(args, nil); + if (args == args_ex) + return elem; + return rlcp(cons(sym, args_ex), elem); + } else if (sym == call_s) { + if (atom(args)) { + return elem; + } else { + val arg1 = car(args); + val arg1_ex = expand(arg1, nil); + if (arg1 == arg1_ex) + return elem; + return rlcp(cons(sym, cons(arg1_ex, cdr(args))), elem); + } + } else if (sym == cat_s) { + if (atom(args) || atom(cdr(args))) { + return elem; + } else { + val arg1 = car(args); + val arg2 = cadr(args); + val arg2_ex = expand(arg2, nil); + if (arg2 == arg2_ex) + return elem; + return rlcp(cons(sym, cons(arg1, cons(arg2_ex, cddr(args)))), elem); + } + } else if (sym == next_s) { + val args_ex = match_expand_keyword_args(args); + if (args == args_ex) + return elem; + return rlcp(cons(sym, args_ex), elem); + } else { +out: + return rlcp(cons(sym, expand_meta(args, nil)), elem); + } + } +} + static val v_collect(match_files_ctx *c) { spec_bind (specline, first_spec, c->spec); @@ -29,6 +29,7 @@ extern val text_s, choose_s, gather_s, do_s, require_s; extern val close_s, load_s, include_s, mod_s, modlast_s, line_s; extern val counter_k, vars_k, env_k, var_k; val match_expand_keyword_args(val elem); +val match_expand_elem(val elem); val match_filter(val name, val arg, val other_args); val match_fun(val name, val args, val input, val files); val include(val specline); @@ -102,6 +102,7 @@ int parse_once(val stream, val name, parser_t *parser); int parse(parser_t *parser, val name, enum prime_parser); val source_loc(val form); val source_loc_str(val form, val alt); +val expand_meta(val form, val menv); val rlset(val form, val info); void parser_reset(parser_t *); INLINE val rlcp(val to, val from) @@ -63,7 +63,6 @@ static val define_transform(parser_t *parser, val define_form); static val lit_char_helper(val litchars); static val optimize_text(val text_form); static val unquotes_occur(val quoted_form, int level); -static val expand_meta(val form, val menv); static val rlrec(parser_t *, val form, val line); static wchar_t char_from_name(const wchar_t *name); static val make_expr(parser_t *, val sym, val rest, val lineno); @@ -460,9 +459,7 @@ elem : texts { $$ = rlcp(cons(text_s, $1), $1); expand_forms(rest($1), nil)), $1); else - $$ = rlcp(cons(sym, - expand_meta(rest($1), nil)), - $1); } + $$ = match_expand_elem($1); } | COLL exprs_opt ')' elems_opt END { val args = match_expand_keyword_args($2); $$ = list(coll_s, $4, nil, args, nao); rl($$, num($1)); } @@ -1445,7 +1442,7 @@ static val unquotes_occur(val quoted_form, int level) } } -static val expand_meta(val form, val menv) +val expand_meta(val form, val menv) { val sym; |