;;; list. START-VAR, NEXT-VAR and RESULT-VAR are bound to the start and
;;; result continuations for the resulting IR1. KIND is the function
;;; kind to associate with NAME.
-(defmacro def-ir1-translator (name (lambda-list start-var next-var result-var
- &key (kind :special-form))
- &body body)
+(defmacro def-ir1-translator (name (lambda-list start-var next-var result-var)
+ &body body)
(let ((fn-name (symbolicate "IR1-CONVERT-" name))
(n-form (gensym))
(n-env (gensym)))
`(progn
(declaim (ftype (function (ctran ctran (or lvar null) t) (values))
,fn-name))
- (defun ,fn-name (,start-var ,next-var ,result-var ,n-form)
- (let ((,n-env *lexenv*))
- ,@decls
- ,body
- (values)))
+ (defun ,fn-name (,start-var ,next-var ,result-var ,n-form
+ &aux (,n-env *lexenv*))
+ (declare (ignorable ,start-var ,next-var ,result-var))
+ ,@decls
+ ,body
+ (values))
,@(when doc
`((setf (fdocumentation ',name 'function) ,doc)))
;; FIXME: Evidently "there can only be one!" -- we overwrite any
;; other :IR1-CONVERT value. This deserves a warning, I think.
(setf (info :function :ir1-convert ',name) #',fn-name)
- (setf (info :function :kind ',name) ,kind)
+ ;; FIXME: rename this to SPECIAL-OPERATOR, to update it to
+ ;; the 1990s?
+ (setf (info :function :kind ',name) :special-form)
;; It's nice to do this for error checking in the target
;; SBCL, but it's not nice to do this when we're running in
;; the cross-compilation host Lisp, which owns the
;; SYMBOL-FUNCTION of its COMMON-LISP symbols.
#-sb-xc-host
- ,@(when (eq kind :special-form)
- `((setf (symbol-function ',name)
- (lambda (&rest rest)
- (declare (ignore rest))
- (error 'special-form-function
- :name ',name)))))))))
+ (let ((fun (lambda (&rest rest)
+ (declare (ignore rest))
+ (error 'special-form-function :name ',name))))
+ (setf (%simple-fun-arglist fun) ',lambda-list)
+ (setf (symbol-function ',name) fun))
+ ',name))))
;;; (This is similar to DEF-IR1-TRANSLATOR, except that we pass if the
;;; syntax is invalid.)
(let ((n-args (gensym)))
`(progn
(defun ,name (,n-node ,@vars)
+ (declare (ignorable ,@vars))
(let ((,n-args (basic-combination-args ,n-node)))
,(parse-deftransform lambda-list body n-args
`(return-from ,name nil))))
;;; Like DO-NODES, only iterating in reverse order. Should be careful
;;; with block being split under us.
-(defmacro do-nodes-backwards ((node-var lvar block) &body body)
+(defmacro do-nodes-backwards ((node-var lvar block &key restart-p) &body body)
(let ((n-block (gensym))
(n-prev (gensym)))
`(loop with ,n-block = ,block
- for ,node-var = (block-last ,n-block) then (ctran-use ,n-prev)
+ for ,node-var = (block-last ,n-block) then
+ ,(if restart-p
+ `(if (eq ,n-block (ctran-block ,n-prev))
+ (ctran-use ,n-prev)
+ (block-last ,n-block))
+ `(ctran-use ,n-prev))
for ,n-prev = (when ,node-var (node-prev ,node-var))
and ,lvar = (when (and ,node-var (valued-node-p ,node-var))
(node-lvar ,node-var))
- while ,node-var
+ while ,(if restart-p
+ `(and ,node-var (not (block-to-be-deleted-p ,n-block)))
+ node-var)
do (progn
,@body))))