Skip to content

Instantly share code, notes, and snippets.

@kurohuku
Created December 19, 2013 16:04
Show Gist options
  • Save kurohuku/8041680 to your computer and use it in GitHub Desktop.
Save kurohuku/8041680 to your computer and use it in GitHub Desktop.
(defun split-method-call (str)
(let* ((strs (coerce (jcall "split" str "/") 'list))
(method (car (last strs)))
(class (format nil "~{~A~^/~}" (butlast strs))))
(list class method)))
(defun static-field-p (str)
(destructuring-bind (class field)
(split-method-call str)
(and (not (string= "" class))
(not (some #'lower-case-p field)))))
(defun make-field-access (str)
(destructuring-bind (class field)
(split-method-call str)
`(jfield ,class ,field)))
(defun abcl-java-interop-reader (stream ch1 ch2)
(declare (ignorable ch1 ch2))
(let* ((*readtable* (copy-readtable))
(prev-readtable-case (readtable-case *readtable*)))
(setf (readtable-case *readtable*) :preserve)
(let ((interop (read stream)))
(etypecase interop
((string))
((symbol) (setf interop (symbol-name interop))))
(when (static-field-p interop)
(return-from abcl-java-interop-reader
(make-field-access interop)))
(setf (readtable-case *readtable*) prev-readtable-case)
(let ((following-forms (read-delimited-list #\) stream)))
(unread-char #\) stream)
(cond
((jcall "startsWith" interop ".") ; method call
`(lambda ()
(jcall ,(subseq interop 1) ,@following-forms)))
((jcall "endsWith" interop ".") ; create instance
`(lambda ()
(jnew ,(subseq interop 0 (1- (length interop)))
,@following-forms)))
((jcall "contains" interop "/")
(destructuring-bind (class method)
(split-method-call interop)
`(lambda ()
(jstatic ,method (jclass ,class) ,@following-forms)))))))))
(set-dispatch-macro-character #\# #\! #'abcl-java-interop-reader)
;;;; example
(jstatic "showMessageDialog" "javax.swing.JOptionPane" nil "Hello")
(#!javax.swing.JOptionPane/showMessageDialog nil "Hello")
(defun make-jframe ()
(let ((frame (#!javax.swing.JFrame.)))
(#!.setSize frame 200 200)
(#!.setVisible frame +true+)))
(defun make-jframe-with-btn ()
(let* ((frame (#!javax.swing.JFrame.))
(pane (#!.getContentPane frame)))
(#!.setSize frame 200 200)
(#!.add pane
(#!javax.swing.JButton. "Button")
#!java.awt.BorderLayout/CENTER)
(#!.setVisible frame +true+)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment