da75eb42 |
(in-package :objc-runtime)
|
116081f3 |
#+ccl
(defgeneric send-message (object message &rest args)
(:method ((object ccl:macptr) (message (eql 'alloc)) &rest args)
(apply #'objc-msg-send object (ensure-selector "alloc") args)))
|
6b08248f |
(defun read-until (test symbol-prefix &optional stop-before-chars)
"Read from a string until"
(lambda (s c b)
(declare (ignore c b))
(let ((class-name (coerce (loop for next-char = (peek-char nil s nil nil t)
|
9a92915d |
while next-char
until (funcall test next-char)
collect (read-char s t nil t)
finally (when (and (not (member next-char
stop-before-chars))
(funcall test next-char))
(read-char s t nil t)))
|
6b08248f |
'string)))
`(,symbol-prefix ,class-name))))
|
60bee14d |
(defmacro objc-send (obj message return &rest args)
(let* ((return-t (case return
(:nsstring :pointer)
(t return)))
(result `(cffi:foreign-funcall "objc_msgSend"
:pointer ,obj
:pointer ,message
,@args
,return-t)))
(case return
(:nsstring `(objc-send ,result
(ensure-selector "UTF8String")
:string))
(t result))))
|
9a92915d |
(defun read-objc-form (s char)
(declare (ignore char))
|
60bee14d |
(let* ((info (read-delimited-list #\] s t))
(safe-p (when (eql #\? (peek-char nil s nil #\p t))
(read-char s t nil t)))
(return-t (case (peek-char nil s nil #\p t)
(#\# (read-char s t nil t) :int)
(#\& (read-char s t nil t) :pointer)
(#\@ (read-char s t nil t) :nsstring)
(#\b (read-char s t nil t) :bool)
(#\s (read-char s t nil t) :string)
(t :pointer))))
(when info
(destructuring-bind (obj message . args) info
(if safe-p
`(safe-objc-msg-send ,return-t ,obj ,message ,@args)
`(objc-send ,obj ,message ,return-t ,@args))))))
|
9a92915d |
|
da75eb42 |
(named-readtables:defreadtable :objc-readtable
(:merge :standard)
(:syntax-from :standard #\) #\])
|
9a92915d |
(:macro-char #\[ 'read-objc-form nil)
|
da75eb42 |
(:dispatch-macro-char #\# #\@
(lambda (s c b)
c b
|
6b08248f |
(let ((class-name (coerce (loop for c = (peek-char nil s nil nil t)
|
9a92915d |
until (or (null c)
(serapeum:whitespacep c)
(member c
'(#\) #\( #\[ #\])))
collect (read-char s t nil t))
|
da75eb42 |
'string)))
|
382ab041 |
`(ensure-class ,class-name))))
|
6b08248f |
(:macro-char #\@ :dispatch t)
(:dispatch-macro-char #\@ #\( (read-until (serapeum:op (char= _ #\)))
'ensure-selector))
(:dispatch-macro-char #\@ #\" (read-until (serapeum:op (char= _ #\"))
'make-nsstring)))
|