Make mixins smarter, fix interactor

db4
Slava Pestov 2008-01-04 22:10:49 -04:00
parent c86e95bc30
commit 55efffed6c
12 changed files with 140 additions and 52 deletions

View File

@ -157,7 +157,7 @@ UNION: redefine-bug-2 redefine-bug-1 quotation ;
[ t ] [ quotation redefine-bug-2 class< ] unit-test [ t ] [ quotation redefine-bug-2 class< ] unit-test
[ redefine-bug-2 ] [ fixnum quotation class-or ] unit-test [ redefine-bug-2 ] [ fixnum quotation class-or ] unit-test
"IN: temporary USE: math UNION: redefine-bug-1 bignum ;" eval [ ] [ "IN: temporary USE: math UNION: redefine-bug-1 bignum ;" eval ] unit-test
[ t ] [ bignum redefine-bug-1 class< ] unit-test [ t ] [ bignum redefine-bug-1 class< ] unit-test
[ f ] [ fixnum redefine-bug-2 class< ] unit-test [ f ] [ fixnum redefine-bug-2 class< ] unit-test
@ -173,3 +173,35 @@ FORGET: forget-class-bug-1
FORGET: forget-class-bug-2 FORGET: forget-class-bug-2
[ t ] [ integer dll class-or interned? ] unit-test [ t ] [ integer dll class-or interned? ] unit-test
DEFER: mixin-forget-test-g
[ ] [
{
"USING: sequences ;"
"IN: temporary"
"MIXIN: mixin-forget-test"
"INSTANCE: sequence mixin-forget-test"
"GENERIC: mixin-forget-test-g ( x -- y )"
"M: mixin-forget-test mixin-forget-test-g ;"
} "\n" join <string-reader> "mixin-forget-test"
parse-stream drop
] unit-test
[ { } ] [ { } mixin-forget-test-g ] unit-test
[ H{ } mixin-forget-test-g ] unit-test-fails
[ ] [
{
"USING: hashtables ;"
"IN: temporary"
"MIXIN: mixin-forget-test"
"INSTANCE: hashtable mixin-forget-test"
"GENERIC: mixin-forget-test-g ( x -- y )"
"M: mixin-forget-test mixin-forget-test-g ;"
} "\n" join <string-reader> "mixin-forget-test"
parse-stream drop
] unit-test
[ { } mixin-forget-test-g ] unit-test-fails
[ H{ } ] [ H{ } mixin-forget-test-g ] unit-test

View File

@ -239,8 +239,6 @@ M: word uncache-class drop ;
: uncache-classes ( assoc -- ) : uncache-classes ( assoc -- )
[ drop uncache-class ] assoc-each ; [ drop uncache-class ] assoc-each ;
GENERIC: update-methods ( class -- )
PRIVATE> PRIVATE>
: define-class-props ( members superclass metaclass -- assoc ) : define-class-props ( members superclass metaclass -- assoc )
@ -265,7 +263,7 @@ PRIVATE>
uncache-classes uncache-classes
dupd (define-class) dupd (define-class)
] keep cache-classes ] keep cache-classes
r> [ update-methods ] [ drop ] if ; r> [ changed-class ] [ drop ] if ;
GENERIC: class ( object -- class ) inline GENERIC: class ( object -- class ) inline

54
core/classes/mixin/mixin.factor Normal file → Executable file
View File

