X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Flist.lisp;h=9cb8e450d70a616e9bafdebd318eca0d92319bb9;hb=2b8e5aefd311f464311cfa3e73b5e25dd76de1cc;hp=58226f84dc9361a104d3b2b5ec970bdeb309ae5b;hpb=28497368589003d049952a50c10ebc93fe974024;p=jscl.git diff --git a/src/list.lisp b/src/list.lisp index 58226f8..9cb8e45 100644 --- a/src/list.lisp +++ b/src/list.lisp @@ -360,3 +360,51 @@ (when (member (funcall key x) list2 :test test :key key) (push x new-list))) new-list)) + +(defun get-properties (plist indicator-list) + (do* ((plist plist (cddr plist)) + (cdr (cdr plist) (cdr plist)) + (car (car plist) (car plist))) + ((null plist) (values nil nil nil)) + (when (null cdr) + (error "malformed property list ~S" plist)) + (let ((found (member car indicator-list :test #'eq))) + (when found + (return (values car (cadr plist) plist)))))) + +(defun getf (plist indicator &optional default) + (do* ((plist plist (cddr plist)) + (cdr (cdr plist) (cdr plist)) + (car (car plist) (car plist))) + ((null plist) default) + (when (null cdr) + (error "malformed property list ~S" plist)) + (when (eq indicator car) + (return (cadr plist))))) + +(defun %putf (plist indicator new-value) + (do* ((tail plist (cddr tail)) + (cdr (cdr tail) (cdr tail)) + (car (car tail) (car tail))) + ((null tail) (list* indicator new-value plist)) + (when (null cdr) + (error "malformed property list ~S" tail)) + (when (eq indicator car) + ;; TODO: should be cadr, needs a defsetf for that + (setf (car (cdr tail)) new-value) + (return tail)))) + +(define-setf-expander getf (plist indicator &optional default) + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-expansion plist) + (let ((store (gensym)) + (indicator-sym (gensym)) + (default-sym (and default (gensym)))) + (values `(,indicator-sym ,@(and default `(,default-sym)) ,@dummies) + `(,indicator ,@(and default `(,default)) ,@vals) + `(,store) + `(let ((,(car newval) (%putf ,getter ,indicator-sym ,store)) + ,@(cdr newval)) + ,setter + ,store) + `(getf ,getter ,indicator-sym ,@(and default `(,default-sym)))))))