summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--eval.c38
-rw-r--r--match.c58
-rw-r--r--parser.y18
4 files changed, 73 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index d75b535a..9fb4c8ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/eval.c b/eval.c
index 3adeb6b8..48df1f38 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
diff --git a/match.c b/match.c
index df25c6eb..2aee0df9 100644
--- a/match.c
+++ b/match.c
@@ -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));
diff --git a/parser.y b/parser.y
index 2e254954..d9b4f241 100644
--- a/parser.y
+++ b/parser.y
@@ -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;