;-*- Mode:     Lisp -*-
;;;; Author:   Paul Dietz
;;;; Created:  Sat Jun 14 05:51:41 2003
;;;; Contains: Tests fo SPECIAL-OPERATOR-P

(in-package :cl-test)

;;; See section 3.1.2.1.2.1
(defparameter +special-operators+
  '(block let* return-from catch load-time-value setq eval-when
	  locally symbol-macrolet flet macrolet tagbody function
	  multiple-value-call the go multiple-value-prog1 throw if
	  progn unwind-protect labels progv let quote))


;;; All the symbols in +special-operators+ are special operators
(deftest special-operator-p.1
  (loop for s in +special-operators+
	unless (special-operator-p s)
	collect s)
  nil)

;;; None of the standard symbols except those in +special-operators+
;;; are special operators, unless they have a macro function
;;; (See the page for MACRO-FUNCTION)

(deftest special-operator-p.2
  (let ((p (find-package "CL")))
    (loop for name in *cl-symbol-names*
	  unless (or (member name +special-operators+ :test #'string=)
		     (let ((sym (find-symbol name p)))
		       (or (not (special-operator-p sym))
			   (macro-function sym))))
	  collect name))
  nil)

(deftest special-operator-p.order.1
  (let ((i 0))
    (values (notnot (special-operator-p (progn (incf i) 'catch)))
	    i))
  t 1)

(deftest special-operator-p.error.1
  (classify-error (special-operator-p 1))
  type-error)

(deftest special-operator-p.error.2
  (classify-error (special-operator-p))
  program-error)

(deftest special-operator-p.error.3
  (classify-error (special-operator-p 'cons 'cons))
  program-error)

