source: branches/1.1.x/src/org/armedbear/lisp/proclaim.lisp

Last change on this file was 12749, checked in by Mark Evenson, 14 years ago

Undo previous commmit.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.6 KB
Line 
1;;; proclaim.lisp
2;;;
3;;; Copyright (C) 2003-2006 Peter Graves
4;;; $Id: proclaim.lisp 12749 2010-06-09 11:27:42Z mevenson $
5;;;
6;;; This program is free software; you can redistribute it and/or
7;;; modify it under the terms of the GNU General Public License
8;;; as published by the Free Software Foundation; either version 2
9;;; of the License, or (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19;;;
20;;; As a special exception, the copyright holders of this library give you
21;;; permission to link this library with independent modules to produce an
22;;; executable, regardless of the license terms of these independent
23;;; modules, and to copy and distribute the resulting executable under
24;;; terms of your choice, provided that you also meet, for each linked
25;;; independent module, the terms and conditions of the license of that
26;;; module.  An independent module is a module which is not derived from
27;;; or based on this library.  If you modify this library, you may extend
28;;; this exception to your version of the library, but you are not
29;;; obligated to do so.  If you do not wish to do so, delete this
30;;; exception statement from your version.
31
32(in-package #:system)
33
34(export '(check-declaration-type proclaimed-type proclaimed-ftype ftype-result-type *inline-declarations*))
35
36(defmacro declaim (&rest decls)
37`(eval-when (:compile-toplevel :load-toplevel :execute)
38   ,@(mapcar (lambda (decl) `(proclaim ',decl))
39             decls)))
40
41(defun declaration-error (name)
42  (error 'simple-error
43         :format-control "The symbol ~S cannot be both the name of a type and the name of a declaration."
44         :format-arguments (list name)))
45
46(defvar *inline-declarations* nil)
47(defvar *declaration-types* (make-hash-table :test 'eq))
48
49;; "A symbol cannot be both the name of a type and the name of a declaration.
50;; Defining a symbol as the name of a class, structure, condition, or type,
51;; when the symbol has been declared as a declaration name, or vice versa,
52;; signals an error."
53(defun check-declaration-type (name)
54  (when (gethash1 name (the hash-table *declaration-types*))
55    (declaration-error name)))
56
57(defun proclaim (declaration-specifier)
58  (unless (symbolp (car declaration-specifier))
59    (%type-error (car declaration-specifier) 'symbol))
60  ;; (cdr declaration-specifier) must be a proper list.
61  (unless (listp (cddr declaration-specifier))
62    (%type-error (cddr declaration-specifier) 'list))
63  (case (car declaration-specifier)
64    (SPECIAL
65     (dolist (name (cdr declaration-specifier))
66       (%defvar name)))
67    (OPTIMIZE
68     (dolist (spec (cdr declaration-specifier))
69       (let ((val 3)
70             (quality spec))
71         (when (consp spec)
72           (setf quality (%car spec)
73                 val (cadr spec)))
74         (when (and (fixnump val)
75                    (<= 0 val 3))
76           (case quality
77             (SPEED
78              (setf *speed* val))
79             (SPACE
80              (setf *space* val))
81             (SAFETY
82              (setf *safety* val))
83             (DEBUG
84              (setf *debug* val)))))))
85    (FTYPE
86     (unless (cdr declaration-specifier)
87       (error "No type specified in FTYPE declaration: ~S" declaration-specifier))
88     (apply 'proclaim-ftype (cdr declaration-specifier)))
89    (TYPE
90     (unless (cdr declaration-specifier)
91       (error "No type specified in TYPE declaration: ~S" declaration-specifier))
92     (apply 'proclaim-type (cdr declaration-specifier)))
93    ((INLINE NOTINLINE)
94     (dolist (name (cdr declaration-specifier))
95       (if (symbolp name)
96         (setf (get name '%inline) (car declaration-specifier))
97   (push (cons name (car declaration-specifier)) *inline-declarations*))))
98    (DECLARATION
99     (dolist (name (cdr declaration-specifier))
100       (when (or (get name 'deftype-definition)
101                 (find-class name nil))
102         (declaration-error name))
103       (setf (gethash name (the hash-table *declaration-types*)) name)))
104    (:explain
105     (dolist (spec (cdr declaration-specifier))
106       (let ((val t)
107             (quality spec))
108         (when (consp spec)
109           (setf quality (%car spec))
110           (when (= (length spec) 2)
111             (setf val (%cadr spec))))
112         (if val
113             (pushnew quality *explain*)
114             (setf *explain* (remove quality *explain*))))))))
115
116(defun proclaim-type (type &rest names)
117  (dolist (name names)
118    (setf (get name 'proclaimed-type) type)))
119
120(defun proclaimed-type (name)
121  (get name 'proclaimed-type))
122
123(declaim (type hash-table *proclaimed-ftypes*))
124(defconst *proclaimed-ftypes* (make-hash-table :test 'equal))
125
126(declaim (inline proclaim-ftype-1))
127(defun proclaim-ftype-1 (ftype name)
128  (declare (optimize speed))
129  (if (symbolp name)
130      (setf (get name 'proclaimed-ftype) ftype)
131      (setf (gethash name *proclaimed-ftypes*) ftype)))
132(declaim (notinline proclaim-ftype-1))
133
134(defun proclaim-ftype (ftype &rest names)
135  (declare (optimize speed))
136  (declare (inline proclaim-ftype-1))
137  (dolist (name names)
138    (proclaim-ftype-1 ftype name)))
139
140(defun proclaimed-ftype (name)
141  (if (symbolp name)
142      (get name 'proclaimed-ftype)
143      (gethash1 name *proclaimed-ftypes*)))
144
145(defun ftype-result-type (ftype)
146  (if (atom ftype)
147      '*
148      (let ((result-type (third ftype)))
149        (if result-type
150            result-type
151            '*))))
Note: See TracBrowser for help on using the repository browser.