@ -1,6 +1,7 @@
! Copyright (C) 2004, 2007 Slava Pestov. ! Copyright (C) 2004, 2007 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: classes classes.union words kernel sequences ; USING: classes classes.union words kernel sequences
definitions prettyprint.backend ;
IN: classes.mixin IN: classes.mixin
PREDICATE: union-class mixin-class "mixin" word-prop ; PREDICATE: union-class mixin-class "mixin" word-prop ;
@ -19,11 +20,48 @@ M: mixin-class reset-class
{ } redefine-mixin-class { } redefine-mixin-class
] if ; ] if ;
TUPLE: check-mixin-class mixin ;
: check-mixin-class ( mixin -- mixin )
dup mixin-class? [
\ check-mixin-class construct-boa throw
] unless ;
: if-mixin-member? ( class mixin true false -- )
>r >r check-mixin-class 2dup members memq? r> r> if ; inline
: change-mixin-class ( class mixin quot -- )
[ members swap bootstrap-word ] swap compose keep
swap redefine-mixin-class ; inline
: add-mixin-instance ( class mixin -- ) : add-mixin-instance ( class mixin -- )
dup mixin-class? [ "Not a mixin class" throw ] unless [ 2drop ] [ [ add ] change-mixin-class ] if-mixin-member? ;
2dup members memq? [
2drop : remove-mixin-instance ( class mixin -- )
] [ [ [ swap remove ] change-mixin-class ] [ 2drop ] if-mixin-member? ;
[ members swap bootstrap-word add ] keep swap
redefine-mixin-class ! Definition protocol implementation ensures that removing an
] if ; ! INSTANCE: declaration from a source file updates the mixin.
TUPLE: mixin-instance loc class mixin ;
: <mixin-instance> ( class mixin -- definition )
{ set-mixin-instance-class set-mixin-instance-mixin }
mixin-instance construct ;
M: mixin-instance where mixin-instance-loc ;
M: mixin-instance set-where set-mixin-instance-loc ;
M: mixin-instance synopsis*
\ INSTANCE: pprint-word
dup mixin-instance-class pprint-word
mixin-instance-mixin pprint-word ;
M: mixin-instance definer drop \ INSTANCE: f ;
M: mixin-instance definition drop f ;
M: mixin-instance forget
dup mixin-instance-class
swap mixin-instance-mixin
remove-mixin-instance ;

View File

@ -14,7 +14,7 @@ $nl
{ $subsection uses } { $subsection uses }
"When a definition is changed, all definitions which depend on it are notified via a hook:" "When a definition is changed, all definitions which depend on it are notified via a hook:"
{ $subsection redefined* } { $subsection redefined* }
"Definitions must implement a few operations used for printing them in human and computer-readable form:" "Definitions must implement a few operations used for printing them in source form:"
{ $subsection synopsis* } { $subsection synopsis* }
{ $subsection definer } { $subsection definer }
{ $subsection definition } ; { $subsection definition } ;

View File

@ -44,7 +44,10 @@ M: object redefined* drop ;
: delete-xref ( defspec -- ) : delete-xref ( defspec -- )
dup unxref crossref get delete-at ; dup unxref crossref get delete-at ;
GENERIC: update-methods ( class -- )
SYMBOL: changed-words SYMBOL: changed-words
SYMBOL: changed-classes
SYMBOL: old-definitions SYMBOL: old-definitions
SYMBOL: new-definitions SYMBOL: new-definitions
@ -91,12 +94,19 @@ TUPLE: no-compilation-unit word ;
[ no-compilation-unit ] unless* [ no-compilation-unit ] unless*
set-at ; set-at ;
: changed-class ( class -- )
dup changed-classes get
[ no-compilation-unit ] unless*
set-at ;
: with-compilation-unit ( quot -- ) : with-compilation-unit ( quot -- )
[ [
H{ } clone changed-words set H{ } clone changed-words set
H{ } clone changed-classes set
<definitions> new-definitions set <definitions> new-definitions set
<definitions> old-definitions set <definitions> old-definitions set
[ [
changed-classes get keys [ update-methods ] each
changed-words get keys recompile-hook get call changed-words get keys recompile-hook get call
] [ ] cleanup ] [ ] cleanup
] with-scope ; inline ] with-scope ; inline

View File

