factor/basis/cocoa/subclassing/subclassing.factor

103 lines
3.1 KiB
Factor
Raw Normal View History

! Copyright (C) 2006, 2010 Slava Pestov, Joe Groff.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.c-types alien.parser alien.strings arrays
assocs combinators compiler hashtables kernel lexer libc
locals.parser locals.types math namespaces parser sequences
words cocoa.messages cocoa.runtime locals compiler.units
io.encodings.utf8 continuations make fry effects stack-checker
stack-checker.errors ;
2007-09-20 18:09:08 -04:00
IN: cocoa.subclassing
: init-method ( method -- sel imp types )
first3 swap
2009-03-17 03:19:50 -04:00
[ sel_registerName ] [ execute( -- xt ) ] [ utf8 string>alien ]
2008-09-12 23:18:47 -04:00
tri* ;
2008-09-12 23:01:07 -04:00
2008-12-04 22:22:48 -05:00
: throw-if-false ( obj what -- )
swap { f 0 } member?
[ "Failed to " prepend throw ] [ drop ] if ;
: add-method ( class sel imp types -- )
class_addMethod "add method to class" throw-if-false ;
2007-09-20 18:09:08 -04:00
: add-methods ( methods class -- )
2008-12-04 22:22:48 -05:00
'[ [ _ ] dip init-method add-method ] each ;
: add-protocol ( class protocol -- )
class_addProtocol "add protocol to class" throw-if-false ;
2007-09-20 18:09:08 -04:00
: add-protocols ( protocols class -- )
2008-12-04 22:22:48 -05:00
'[ [ _ ] dip objc-protocol add-protocol ] each ;
2007-09-20 18:09:08 -04:00
: (define-objc-class) ( methods protocols superclass name -- )
[ objc-class ] dip 0 objc_allocateClassPair
2008-12-04 22:22:48 -05:00
[ add-protocols ] [ add-methods ] [ objc_registerClassPair ]
tri ;
2007-09-20 18:09:08 -04:00
: encode-type ( type -- encoded )
dup alien>objc-types get at [ ] [ no-objc-type ] ?if ;
2007-09-20 18:09:08 -04:00
: encode-types ( return types -- encoding )
swap prefix [ encode-type "0" append ] map concat ;
2007-09-20 18:09:08 -04:00
: prepare-method ( ret types quot -- type imp )
[ [ encode-types ] 2keep ] dip
2010-03-31 22:20:35 -04:00
'[ _ _ cdecl _ alien-callback ]
(( -- callback )) 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
2008-12-04 22:22:48 -05:00
:: (redefine-objc-method) ( class method -- )
method init-method :> ( sel imp types )
class sel class_getInstanceMethod [
imp method_setImplementation drop
] [
class sel imp types add-method
] if* ;
2008-09-09 01:53:22 -04:00
: redefine-objc-methods ( methods name -- )
2008-09-09 01:53:22 -04:00
dup class-exists? [
2008-12-04 22:22:48 -05:00
objc_getClass '[ [ _ ] dip (redefine-objc-method) ] each
] [ 2drop ] if ;
2007-09-20 18:09:08 -04:00
:: define-objc-class ( name superclass protocols methods -- )
methods prepare-methods :> methods
name "cocoa.classes" create drop
methods name redefine-objc-methods
name [ methods protocols superclass name (define-objc-class) ] import-objc-class ;
2007-09-20 18:09:08 -04:00
SYNTAX: CLASS:
scan-token
"<" expect
scan-token
"[" parse-tokens
\ ] parse-until define-objc-class ;
: (parse-selector) ( -- )
scan-token {
{ [ dup "[" = ] [ drop ] }
{ [ dup ":" tail? ] [ scan-c-type scan-token 3array , (parse-selector) ] }
[ f f 3array , "[" expect ]
} cond ;
: parse-selector ( -- selector types names )
[ (parse-selector) ] { } make
flip first3
[ concat ]
[ sift { id SEL } prepend ]
[ sift { "self" "selector" } prepend ] tri* ;
: parse-method-body ( names -- quot )
[ [ make-local ] map ] H{ } make-assoc
(parse-lambda) <lambda> ?rewrite-closures first ;
SYNTAX: METHOD:
scan-c-type
parse-selector
parse-method-body [ swap ] 2dip 4array
suffix! ;