Mercurial > hg > xemacs-beta
diff lisp/tl/tl-list.el @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | |
children | 4b173ad71786 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/tl/tl-list.el Mon Aug 13 08:46:56 2007 +0200 @@ -0,0 +1,386 @@ +;;; tl-list.el --- utility functions about list + +;; Copyright (C) 1987 .. 1996 Free Software Foundation, Inc. + +;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp> +;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> +;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> +;; Version: +;; $Id: tl-list.el,v 1.1.1.1 1996/12/18 03:55:31 steve Exp $ +;; Keywords: list + +;; This file is part of tl (Tiny Library). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with This program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Code: + +(require 'file-detect) + +(cond ((file-installed-p "cl-seq.elc") + (require 'cless) + ) + (t + ;; New cl is not exist (Don't use old cl.el) + +(defun last (ls &optional n) + "Returns the last element in list LS. +With optional argument N, returns Nth-to-last link (default 1). +\[tl-list.el; tomo's Common Lisp emulating function]" + (nthcdr (- (length ls) (or n 1)) ls) + ) + +;; imported from cl.el +(defun list* (arg &rest rest) + "Return a new list with specified args as elements, cons'd to last arg. +Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to +`(cons A (cons B (cons C D)))'." + (cond ((not rest) arg) + ((not (cdr rest)) (cons arg (car rest))) + (t (let* ((n (length rest)) + (copy (copy-sequence rest)) + (last (nthcdr (- n 2) copy))) + (setcdr last (car (cdr last))) + (cons arg copy))))) + +(defconst :test ':test) + +(defun MEMBER (elt list &rest keywords) + (let ((test + (or + (let ((ret (memq ':test keywords))) + (car (cdr ret)) + ) + 'eq))) + (cond ((eq test 'eq) + (memq elt list) + ) + ((eq test 'equal) + (member elt list) + ) + (t + (catch 'tag + (while list + (let* ((cell (car list)) + (ret (funcall test elt cell)) + ) + (if ret + (throw 'tag list) + )) + (setq list (cdr list)) + )))))) + +(defun ASSOC (key alist &rest keywords) + (let ((test + (or + (let ((ret (memq ':test keywords))) + (car (cdr ret)) + ) + 'eq))) + (cond ((eq test 'eq) + (assq key alist) + ) + ((eq test 'equal) + (assoc key alist) + ) + (t + (catch 'tag + (while alist + (let* ((cell (car alist)) + (ret (funcall test key (car cell))) + ) + (if ret + (throw 'tag cell) + )) + (setq alist (cdr alist)) + )))))) +)) + +(autoload 'compress-sorted-numbers "range") +(autoload 'expand-range "range") +(autoload 'member-of-range "range") + + +;;; @ list +;;; + +(defun nnth-prev (n ls) + "Modify list LS to remove elements after N th. [tl-list.el]" + (and (> n 0) + (let ((cell (nthcdr (1- n) ls))) + (if (consp cell) + (setcdr cell nil) + ) + ls))) + +(defun nth-prev (n ls) + "Return the first N elements. [tl-list.el]" + (let (dest) + (while (and (> n 0) ls) + (setq dest (cons (car ls) dest)) + (setq ls (cdr ls) + n (1- n)) + ) + (nreverse dest) + )) + +(defun nexcept-nth (n ls) + "Modify list LS to remove N th element. [tl-list.el]" + (cond ((< n 0) ls) + ((= n 0) (cdr ls)) + (t + (let ((cell (nthcdr (1- n) ls))) + (if (consp cell) + (setcdr cell (cdr (cdr cell))) + )) + ls))) + +(defun except-nth (n ls) + "Return elements of LS except N th. [tl-list.el]" + (if (< n 0) + ls + (let (dest) + (while (and (> n 0) ls) + (setq dest (cons (car ls) dest)) + (setq ls (cdr ls) + n (1- n)) + ) + (setq ls (cdr ls)) + (while dest + (setq ls (cons (car dest) ls)) + (setq dest (cdr dest)) + ) + ls))) + +(defun last-element (ls) + "Return last element. [tl-list.el]" + (car (last ls)) + ) + +(defun cons-element (elt ls) + "Cons ELT to LS if ELT is not nil. [tl-list.el]" + (if elt + (cons elt ls) + ls)) + +(defun cons-if (elt ls) + "Cons ELT to LS if LS is not nil, otherwise return nil. [tl-list.el]" + (if ls + (cons elt ls) + )) + +(defun append-element (ls elt) + "Append ELT to last of LS if ELT is not nil. [tl-list.el]" + (if elt + (append ls (list elt)) + ls)) + + +;;; @ permutation and combination +;;; + +(defun every-combination (prev &rest rest) + "Every arguments are OR list, +and return list of all possible sequence. [tl-list.el]" + (if (null prev) + (setq prev '(nil)) + ) + (cond ((null rest) + (mapcar 'list prev) + ) + (t (let (dest + (pr prev) + (rest-mixed (apply 'every-combination rest)) + ) + (while pr + (let ((rr rest-mixed)) + (while rr + (setq dest (cons (cons (car pr)(car rr)) dest)) + (setq rr (cdr rr)) + )) + (setq pr (cdr pr)) + ) + (nreverse dest) + )) + )) + +(defun permute (&rest ls) + "Return permutation of arguments as list. [tl-list.el]" + (let ((len (length ls))) + (if (<= len 1) + (list ls) + (let (prev + (rest ls) + c dest) + (while rest + (setq c (car rest)) + (setq rest (cdr rest)) + (setq dest + (nconc dest + (mapcar (function + (lambda (s) + (cons c s) + )) + (apply (function permute) + (append prev rest)) + ))) + (setq prev (nconc prev (list c))) + ) + dest) + ))) + + +;;; @ index +;;; + +(defun index (start end &optional inc) + "Return list of numbers from START to END. +Element of the list increases by INC (default value is 1). +\[tl-list.el; ELIS compatible function]" + (or inc + (setq inc 1) + ) + (let ((pred (if (>= inc 0) + (function <=) + (function >=) + )) + (i start) + dest) + (while (funcall pred i end) + (setq dest (cons i dest)) + (setq i (+ i inc)) + ) + (nreverse dest) + )) + + +;;; @ set +;;; + +(defun map-union (func ls) + "Apply FUNC to each element of LS. +And return union of each result returned by FUNC. [tl-list.el]" + (let ((r ls) ret rc dest) + (while r + (setq ret (funcall func (car r))) + (while ret + (setq rc (car ret)) + (or (member rc dest) + (setq dest (cons rc dest)) + ) + (setq ret (cdr ret)) + ) + (setq r (cdr r)) + ) + (nreverse dest) + )) + + +;;; @ alist +;;; + +(defun put-alist (item value alist) + "Modify ALIST to set VALUE to ITEM. +If there is a pair whose car is ITEM, replace its cdr by VALUE. +If there is not such pair, create new pair (ITEM . VALUE) and +return new alist whose car is the new pair and cdr is ALIST. +\[tl-list.el; tomo's ELIS like function]" + (let ((pair (assoc item alist))) + (if pair + (progn + (setcdr pair value) + alist) + (cons (cons item value) alist) + ))) + +(defun del-alist (item alist) + "If there is a pair whose key is <ITEM>, delete it from <ALIST>. +\[tl-list.el; mol's ELIS emulating function]" + (if (equal item (car (car alist))) + (cdr alist) + (let ((pr alist) + (r (cdr alist)) + ) + (catch 'tag + (while (not (null r)) + (if (equal item (car (car r))) + (progn + (rplacd pr (cdr r)) + (throw 'tag alist))) + (setq pr r) + (setq r (cdr r)) + ) + alist)))) + +(defun assoc-value (item alist) + "Return value of <ITEM> from <ALIST>. [tl-list.el]" + (cdr (assoc item alist)) + ) + +(defun set-alist (symbol item value) + "Modify a alist indicated by SYMBOL to set VALUE to ITEM. [tl-list.el]" + (or (boundp symbol) + (set symbol nil) + ) + (set symbol (put-alist item value (symbol-value symbol))) + ) + +(defun remove-alist (symbol item) + "Remove ITEM from the alist indicated by SYMBOL. [tl-list.el]" + (and (boundp symbol) + (set symbol (del-alist item (symbol-value symbol))) + )) + +(defun modify-alist (modifier default) + "Modify alist DEFAULT into alist MODIFIER. [tl-list.el]" + (mapcar (function + (lambda (as) + (setq default (put-alist (car as)(cdr as) default)) + )) + modifier) + default) + +(defun set-modified-alist (sym modifier) + "Modify a value of a symbol SYM into alist MODIFIER. +The symbol SYM should be alist. If it is not bound, +its value regard as nil. [tl-list.el]" + (if (not (boundp sym)) + (set sym nil) + ) + (set sym (modify-alist modifier (eval sym))) + ) + + +;;; @ poly-apply +;;; + +(defun poly-funcall (functions arg) + (while functions + (setq arg (funcall (car functions) arg) + functions (cdr functions)) + ) + arg) + + +;;; @ end +;;; + +(provide 'tl-list) + +(require 'tl-seq) +(require 'tl-atype) + +;;; tl-list.el ends here