@ -148,7 +148,7 @@ unit-test
{ {
"USING: io kernel sequences words ;" "USING: io kernel sequences words ;"
"IN: temporary" "IN: temporary"
": retain-stack-layout" ": retain-stack-layout ( x -- )"
" dup stream-readln stream-readln" " dup stream-readln stream-readln"
" >r [ define ] map r>" " >r [ define ] map r>"
" define ;" " define ;"
@ -162,7 +162,7 @@ unit-test
{ {
"USING: kernel math sequences strings ;" "USING: kernel math sequences strings ;"
"IN: temporary" "IN: temporary"
": soft-break-layout" ": soft-break-layout ( x y -- ? )"
" over string? [" " over string? ["
" over hashcode over hashcode number=" " over hashcode over hashcode number="
" [ sequence= ] [ 2drop f ] if" " [ sequence= ] [ 2drop f ] if"
@ -204,7 +204,7 @@ unit-test
{ {
"USING: io kernel parser ;" "USING: io kernel parser ;"
"IN: temporary" "IN: temporary"
": string-layout-test" ": string-layout-test ( error -- )"
" \"Expected \" write dup unexpected-want expected>string write" " \"Expected \" write dup unexpected-want expected>string write"
" \" but got \" write unexpected-got expected>string print ;" " \" but got \" write unexpected-got expected>string print ;"
} ; } ;
@ -256,7 +256,7 @@ unit-test
: another-narrow-test : another-narrow-test
{ {
"IN: temporary" "IN: temporary"
": another-narrow-layout" ": another-narrow-layout ( -- obj )"
" H{" " H{"
" { 1 2 }" " { 1 2 }"
" { 3 4 }" " { 3 4 }"
@ -275,8 +275,10 @@ unit-test
: class-see-test : class-see-test
{ {
"IN: temporary" "IN: temporary"
"TUPLE: class-see-layout bar ;" "TUPLE: class-see-layout ;"
"GENERIC: class-see-layout" ""
"IN: temporary"
"GENERIC: class-see-layout ( x -- y )"
"" ""
"USING: temporary ;" "USING: temporary ;"
"M: class-see-layout class-see-layout ;" "M: class-see-layout class-see-layout ;"

View File

@ -249,14 +249,17 @@ M: word see-class* drop ;
M: builtin-class see-class* M: builtin-class see-class*
drop "! Built-in class" comment. ; drop "! Built-in class" comment. ;
: see-all ( seq -- ) natural-sort [ nl see ] each ; : see-all ( seq -- )
natural-sort [ nl see ] each ;
: see-implementors ( class -- seq ) : see-implementors ( class -- seq )
dup implementors [ 2array ] curry* map ; dup implementors [ 2array ] curry* map ;
: see-class ( class -- ) : see-class ( class -- )
dup class? [ dup class? [
dup seeing-word dup see-class* [
dup seeing-word dup see-class*
] with-use nl
] when drop ; ] when drop ;
: see-methods ( generic -- seq ) : see-methods ( generic -- seq )
@ -264,10 +267,13 @@ M: builtin-class see-class*
[ 2array ] curry map ; [ 2array ] curry map ;
M: word see M: word see
[ dup see-class
dup see-class dup class? over symbol? not and [
dup class? over symbol? and not [ dup (see) ] when nl
] with-use nl ] when
dup class? over symbol? and not [
[ dup (see) ] with-use nl
] when
[ [
dup class? [ dup see-implementors % ] when dup class? [ dup see-implementors % ] when
dup generic? [ dup see-methods % ] when dup generic? [ dup see-methods % ] when

View File

@ -134,7 +134,11 @@ IN: bootstrap.syntax
CREATE-CLASS define-mixin-class CREATE-CLASS define-mixin-class
] define-syntax ] define-syntax
"INSTANCE:" [ scan-word scan-word add-mixin-instance ] define-syntax "INSTANCE:" [
location >r
scan-word scan-word 2dup add-mixin-instance
<mixin-instance> r> remember-definition
] define-syntax
"PREDICATE:" [ "PREDICATE:" [
scan-word scan-word

View File

@ -115,7 +115,7 @@ drag-timer construct-empty drag-timer set-global
: start-drag-timer ( -- ) : start-drag-timer ( -- )
hand-buttons get-global empty? [ hand-buttons get-global empty? [
drag-timer get-global 100 100 add-timer drag-timer get-global 100 300 add-timer
] when ; ] when ;
: stop-drag-timer ( -- ) : stop-drag-timer ( -- )

View File

@ -11,9 +11,13 @@ IN: ui.tools.interactor
TUPLE: interactor TUPLE: interactor
history output history output
continuation quot busy? continuation quot busy?
use
help ; help ;
: interactor-use ( interactor -- seq )
use swap
interactor-continuation continuation-name
assoc-stack ;
: init-caret-help ( interactor -- ) : init-caret-help ( interactor -- )
dup editor-caret 100 <delay> swap set-interactor-help ; dup editor-caret 100 <delay> swap set-interactor-help ;
@ -67,11 +71,13 @@ M: interactor model-changed
t over set-interactor-busy? t over set-interactor-busy?
interactor-continuation schedule-thread-with ; interactor-continuation schedule-thread-with ;
: clear-input ( interactor -- ) gadget-model clear-doc ;
: interactor-finish ( interactor -- ) : interactor-finish ( interactor -- )
[ editor-string ] keep [ editor-string ] keep
[ interactor-input. ] 2keep [ interactor-input. ] 2keep
[ add-interactor-history ] keep [ add-interactor-history ] keep
gadget-model clear-doc ; clear-input ;
: interactor-eof ( interactor -- ) : interactor-eof ( interactor -- )
dup interactor-busy? [ dup interactor-busy? [
@ -108,9 +114,6 @@ M: interactor stream-read
M: interactor stream-read-partial M: interactor stream-read-partial
stream-read ; stream-read ;
: save-use ( interactor -- )
use get swap set-interactor-use ;
: go-to-error ( interactor error -- ) : go-to-error ( interactor error -- )
dup parse-error-line 1- swap parse-error-col 2array dup parse-error-line 1- swap parse-error-col 2array
over set-caret over set-caret
@ -122,7 +125,7 @@ M: interactor stream-read-partial
: try-parse ( lines interactor -- quot/error/f ) : try-parse ( lines interactor -- quot/error/f )
[ [
>r parse-lines-interactive r> save-use drop parse-lines-interactive
] [ ] [
>r f swap set-interactor-busy? drop r> >r f swap set-interactor-busy? drop r>
dup delegate unexpected-eof? [ drop f ] when dup delegate unexpected-eof? [ drop f ] when
@ -136,19 +139,18 @@ M: interactor stream-read-partial
} cond ; } cond ;
M: interactor stream-read-quot M: interactor stream-read-quot
[ save-use ] keep [ interactor-yield ] keep {
[ interactor-yield ] keep over quotation? [ { [ over not ] [ drop ] }
drop { [ over callable? ] [ drop ] }
] [ { [ t ] [
[ handle-interactive ] keep swap [ handle-interactive ] keep swap
[ interactor-finish ] [ nip stream-read-quot ] if [ interactor-finish ] [ nip stream-read-quot ] if
] if ; ] }
} cond ;
M: interactor pref-dim* M: interactor pref-dim*
0 over line-height 4 * 2array swap delegate pref-dim* vmax ; 0 over line-height 4 * 2array swap delegate pref-dim* vmax ;
: clear-input gadget-model clear-doc ;
interactor "interactor" f { interactor "interactor" f {
{ T{ key-down f f "RET" } evaluate-input } { T{ key-down f f "RET" } evaluate-input }
{ T{ key-down f { C+ } "k" } clear-input } { T{ key-down f { C+ } "k" } clear-input }

View File

@ -1,7 +1,7 @@
USING: continuations documents ui.tools.interactor USING: continuations documents ui.tools.interactor
ui.tools.listener hashtables kernel namespaces parser sequences ui.tools.listener hashtables kernel namespaces parser sequences
timers tools.test ui.commands ui.gadgets ui.gadgets.editors timers tools.test ui.commands ui.gadgets ui.gadgets.editors
ui.gadgets.panes vocabs words tools.test.ui ; ui.gadgets.panes vocabs words tools.test.ui slots.private ;
IN: temporary IN: temporary
timers [ init-timers ] unless timers [ init-timers ] unless
@ -13,16 +13,12 @@ timers [ init-timers ] unless
[ ] [ <listener-gadget> "listener" set ] unit-test [ ] [ <listener-gadget> "listener" set ] unit-test
"listener" get [ "listener" get [
{ "kernel" } [ vocab-words ] map
"listener" get listener-gadget-input set-interactor-use
[ "dup" ] [ \ dup "listener" get word-completion-string ] unit-test [ "dup" ] [ \ dup "listener" get word-completion-string ] unit-test
[ "USE: words word-name" ] [ "USE: slots.private slot" ]
[ \ word-name "listener" get word-completion-string ] unit-test [ \ slot "listener" get word-completion-string ] unit-test
<pane> <interactor> "i" set <pane> <interactor> "i" set
f "i" get set-interactor-use
[ t ] [ "i" get interactor? ] unit-test [ t ] [ "i" get interactor? ] unit-test

View File

@ -97,9 +97,9 @@ M: listener-operation invoke-command ( target command -- )
listener-gadget-input user-input ; listener-gadget-input user-input ;
: quot-action ( interactor -- lines ) : quot-action ( interactor -- lines )
dup control-value swap dup control-value
2dup add-interactor-history dup "\n" join pick add-interactor-history
select-all ; swap select-all ;
TUPLE: stack-display ; TUPLE: stack-display ;