118 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Factor
		
	
	
		
		
			
		
	
	
			118 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Factor
		
	
	
| 
								 | 
							
								! Copyright (C) 2006, 2007 Slava Pestov
							 | 
						||
| 
								 | 
							
								! See http://factorcode.org/license.txt for BSD license.
							 | 
						||
| 
								 | 
							
								USING: alien alien.c-types arrays assocs combinators compiler
							 | 
						||
| 
								 | 
							
								hashtables kernel libc math namespaces parser sequences words
							 | 
						||
| 
								 | 
							
								cocoa.messages cocoa.runtime ;
							 | 
						||
| 
								 | 
							
								IN: cocoa.subclassing
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: init-method ( method alien -- )
							 | 
						||
| 
								 | 
							
								    >r first3 r>
							 | 
						||
| 
								 | 
							
								    [ >r execute r> set-objc-method-imp ] keep
							 | 
						||
| 
								 | 
							
								    [ >r malloc-char-string r> set-objc-method-types ] keep
							 | 
						||
| 
								 | 
							
								    >r sel_registerName r> set-objc-method-name ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <empty-method-list> ( n -- alien )
							 | 
						||
| 
								 | 
							
								    "objc-method-list" heap-size
							 | 
						||
| 
								 | 
							
								    "objc-method" heap-size pick * + 1 calloc
							 | 
						||
| 
								 | 
							
								    [ set-objc-method-list-count ] keep ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <method-list> ( methods -- alien )
							 | 
						||
| 
								 | 
							
								    dup length dup <empty-method-list> -rot
							 | 
						||
| 
								 | 
							
								    [ pick method-list@ objc-method-nth init-method ] 2each ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: define-objc-methods ( class methods -- )
							 | 
						||
| 
								 | 
							
								    <method-list> class_addMethods ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <objc-class> ( name info -- class )
							 | 
						||
| 
								 | 
							
								    "objc-class" malloc-object
							 | 
						||
| 
								 | 
							
								    [ set-objc-class-info ] keep
							 | 
						||
| 
								 | 
							
								    [ >r malloc-char-string r> set-objc-class-name ] keep ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <protocol-list> ( name -- protocol-list )
							 | 
						||
| 
								 | 
							
								    "objc-protocol-list" malloc-object
							 | 
						||
| 
								 | 
							
								    1 over set-objc-protocol-list-count
							 | 
						||
| 
								 | 
							
								    swap objc-protocol over set-objc-protocol-list-class ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								! The Objective C object model is a bit funny.
							 | 
						||
| 
								 | 
							
								! Every class has a metaclass.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								! The superclass of the metaclass of X is the metaclass of the
							 | 
						||
| 
								 | 
							
								! superclass of X.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								! The metaclass of the metaclass of X is the metaclass of the
							 | 
						||
| 
								 | 
							
								! root class of X.
							 | 
						||
| 
								 | 
							
								: meta-meta-class ( class -- class ) root-class objc-class-isa ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: copy-instance-size ( class -- )
							 | 
						||
| 
								 | 
							
								    dup objc-class-super-class objc-class-instance-size
							 | 
						||
| 
								 | 
							
								    swap set-objc-class-instance-size ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <meta-class> ( superclass name -- class )
							 | 
						||
| 
								 | 
							
								    CLS_META <objc-class>
							 | 
						||
| 
								 | 
							
								    [ >r dup objc-class-isa r> set-objc-class-super-class ] keep
							 | 
						||
| 
								 | 
							
								    [ >r meta-meta-class r> set-objc-class-isa ] keep
							 | 
						||
| 
								 | 
							
								    dup copy-instance-size ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: set-protocols ( protocols class -- )
							 | 
						||
| 
								 | 
							
								    swap {
							 | 
						||
| 
								 | 
							
								        { [ dup empty? ] [ 2drop ] }
							 | 
						||
| 
								 | 
							
								        { [ dup length 1 = ] [
							 | 
						||
| 
								 | 
							
								            first <protocol-list>
							 | 
						||
| 
								 | 
							
								            swap set-objc-class-protocols
							 | 
						||
| 
								 | 
							
								        ] }
							 | 
						||
| 
								 | 
							
								    } cond ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: <new-class> ( protocols metaclass superclass name -- class )
							 | 
						||
| 
								 | 
							
								    CLS_CLASS <objc-class>
							 | 
						||
| 
								 | 
							
								    [ set-objc-class-super-class ] keep
							 | 
						||
| 
								 | 
							
								    [ set-objc-class-isa ] keep
							 | 
						||
| 
								 | 
							
								    [ set-protocols ] keep
							 | 
						||
| 
								 | 
							
								    dup copy-instance-size ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: (define-objc-class) ( protocols superclass name imeth -- )
							 | 
						||
| 
								 | 
							
								    >r
							 | 
						||
| 
								 | 
							
								    >r objc-class r>
							 | 
						||
| 
								 | 
							
								    [ <meta-class> ] 2keep <new-class> dup objc_addClass
							 | 
						||
| 
								 | 
							
								    r> <method-list> class_addMethods ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: encode-types ( return types -- encoding )
							 | 
						||
| 
								 | 
							
								    swap add* [
							 | 
						||
| 
								 | 
							
								        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 ,
							 | 
						||
| 
								 | 
							
								    ] [ ] make compile-quot ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: prepare-methods ( methods -- methods )
							 | 
						||
| 
								 | 
							
								    [ first4 prepare-method 3array ] map ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: redefine-objc-methods ( imeth name -- )
							 | 
						||
| 
								 | 
							
								    dup class-exists? [
							 | 
						||
| 
								 | 
							
								        objc_getClass swap define-objc-methods
							 | 
						||
| 
								 | 
							
								    ] [
							 | 
						||
| 
								 | 
							
								        2drop
							 | 
						||
| 
								 | 
							
								    ] if ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SYMBOL: +name+
							 | 
						||
| 
								 | 
							
								SYMBOL: +protocols+
							 | 
						||
| 
								 | 
							
								SYMBOL: +superclass+
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: define-objc-class ( imeth hash -- )
							 | 
						||
| 
								 | 
							
								    clone [
							 | 
						||
| 
								 | 
							
								        prepare-methods
							 | 
						||
| 
								 | 
							
								        +name+ get 2dup redefine-objc-methods swap [
							 | 
						||
| 
								 | 
							
								            +protocols+ get , +superclass+ get , +name+ get , ,
							 | 
						||
| 
								 | 
							
								            \ (define-objc-class) ,
							 | 
						||
| 
								 | 
							
								        ] [ ] make import-objc-class
							 | 
						||
| 
								 | 
							
								    ] bind ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: define-objc-class-early ( hash -- )
							 | 
						||
| 
								 | 
							
								    +name+ swap at "cocoa.classes" create drop ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: CLASS:
							 | 
						||
| 
								 | 
							
								    parse-definition unclip >r parsed r>
							 | 
						||
| 
								 | 
							
								    >hashtable dup define-objc-class-early parsed
							 | 
						||
| 
								 | 
							
								    \ define-objc-class parsed ; parsing
							 |