;;; -*- Mode:LISP; Package:COMPILER; Readtable:CL; Base:10; Lowercase:T -*- ;;;Nested IF optimizer. ;;; ;;;Advantages: ;;; ;;; 1) Optimize both CL and ZL defs uniformly ;;; 2) Optimizes nested IFs into subsequent COND clauses; i.e., ;;; A. Turns (IF (IF ...)) ;;; Into (COND ( ) ( ...)) ;;; B. Turns (IF (IF ) ) ;;; Into (COND ((not ) ) ( ) (t )) (defun fix-nested-ifs (form) (cons 'cond (t-if-or-nil form))) (defun fix-oldstyle-if (form) `(cond (,(cadr form) ,(caddr form)) (t ,@(cdddr form)))) (defun t-if-or-nil (form) (cond ((not (memq (car-safe form) ;Not a nested IF '(zl:if lisp:if))) ; (not on the list of IFs), (ncons (list t form))) ; so end of COND. ((> (length form) 4) ;ELSE clause has multiple forms; (and (eq (car form) 'lisp:if) ; for CommonLISP, (warn 'improper-common-lisp :obsolete ; issue warning, "~S used with ~D extra argument~:P." 'lisp:if (- (length form) 4))) (cdr (fix-oldstyle-if form))) ; ...then treat like PROGN. ((memq (car-safe (third form)) '(zl:if lisp:if)) (t-if-or-nil `(if (not ,(second form)) ,(fourth form) ,(third form)))) (t `((,(second form) ,(third form)) ;Collect this COND clause, ,@(t-if-or-nil (fourth form)))))) ; and look for more. ;;;Set optimizers on both IF variants: (defoptimizer fix-cli-if cli:if (form) (fix-nested-ifs form)) (defoptimizer fix-zli-if if (form) (fix-nested-ifs form)) #| TEST CASES -- be sure to test in both ZL and CL mode! (defun flit (x l) (if (null l) nil (if (< (car l) 0) (flit x (cdr l)) (if x (print 'test-atomic-case) (if (cdr x) (print 'test-incompatible-case) (print 'another-incompatible-case) (print 'yet-another)) (print 'this-only-gets-signalled-in-commonlisp-mode) (cons (car l) (flit x (cdr l))))))) (defun simp (x) (if x (print 'hi) (print 'bye)) (print (if x 'hi 'bye 'solong)) (if x 'ok 'really 'bye-anyway)) (progn 'turn-off-if-optimizers (setf (get 'lisp:if 'optimizers) nil) (setf (get 'zl:if 'optimizers) nil)) |#