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