factor/basis/cocoa/subclassing/subclassing.factor

85 lines
2.5 KiB
Factor
Raw Normal View History

! Copyright (C) 2006, 2008 Slava Pestov
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-04-20 06:15:46 -04:00
USING: alien alien.c-types alien.strings arrays assocs
combinators compiler hashtables kernel libc math namespaces
parser sequences words cocoa.messages cocoa.runtime
compiler.units io.encodings.ascii generalizations
continuations make ;
2007-09-20 18:09:08 -04:00
IN: cocoa.subclassing
: init-method ( method -- sel imp types )
first3 swap
2008-09-12 23:01:07 -04:00
[ sel_registerName ] [ execute ] [ ascii string>alien ] ;
: throw-if-false ( YES/NO -- )
zero? [ "Failed to add method or protocol to class" throw ] when ;
2007-09-20 18:09:08 -04:00
: add-methods ( methods class -- )
swap
2008-09-12 23:01:07 -04:00
[ init-method class_addMethod throw-if-false ] with each ;
2007-09-20 18:09:08 -04:00
: add-protocols ( protocols class -- )
2008-09-12 23:01:07 -04:00
swap [ objc-protocol class_addProtocol throw-if-false ] with each ;
2007-09-20 18:09:08 -04:00
: (define-objc-class) ( protocols superclass name imeth -- )
-rot
[ objc-class ] dip 0 objc_allocateClassPair
[ add-methods ] [ add-protocols ] [ objc_registerClassPair ]
tri ;
2007-09-20 18:09:08 -04:00
: encode-types ( return types -- encoding )
2008-03-31 22:32:31 -04:00
swap prefix [
2007-09-20 18:09:08 -04:00
alien>objc-types get at "0" append
] map concat ;
: prepare-method ( ret types quot -- type imp )
>r [ encode-types ] 2keep r> [
"cdecl" swap 4array % \ alien-callback ,
2007-12-24 19:40:09 -05:00
] [ ] make define-temp ;
2007-09-20 18:09:08 -04:00
: prepare-methods ( methods -- methods )
[
[ first4 prepare-method 3array ] map
] with-compilation-unit ;
2007-09-20 18:09:08 -04:00
: types= ( a b -- ? )
[ ascii alien>string ] bi@ = ;
2008-09-09 01:53:22 -04:00
: (verify-method-type) ( class sel types -- )
[ class_getInstanceMethod method_getTypeEncoding ]
dip types=
[ "Objective-C method types cannot be changed once defined" throw ]
unless ;
: verify-method-type ( class sel imp types -- class sel imp types )
4 ndup nip (verify-method-type) ;
2008-09-09 01:53:22 -04:00
: (redefine-objc-method) ( class method -- )
init-method ! verify-method-type
drop
[ class_getInstanceMethod ] dip method_setImplementation drop ;
: redefine-objc-methods ( imeth name -- )
dup class-exists? [
objc_getClass swap [ (redefine-objc-method) ] with each
] [
2drop
] if ;
2007-09-20 18:09:08 -04:00
SYMBOL: +name+
SYMBOL: +protocols+
SYMBOL: +superclass+
: define-objc-class ( imeth hash -- )
clone [
prepare-methods
+name+ get "cocoa.classes" create drop
2008-09-09 01:53:22 -04:00
+name+ get 2dup redefine-objc-methods swap [
2007-09-20 18:09:08 -04:00
+protocols+ get , +superclass+ get , +name+ get , ,
\ (define-objc-class) ,
] [ ] make import-objc-class
] bind ;
: CLASS:
parse-definition unclip
>hashtable define-objc-class ; parsing