factor/core/generic/standard/standard.factor

169 lines
4.4 KiB
Factor
Raw Normal View History

2008-02-17 01:37:54 -05:00
! Copyright (C) 2005, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: arrays assocs kernel kernel.private slots.private math
namespaces sequences vectors words quotations definitions
2008-02-11 02:19:53 -05:00
hashtables layouts combinators sequences.private generic
2008-04-02 03:44:10 -04:00
classes classes.algebra classes.private generic.standard.engines
generic.standard.engines.tag generic.standard.engines.predicate
generic.standard.engines.tuple accessors ;
2007-09-20 18:09:08 -04:00
IN: generic.standard
GENERIC: dispatch# ( word -- n )
M: word dispatch# "combination" word-prop dispatch# ;
2008-04-02 03:44:10 -04:00
: unpickers
2007-09-20 18:09:08 -04:00
{
2008-04-02 03:44:10 -04:00
[ nip ]
[ >r nip r> swap ]
[ >r >r nip r> r> -rot ]
} ; inline
2007-09-20 18:09:08 -04:00
: unpicker ( -- quot ) \ (dispatch#) get unpickers nth ;
2008-03-20 16:00:49 -04:00
ERROR: no-method object generic ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
: error-method ( word -- quot )
2007-09-20 18:09:08 -04:00
picker swap [ no-method ] curry append ;
: empty-method ( word -- quot )
2007-09-20 18:09:08 -04:00
[
picker % [ delegate dup ] %
unpicker over suffix ,
error-method \ drop prefix , \ if ,
2007-09-20 18:09:08 -04:00
] [ ] make ;
: default-method ( word -- pair )
"default-method" word-prop
object bootstrap-word swap 2array ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
: push-method ( method specializer atomic assoc -- )
2007-09-20 18:09:08 -04:00
[
2008-04-02 03:44:10 -04:00
[ H{ } clone <predicate-dispatch-engine> ] unless*
[ methods>> set-at ] keep
] change-at ;
: flatten-method ( class method assoc -- )
>r >r dup flatten-class keys swap r> r> [
>r spin r> push-method
] 3curry each ;
: flatten-methods ( assoc -- assoc' )
H{ } clone [
[
flatten-method
] curry assoc-each
] keep ;
: <big-dispatch-engine> ( assoc -- engine )
flatten-methods
convert-tuple-methods
convert-hi-tag-methods
<lo-tag-dispatch-engine> ;
: find-default ( methods -- quot )
#! Side-effects methods.
2008-04-02 19:50:21 -04:00
object bootstrap-word swap delete-at* [
2008-04-02 03:44:10 -04:00
drop generic get "default-method" word-prop 1quotation
] unless ;
GENERIC: mangle-method ( method generic -- quot )
2008-04-02 19:50:21 -04:00
: single-combination ( word -- quot )
2008-04-02 03:44:10 -04:00
[
2008-04-02 19:50:21 -04:00
object bootstrap-word assumed set {
[ generic set ]
[ "engines" word-prop forget-all ]
[ V{ } clone "engines" set-word-prop ]
2008-04-02 03:44:10 -04:00
[
2008-04-02 19:50:21 -04:00
"methods" word-prop
[ generic get mangle-method ] assoc-map
[ find-default default set ]
[
generic get "inline" word-prop [
<predicate-dispatch-engine>
] [
<big-dispatch-engine>
] if
] bi
engine>quot
]
} cleave
2008-04-02 03:44:10 -04:00
] with-scope ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
TUPLE: standard-combination # ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
C: <standard-combination> standard-combination
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
PREDICATE: standard-generic < generic
"combination" word-prop standard-combination? ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
PREDICATE: simple-generic < standard-generic
"combination" word-prop #>> zero? ;
2007-09-20 18:09:08 -04:00
2008-04-02 03:44:10 -04:00
: define-simple-generic ( word -- )
T{ standard-combination f 0 } define-generic ;
: with-standard ( combination quot -- quot' )
>r #>> (dispatch#) r> with-variable ; inline
2008-04-02 03:44:10 -04:00
M: standard-generic mangle-method
drop 1quotation ;
2007-09-20 18:09:08 -04:00
M: standard-combination make-default-method
2008-04-02 03:44:10 -04:00
[ empty-method ] with-standard ;
2007-09-20 18:09:08 -04:00
M: standard-combination perform-combination
2008-04-02 19:50:21 -04:00
[ drop ] [ [ single-combination ] with-standard ] 2bi define ;
2007-09-20 18:09:08 -04:00
M: standard-combination dispatch# #>> ;
ERROR: inconsistent-next-method object class generic ;
ERROR: no-next-method class generic ;
M: standard-generic next-method-quot
[
[
[ [ instance? ] curry ]
[ dispatch# (picker) ] bi* prepend %
]
[
2dup next-method
[ 2nip 1quotation ]
[ [ no-next-method ] 2curry ] if* ,
]
[ [ inconsistent-next-method ] 2curry , ]
2tri
2008-04-02 22:31:41 -04:00
\ if ,
] [ ] make ;
2007-09-20 18:09:08 -04:00
TUPLE: hook-combination var ;
C: <hook-combination> hook-combination
2008-04-02 03:44:10 -04:00
PREDICATE: hook-generic < generic
"combination" word-prop hook-combination? ;
: with-hook ( combination quot -- quot' )
2007-09-20 18:09:08 -04:00
0 (dispatch#) [
2008-04-02 03:44:10 -04:00
dip var>> [ get ] curry prepend
] with-variable ; inline
M: hook-combination dispatch# drop 0 ;
2008-04-02 03:44:10 -04:00
M: hook-generic mangle-method
drop 1quotation [ drop ] prepend ;
M: hook-combination make-default-method
[ error-method ] with-hook ;
M: hook-combination perform-combination
2008-04-02 19:50:21 -04:00
[ drop ] [ [ single-combination ] with-hook ] 2bi define ;
2007-09-20 18:09:08 -04:00
M: simple-generic definer drop \ GENERIC: f ;
2008-01-06 11:13:44 -05:00
M: standard-generic definer drop \ GENERIC# f ;
M: hook-generic definer drop \ HOOK: f ;