Added several new utility macros, including a primitive DESTRUCTURING-BIND.
authorDaniel Gackle <danielgackle@gmail.com>
Sun, 12 Apr 2009 06:15:41 +0000 (23:15 -0700)
committerVladimir Sedach <vsedach@gmail.com>
Sun, 12 Apr 2009 23:10:31 +0000 (17:10 -0600)
src/lib/ps-macro-lib.lisp
src/package.lisp

index 6399f6e..47937df 100644 (file)
 (defpsmacro null (x)
   `(= ,x nil))
 
+(defpsmacro undefined (x)
+  `(=== undefined ,x))
+
+(defpsmacro defined (x)
+  `(not (undefined ,x)))
+
 (defpsmacro @ (obj &rest props)
   "Handy slot-value/aref composition macro."
   (if props
 (defpsmacro with-lambda (()  &body body)
   "Wraps BODY in a lambda so that it can be treated as an expression."
   `((lambda () ,@body)))
+
+(defpsmacro stringp (x)
+  `(= (typeof ,x) "string"))
+
+(defpsmacro numberp (x)
+  `(= (typeof ,x) "number"))
+
+(defpsmacro functionp (x)
+  `(= (typeof ,x) "function"))
+
+(defpsmacro objectp (x)
+  `(= (typeof ,x) "object"))
+
+(defpsmacro memoize (fn-expr)
+  (destructuring-bind (defun fn-name (arg) &rest fn-body)
+      fn-expr
+    (declare (ignore defun))
+    (with-ps-gensyms (table value compute-fn)
+      `(let ((,table {}))
+         (defun ,compute-fn (,arg) ,@fn-body)
+         (defun ,fn-name (,arg)
+           (let ((,value (aref ,table ,arg)))
+             (when (null ,value)
+               (setf ,value (,compute-fn ,arg))
+               (setf (aref ,table ,arg) ,value))
+             (return ,value)))))))
+
+(defpsmacro append (arr1 &rest arrs)
+  (if arrs
+      `((@ ,arr1 :concat) ,@arrs)
+      arr1))
+
+(defpsmacro apply (fn &rest args)
+  (let ((arglist (if (> (length args) 1)
+                     `(append (list ,@(butlast args)) ,(car (last args)))
+                     (first args))))
+    `((@ ,fn :apply) this ,arglist)))
+
+(defpsmacro destructuring-bind (vars expr &body body)
+  ;; a simple implementation that for now only supports flat lists
+  (let* ((arr (if (complex-js-expr-p expr) (ps-gensym) expr))
+         (n -1)
+         (bindings
+          (append (unless (equal arr expr) `((,arr ,expr)))
+                  (mapcar (lambda (var) `(,var (aref ,arr ,(incf n)))) vars))))
+    `(let ,bindings ,@body)))
index f5e6e01..dc3a441 100644 (file)
       #:concat-string
       #:length
       #:null
+      #:defined
+      #:undefined
       #:@
       #:with-lambda
+      #:stringp
+      #:numberp
+      #:functionp
+      #:objectp
+      #:memoize
+      #:append
+      #:apply
+      #:destructuring-bind
 
       ;; js runtime utils
       #:*ps-lisp-library*