From 2496d222fb0a451372989e846a1db0ec4e6e6fa6 Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Thu, 1 Dec 2011 13:40:53 -0800
Subject: Dropping the silly cons return value from txeval. Two interfaces are
 provided to the function. One throws on unbound variable, the other which
 evaluates them to the symbol noval_s (used in exception handling).

* match.c (do_txeval): New static function.
(txeval): Functionality moved to do_txeval.
(txeval_allow_ub): New static function.
(vars_to_bindings, h_fun, v_freeform, v_next, v_merge, v_bind, v_set,
v_cat, v_output, v_deffilter, v_fun): No need to
use cdr to get the value from txeval.
(v_throw): Use txeval_ub_allowed, since unbound variables
are allowed in throw.
(v_try): Detect unbound arguments by checking for noval_s rather than
nil. No need to use cdr.
---
 match.c | 85 +++++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 46 insertions(+), 39 deletions(-)

(limited to 'match.c')

diff --git a/match.c b/match.c
index e91c0f78..e942faf2 100644
--- a/match.c
+++ b/match.c
@@ -328,7 +328,7 @@ static val vars_to_bindings(val spec, val vars, val bindings)
       list_collect (tail, cons(item, noval_s));
     } else if (consp(item) && bindable(first(item))) {
       list_collect (tail, cons(first(item), 
-                               cdr(txeval(spec, second(item), bindings))));
+                               txeval(spec, second(item), bindings)));
     } else { 
       sem_error(spec, lit("not a variable spec: ~a"), item, nao);
     }
@@ -1014,7 +1014,7 @@ static val h_fun(match_line_ctx c, match_line_ctx *cout)
         }
       } else {
         val val = txeval(elem, arg, c.bindings);
-        bindings_cp = acons_new(param, cdr(val), bindings_cp);
+        bindings_cp = acons_new(param, val, bindings_cp);
       }
     }
 
@@ -1317,37 +1317,41 @@ static val subst_vars(val spec, val bindings, val filter)
   return out;
 }
 
-static val txeval(val spec, val form, val bindings)
+static val do_txeval(val spec, val form, val bindings, val allow_unbound)
 {
   val ret = nil;
 
   uw_catch_begin (cons(query_error_s, nil), exc_sym, exc);
   {
     if (!form) {
-      ret = cons(t, form);
+      ret = form;
     } else if (bindable(form)) {
-      ret = assoc(bindings, form);
+      val binding = assoc(bindings, form);
+      if (!binding) {
+        if (allow_unbound)
+          ret = noval_s;
+        else
+          sem_error(spec, lit("unbound variable ~s"), form, nao);
+      } else {
+        ret = cdr(binding);
+      }
     } else if (consp(form)) {
       if (first(form) == quasi_s) {
-        ret = cons(t, cat_str(subst_vars(rest(form), bindings, nil), nil));
+        ret = cat_str(subst_vars(rest(form), bindings, nil), nil);
       } else if (regexp(car(form))) {
-        ret = cons(t, form);
+        ret = form;
       } else if (first(form) == var_s) {
-        sem_error(spec, lit("metavariable @~a syntax cannot be used here"),
+        sem_error(spec, lit("metavariable @~s syntax cannot be used here"),
                   second(form), nao);
       } else if (first(form) == expr_s) {
-        ret = cons(t, eval(rest(form), make_env(bindings, nil, nil), form));
+        ret = eval(rest(form), make_env(bindings, nil, nil), form);
       } else {
-        val subforms = mapcar(curry_123_2(func_n3(txeval), 
-                                          spec, bindings), form);
-
-        if (all_satisfy(subforms, identity_f, nil))
-          ret = cons(t, mapcar(func_n1(cdr), subforms));
+        ret =  mapcar(curry_123_2(func_n3(txeval), spec, bindings), form);
       }
     } else if (stringp(form)) {
-      ret = cons(t, form);
+      ret = form;
     } else {
-      ret = cons(t, form);
+      ret = form;
     }
 
     uw_catch (exc_sym, exc) {
@@ -1362,12 +1366,19 @@ static val txeval(val spec, val form, val bindings)
   }
   uw_catch_end;
 
-  if (!ret)
-    sem_error(spec, lit("unbound variable in form ~s"), form, nao);
-
   return ret;
 }
 
+static val txeval(val spec, val form, val bindings)
+{
+  return do_txeval(spec, form, bindings, nil);
+}
+
+static val txeval_allow_ub(val spec, val form, val bindings)
+{
+  return do_txeval(spec, form, bindings, t);
+}
+
 enum fpip_close { fpip_fclose, fpip_pclose, fpip_closedir };
 
 typedef struct fpip {
@@ -1796,9 +1807,8 @@ static val v_freeform(match_files_ctx *c)
   spec_bind (specline, first_spec, c->spec);
 
   val args = rest(first_spec);
-  val vals = mapcar(func_n1(cdr),
-                       mapcar(curry_123_2(func_n3(txeval),
-                                          first_spec, c->bindings), args));
+  val vals = mapcar(curry_123_2(func_n3(txeval), first_spec, c->bindings),
+                    args);
 
   if ((c->spec = rest(c->spec)) == nil) {
     sem_error(first_spec,
@@ -1932,8 +1942,7 @@ static val v_next(match_files_ctx *c)
       val list_expr = cdr(assoc(alist, list_k));
       val string_expr = cdr(assoc(alist, string_k));
       val nothrow = cdr(assoc(alist, nothrow_k));
-      val eval = txeval(specline, source, c->bindings);
-      val str = cdr(eval);
+      val str = txeval(specline, source, c->bindings);
 
       if (!from_var && !source && !string_expr && !list_expr)
         sem_error(specline, lit("next: source required before keyword arguments"), nao);
@@ -1964,7 +1973,7 @@ static val v_next(match_files_ctx *c)
           return nil;
         }
       } else if (list_expr) {
-        val list_val = cdr(txeval(specline, list_expr, c->bindings));
+        val list_val = txeval(specline, list_expr, c->bindings);
         cons_bind (new_bindings, success,
                    match_files(mf_file_data(*c, lit("var"),
                                flatten(list_val), num(1))));
@@ -1974,7 +1983,7 @@ static val v_next(match_files_ctx *c)
                       if3(c->data, cons(c->data, c->data_lineno), t));
         return nil;
       } else if (string_expr) {
-        val str_val = cdr(txeval(specline, string_expr, c->bindings));
+        val str_val = txeval(specline, string_expr, c->bindings);
         if (!stringp(str_val))
           sem_error(specline, lit(":string arg ~s evaluated to non-string ~s"), string_expr, str_val, nao);
 
@@ -2504,9 +2513,9 @@ static val v_merge(match_files_ctx *c)
       val arg_eval = txeval(specline, arg, c->bindings);
 
       if (merged)
-        merged = weird_merge(merged, cdr(arg_eval));
+        merged = weird_merge(merged, arg_eval);
       else
-        merged = cdr(arg_eval);
+        merged = arg_eval;
     }
   }
 
@@ -2560,8 +2569,7 @@ static val v_bind(match_files_ctx *c)
   uw_env_begin;
   uw_set_match_context(cons(c->spec, c->bindings));
 
-  c->bindings = dest_bind(specline, c->bindings, pattern,
-                         cdr(value), testfun);
+  c->bindings = dest_bind(specline, c->bindings, pattern, value, testfun);
 
   uw_env_end;
 
@@ -2600,7 +2608,7 @@ static val v_set(match_files_ctx *c)
   val form = second(args);
   val val = txeval(specline, form, c->bindings);
 
-  dest_set(specline, c->bindings, pattern, cdr(val));
+  dest_set(specline, c->bindings, pattern, val);
 
   return next_spec_k;
 }
