]> gitweb.factorcode.org Git - factor.git/blob - extra/roles/roles.factor
Merge git://github.com/bogiebro/factor into bogiebro2
[factor.git] / extra / roles / roles.factor
1 ! (c)2009 Joe Groff bsd license
2 USING: accessors arrays classes classes.mixin classes.parser
3 classes.tuple classes.tuple.parser combinators
4 combinators.short-circuit kernel lexer make parser sequences
5 sets strings words ;
6 IN: roles
7
8 ERROR: role-slot-overlap class slots ;
9 ERROR: multiple-inheritance-attempted classes ;
10
11 PREDICATE: role < mixin-class
12     "role-slots" word-prop >boolean ;
13
14 : parse-role-definition ( -- class superroles slots )
15     CREATE-CLASS scan {
16         { ";" [ { } { } ] }
17         { "<" [ scan-word 1array [ parse-tuple-slots ] { } make ] }
18         { "<{" [ \ } parse-until >array [ parse-tuple-slots ] { } make ] }
19         [ { } swap [ parse-slot-name [ parse-tuple-slots ] when ] { } make ]
20     } case ;
21
22 : slot-name ( name/array -- name )
23     dup string? [ ] [ first ] if ;
24 : slot-names ( array -- names )
25     [ slot-name ] map ;
26
27 : role-slots ( role -- slots )
28     [ "superroles" word-prop [ role-slots ] map concat ]
29     [ "role-slots" word-prop ] bi append ;
30
31 : role-or-tuple-slot-names ( role-or-tuple -- names )
32     dup role?
33     [ role-slots slot-names ]
34     [ all-slots [ name>> ] map ] if ;
35
36 : check-for-slot-overlap ( class roles-and-superclass slots -- )
37     [ [ role-or-tuple-slot-names ] map concat ] [ slot-names ] bi* append
38     duplicates dup empty? [ 2drop ] [ role-slot-overlap ] if ;
39
40 : roles>slots ( roles-and-superclass slots -- superclass slots' )
41     [
42         [ role? ] partition
43         dup length {
44             { 0 [ drop tuple ] }
45             { 1 [ first ] }
46             [ drop multiple-inheritance-attempted ]
47         } case
48         swap [ role-slots ] map concat
49     ] dip append ;
50
51 : add-to-roles ( class roles -- )
52     [ add-mixin-instance ] with each ;
53
54 : (define-role) ( class superroles slots -- )
55     [ "superroles" set-word-prop ] [ "role-slots" set-word-prop ] bi-curry*
56     [ define-mixin-class ] tri ;
57
58 : define-role ( class superroles slots -- )
59     [ check-for-slot-overlap ] [ (define-role) ] [ drop add-to-roles ] 3tri ;
60
61 : define-tuple-class-with-roles ( class roles-and-superclass slots -- )
62     [ check-for-slot-overlap ]
63     [ roles>slots define-tuple-class ]
64     [ drop [ role? ] filter add-to-roles ] 3tri ;
65
66 SYNTAX: ROLE: parse-role-definition define-role ;
67 SYNTAX: TUPLE: parse-role-definition define-tuple-class-with-roles ;
68
69