X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fsset.lisp;h=609f5556ff4d538af4b6ae8f5d452f4f3d1c7428;hb=a4882e3023fdd5e777169a4cbede33605281173c;hp=9106839609db5ba109e10359472fa293218f6cb5;hpb=416152f084604094445a758ff399871132dff2bd;p=sbcl.git diff --git a/src/compiler/sset.lisp b/src/compiler/sset.lisp index 9106839..609f555 100644 --- a/src/compiler/sset.lisp +++ b/src/compiler/sset.lisp @@ -19,8 +19,8 @@ ;;; SSET-ELEMENT structure. We allow an initial value of NIL to mean ;;; that no ordering has been assigned yet (although an ordering must ;;; be assigned before doing set operations.) -(defstruct (sset-element (:constructor nil) - (:copier nil)) +(def!struct (sset-element (:constructor nil) + (:copier nil)) (number nil :type (or index null))) (defstruct (sset (:copier nil)) @@ -39,177 +39,181 @@ ;;; Destructively add ELEMENT to SET. If ELEMENT was not in the set, ;;; then we return true, otherwise we return false. -(declaim (ftype (function (sset-element sset) boolean) sset-adjoin)) +(declaim (ftype (sfunction (sset-element sset) boolean) sset-adjoin)) (defun sset-adjoin (element set) (let ((number (sset-element-number element)) - (elements (sset-elements set))) + (elements (sset-elements set))) (do ((prev elements current) - (current (cdr elements) (cdr current))) - ((null current) - (setf (cdr prev) (list element)) - t) + (current (cdr elements) (cdr current))) + ((null current) + (setf (cdr prev) (list element)) + t) (let ((el (car current))) - (when (>= (sset-element-number el) number) - (when (eq el element) - (return nil)) - (setf (cdr prev) (cons element current)) - (return t)))))) + (when (>= (sset-element-number el) number) + (when (eq el element) + (return nil)) + (setf (cdr prev) (cons element current)) + (return t)))))) ;;; Destructively remove ELEMENT from SET. If element was in the set, ;;; then return true, otherwise return false. -(declaim (ftype (function (sset-element sset) boolean) sset-delete)) +(declaim (ftype (sfunction (sset-element sset) boolean) sset-delete)) (defun sset-delete (element set) (let ((elements (sset-elements set))) (do ((prev elements current) - (current (cdr elements) (cdr current))) - ((null current) nil) + (current (cdr elements) (cdr current))) + ((null current) nil) (when (eq (car current) element) - (setf (cdr prev) (cdr current)) - (return t))))) + (setf (cdr prev) (cdr current)) + (return t))))) ;;; Return true if ELEMENT is in SET, false otherwise. -(declaim (ftype (function (sset-element sset) boolean) sset-member)) +(declaim (ftype (sfunction (sset-element sset) boolean) sset-member)) (defun sset-member (element set) (declare (inline member)) (not (null (member element (cdr (sset-elements set)) :test #'eq)))) +(declaim (ftype (sfunction (sset sset) boolean) sset=)) +(defun sset= (set1 set2) + (equal (sset-elements set1) (sset-elements set2))) + ;;; Return true if SET contains no elements, false otherwise. -(declaim (ftype (function (sset) boolean) sset-empty)) +(declaim (ftype (sfunction (sset) boolean) sset-empty)) (defun sset-empty (set) (null (cdr (sset-elements set)))) ;;; Return a new copy of SET. -(declaim (ftype (function (sset) sset) copy-sset)) +(declaim (ftype (sfunction (sset) sset) copy-sset)) (defun copy-sset (set) (make-sset :elements (copy-list (sset-elements set)))) ;;; Perform the appropriate set operation on SET1 and SET2 by ;;; destructively modifying SET1. We return true if SET1 was modified, ;;; false otherwise. -(declaim (ftype (function (sset sset) boolean) sset-union sset-intersection - sset-difference)) +(declaim (ftype (sfunction (sset sset) boolean) sset-union sset-intersection + sset-difference)) (defun sset-union (set1 set2) (let* ((prev-el1 (sset-elements set1)) - (el1 (cdr prev-el1)) - (changed nil)) + (el1 (cdr prev-el1)) + (changed nil)) (do ((el2 (cdr (sset-elements set2)) (cdr el2))) - ((null el2) changed) + ((null el2) changed) (let* ((e (car el2)) - (num2 (sset-element-number e))) - (loop - (when (null el1) - (setf (cdr prev-el1) (copy-list el2)) - (return-from sset-union t)) - (let ((num1 (sset-element-number (car el1)))) - (when (>= num1 num2) - (if (> num1 num2) - (let ((new (cons e el1))) - (setf (cdr prev-el1) new) - (setq prev-el1 new - changed t)) - (shiftf prev-el1 el1 (cdr el1))) - (return)) - (shiftf prev-el1 el1 (cdr el1)))))))) + (num2 (sset-element-number e))) + (loop + (when (null el1) + (setf (cdr prev-el1) (copy-list el2)) + (return-from sset-union t)) + (let ((num1 (sset-element-number (car el1)))) + (when (>= num1 num2) + (if (> num1 num2) + (let ((new (cons e el1))) + (setf (cdr prev-el1) new) + (setq prev-el1 new + changed t)) + (shiftf prev-el1 el1 (cdr el1))) + (return)) + (shiftf prev-el1 el1 (cdr el1)))))))) (defun sset-intersection (set1 set2) (let* ((prev-el1 (sset-elements set1)) - (el1 (cdr prev-el1)) - (changed nil)) + (el1 (cdr prev-el1)) + (changed nil)) (do ((el2 (cdr (sset-elements set2)) (cdr el2))) - ((null el2) - (cond (el1 - (setf (cdr prev-el1) nil) - t) - (t changed))) + ((null el2) + (cond (el1 + (setf (cdr prev-el1) nil) + t) + (t changed))) (let ((num2 (sset-element-number (car el2)))) - (loop - (when (null el1) - (return-from sset-intersection changed)) - (let ((num1 (sset-element-number (car el1)))) - (when (>= num1 num2) - (when (= num1 num2) - (shiftf prev-el1 el1 (cdr el1))) - (return)) - (pop el1) - (setf (cdr prev-el1) el1) - (setq changed t))))))) + (loop + (when (null el1) + (return-from sset-intersection changed)) + (let ((num1 (sset-element-number (car el1)))) + (when (>= num1 num2) + (when (= num1 num2) + (shiftf prev-el1 el1 (cdr el1))) + (return)) + (pop el1) + (setf (cdr prev-el1) el1) + (setq changed t))))))) (defun sset-difference (set1 set2) (let* ((prev-el1 (sset-elements set1)) - (el1 (cdr prev-el1)) - (changed nil)) + (el1 (cdr prev-el1)) + (changed nil)) (do ((el2 (cdr (sset-elements set2)) (cdr el2))) - ((null el2) changed) + ((null el2) changed) (let ((num2 (sset-element-number (car el2)))) - (loop - (when (null el1) - (return-from sset-difference changed)) - (let ((num1 (sset-element-number (car el1)))) - (when (>= num1 num2) - (when (= num1 num2) - (pop el1) - (setf (cdr prev-el1) el1) - (setq changed t)) - (return)) - (shiftf prev-el1 el1 (cdr el1)))))))) + (loop + (when (null el1) + (return-from sset-difference changed)) + (let ((num1 (sset-element-number (car el1)))) + (when (>= num1 num2) + (when (= num1 num2) + (pop el1) + (setf (cdr prev-el1) el1) + (setq changed t)) + (return)) + (shiftf prev-el1 el1 (cdr el1)))))))) ;;; Destructively modify SET1 to include its union with the difference -;;; of SET2 and SET3. We return true if Set1 was modified, false +;;; of SET2 and SET3. We return true if SET1 was modified, false ;;; otherwise. -(declaim (ftype (function (sset sset sset) boolean) sset-union-of-difference)) +(declaim (ftype (sfunction (sset sset sset) boolean) sset-union-of-difference)) (defun sset-union-of-difference (set1 set2 set3) (let* ((prev-el1 (sset-elements set1)) - (el1 (cdr prev-el1)) - (el3 (cdr (sset-elements set3))) - (changed nil)) + (el1 (cdr prev-el1)) + (el3 (cdr (sset-elements set3))) + (changed nil)) (do ((el2 (cdr (sset-elements set2)) (cdr el2))) - ((null el2) changed) + ((null el2) changed) (let* ((e (car el2)) - (num2 (sset-element-number e))) - (loop - (when (null el3) - (loop - (when (null el1) - (setf (cdr prev-el1) (copy-list el2)) - (return-from sset-union-of-difference t)) - (let ((num1 (sset-element-number (car el1)))) - (when (>= num1 num2) - (if (> num1 num2) - (let ((new (cons e el1))) - (setf (cdr prev-el1) new) - (setq prev-el1 new changed t)) - (shiftf prev-el1 el1 (cdr el1))) - (return)) - (shiftf prev-el1 el1 (cdr el1)))) - (return)) - (let ((num3 (sset-element-number (car el3)))) - (when (<= num2 num3) - (unless (= num2 num3) - (loop - (when (null el1) - (do ((el2 el2 (cdr el2))) - ((null el2) - (return-from sset-union-of-difference changed)) - (let* ((e (car el2)) - (num2 (sset-element-number e))) - (loop - (when (null el3) - (setf (cdr prev-el1) (copy-list el2)) - (return-from sset-union-of-difference t)) - (setq num3 (sset-element-number (car el3))) - (when (<= num2 num3) - (unless (= num2 num3) - (let ((new (cons e el1))) - (setf (cdr prev-el1) new) - (setq prev-el1 new changed t))) - (return)) - (pop el3))))) - (let ((num1 (sset-element-number (car el1)))) - (when (>= num1 num2) - (if (> num1 num2) - (let ((new (cons e el1))) - (setf (cdr prev-el1) new) - (setq prev-el1 new changed t)) - (shiftf prev-el1 el1 (cdr el1))) - (return)) - (shiftf prev-el1 el1 (cdr el1))))) - (return))) - (pop el3)))))) + (num2 (sset-element-number e))) + (loop + (when (null el3) + (loop + (when (null el1) + (setf (cdr prev-el1) (copy-list el2)) + (return-from sset-union-of-difference t)) + (let ((num1 (sset-element-number (car el1)))) + (when (>= num1 num2) + (if (> num1 num2) + (let ((new (cons e el1))) + (setf (cdr prev-el1) new) + (setq prev-el1 new changed t)) + (shiftf prev-el1 el1 (cdr el1))) + (return)) + (shiftf prev-el1 el1 (cdr el1)))) + (return)) + (let ((num3 (sset-element-number (car el3)))) + (when (<= num2 num3) + (unless (= num2 num3) + (loop + (when (null el1) + (do ((el2 el2 (cdr el2))) + ((null el2) + (return-from sset-union-of-difference changed)) + (let* ((e (car el2)) + (num2 (sset-element-number e))) + (loop + (when (null el3) + (setf (cdr prev-el1) (copy-list el2)) + (return-from sset-union-of-difference t)) + (setq num3 (sset-element-number (car el3))) + (when (<= num2 num3) + (unless (= num2 num3) + (let ((new (cons e el1))) + (setf (cdr prev-el1) new) + (setq prev-el1 new changed t))) + (return)) + (pop el3))))) + (let ((num1 (sset-element-number (car el1)))) + (when (>= num1 num2) + (if (> num1 num2) + (let ((new (cons e el1))) + (setf (cdr prev-el1) new) + (setq prev-el1 new changed t)) + (shiftf prev-el1 el1 (cdr el1))) + (return)) + (shiftf prev-el1 el1 (cdr el1))))) + (return))) + (pop el3))))))