75 lines
2.1 KiB
Factor
Executable File
75 lines
2.1 KiB
Factor
Executable File
! Copyright (C) 2004, 2008 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: classes classes.union words kernel sequences
|
|
definitions combinators arrays ;
|
|
IN: classes.mixin
|
|
|
|
PREDICATE: union-class mixin-class "mixin" word-prop ;
|
|
|
|
M: mixin-class reset-class
|
|
{ "metaclass" "members" "mixin" } reset-props ;
|
|
|
|
: redefine-mixin-class ( class members -- )
|
|
dupd define-union-class
|
|
t "mixin" set-word-prop ;
|
|
|
|
: define-mixin-class ( class -- )
|
|
dup mixin-class? [
|
|
drop
|
|
] [
|
|
{ } redefine-mixin-class
|
|
] if ;
|
|
|
|
TUPLE: check-mixin-class mixin ;
|
|
|
|
: check-mixin-class ( mixin -- mixin )
|
|
dup mixin-class? [
|
|
\ check-mixin-class construct-boa throw
|
|
] unless ;
|
|
|
|
: if-mixin-member? ( class mixin true false -- )
|
|
>r >r check-mixin-class 2dup members memq? r> r> if ; inline
|
|
|
|
: change-mixin-class ( class mixin quot -- )
|
|
[ members swap bootstrap-word ] swap compose keep
|
|
swap redefine-mixin-class ; inline
|
|
|
|
: add-mixin-instance ( class mixin -- )
|
|
[ 2drop ] [ [ add ] change-mixin-class ] if-mixin-member? ;
|
|
|
|
: remove-mixin-instance ( class mixin -- )
|
|
[ [ swap remove ] change-mixin-class ] [ 2drop ] if-mixin-member? ;
|
|
|
|
! Definition protocol implementation ensures that removing an
|
|
! INSTANCE: declaration from a source file updates the mixin.
|
|
TUPLE: mixin-instance loc class mixin ;
|
|
|
|
M: mixin-instance equal?
|
|
{
|
|
{ [ over mixin-instance? not ] [ f ] }
|
|
{ [ 2dup [ mixin-instance-class ] 2apply = not ] [ f ] }
|
|
{ [ 2dup [ mixin-instance-mixin ] 2apply = not ] [ f ] }
|
|
{ [ t ] [ t ] }
|
|
} cond 2nip ;
|
|
|
|
M: mixin-instance hashcode*
|
|
{ mixin-instance-class mixin-instance-mixin } get-slots
|
|
2array hashcode* ;
|
|
|
|
: <mixin-instance> ( class mixin -- definition )
|
|
{ set-mixin-instance-class set-mixin-instance-mixin }
|
|
mixin-instance construct ;
|
|
|
|
M: mixin-instance where mixin-instance-loc ;
|
|
|
|
M: mixin-instance set-where set-mixin-instance-loc ;
|
|
|
|
M: mixin-instance definer drop \ INSTANCE: f ;
|
|
|
|
M: mixin-instance definition drop f ;
|
|
|
|
M: mixin-instance forget*
|
|
dup mixin-instance-class
|
|
swap mixin-instance-mixin dup mixin-class?
|
|
[ remove-mixin-instance ] [ 2drop ] if ;
|