diff options
-rw-r--r-- | match.c | 68 | ||||
-rw-r--r-- | match.h | 5 | ||||
-rw-r--r-- | parser.y | 42 | ||||
-rw-r--r-- | txr.c | 4 |
4 files changed, 102 insertions, 17 deletions
@@ -71,7 +71,7 @@ val filter_s; val noval_s; static val h_directive_table, v_directive_table; -static val non_matching_directive_table; +static val non_matching_directive_table, binding_directive_table; static void debuglf(val form, val fmt, ...) { @@ -4401,6 +4401,55 @@ val extract(val spec, val files, val predefined_bindings) return result; } +void match_reg_var(val sym) +{ + if (bindable(sym) && !uw_tentative_def_exists(sym)) { + val tag = cons(var_s, sym); + uw_purge_deferred_warning(tag); + uw_register_tentative_def(tag); + } +} + +static void match_reg_var_rec(val sym) +{ + if (consp(sym)) { + match_reg_var_rec(car(sym)); + match_reg_var_rec(cdr(sym)); + return; + } + match_reg_var(sym); +} + +void match_reg_params(val params) +{ + for (; params; params = cdr(params)) { + val var = car(params); + if (atom(var)) + match_reg_var(var); + else + match_reg_var(car(var)); + } +} + +void match_reg_elem(val elem) +{ + if (consp(elem)) { + val sym = car(elem); + val vpos = gethash(binding_directive_table, sym); + if (vpos) { + val var = ref(elem, vpos); + match_reg_var_rec(var); + } else if (!gethash(h_directive_table, sym) && + !gethash(v_directive_table, sym)) + { + elem = cdr(elem); + for (; consp(elem); elem = cdr(elem)) + match_reg_var(car(elem)); + match_reg_var(elem); + } + } +} + static void syms_init(void) { decline_k = intern(lit("decline"), keyword_package); @@ -4452,12 +4501,14 @@ static void syms_init(void) static void dir_tables_init(void) { + protect(&h_directive_table, &v_directive_table, + &non_matching_directive_table, &binding_directive_table, + convert(val *, 0)); + h_directive_table = make_hash(nil, nil, nil); v_directive_table = make_hash(nil, nil, nil); non_matching_directive_table = make_hash(nil, nil, nil); - - protect(&h_directive_table, &v_directive_table, - &non_matching_directive_table, convert(val *, 0)); + binding_directive_table = make_hash(nil, nil, nil); sethash(v_directive_table, skip_s, cptr(coerce(mem_t *, v_skip))); sethash(v_directive_table, fuzz_s, cptr(coerce(mem_t *, v_fuzz))); @@ -4558,6 +4609,15 @@ static void dir_tables_init(void) sethash(non_matching_directive_table, do_s, t); sethash(non_matching_directive_table, load_s, t); sethash(non_matching_directive_table, close_s, t); + + sethash(binding_directive_table, var_s, one); + sethash(binding_directive_table, merge_s, one); + sethash(binding_directive_table, bind_s, one); + sethash(binding_directive_table, rebind_s, one); + sethash(binding_directive_table, line_s, one); + sethash(binding_directive_table, chr_s, one); + sethash(binding_directive_table, data_s, one); + sethash(binding_directive_table, name_s, one); } void match_init(void) @@ -27,11 +27,14 @@ 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; +extern val counter_k, vars_k, env_k, var_k, into_k, named_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); val extract(val spec, val filenames, val bindings); +void match_reg_var(val sym); +void match_reg_params(val params); +void match_reg_elem(val elem); void match_init(void); @@ -59,6 +59,7 @@ static val sym_helper(parser_t *parser, wchar_t *lexeme, val meta_allowed); static val repeat_rep_helper(val sym, val args, val main, val parts); +static void process_catch_exprs(val exprs); static val define_transform(parser_t *parser, val define_form); static val lit_char_helper(val litchars); static val optimize_text(val text_form); @@ -452,14 +453,16 @@ texts : text %prec LOW { $$ = rlcp(cons($1, nil), $1); } elem : texts { $$ = rlcp(cons(text_s, $1), $1); $$ = rlcp(optimize_text($$), $$); } - | var { $$ = rl($1, num(parser->lineno)); } + | var { $$ = rl($1, num(parser->lineno)); + match_reg_elem($$); } | list { val sym = first($1); if (sym == do_s || sym == require_s) $$ = rlcp(cons(sym, expand_forms(rest($1), nil)), $1); else - $$ = match_expand_elem($1); } + { $$ = match_expand_elem($1); + match_reg_elem($$); } } | COLL exprs_opt ')' elems_opt END { val args = match_expand_keyword_args($2); $$ = list(coll_s, $4, nil, args, nao); rl($$, num($1)); } @@ -498,7 +501,8 @@ elem : texts { $$ = rlcp(cons(text_s, $1), $1); rl($$, num($1)); } | DEFINE exprs ')' elems END { $$ = list(define_s, t, $4, $2, nao); - rl($$, num($1)); } + rl($$, num($1)); + match_reg_params($2); } ; clause_parts_h : elems_opt additional_parts_h { $$ = if2($1, cons($1, $2)); } @@ -512,7 +516,8 @@ additional_parts_h : END { $$ = nil; } define_clause : DEFINE exprs ')' newl clauses_opt END newl { $$ = list(define_s, $2, $5, nao); - rl($$, num($1)); } + rl($$, num($1)); + match_reg_params($2); } | DEFINE ')' newl clauses_opt END newl { $$ = list(define_s, nil, $4, nao); @@ -548,6 +553,7 @@ catch_clauses_opt : CATCH ')' newl clauses_opt catch_clauses_opt { $$ = cons(list(catch_s, $2, $5, nao), $6); + process_catch_exprs($2); rl($$, num($1)); } | FINALLY newl clauses_opt { $$ = cons(list(finally_s, nil, @@ -583,8 +589,11 @@ output_clause : OUTPUT ')' o_elems '\n' val args = if3(dest_ex == dest, $2, cons(dest_ex, rest)); $$ = list(output_s, $5, args, nao); - rl($$, num($1)); } - + rl($$, num($1)); + { val into_var = second(memql(into_k, args)); + val named_var = second(memql(named_k, args)); + match_reg_var(into_var); + match_reg_var(named_var); } } | OUTPUT exprs ')' o_elems '\n' out_clauses END newl { $$ = nil; @@ -1287,6 +1296,7 @@ static val expand_repeat_rep_args(val args) ptail = list_collect(ptail, list(first(arg), expand(second(arg), nil), nao)); + match_reg_var(first(arg)); } else { ptail = list_collect(ptail, arg); } @@ -1300,6 +1310,8 @@ static val expand_repeat_rep_args(val args) ptail = list_collect(ptail, arg); continue; } + } else if (exp_pair) { + match_reg_var(arg); } exp_pair = exp_pairs = nil; @@ -1361,6 +1373,18 @@ static val repeat_rep_helper(val sym, val args, val main, val parts) nreverse(modlast_parts), nao); } +static void process_catch_exprs(val exprs) +{ + val params = rest(exprs); + for (; params; params = cdr(params)) { + val param = first(params); + if (consp(param)) + match_reg_var(car(param)); + else + match_reg_var(param); + } +} + static val define_transform(parser_t *parser, val define_form) { scanner_t *scnr = parser->scanner; @@ -1697,7 +1721,6 @@ void yybadtoken(parser_t *parser, int tok, val context) int parse_once(val stream, val name, parser_t *parser) { int res = 0; - uw_frame_t uw_handler; #if CONFIG_DEBUG_SUPPORT debug_state_t ds = debug_set_state(opt_dbg_expansion ? 0 : -1, opt_dbg_expansion); @@ -1708,9 +1731,6 @@ int parse_once(val stream, val name, parser_t *parser) parser->stream = stream; parser->name = name; - uw_push_handler(&uw_handler, cons(warning_s, nil), - func_n1v(uw_muffle_warning)); - uw_catch_begin(cons(error_s, nil), esym, eobj); res = yyparse(parser->scanner, parser); @@ -1731,8 +1751,6 @@ int parse_once(val stream, val name, parser_t *parser) uw_catch_end; - uw_pop_frame(&uw_handler); - return res; } @@ -591,6 +591,8 @@ int txr_main(int argc, char **argv) else bindings = cons(cons(sym, t), bindings); + match_reg_var(sym); + continue; } @@ -976,6 +978,8 @@ int txr_main(int argc, char **argv) close_stream(parse_stream, nil); + uw_dump_deferred_warnings(std_error); + if (parser.errors) return EXIT_FAILURE; |