From 8c0902a00ad68bb3f830274342de608cd36f304d Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 29 Sep 2011 22:02:03 -0700 Subject: * match.c (match_line): Implemented horizontal all, some, none, maybe and cases directives. (match_files): Recognize horizontal version of these directives by the presence of the extra symbol t and do not process. Also, bugfix in the all directive: not resetting the all_match flag when short circuiting out. * parser.y (clause_parts_h, additional_parts_h): New nonterminals. (elem): New clauses added. --- ChangeLog | 11 +++++++++++ match.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- parser.y | 21 ++++++++++++++++++++- 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d0554d2..166adc68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-09-29 Kaz Kylheku + + * match.c (match_line): Implemented horizontal all, some, + none, maybe and cases directives. + (match_files): Recognize horizontal version of these directives + by the presence of the extra symbol t and do not process. + Also, bugfix in the all directive: not resetting the + all_match flag when short circuiting out. + * parser.y (clause_parts_h, additional_parts_h): New nonterminals. + (elem): New clauses added. + 2011-09-29 Kaz Kylheku * match.c (chars_k): New variable. diff --git a/match.c b/match.c index 68f05600..0ed7daed 100644 --- a/match.c +++ b/match.c @@ -562,6 +562,52 @@ next_coll: val rev = cons(car(pair), nreverse(cdr(pair))); bindings = cons(rev, bindings); } + } else if (directive == all_s || directive == some_s || + directive == none_s || directive == maybe_s || + directive == cases_s) + { + val specs; + val all_match = t; + val some_match = nil; + val max_pos = pos; + + for (specs = rest(rest(elem)); specs != nil; specs = cdr(specs)) { + val nested_spec = first(specs); + cons_bind (new_bindings, new_pos, + match_line(bindings, nested_spec, dataline, pos, + spec_lineno, data_lineno, file)); + if (new_pos) { + bindings = new_bindings; + some_match = t; + if (gt(new_pos, max_pos)) + max_pos = new_pos; + if (directive == cases_s || directive == none_s) + break; + } else { + all_match = nil; + if (directive == all_s) + break; + } + } + + if (directive == all_s && !all_match) { + debuglf(spec_lineno, lit("all: some clauses didn't match"), nao); + return nil; + } + + if ((directive == some_s || directive == cases_s) && !some_match) { + debuglf(spec_lineno, lit("some/cases: no clauses matched"), nao); + return nil; + } + + if (directive == none_s && some_match) { + debuglf(spec_lineno, lit("none: some clauses matched"), nao); + return nil; + } + + /* No check for maybe, since it always succeeds. */ + + pos = max_pos; } else if (consp(directive) || stringp(directive)) { cons_bind (find, len, search_str_tree(dataline, elem, pos, nil)); val newpos; @@ -1268,8 +1314,8 @@ repeat_spec_same_data: if3(data, cons(data, num(data_lineno)), t)); return nil; } - } else if (sym == some_s || sym == all_s || sym == none_s || - sym == maybe_s || sym == cases_s) + } else if ((sym == some_s || sym == all_s || sym == none_s || + sym == maybe_s || sym == cases_s) && second(first_spec) != t) { val specs; val all_match = t; @@ -1302,9 +1348,9 @@ repeat_spec_same_data: if (sym == cases_s || sym == none_s) break; } else { + all_match = nil; if (sym == all_s) break; - all_match = nil; } } diff --git a/parser.y b/parser.y index 17ad883a..cc66a96f 100644 --- a/parser.y +++ b/parser.y @@ -67,7 +67,8 @@ static val parsed_spec; %type all_clause some_clause none_clause maybe_clause %type cases_clause collect_clause clause_parts additional_parts %type output_clause define_clause try_clause catch_clauses_opt -%type line elems_opt elems elem var var_op +%type line elems_opt elems clause_parts_h additional_parts_h +%type elem var var_op %type list exprs exprs_opt expr out_clauses out_clauses_opt out_clause %type repeat_clause repeat_parts_opt o_line %type o_elems_opt o_elems_opt2 o_elems o_elem rep_elem rep_parts_opt @@ -206,8 +207,26 @@ elem : TEXT { $$ = string_own($1); } UNTIL elems END { $$ = list(coll_s, $4, $6, $2, nao); } | COLL error { $$ = nil; yybadtoken(yychar, lit("coll clause")); } + | ALL clause_parts_h { $$ = cons(all_s, cons(t, $2)); } + | ALL END { yyerror("empty all clause"); } + | SOME clause_parts_h { $$ = cons(some_s, cons(t, $2)); } + | SOME END { yyerror("empty some clause"); } + | NONE clause_parts_h { $$ = cons(none_s, cons(t, $2)); } + | NONE END { yyerror("empty none clause"); } + | MAYBE clause_parts_h { $$ = cons(maybe_s, cons(t, $2)); } + | MAYBE END { yyerror("empty maybe clause"); } + | CASES clause_parts_h { $$ = cons(cases_s, cons(t, $2)); } + | CASES END { yyerror("empty cases clause"); } ; +clause_parts_h : elems additional_parts_h { $$ = cons($1, $2); } + ; + +additional_parts_h : END { $$ = nil; } + | AND elems additional_parts_h { $$ = cons($2, $3); } + | OR elems additional_parts_h { $$ = cons($2, $3); } + ; + define_clause : DEFINE exprs ')' newl clauses_opt END newl { $$ = list(define_s, $2, $5, nao); } -- cgit v1.2.3