diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | eval.c | 38 | ||||
-rw-r--r-- | match.c | 58 | ||||
-rw-r--r-- | parser.y | 18 |
4 files changed, 73 insertions, 61 deletions
@@ -1,5 +1,25 @@ 2014-10-03 Kaz Kylheku <kaz@kylheku.com> + Eliminating the extra list wrapping applied to regular + expression objects in the syntax tree. The parser + just puts out a #<regex ...> instead of (#<regex ...> regex-syntax). + + * eval.c (do_eval): We no longer need the hack of + treating (#<regex> ...) as a special form which + evaluates to #<regex>. + (expand): We no longer have to skip over regex syntax, + so the case is removed. + + * match.c (h_var, do_txeval, do_match_line): regexp cases are no longer + subcases of consp but stand on their own. In do_match_line, we + introduce a COBJ case into the type switch for regexes. + + * parser.y: regexes are now compiled in the regex and lisp_regex + grammar rules instead of the dependent rules, and are not wrapped in + extra syntax. + +2014-10-03 Kaz Kylheku <kaz@kylheku.com> + * match.c (h_var): Fix regression introduced in 2014-08-11 commit. The incompleteness of that change broke the case of an unbound variable followed by a bound variable. The value of the @@ -938,30 +938,24 @@ static val do_eval(val form, val env, val ctx_form, } } else if (consp(form)) { val oper = car(form); + val entry = gethash(op_table, oper); - if (regexp(oper)) - debug_return (oper); - - { - val entry = gethash(op_table, oper); - - if (entry) { - opfun_t fp = (opfun_t) cptr_get(entry); + if (entry) { + opfun_t fp = (opfun_t) cptr_get(entry); + last_form_evaled = form; + debug_return (fp(form, env)); + } else { + val fbinding = lookup_fun(env, oper); + if (!fbinding) { last_form_evaled = form; - debug_return (fp(form, env)); + eval_error(form, lit("no such function or operator: ~s"), oper, nao); + abort(); } else { - val fbinding = lookup_fun(env, oper); - if (!fbinding) { - last_form_evaled = form; - eval_error(form, lit("no such function or operator: ~s"), oper, nao); - abort(); - } else { - val args = do_eval_args(rest(form), env, form, &lookup_var); - debug_frame(oper, args, nil, env, nil, nil, nil); - last_form_evaled = form; - debug_return (apply(cdr(fbinding), args, form)); - debug_end; - } + val args = do_eval_args(rest(form), env, form, &lookup_var); + debug_frame(oper, args, nil, env, nil, nil, nil); + last_form_evaled = form; + debug_return (apply(cdr(fbinding), args, form)); + debug_end; } } } else { @@ -2817,8 +2811,6 @@ tail: return rlcp(cons(sym, quasi_ex), form); } else if (sym == catch_s) { return expand_catch(rest(form), menv); - } else if (sym == regex_s || regexp(sym)) { - return form; /* regex syntax isn't Lisp code; don't expand! */ } else if (sym == macro_time_s) { val args = rest(form); val args_ex = expand_forms(args, menv); @@ -522,7 +522,7 @@ static val h_var(match_line_ctx *c) c->specline = rlcp(cons(cdr(pair), c->specline), c->specline); } return repeat_spec_k; - } else if (consp(modifier)) { /* var bound over text matched by form */ + } else if (consp(modifier) || regexp(modifier)) { /* var bound over text matched by form */ cons_bind (new_bindings, new_pos, match_line(ml_specline(*c, modifiers))); @@ -575,22 +575,22 @@ static val h_var(match_line_ctx *c) if (sym) c->bindings = acons(sym, sub_str(c->dataline, c->pos, find), c->bindings); c->pos = plus(find, length_str(next)); + } else if (regexp(next)) { + val find = search_regex(c->dataline, next, c->pos, modifier); + val fpos = car(find); + val flen = cdr(find); + if (!find) { + LOG_MISMATCH("var delimiting regex"); + return nil; + } + LOG_MATCH("var delimiting regex", fpos); + if (sym) + c->bindings = acons(sym, sub_str(c->dataline, c->pos, fpos), c->bindings); + c->pos = if3(flen == t, t, plus(fpos, flen)); } else if (consp(next)) { val op = first(next); - if (regexp(op)) { - val find = search_regex(c->dataline, op, c->pos, modifier); - val fpos = car(find); - val flen = cdr(find); - if (!find) { - LOG_MISMATCH("var delimiting regex"); - return nil; - } - LOG_MATCH("var delimiting regex", fpos); - if (sym) - c->bindings = acons(sym, sub_str(c->dataline, c->pos, fpos), c->bindings); - c->pos = if3(flen == t, t, plus(fpos, flen)); - } else if (op == var_s) { + if (op == var_s) { /* Unbound var followed by var: the following one must either be bound, or must specify a regex. */ val second_sym = second(next); @@ -603,8 +603,8 @@ static val h_var(match_line_ctx *c) second_sym, nao); } - if (!pair && consp(next_modifier)) { - val find = search_regex(c->dataline, first(next_modifier), c->pos, modifier); + if (!pair && regexp(next_modifier)) { + val find = search_regex(c->dataline, next_modifier, c->pos, modifier); val fpos = car(find); val flen = cdr(find); @@ -1176,15 +1176,7 @@ static val do_match_line(match_line_ctx *c) { val directive = first(elem); - if (regexp(directive)) { - val past = match_regex(c->dataline, directive, c->pos); - if (nilp(past)) { - LOG_MISMATCH("regex"); - debug_return (nil); - } - LOG_MATCH("regex", past); - c->pos = past; - } else if (consp(directive) || stringp(directive)) { + if (consp(directive) || stringp(directive)) { val len = match_str_tree(c->dataline, elem, c->pos); val newpos; @@ -1259,6 +1251,18 @@ static val do_match_line(match_line_ctx *c) c->pos = newpos; break; } + case COBJ: + if (elem->co.cls == regex_s) { + val past = match_regex(c->dataline, elem, c->pos); + if (nilp(past)) { + LOG_MISMATCH("regex"); + debug_return (nil); + } + LOG_MATCH("regex", past); + c->pos = past; + break; + } + /* fallthrough */ default: sem_error(elem, lit("unsupported object in spec: ~s"), elem, nao); } @@ -1447,7 +1451,7 @@ static val do_txeval(val spec, val form, val bindings, val allow_unbound) uw_fast_return(nil); { - if (!form) { + if (!form || regexp(form)) { ret = form; } else if (bindable(form)) { val binding = or2(assoc(form, bindings), lookup_var(nil, form)); @@ -1475,8 +1479,6 @@ static val do_txeval(val spec, val form, val bindings, val allow_unbound) tail = list_collect(tail, subst_vars(cdr(car(iter)), bindings, nil)); ret = out; uw_env_end; - } else if (regexp(sym)) { - ret = form; } else if (sym == var_s) { uw_env_begin; uw_set_match_context(cons(spec, bindings)); @@ -360,13 +360,12 @@ text : TEXT { $$ = rl(string_own($1), num(parser->lineno)); | SPACE { if ($1[0] == ' ' && $1[1] == 0) { val spaces = list(oneplus_s, chr(' '), nao); - $$ = cons(regex_compile(spaces, nil), spaces); + $$ = regex_compile(spaces, nil); rl($$, num(parser->lineno)); free($1); } else { $$ = rl(string_own($1), num(parser->lineno)); }} - | regex { $$ = cons(regex_compile(rest($1), nil), - rest($1)); + | regex { $$ = $1; rl($$, num(parser->lineno)); } | EMPTY { $$ = null_string; } ; @@ -661,8 +660,7 @@ var_op : '*' { $$ = list(t, nao); } ; modifiers : NUMBER { $$ = cons($1, nil); } - | regex { $$ = cons(cons(regex_compile(rest($1), nil), - rest($1)), nil); + | regex { $$ = cons($1, nil); rlcp($$, $1); } | list { $$ = rlcp(cons(expand_meta($1, nil), nil), $1); } @@ -755,9 +753,7 @@ n_expr : SYMTOK { $$ = symhlpr($1, t); } | list { $$ = $1; } | vector { $$ = $1; } | hash { $$ = $1; } - | lisp_regex { $$ = cons(regex_compile(rest($1), nil), - rest($1)); - rlcp($$, $1); } + | lisp_regex { $$ = $1; } | chrlit { $$ = $1; } | strlit { $$ = $1; } | quasilit { $$ = $1; } @@ -773,7 +769,8 @@ n_exprs_opt : n_exprs { $$ = $1; } | /* empty */ { $$ = nil; } ; -regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex(scnr); +regex : '/' regexpr '/' { $$ = regex_compile($2, nil); + end_of_regex(scnr); rl($$, num(parser->lineno)); } | '/' error { $$ = nil; yybadtok(yychar, lit("regex")); @@ -781,7 +778,8 @@ regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex(scnr); ; lisp_regex : HASH_SLASH regexpr '/' - { $$ = cons(regex_s, $2); end_of_regex(scnr); + { $$ = regex_compile($2, nil); + end_of_regex(scnr); rl($$, num(parser->lineno)); } | HASH_SLASH error { $$ = nil; |