1 ;;; calist.el --- Condition functions
3 ;; Copyright (C) 1998 Free Software Foundation, Inc.
4 ;; Copyright (C) 1999 Electrotechnical Laboratory, JAPAN.
5 ;; Licensed to the Free Software Foundation.
7 ;; Author: MORIOKA Tomohiko <tomo@m17n.org>
8 ;; Keywords: condition, alist, tree
10 ;; This file is part of APEL (A Portable Emacs Library).
12 ;; This program is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 2, or (at
15 ;; your option) any later version.
17 ;; This program is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
29 (eval-when-compile (require 'cl))
33 (defvar calist-package-alist nil)
34 (defvar calist-field-match-method-obarray nil)
36 (defun make-calist-package (name)
37 "Create a new calist-package."
38 (let ((p (make-vector 7 0)))
39 (set-alist 'calist-package-alist name p)
42 (defun find-calist-package (name)
43 "Return a calist-package by NAME."
44 (cdr (assq name calist-package-alist)))
46 (defun in-calist-package (name)
47 "Set the current calist-package to a new or existing calist-package."
48 (setq calist-field-match-method-obarray
49 (or (find-calist-package name)
50 (make-calist-package name))))
52 (in-calist-package 'standard)
54 (defun define-calist-field-match-method (field-type function)
55 "Set field-match-method for FIELD-TYPE to FUNCTION."
56 (fset (intern (symbol-name field-type) calist-field-match-method-obarray)
59 (defun calist-default-field-match-method (calist field-type field-value)
60 (let ((s-field (assoc field-type calist)))
62 (cons (cons field-type field-value) calist)
66 ((equal (cdr s-field) field-value)
69 (define-calist-field-match-method t #'calist-default-field-match-method)
71 (defsubst calist-field-match-method (field-type)
74 (symbol-name field-type) calist-field-match-method-obarray)
75 (intern-soft "t" calist-field-match-method-obarray))))
77 (defsubst calist-field-match (calist field-type field-value)
78 (funcall (calist-field-match-method field-type)
79 calist field-type field-value))
81 (defun ctree-match-calist (rule-tree alist)
82 "Return matched condition-alist if ALIST matches RULE-TREE."
85 (let ((type (car rule-tree))
86 (choices (cdr rule-tree))
90 (let* ((choice (car choices))
91 (choice-value (car choice)))
92 (if (eq choice-value t)
94 (let ((ret-alist (calist-field-match alist type (car choice))))
98 (ctree-match-calist (cdr choice) ret-alist)
101 (setq choices (cdr choices)))
103 (let ((ret-alist (calist-field-match alist type t)))
106 (ctree-match-calist (cdr default) ret-alist)
110 (defun ctree-match-calist-partially (rule-tree alist)
111 "Return matched condition-alist if ALIST matches RULE-TREE."
114 (let ((type (car rule-tree))
115 (choices (cdr rule-tree))
119 (let* ((choice (car choices))
120 (choice-value (car choice)))
121 (if (eq choice-value t)
122 (setq default choice)
123 (let ((ret-alist (calist-field-match alist type (car choice))))
127 (ctree-match-calist-partially
128 (cdr choice) ret-alist)
131 (setq choices (cdr choices)))
133 (let ((ret-alist (calist-field-match alist type t)))
136 (ctree-match-calist-partially (cdr default) ret-alist)
138 (calist-field-match alist type t))
141 (defun ctree-find-calist (rule-tree alist &optional all)
142 "Return list of condition-alist which matches ALIST in RULE-TREE.
143 If optional argument ALL is specified, default rules are not ignored
144 even if other rules are matched for ALIST."
147 (let ((type (car rule-tree))
148 (choices (cdr rule-tree))
151 (let* ((choice (car choices))
152 (choice-value (car choice)))
153 (if (eq choice-value t)
154 (setq default choice)
155 (let ((ret-alist (calist-field-match alist type (car choice))))
158 (let ((ret (ctree-find-calist
159 (cdr choice) ret-alist all)))
161 (let ((elt (car ret)))
162 (or (member elt dest)
163 (setq dest (cons elt dest))
167 (or (member ret-alist dest)
168 (setq dest (cons ret-alist dest)))
170 (setq choices (cdr choices)))
171 (or (and (not all) dest)
173 (let ((ret-alist (calist-field-match alist type t)))
176 (let ((ret (ctree-find-calist
177 (cdr default) ret-alist all)))
179 (let ((elt (car ret)))
180 (or (member elt dest)
181 (setq dest (cons elt dest))
185 (or (member ret-alist dest)
186 (setq dest (cons ret-alist dest)))
191 (defun calist-to-ctree (calist)
192 "Convert condition-alist CALIST to condition-tree."
194 (let* ((cell (car calist)))
196 (list (cons (cdr cell)
197 (calist-to-ctree (cdr calist))
200 (defun ctree-add-calist-strictly (ctree calist)
201 "Add condition CALIST to condition-tree CTREE without default clause."
202 (cond ((null calist) ctree)
204 (calist-to-ctree calist)
207 (let* ((type (car ctree))
209 (ret (assoc type calist)))
213 (let ((cell (car values)))
214 (if (equal (car cell)(cdr ret))
217 (ctree-add-calist-strictly
219 (delete ret (copy-alist calist)))
221 (setq values (cdr values)))
222 (setcdr ctree (cons (cons (cdr ret)
224 (delete ret (copy-alist calist))))
229 (let ((cell (car values)))
231 (ctree-add-calist-strictly (cdr cell) calist))
233 (setq values (cdr values))))
237 (defun ctree-add-calist-with-default (ctree calist)
238 "Add condition CALIST to condition-tree CTREE with default clause."
239 (cond ((null calist) ctree)
241 (let* ((cell (car calist))
246 (cons value (calist-to-ctree (cdr calist)))))
249 (let* ((type (car ctree))
251 (ret (assoc type calist)))
255 (let ((cell (car values)))
256 (if (equal (car cell)(cdr ret))
259 (ctree-add-calist-with-default
261 (delete ret (copy-alist calist)))
263 (setq values (cdr values)))
264 (if (assq t (cdr ctree))
266 (cons (cons (cdr ret)
268 (delete ret (copy-alist calist))))
274 (delete ret (copy-alist calist))))
279 (let ((cell (car values)))
281 (ctree-add-calist-with-default (cdr cell) calist))
283 (setq values (cdr values)))
284 (let ((cell (assq t (cdr ctree))))
287 (ctree-add-calist-with-default (cdr cell)
289 (let ((elt (cons t (calist-to-ctree calist))))
290 (or (member elt (cdr ctree))
291 (setcdr ctree (cons elt (cdr ctree)))
297 (defun ctree-set-calist-strictly (ctree-var calist)
298 "Set condition CALIST in CTREE-VAR without default clause."
300 (ctree-add-calist-strictly (symbol-value ctree-var) calist)))
302 (defun ctree-set-calist-with-default (ctree-var calist)
303 "Set condition CALIST to CTREE-VAR with default clause."
305 (ctree-add-calist-with-default (symbol-value ctree-var) calist)))
313 ;;; calist.el ends here