Don't emit first engine in the sequence

db4
Slava Pestov 2008-04-17 03:07:17 -05:00
parent 91e516853a
commit deb51fbd00
2 changed files with 79 additions and 40 deletions

View File

@ -1,8 +1,11 @@
IN: generic.standard.engines.tuple ! Copyright (c) 2008 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
USING: kernel classes.tuple.private hashtables assocs sorting USING: kernel classes.tuple.private hashtables assocs sorting
accessors combinators sequences slots.private math.parser words accessors combinators sequences slots.private math.parser words
effects namespaces generic generic.standard.engines effects namespaces generic generic.standard.engines
classes.algebra math math.private quotations arrays ; classes.algebra math math.private kernel.private
quotations arrays ;
IN: generic.standard.engines.tuple
TUPLE: echelon-dispatch-engine n methods ; TUPLE: echelon-dispatch-engine n methods ;
@ -28,13 +31,13 @@ TUPLE: tuple-dispatch-engine echelons ;
: <tuple-dispatch-engine> ( methods -- engine ) : <tuple-dispatch-engine> ( methods -- engine )
echelon-sort echelon-sort
[ [
over zero? [ ! over zero? [
dup assoc-empty? ! dup assoc-empty?
[ drop f ] [ values first ] if ! [ drop f ] [ values first ] if
] [ ! ] [
dupd <echelon-dispatch-engine> dupd <echelon-dispatch-engine>
] if ! ] if
] assoc-map [ nip ] assoc-subset ] assoc-map ! [ nip ] assoc-subset
\ tuple-dispatch-engine boa ; \ tuple-dispatch-engine boa ;
: convert-tuple-methods ( assoc -- assoc' ) : convert-tuple-methods ( assoc -- assoc' )
@ -48,52 +51,51 @@ M: trivial-tuple-dispatch-engine engine>quot
>alist V{ } clone [ hashcode 1array ] distribute-buckets >alist V{ } clone [ hashcode 1array ] distribute-buckets
[ <trivial-tuple-dispatch-engine> ] map ; [ <trivial-tuple-dispatch-engine> ] map ;
: word-hashcode% [ 1 slot ] % ;
: class-hash-dispatch-quot ( methods -- quot ) : class-hash-dispatch-quot ( methods -- quot )
#! 1 slot == word hashcode
[ [
[ dup 1 slot ] % \ dup ,
word-hashcode%
hash-methods [ engine>quot ] map hash-dispatch-quot % hash-methods [ engine>quot ] map hash-dispatch-quot %
] [ ] make ; ] [ ] make ;
: tuple-dispatch-engine-word-name ( engine -- string ) : engine-word-name ( -- string )
[ generic get word-name "/tuple-dispatch-engine" append ;
generic get word-name %
"/tuple-dispatch-engine/" %
n>> #
] "" make ;
PREDICATE: tuple-dispatch-engine-word < word PREDICATE: engine-word < word
"tuple-dispatch-generic" word-prop generic? ; "tuple-dispatch-generic" word-prop generic? ;
M: tuple-dispatch-engine-word stack-effect M: engine-word stack-effect
"tuple-dispatch-generic" word-prop "tuple-dispatch-generic" word-prop
[ extra-values ] [ stack-effect ] bi [ extra-values ] [ stack-effect ] bi
dup [ clone [ length + ] change-in ] [ 2drop f ] if ; dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
M: tuple-dispatch-engine-word compiled-crossref? M: engine-word compiled-crossref?
drop t ; drop t ;
: remember-engine ( word -- ) : remember-engine ( word -- )
generic get "engines" word-prop push ; generic get "engines" word-prop push ;
: <tuple-dispatch-engine-word> ( engine -- word ) : <engine-word> ( -- word )
tuple-dispatch-engine-word-name f <word> engine-word-name f <word>
[ generic get "tuple-dispatch-generic" set-word-prop ] dup generic get "tuple-dispatch-generic" set-word-prop ;
[ remember-engine ]
[ ]
tri ;
: define-tuple-dispatch-engine-word ( engine quot -- word ) : define-engine-word ( quot -- word )
>r <tuple-dispatch-engine-word> dup r> define ; >r <engine-word> dup r> define ;
: array-nth% 2 + , [ slot { word } declare ] % ;
: tuple-layout-superclasses ( obj -- array )
{ tuple } declare
1 slot { tuple-layout } declare
4 slot { array } declare ; inline
: tuple-dispatch-engine-body ( engine -- quot ) : tuple-dispatch-engine-body ( engine -- quot )
#! 1 slot == tuple-layout
#! 2 slot == 0 array-nth
#! 4 slot == layout-superclasses
[ [
picker % picker %
[ 1 slot 4 slot ] % [ tuple-layout-superclasses ] %
[ n>> 2 + , [ slot ] % ] [ n>> array-nth% ]
[ [
methods>> [ methods>> [
<trivial-tuple-dispatch-engine> engine>quot <trivial-tuple-dispatch-engine> engine>quot
@ -104,25 +106,54 @@ M: tuple-dispatch-engine-word compiled-crossref?
] [ ] make ; ] [ ] make ;
M: echelon-dispatch-engine engine>quot M: echelon-dispatch-engine engine>quot
dup tuple-dispatch-engine-body dup n>> zero? [
define-tuple-dispatch-engine-word methods>> dup assoc-empty?
1quotation ; [ drop default get ] [ values first engine>quot ] if
] [
[
picker %
[ tuple-layout-superclasses ] %
[ n>> array-nth% ]
[
methods>> [
<trivial-tuple-dispatch-engine> engine>quot
] [
class-hash-dispatch-quot
] if-small? %
] bi
] [ ] make
] if ;
: >=-case-quot ( alist -- quot ) : >=-case-quot ( alist -- quot )
default get [ drop ] prepend swap default get [ drop ] prepend swap
[ >r [ dupd fixnum>= ] curry r> \ drop prefix ] assoc-map [ >r [ dupd fixnum>= ] curry r> \ drop prefix ] assoc-map
alist>quot ; alist>quot ;
: tuple-layout-echelon ( obj -- array )
{ tuple } declare
1 slot { tuple-layout } declare
5 slot ; inline
: unclip-last [ 1 head* ] [ peek ] bi ;
M: tuple-dispatch-engine engine>quot M: tuple-dispatch-engine engine>quot
#! 1 slot == tuple-layout
#! 5 slot == layout-echelon
[ [
picker % picker %
[ 1 slot 5 slot ] % [ tuple-layout-echelon ] %
echelons>>
[ [
tuple assumed set tuple assumed set
[ engine>quot dup default set ] assoc-map echelons>> dup empty? [
unclip-last
[
[
engine>quot define-engine-word
[ remember-engine ] [ 1quotation ] bi
dup default set
] assoc-map
]
[ first2 engine>quot 2array ] bi*
suffix
] unless
] with-scope ] with-scope
>=-case-quot % >=-case-quot %
] [ ] make ; ] [ ] make ;

View File

@ -251,6 +251,14 @@ HOOK: my-tuple-hook my-var ( -- x )
M: sequence my-tuple-hook my-hook ; M: sequence my-tuple-hook my-hook ;
TUPLE: m-t-h-a ;
M: m-t-h-a my-tuple-hook "foo" ;
TUPLE: m-t-h-b < m-t-h-a ;
M: m-t-h-b my-tuple-hook "bar" ;
[ f ] [ [ f ] [
\ my-tuple-hook [ "engines" word-prop ] keep prefix \ my-tuple-hook [ "engines" word-prop ] keep prefix
[ 1quotation infer ] map all-equal? [ 1quotation infer ] map all-equal?