factor/basis/cocoa/messages/messages.factor

216 lines
5.8 KiB
Factor
Raw Normal View History

2008-04-20 06:15:46 -04:00
! Copyright (C) 2006, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien alien.c-types alien.strings arrays assocs
combinators compiler kernel math namespaces make parser
prettyprint prettyprint.sections quotations sequences strings
words cocoa.runtime io macros memoize debugger
io.encodings.ascii effects compiler.generator libc libc.private
parser lexer init core-foundation ;
2007-09-20 18:09:08 -04:00
IN: cocoa.messages
: make-sender ( method function -- quot )
[ over first , f , , second , \ alien-invoke , ] [ ] make ;
: sender-stub-name ( method function -- string )
[ % "_" % unparse % ] "" make ;
: sender-stub ( method function -- word )
2007-12-26 20:41:02 -05:00
[ sender-stub-name f <word> dup ] 2keep
2007-09-20 18:09:08 -04:00
over first large-struct? [ "_stret" append ] when
make-sender define ;
2007-09-20 18:09:08 -04:00
SYMBOL: message-senders
SYMBOL: super-message-senders
2007-10-06 13:39:59 -04:00
message-senders global [ H{ } assoc-like ] change-at
super-message-senders global [ H{ } assoc-like ] change-at
2007-09-20 18:09:08 -04:00
: cache-stub ( method function hash -- )
[
over get [ 2drop ] [ over >r sender-stub r> set ] if
] bind ;
: cache-stubs ( method -- )
dup
"objc_msgSendSuper" super-message-senders get cache-stub
"objc_msgSend" message-senders get cache-stub ;
: <super> ( receiver -- super )
"objc-super" <c-object> [
>r dup object_getClass class_getSuperclass r>
2007-09-20 18:09:08 -04:00
set-objc-super-class
] keep
[ set-objc-super-receiver ] keep ;
TUPLE: selector name object ;
MEMO: <selector> ( name -- sel ) f \ selector boa ;
2007-09-20 18:09:08 -04:00
: selector ( selector -- alien )
2008-08-29 11:24:22 -04:00
dup object>> expired? [
dup name>> sel_registerName
[ >>object drop ] keep
2007-09-20 18:09:08 -04:00
] [
2008-08-29 11:24:22 -04:00
object>>
2007-09-20 18:09:08 -04:00
] if ;
SYMBOL: objc-methods
2007-10-06 13:39:59 -04:00
objc-methods global [ H{ } assoc-like ] change-at
2007-09-20 18:09:08 -04:00
: lookup-method ( selector -- method )
dup objc-methods get at
[ ] [ "No such method: " prepend throw ] ?if ;
2007-09-20 18:09:08 -04:00
: make-dip ( quot n -- quot' )
dup
\ >r <repetition> >quotation -rot
\ r> <repetition> >quotation 3append ;
2007-10-06 13:39:59 -04:00
MEMO: make-prepare-send ( selector method super? -- quot )
2007-09-20 18:09:08 -04:00
[
[ \ <super> , ] when
swap <selector> , \ selector ,
2007-09-20 18:09:08 -04:00
] [ ] make
swap second length 2 - make-dip ;
2007-09-20 18:09:08 -04:00
MACRO: (send) ( selector super? -- quot )
2007-10-06 13:39:59 -04:00
>r dup lookup-method r>
[ make-prepare-send ] 2keep
super-message-senders message-senders ? get at
[ slip execute ] 2curry ;
2007-09-20 18:09:08 -04:00
2008-01-24 18:20:27 -05:00
: send ( receiver args... selector -- return... ) f (send) ; inline
2007-09-20 18:09:08 -04:00
\ send soft "break-after" set-word-prop
2008-01-24 18:20:27 -05:00
: super-send ( receiver args... selector -- return... ) t (send) ; inline
2007-09-20 18:09:08 -04:00
\ super-send soft "break-after" set-word-prop
! Runtime introspection
: (objc-class) ( string word -- class )
dupd execute
[ ] [ "No such class: " prepend throw ] ?if ; inline
2007-09-20 18:09:08 -04:00
: objc-class ( string -- class )
\ objc_getClass (objc-class) ;
: objc-protocol ( string -- class )
\ objc_getProtocol (objc-class) ;
: objc-meta-class ( string -- class )
\ objc_getMetaClass (objc-class) ;
SYMBOL: objc>alien-types
H{
{ "c" "char" }
{ "i" "int" }
{ "s" "short" }
{ "l" "long" }
{ "q" "longlong" }
{ "C" "uchar" }
{ "I" "uint" }
{ "S" "ushort" }
{ "L" "ulong" }
{ "Q" "ulonglong" }
{ "f" "float" }
{ "d" "double" }
{ "B" "bool" }
{ "v" "void" }
{ "*" "char*" }
{ "@" "id" }
{ "#" "id" }
{ ":" "SEL" }
} objc>alien-types set-global
! The transpose of the above map
SYMBOL: alien>objc-types
objc>alien-types get [ swap ] assoc-map
! A hack...
"ptrdiff_t" heap-size {
{ 4 [ H{
{ "NSPoint" "{_NSPoint=ff}" }
{ "NSRect" "{_NSRect=ffff}" }
{ "NSSize" "{_NSSize=ff}" }
{ "NSRange" "{_NSRange=II}" }
} ] }
{ 8 [ H{
{ "NSPoint" "{_NSPoint=dd}" }
{ "NSRect" "{_NSRect=dddd}" }
{ "NSSize" "{_NSSize=dd}" }
{ "NSRange" "{_NSRange=QQ}" }
} ] }
} case
assoc-union alien>objc-types set-global
2007-09-20 18:09:08 -04:00
: objc-struct-type ( i string -- ctype )
2dup CHAR: = -rot index-from swap subseq
2007-09-20 18:09:08 -04:00
dup c-types get key? [
"Warning: no such C type: " write dup print
drop "void*"
] unless ;
: (parse-objc-type) ( i string -- ctype )
2dup nth >r >r 1+ r> r> {
{ [ dup "rnNoORV" member? ] [ drop (parse-objc-type) ] }
{ [ dup CHAR: ^ = ] [ 3drop "void*" ] }
{ [ dup CHAR: { = ] [ drop objc-struct-type ] }
{ [ dup CHAR: [ = ] [ 3drop "void*" ] }
2008-04-11 13:55:57 -04:00
[ 2nip 1string objc>alien-types get at ]
2007-09-20 18:09:08 -04:00
} cond ;
: parse-objc-type ( string -- ctype ) 0 swap (parse-objc-type) ;
: method-arg-type ( method i -- type )
method_copyArgumentType
[ ascii alien>string parse-objc-type ] keep
(free) ;
2007-09-20 18:09:08 -04:00
: method-arg-types ( method -- args )
dup method_getNumberOfArguments
[ method-arg-type ] with map ;
2007-09-20 18:09:08 -04:00
: method-return-type ( method -- ctype )
method_copyReturnType
[ ascii alien>string parse-objc-type ] keep
(free) ;
2007-09-20 18:09:08 -04:00
: register-objc-method ( method -- )
dup method-return-type over method-arg-types 2array
dup cache-stubs
swap method_getName sel_getName
2007-09-20 18:09:08 -04:00
objc-methods get set-at ;
: (register-objc-methods) ( methods count -- methods )
over [ void*-nth register-objc-method ] curry each ;
2007-09-20 18:09:08 -04:00
: register-objc-methods ( class -- )
0 <uint> [ class_copyMethodList ] keep *uint
(register-objc-methods) (free) ;
2007-09-20 18:09:08 -04:00
: class-exists? ( string -- class ) objc_getClass >boolean ;
: unless-defined ( class quot -- )
>r class-exists? r> unless ; inline
: define-objc-class-word ( name quot -- )
[
over , , \ unless-defined , dup , \ objc-class ,
2008-06-08 16:32:55 -04:00
] [ ] make >r "cocoa.classes" create r>
(( -- class )) define-declared ;
2007-09-20 18:09:08 -04:00
: import-objc-class ( name quot -- )
2dup unless-defined
dupd define-objc-class-word
2007-11-24 16:28:40 -05:00
[
dup
objc-class register-objc-methods
objc-meta-class register-objc-methods
] curry try ;
2007-09-20 18:09:08 -04:00
: root-class ( class -- root )
dup class_getSuperclass [ root-class ] [ ] ?if ;