@@ -2616,8 +2624,7 @@ static val v_cat(match_files_ctx *c)
   } else {
     val existing = assoc(c->bindings, sym);
     if (existing) {
-      val sep = if3(sep_form, 
-                    cdr(txeval(specline, sep_form, c->bindings)),
+      val sep = if3(sep_form, txeval(specline, sep_form, c->bindings),
                     lit(" "));
       *cdr_l(existing) = cat_str(flatten(cdr(existing)), sep);
     } else {
@@ -2647,7 +2654,7 @@ static val v_output(match_files_ctx *c)
     uses_or2;
     val form = first(dest_spec);
     val val = txeval(specline, form, c->bindings);
-    dest = or2(cdr(val), dest);
+    dest = or2(val, dest);
     pop(&dest_spec);
   }
 
@@ -2767,9 +2774,9 @@ static val v_try(match_files_ctx *c)
                 val param = car(piter);
                 val value = car(viter);
 
-                if (value) {
+                if (value != noval_s) {
                   c->bindings = dest_bind(specline, c->bindings, 
-                                         param, cdr(value), equal_f);
+                                         param, value, equal_f);
 
                   if (c->bindings == t) {
                     all_bind = nil;
@@ -2919,7 +2926,7 @@ static val v_throw(match_files_ctx *c)
     sem_error(specline, lit("throw: ~a is not a type symbol"),
               type, nao);
   {
-    val values = mapcar(curry_123_2(func_n3(txeval), 
+    val values = mapcar(curry_123_2(func_n3(txeval_allow_ub), 
                                     specline, c->bindings), args);
     uw_throw(type, values);
   }
@@ -2936,7 +2943,7 @@ static val v_deffilter(match_files_ctx *c)
               first(first_spec), nao);
 
   {
-    val table_evaled = cdr(txeval(specline, table, c->bindings));
+    val table_evaled = txeval(specline, table, c->bindings);
 
     if (!all_satisfy(table_evaled, andf(func_n1(listp), 
                                         chain(func_n1(length),
@@ -3036,7 +3043,7 @@ static val v_fun(match_files_ctx *c)
         }
       } else {
         val val = txeval(specline, arg, c->bindings);
-        bindings_cp = acons_new(param, cdr(val), bindings_cp);
+        bindings_cp = acons_new(param, val, bindings_cp);
       }
     }
 
-- 
cgit v1.2.3