192 lines
4.3 KiB
EmacsLisp
192 lines
4.3 KiB
EmacsLisp
;;; atype.el --- atype functions
|
|
|
|
;; Copyright (C) 1994,1995,1996,1997 Free Software Foundation, Inc.
|
|
|
|
;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
|
|
;; Version: $Id: atype.el,v 6.6 1997/03/10 14:11:23 morioka Exp $
|
|
;; Keywords: atype
|
|
|
|
;; This file is part of APEL (A Portable Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
|
|
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
;; Boston, MA 02110-1301, USA.
|
|
|
|
;;; Code:
|
|
|
|
(require 'emu) ; for backward compatibility.
|
|
(require 'poe) ; delete.
|
|
(require 'alist)
|
|
|
|
|
|
;;; @ field unifier
|
|
;;;
|
|
|
|
(defun field-unifier-for-default (a b)
|
|
(let ((ret
|
|
(cond ((equal a b) a)
|
|
((null (cdr b)) a)
|
|
((null (cdr a)) b)
|
|
)))
|
|
(if ret
|
|
(list nil ret nil)
|
|
)))
|
|
|
|
(defun field-unify (a b)
|
|
(let ((f
|
|
(let ((type (car a)))
|
|
(and (symbolp type)
|
|
(intern (concat "field-unifier-for-" (symbol-name type)))
|
|
))))
|
|
(or (fboundp f)
|
|
(setq f (function field-unifier-for-default))
|
|
)
|
|
(funcall f a b)
|
|
))
|
|
|
|
|
|
;;; @ type unifier
|
|
;;;
|
|
|
|
(defun assoc-unify (class instance)
|
|
(catch 'tag
|
|
(let ((cla (copy-alist class))
|
|
(ins (copy-alist instance))
|
|
(r class)
|
|
cell aret ret prev rest)
|
|
(while r
|
|
(setq cell (car r))
|
|
(setq aret (assoc (car cell) ins))
|
|
(if aret
|
|
(if (setq ret (field-unify cell aret))
|
|
(progn
|
|
(if (car ret)
|
|
(setq prev (put-alist (car (car ret))
|
|
(cdr (car ret))
|
|
prev))
|
|
)
|
|
(if (nth 2 ret)
|
|
(setq rest (put-alist (car (nth 2 ret))
|
|
(cdr (nth 2 ret))
|
|
rest))
|
|
)
|
|
(setq cla (put-alist (car cell)(cdr (nth 1 ret)) cla))
|
|
(setq ins (del-alist (car cell) ins))
|
|
)
|
|
(throw 'tag nil)
|
|
))
|
|
(setq r (cdr r))
|
|
)
|
|
(setq r (copy-alist ins))
|
|
(while r
|
|
(setq cell (car r))
|
|
(setq aret (assoc (car cell) cla))
|
|
(if aret
|
|
(if (setq ret (field-unify cell aret))
|
|
(progn
|
|
(if (car ret)
|
|
(setq prev (put-alist (car (car ret))
|
|
(cdr (car ret))
|
|
prev))
|
|
)
|
|
(if (nth 2 ret)
|
|
(setq rest (put-alist (car (nth 2 ret))
|
|
(cdr (nth 2 ret))
|
|
rest))
|
|
)
|
|
(setq cla (del-alist (car cell) cla))
|
|
(setq ins (put-alist (car cell)(cdr (nth 1 ret)) ins))
|
|
)
|
|
(throw 'tag nil)
|
|
))
|
|
(setq r (cdr r))
|
|
)
|
|
(list prev (append cla ins) rest)
|
|
)))
|
|
|
|
(defun get-unified-alist (db al)
|
|
(let ((r db) ret)
|
|
(catch 'tag
|
|
(while r
|
|
(if (setq ret (nth 1 (assoc-unify (car r) al)))
|
|
(throw 'tag ret)
|
|
)
|
|
(setq r (cdr r))
|
|
))))
|
|
|
|
|
|
;;; @ utilities
|
|
;;;
|
|
|
|
(defun delete-atype (atl al)
|
|
(let* ((r atl) ret oal)
|
|
(setq oal
|
|
(catch 'tag
|
|
(while r
|
|
(if (setq ret (nth 1 (assoc-unify (car r) al)))
|
|
(throw 'tag (car r))
|
|
)
|
|
(setq r (cdr r))
|
|
)))
|
|
(delete oal atl)
|
|
))
|
|
|
|
(defun remove-atype (sym al)
|
|
(and (boundp sym)
|
|
(set sym (delete-atype (eval sym) al))
|
|
))
|
|
|
|
(defun replace-atype (atl old-al new-al)
|
|
(let* ((r atl) ret oal)
|
|
(if (catch 'tag
|
|
(while r
|
|
(if (setq ret (nth 1 (assoc-unify (car r) old-al)))
|
|
(throw 'tag (rplaca r new-al))
|
|
)
|
|
(setq r (cdr r))
|
|
))
|
|
atl)))
|
|
|
|
(defun set-atype (sym al &rest options)
|
|
(if (null (boundp sym))
|
|
(set sym al)
|
|
(let* ((replacement (memq 'replacement options))
|
|
(ignore-fields (car (cdr (memq 'ignore options))))
|
|
(remove (or (car (cdr (memq 'remove options)))
|
|
(let ((ral (copy-alist al)))
|
|
(mapcar (function
|
|
(lambda (type)
|
|
(setq ral (del-alist type ral))
|
|
))
|
|
ignore-fields)
|
|
ral)))
|
|
)
|
|
(set sym
|
|
(or (if replacement
|
|
(replace-atype (eval sym) remove al)
|
|
)
|
|
(cons al
|
|
(delete-atype (eval sym) remove)
|
|
)
|
|
)))))
|
|
|
|
|
|
;;; @ end
|
|
;;;
|
|
|
|
(require 'product)
|
|
(product-provide (provide 'atype) (require 'apel-ver))
|
|
|
|
;;; atype.el ends here
|