[parenscript-devel] A macro for integrating PS with Slime

Daniel Gackle danielgackle at gmail.com
Thu Jun 17 19:02:31 UTC 2010


Below is a DEFUN-JS macro for defining PS functions at the Lisp top-level.
It creates a Lisp stub with the same signature whose body simply throws
an error telling you that you tried to call a PS function from Lisp. Why is
that
useful? Because now your PS functions are fully integrated with Slime.
You can jump around with M-., get arglist info in the minibuffer, and so on.

After a week of using this, I can't believe how much of a difference it
makes.

In PS, DEFUN-JS translates trivially to DEFUN. Of course you still need a
way to collect the JS emitted by all these forms, but PS is agnostic on how
that should be done.

A side note: we also converted nearly all our ps macros to DEFMACRO+PS
forms at the toplevel. This has the neat property that you can now
look at expansions using the highly convenient Slime macroexpand. I doubt
that this is a perfect solution (no doubt you can trip yourself up on
differences
between the CL and PS macro environments), but it's sure handier than
calling
PS::PS-MACROEXPAND from the REPL.

Daniel

p.s. The following has been stripped of a couple of functions specific to
our project. I tested it a bit, but if I missed anything, let me know.


(defmacro defun-js (name lambda-list &body body)
  (declare (ignore body))
  (labels ((sym% (argspec) (if (symbolp argspec) argspec (car argspec))))
    (multiple-value-bind (required optionals restp rest keyp keys allowp
auxp aux morep more-context more-count beyond-requireds? key-object)
        (ps::parse-lambda-list lambda-list)
      (declare (ignore restp keyp allowp auxp aux morep more-context
more-count beyond-requireds? key-object))
      ;; get rid of init forms, which can't be evaluated in Lisp.
      (setf optionals (mapcar #'sym% optionals) keys (mapcar #'sym% keys))
      `(defun ,name (, at required ,@(when optionals `(&optional , at optionals))
                     ,@(when rest `(&rest ,rest)) ,@(when keys `(&key
, at keys)))
         (declare (ignore , at required , at optionals ,@(when rest (list rest))
, at keys))
         (error "The ~s function is js-only and cannot be called from Lisp."
',name)))))

(defpsmacro defun-js (name lambda-list &body body)
  `(defun ,name ,lambda-list , at body))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/parenscript-devel/attachments/20100617/167f784c/attachment.html>


More information about the parenscript-devel mailing list