X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fhash-table.lisp;h=dc4f4180b194b9b25fc224c01eeef887e0c03b22;hb=d0e2cc2ea3ae036fba1d085b9c88a5ffe24de956;hp=e5981506e70d2de9e86ba9cceb4dd44874771f84;hpb=29c5587e4ad81dd1442c5f54cc686a45f7cb9d2e;p=jscl.git diff --git a/src/hash-table.lisp b/src/hash-table.lisp index e598150..dc4f418 100644 --- a/src/hash-table.lisp +++ b/src/hash-table.lisp @@ -13,21 +13,24 @@ ;; You should have received a copy of the GNU General Public License ;; along with JSCL. If not, see . -;;; Javascript dictionaries are the natural way to implement Common +;;; Plain Javascript objects are the natural way to implement Common ;;; Lisp hash tables. However, there is a big differences betweent -;;; them which we need to work around. Javascript dictionaries require -;;; the keys to be strings. To solve that, we map Lisp objects to -;;; strings such that "equivalent" values map to the same string, -;;; regarding the equality predicate used (one of `eq', `eql', `equal' -;;; and `equalp'). +;;; them which we need to work around. Javascript objects require the +;;; keys to be strings. To solve that, we map Lisp objects to strings +;;; such that "equivalent" values map to the same string, regarding +;;; the equality predicate used (one of `eq', `eql', `equal' and +;;; `equalp'). ;;; +;;; Additionally, we want to iterate across the hash table +;;; key-values. So we use a cons (key . value) +;;; as value in the Javascript object. It implicitly gives the +;;; inverse mapping of strings to our objects. ;;; If a hash table has `eq' as test, we need to generate unique ;;; strings for each Lisp object. To do this, we tag the objects with -;;; a `$$jscl_id' property. As a special case, numbers are not -;;; objects, but they can be used for indexin a Javascript dictionary, -;;; we do not need to tag them. +;;; a `$$jscl_id' property. As a special case, numbers do not need to +;;; be tagged, as they can be used to index Javascript objects. (defvar *eq-hash-counter* 0) (defun eq-hash (x) (cond @@ -74,15 +77,17 @@ `(hash-table ,hash-fn ,(new)))) (defun gethash (key hash-table &optional default) - (let ((obj (caddr hash-table)) - (hash (funcall (cadr hash-table) key))) - (values (oget obj hash) - (in hash obj)))) + (let* ((obj (caddr hash-table)) + (hash (funcall (cadr hash-table) key)) + (exists (in hash obj))) + (if exists + (values (cdr (oget obj hash)) t) + (values default nil)))) (defun sethash (new-value key hash-table) (let ((obj (caddr hash-table)) (hash (funcall (cadr hash-table) key))) - (oset new-value obj hash) + (oset (cons key new-value) obj hash) new-value)) @@ -100,3 +105,26 @@ ,g!new-value) `(gethash ,g!new-value ,g!key ,g!hash-table) ; accessing form ))) + + +(defun remhash (key hash-table) + (let ((obj (caddr hash-table)) + (hash (funcall (cadr hash-table) key))) + (prog1 (in hash obj) + (delete-property hash obj)))) + + +(defun hash-table-count (hash-table) + (let ((count 0)) + (map-for-in (lambda (x) + (declare (ignore x)) + (incf count)) + (caddr hash-table)) + count)) + + +(defun maphash (function hash-table) + (map-for-in (lambda (x) + (funcall function (car x) (cdr x))) + (caddr hash-table)) + nil)