1 ;;; calist.el --- Condition functions
3 ;; Copyright (C) 1998 MORIOKA Tomohiko.
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Keywords: condition, alist, tree
8 ;; This file is part of APEL (A Portable Emacs Library).
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with program; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;; Visit <http://www.gnu.org/copyleft/gpl.html> for more information
29 (eval-when-compile (require 'cl))
31 (defvar calist-field-match-method-obarray [nil])
33 (defun define-calist-field-match-method (field-type function)
34 "Set field-match-method for FIELD-TYPE to FUNCTION."
35 (fset (intern (symbol-name field-type) calist-field-match-method-obarray)
38 (defun calist-default-field-match-method (calist field-type field-value)
39 (let ((s-field (assoc field-type calist)))
41 (cons (cons field-type field-value) calist))
44 ((equal (cdr s-field) field-value)
47 (defsubst calist-field-match-method (field-type)
51 (symbol-name field-type) calist-field-match-method-obarray))
52 (error (symbol-function 'calist-default-field-match-method))))
54 (defsubst calist-field-match (calist field-type field-value)
55 (funcall (calist-field-match-method field-type)
56 calist field-type field-value))
58 (defun ctree-match-calist (rule-tree alist)
59 "Return matched condition-alist if ALIST matches RULE-TREE."
62 (let ((type (car rule-tree))
63 (choices (cdr rule-tree))
67 (let* ((choice (car choices))
68 (choice-value (car choice)))
69 (if (eq choice-value t)
71 (let ((ret-alist (calist-field-match alist type (car choice))))
75 (ctree-match-calist (cdr choice) ret-alist)
77 (setq choices (cdr choices)))
79 (let ((ret-alist (calist-field-match alist type t)))
82 (ctree-match-calist (cdr default) ret-alist)
85 (defun ctree-match-calist-partially (rule-tree alist)
86 "Return matched condition-alist if ALIST matches RULE-TREE."
89 (let ((type (car rule-tree))
90 (choices (cdr rule-tree))
94 (let* ((choice (car choices))
95 (choice-value (car choice)))
96 (if (eq choice-value t)
98 (let ((ret-alist (calist-field-match alist type (car choice))))
102 (ctree-match-calist-partially
103 (cdr choice) ret-alist)
105 (setq choices (cdr choices)))
107 (let ((ret-alist (calist-field-match alist type t)))
110 (ctree-match-calist-partially (cdr default) ret-alist)
112 (calist-field-match alist type t))))))
114 (defun ctree-find-calist (rule-tree alist &optional all)
115 "Return list of condition-alist which matches ALIST in RULE-TREE.
116 If optional argument ALL is specified, default rules are not ignored
117 even if other rules are matched for ALIST."
120 (let ((type (car rule-tree))
121 (choices (cdr rule-tree))
124 (let* ((choice (car choices))
125 (choice-value (car choice)))
126 (if (eq choice-value t)
127 (setq default choice)
128 (let ((ret-alist (calist-field-match alist type (car choice))))
131 (let ((ret (ctree-find-calist
132 (cdr choice) ret-alist all)))
134 (let ((elt (car ret)))
135 (or (member elt dest)
136 (setq dest (cons elt dest))))
137 (setq ret (cdr ret))))
138 (or (member ret-alist dest)
139 (setq dest (cons ret-alist dest))))))))
140 (setq choices (cdr choices)))
141 (or (and (not all) dest)
143 (let ((ret-alist (calist-field-match alist type t)))
146 (let ((ret (ctree-find-calist
147 (cdr default) ret-alist all)))
149 (let ((elt (car ret)))
150 (or (member elt dest)
151 (setq dest (cons elt dest))))
152 (setq ret (cdr ret))))
153 (or (member ret-alist dest)
154 (setq dest (cons ret-alist dest)))))))
157 (defun calist-to-ctree (calist)
158 "Convert condition-alist CALIST to condition-tree."
160 (let* ((cell (car calist)))
162 (list (cons (cdr cell)
163 (calist-to-ctree (cdr calist))))))))
165 (defun ctree-add-calist-strictly (ctree calist)
166 "Add condition CALIST to condition-tree CTREE without default clause."
167 (cond ((null calist) ctree)
169 (calist-to-ctree calist))
171 (let* ((type (car ctree))
173 (ret (assoc type calist)))
177 (let ((cell (car values)))
178 (if (equal (car cell)(cdr ret))
181 (ctree-add-calist-strictly
183 (delete ret (copy-alist calist)))))))
184 (setq values (cdr values)))
185 (setcdr ctree (cons (cons (cdr ret)
187 (delete ret (copy-alist calist))))
191 (let ((cell (car values)))
193 (ctree-add-calist-strictly (cdr cell) calist)))
194 (setq values (cdr values)))))
197 (defun ctree-add-calist-with-default (ctree calist)
198 "Add condition CALIST to condition-tree CTREE with default clause."
199 (cond ((null calist) ctree)
201 (let* ((cell (car calist))
206 (cons value (calist-to-ctree (cdr calist)))))))
208 (let* ((type (car ctree))
210 (ret (assoc type calist)))
214 (let ((cell (car values)))
215 (if (equal (car cell)(cdr ret))
218 (ctree-add-calist-with-default
220 (delete ret (copy-alist calist)))))))
221 (setq values (cdr values)))
222 (if (assq t (cdr ctree))
224 (cons (cons (cdr ret)
226 (delete ret (copy-alist calist))))
232 (delete ret (copy-alist calist))))
236 (let ((cell (car values)))
238 (ctree-add-calist-with-default (cdr cell) calist)))
239 (setq values (cdr values)))
240 (let ((cell (assq t (cdr ctree))))
243 (ctree-add-calist-with-default (cdr cell)
245 (let ((elt (cons t (calist-to-ctree calist))))
246 (or (member elt (cdr ctree))
247 (setcdr ctree (cons elt (cdr ctree))))))
250 (defun ctree-set-calist-strictly (ctree-var calist)
251 "Set condition CALIST in CTREE-VAR without default clause."
253 (ctree-add-calist-strictly (symbol-value ctree-var) calist)))
255 (defun ctree-set-calist-with-default (ctree-var calist)
256 "Set condition CALIST to CTREE-VAR with default clause."
258 (ctree-add-calist-with-default (symbol-value ctree-var) calist)))
265 ;;; calist.el ends here