From dd108fe76bf8c124ec7d68ed0a346c54c01ad182 Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Tue, 21 Jan 2014 06:18:34 -0800
Subject: * lib.c (car, cdr, ldiff): Extend to handle vectors and strings.
 Thereby, numerous previously list-only operations in TXR Lisp now magically
 handle strings and vectors.

* txr.1: Documented.
---
 lib.c | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

(limited to 'lib.c')

diff --git a/lib.c b/lib.c
index cbc50869..6e162c22 100644
--- a/lib.c
+++ b/lib.c
@@ -203,6 +203,16 @@ val car(val cons)
       cons->lc.func = nil;
       return cons->lc.car;
     }
+  case VEC:
+    if (zerop(cons->v.vec[vec_length]))
+      return nil;
+    return cons->v.vec[0];
+  case STR:
+  case LIT:
+  case LSTR:
+    if (zerop(length_str(cons)))
+      return nil;
+    return chr_str(cons, zero);
   default:
     type_mismatch(lit("~s is not a cons"), cons, nao);
   }
@@ -223,6 +233,13 @@ val cdr(val cons)
       cons->lc.func = nil;
       return cons->lc.cdr;
     }
+  case VEC:
+  case STR:
+  case LIT:
+  case LSTR:
+    if (le(length(cons), one))
+      return nil;
+    return sub(cons, one, t);
   default:
     type_mismatch(lit("~s is not a cons"), cons, nao);
   }
@@ -611,9 +628,22 @@ val ldiff(val list1, val list2)
 {
   list_collect_decl (out, ptail);
 
-  while (list1 && list1 != list2) {
-    list_collect (ptail, car(list1));
-    list1 = cdr(list1);
+  switch (type(list2)) {
+  case STR:
+  case LIT:
+  case LSTR:
+  case VEC:
+    while (list1 && !equal(list1, list2)) {
+      list_collect (ptail, car(list1));
+      list1 = cdr(list1);
+    }
+    break;
+  default:
+    while (list1 && list1 != list2) {
+      list_collect (ptail, car(list1));
+      list1 = cdr(list1);
+    }
+    break;
   }
 
   return out;
-- 
cgit v1.2.3