1 ! Copyright (C) 2005, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays kernel kernel.private math namespaces
4 sequences strings words effects generic generic.standard
5 classes slots.private combinators accessors ;
8 TUPLE: slot-spec type name offset reader writer ;
10 C: <slot-spec> slot-spec
12 : define-typecheck ( class generic quot -- )
14 dup define-simple-generic
18 : define-slot-word ( class slot word quot -- )
19 rot >fixnum prefix define-typecheck ;
21 : reader-quot ( decl -- quot )
24 dup object bootstrap-word eq?
25 [ drop ] [ 1array , \ declare , ] if
28 : create-accessor ( name effect -- word )
29 >r "accessors" create dup r>
30 "declared-effect" set-word-prop ;
32 : reader-word ( name -- word )
33 ">>" append (( object -- value )) create-accessor ;
35 : define-reader ( class slot name decl -- )
36 [ reader-word ] dip reader-quot define-slot-word ;
38 : writer-word ( name -- word )
39 "(>>" swap ")" 3append (( value object -- )) create-accessor ;
41 ERROR: bad-slot-value value object index ;
43 : writer-quot ( decl -- quot )
45 dup object bootstrap-word eq?
46 [ drop \ set-slot , ] [
48 "predicate" word-prop %
49 [ [ set-slot ] [ bad-slot-value ] if ] %
53 : define-writer ( class slot name decl -- )
54 [ writer-word ] dip writer-quot define-slot-word ;
56 : setter-word ( name -- word )
57 ">>" prepend (( object value -- object )) create-accessor ;
59 : define-setter ( name -- )
60 dup setter-word dup deferred? [
61 [ \ over , swap writer-word , ] [ ] make define-inline
64 : changer-word ( name -- word )
65 "change-" prepend (( object quot -- object )) create-accessor ;
67 : define-changer ( name -- )
68 dup changer-word dup deferred? [
74 ] [ ] make define-inline
77 : define-slot-methods ( class slot-spec -- )
79 [ [ drop ] [ name>> ] bi* define-changer ]
80 [ [ drop ] [ name>> ] bi* define-setter ]
81 [ [ offset>> ] [ name>> ] [ type>> ] tri define-reader ]
82 [ [ offset>> ] [ name>> ] [ type>> ] tri define-writer ]
85 : define-accessors ( class specs -- )
86 [ define-slot-methods ] with each ;
88 : slot-named ( name specs -- spec/f )
89 [ slot-spec-name = ] with find nip ;