LAST and BUTLAST work for improper lists
[jscl.git] / lispstrack.lisp
index 6150d86..562f004 100644 (file)
       (t (nth (1- n) (cdr list)))))
 
   (defun last (x)
-    (if (null (cdr x))
-        x
-        (last (cdr x))))
+    (if (consp (cdr x))
+        (last (cdr x))
+        x))
 
   (defun butlast (x)
-    (if (null (cdr x))
-        nil
-        (cons (car x) (butlast (cdr x)))))
+    (and (consp (cdr x))
+         (cons (car x) (butlast (cdr x)))))
 
   (defun member (x list)
     (cond
         (- x #\0)
         nil))
 
+  (defun subseq (seq a &optional b)
+    (cond
+     ((stringp seq)
+      (if b
+          (slice seq a b)
+          (slice seq a)))
+     (t
+      (error "Unsupported argument."))))
+
   (defun parse-integer (string)
     (let ((value 0)
           (index 0)
 (define-compilation string-length (x)
   (concat "(" (ls-compile x env fenv) ").length"))
 
+(define-compilation slice (string a &optional b)
+  (concat "(function(){" *newline*
+          "var str = " (ls-compile string env fenv) ";" *newline*
+          "var a = " (ls-compile a env fenv) ";" *newline*
+          "var b;" *newline*
+          (if b
+              (concat "b = " (ls-compile b env fenv) ";" *newline*)
+              "")
+          "return str.slice(a,b);" *newline*
+          "})()"))
+
 (define-compilation char (string index)
   (concat "("
           (ls-compile string env fenv)