Merge branch 'master' of git://factorcode.org/git/factor
commit
c89295e520
|
@ -20,6 +20,10 @@ ERROR: not-a-tuple object ;
|
||||||
: all-slots ( class -- slots )
|
: all-slots ( class -- slots )
|
||||||
superclasses [ "slots" word-prop ] map concat ;
|
superclasses [ "slots" word-prop ] map concat ;
|
||||||
|
|
||||||
|
PREDICATE: immutable-tuple-class < tuple-class ( class -- ? )
|
||||||
|
#! Delegation
|
||||||
|
all-slots rest-slice [ read-only>> ] all? ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: tuple-layout ( class -- layout )
|
: tuple-layout ( class -- layout )
|
||||||
|
|
|
@ -165,13 +165,9 @@ GENERIC: boa ( ... class -- tuple )
|
||||||
compose compose ; inline
|
compose compose ; inline
|
||||||
|
|
||||||
! Booleans
|
! Booleans
|
||||||
: not ( obj -- ? )
|
: not ( obj -- ? ) f t ? ; inline
|
||||||
#! Not inline because its special-cased by compiler.
|
|
||||||
f eq? ;
|
|
||||||
|
|
||||||
: and ( obj1 obj2 -- ? )
|
: and ( obj1 obj2 -- ? ) over ? ; inline
|
||||||
#! Not inline because its special-cased by compiler.
|
|
||||||
over ? ;
|
|
||||||
|
|
||||||
: >boolean ( obj -- ? ) t f ? ; inline
|
: >boolean ( obj -- ? ) t f ? ; inline
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,9 @@ TUPLE: interval { from read-only } { to read-only } ;
|
||||||
]
|
]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
: intervals-intersect? ( i1 i2 -- ? )
|
||||||
|
interval-intersect empty-interval eq? not ;
|
||||||
|
|
||||||
: interval-union ( i1 i2 -- i3 )
|
: interval-union ( i1 i2 -- i3 )
|
||||||
{
|
{
|
||||||
{ [ dup empty-interval eq? ] [ drop ] }
|
{ [ dup empty-interval eq? ] [ drop ] }
|
||||||
|
|
|
@ -8,13 +8,17 @@ IN: slots
|
||||||
|
|
||||||
TUPLE: slot-spec name offset class initial read-only reader writer ;
|
TUPLE: slot-spec name offset class initial read-only reader writer ;
|
||||||
|
|
||||||
|
PREDICATE: reader < word "reader" word-prop ;
|
||||||
|
|
||||||
|
PREDICATE: writer < word "writer" word-prop ;
|
||||||
|
|
||||||
: <slot-spec> ( -- slot-spec )
|
: <slot-spec> ( -- slot-spec )
|
||||||
slot-spec new
|
slot-spec new
|
||||||
object bootstrap-word >>class ;
|
object bootstrap-word >>class ;
|
||||||
|
|
||||||
: define-typecheck ( class generic quot props -- )
|
: define-typecheck ( class generic quot props -- )
|
||||||
[ dup define-simple-generic create-method ] 2dip
|
[ dup define-simple-generic create-method ] 2dip
|
||||||
[ [ props>> ] [ drop ] [ [ t ] H{ } map>assoc ] tri* update ]
|
[ [ props>> ] [ drop ] [ ] tri* update ]
|
||||||
[ drop define ]
|
[ drop define ]
|
||||||
3bi ;
|
3bi ;
|
||||||
|
|
||||||
|
@ -31,17 +35,23 @@ TUPLE: slot-spec name offset class initial read-only reader writer ;
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
: reader-word ( name -- word )
|
: reader-word ( name -- word )
|
||||||
">>" append (( object -- value )) create-accessor ;
|
">>" append (( object -- value )) create-accessor
|
||||||
|
dup t "reader" set-word-prop ;
|
||||||
|
|
||||||
: reader-props ( slot-spec -- seq )
|
: reader-props ( slot-spec -- assoc )
|
||||||
read-only>> { "foldable" "flushable" } { "flushable" } ? ;
|
[
|
||||||
|
[ "reading" set ]
|
||||||
|
[ read-only>> [ t "foldable" set ] when ] bi
|
||||||
|
t "flushable" set
|
||||||
|
] H{ } make-assoc ;
|
||||||
|
|
||||||
: define-reader ( class slot-spec -- )
|
: define-reader ( class slot-spec -- )
|
||||||
[ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
|
[ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
|
||||||
define-typecheck ;
|
define-typecheck ;
|
||||||
|
|
||||||
: writer-word ( name -- word )
|
: writer-word ( name -- word )
|
||||||
"(>>" swap ")" 3append (( value object -- )) create-accessor ;
|
"(>>" swap ")" 3append (( value object -- )) create-accessor
|
||||||
|
dup t "writer" set-word-prop ;
|
||||||
|
|
||||||
ERROR: bad-slot-value value class ;
|
ERROR: bad-slot-value value class ;
|
||||||
|
|
||||||
|
@ -77,8 +87,12 @@ ERROR: bad-slot-value value class ;
|
||||||
} cond
|
} cond
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
|
: writer-props ( slot-spec -- assoc )
|
||||||
|
[ "writing" set ] H{ } make-assoc ;
|
||||||
|
|
||||||
: define-writer ( class slot-spec -- )
|
: define-writer ( class slot-spec -- )
|
||||||
[ name>> writer-word ] [ writer-quot ] bi { } define-typecheck ;
|
[ name>> writer-word ] [ writer-quot ] [ writer-props ] tri
|
||||||
|
define-typecheck ;
|
||||||
|
|
||||||
: setter-word ( name -- word )
|
: setter-word ( name -- word )
|
||||||
">>" prepend (( object value -- object )) create-accessor ;
|
">>" prepend (( object value -- object )) create-accessor ;
|
||||||
|
|
|
@ -187,6 +187,7 @@ M: word reset-word
|
||||||
"parsing" "inline" "recursive" "foldable" "flushable"
|
"parsing" "inline" "recursive" "foldable" "flushable"
|
||||||
"predicating"
|
"predicating"
|
||||||
"reading" "writing"
|
"reading" "writing"
|
||||||
|
"reader" "writer"
|
||||||
"constructing"
|
"constructing"
|
||||||
"declared-effect" "constructor-quot" "delimiter"
|
"declared-effect" "constructor-quot" "delimiter"
|
||||||
} reset-props ;
|
} reset-props ;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! 24, the Factor game!
|
! 24, the Factor game!
|
||||||
|
|
||||||
USING: kernel random namespaces shuffle sequences
|
USING: kernel random namespaces shuffle sequences
|
||||||
parser io math prettyprint combinators
|
parser io math prettyprint combinators continuations
|
||||||
vectors words quotations accessors math.parser
|
vectors words quotations accessors math.parser
|
||||||
backtrack math.ranges locals fry memoize macros assocs ;
|
backtrack math.ranges locals fry memoize macros assocs ;
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ M: object run-pipeline-element
|
||||||
[ |dispose drop ]
|
[ |dispose drop ]
|
||||||
[
|
[
|
||||||
swap >process
|
swap >process
|
||||||
[ swap in>> or ] change-stdout
|
[ swap in>> or ] change-stdin
|
||||||
run-detached
|
run-detached
|
||||||
]
|
]
|
||||||
[ in>> dispose ]
|
[ in>> dispose ]
|
||||||
|
@ -200,8 +200,8 @@ M: object run-pipeline-element
|
||||||
[ [ |dispose drop ] bi@ ]
|
[ [ |dispose drop ] bi@ ]
|
||||||
[
|
[
|
||||||
rot >process
|
rot >process
|
||||||
[ swap out>> or ] change-stdout
|
|
||||||
[ swap in>> or ] change-stdin
|
[ swap in>> or ] change-stdin
|
||||||
|
[ swap out>> or ] change-stdout
|
||||||
run-detached
|
run-detached
|
||||||
]
|
]
|
||||||
[ [ out>> dispose ] [ in>> dispose ] bi* ]
|
[ [ out>> dispose ] [ in>> dispose ] bi* ]
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
IN: io.unix.launcher.tests
|
IN: io.unix.launcher.tests
|
||||||
USING: io.files tools.test io.launcher arrays io namespaces
|
USING: io.files tools.test io.launcher arrays io namespaces
|
||||||
continuations math io.encodings.binary io.encodings.ascii
|
continuations math io.encodings.binary io.encodings.ascii
|
||||||
accessors kernel sequences io.encodings.utf8 destructors ;
|
accessors kernel sequences io.encodings.utf8 destructors
|
||||||
|
io.streams.duplex ;
|
||||||
|
|
||||||
[ ] [
|
[ ] [
|
||||||
[ "launcher-test-1" temp-file delete-file ] ignore-errors
|
[ "launcher-test-1" temp-file delete-file ] ignore-errors
|
||||||
|
@ -111,4 +112,12 @@ accessors kernel sequences io.encodings.utf8 destructors ;
|
||||||
"append-test" temp-file utf8 file-contents
|
"append-test" temp-file utf8 file-contents
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ ] [ "ls" utf8 <process-stream> contents drop ] unit-test
|
[ t ] [ "ls" utf8 <process-stream> contents >boolean ] unit-test
|
||||||
|
|
||||||
|
[ "Hello world.\n" ] [
|
||||||
|
"cat" utf8 <process-stream> [
|
||||||
|
"Hello world.\n" write
|
||||||
|
output-stream get dispose
|
||||||
|
input-stream get contents
|
||||||
|
] with-stream
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -50,7 +50,6 @@ DEFER: expansion
|
||||||
METHOD: expand { back-quoted-expr }
|
METHOD: expand { back-quoted-expr }
|
||||||
expr>>
|
expr>>
|
||||||
expr
|
expr
|
||||||
ast>>
|
|
||||||
command>>
|
command>>
|
||||||
expansion
|
expansion
|
||||||
utf8 <process-stream>
|
utf8 <process-stream>
|
||||||
|
@ -122,7 +121,7 @@ DEFER: shell
|
||||||
{ [ dup f = ] [ drop ] }
|
{ [ dup f = ] [ drop ] }
|
||||||
{ [ dup "exit" = ] [ drop ] }
|
{ [ dup "exit" = ] [ drop ] }
|
||||||
{ [ dup "" = ] [ drop shell ] }
|
{ [ dup "" = ] [ drop shell ] }
|
||||||
{ [ dup expr ] [ expr ast>> chant shell ] }
|
{ [ dup expr ] [ expr chant shell ] }
|
||||||
{ [ t ] [ drop "ix: ignoring input" print shell ] }
|
{ [ t ] [ drop "ix: ignoring input" print shell ] }
|
||||||
}
|
}
|
||||||
cond ;
|
cond ;
|
||||||
|
|
|
@ -12,9 +12,9 @@ TUPLE: labelled-gadget < track content ;
|
||||||
|
|
||||||
: <labelled-gadget> ( gadget title -- newgadget )
|
: <labelled-gadget> ( gadget title -- newgadget )
|
||||||
{ 0 1 } labelled-gadget new-track
|
{ 0 1 } labelled-gadget new-track
|
||||||
swap <label> reverse-video-theme f track-add*
|
swap <label> reverse-video-theme f track-add
|
||||||
swap >>content
|
swap >>content
|
||||||
dup content>> 1 track-add* ;
|
dup content>> 1 track-add ;
|
||||||
|
|
||||||
M: labelled-gadget focusable-child* labelled-gadget-content ;
|
M: labelled-gadget focusable-child* labelled-gadget-content ;
|
||||||
|
|
||||||
|
|
|
@ -65,10 +65,10 @@ M: f >label drop <gadget> ;
|
||||||
|
|
||||||
: label-on-left ( gadget label -- button )
|
: label-on-left ( gadget label -- button )
|
||||||
{ 1 0 } <track>
|
{ 1 0 } <track>
|
||||||
swap >label f track-add*
|
swap >label f track-add
|
||||||
swap 1 track-add* ;
|
swap 1 track-add ;
|
||||||
|
|
||||||
: label-on-right ( label gadget -- button )
|
: label-on-right ( label gadget -- button )
|
||||||
{ 1 0 } <track>
|
{ 1 0 } <track>
|
||||||
swap f track-add*
|
swap f track-add
|
||||||
swap >label 1 track-add* ;
|
swap >label 1 track-add ;
|
||||||
|
|
|
@ -71,9 +71,9 @@ M: value-ref finish-editing
|
||||||
: <slot-editor> ( ref -- gadget )
|
: <slot-editor> ( ref -- gadget )
|
||||||
{ 0 1 } slot-editor new-track
|
{ 0 1 } slot-editor new-track
|
||||||
swap >>ref
|
swap >>ref
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
<source-editor> >>text
|
<source-editor> >>text
|
||||||
dup text>> <scroller> 1 track-add*
|
dup text>> <scroller> 1 track-add
|
||||||
dup revert ;
|
dup revert ;
|
||||||
|
|
||||||
M: slot-editor pref-dim* call-next-method { 600 200 } vmin ;
|
M: slot-editor pref-dim* call-next-method { 600 200 } vmin ;
|
||||||
|
@ -97,8 +97,8 @@ TUPLE: editable-slot < track printer ref ;
|
||||||
|
|
||||||
: display-slot ( gadget editable-slot -- )
|
: display-slot ( gadget editable-slot -- )
|
||||||
dup clear-track
|
dup clear-track
|
||||||
swap 1 track-add*
|
swap 1 track-add
|
||||||
<edit-button> f track-add*
|
<edit-button> f track-add
|
||||||
drop ;
|
drop ;
|
||||||
|
|
||||||
: update-slot ( editable-slot -- )
|
: update-slot ( editable-slot -- )
|
||||||
|
@ -109,7 +109,7 @@ TUPLE: editable-slot < track printer ref ;
|
||||||
[ clear-track ]
|
[ clear-track ]
|
||||||
[
|
[
|
||||||
dup ref>> <slot-editor>
|
dup ref>> <slot-editor>
|
||||||
[ 1 track-add* drop ]
|
[ 1 track-add drop ]
|
||||||
[ [ scroll>gadget ] [ request-focus ] bi* ] 2bi
|
[ [ scroll>gadget ] [ request-focus ] bi* ] 2bi
|
||||||
] bi ;
|
] bi ;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ IN: ui.gadgets.status-bar
|
||||||
|
|
||||||
: open-status-window ( gadget title -- )
|
: open-status-window ( gadget title -- )
|
||||||
f <model> [ <world> ] keep
|
f <model> [ <world> ] keep
|
||||||
<status-bar> f track-add*
|
<status-bar> f track-add
|
||||||
open-world-window ;
|
open-world-window ;
|
||||||
|
|
||||||
: show-summary ( object gadget -- )
|
: show-summary ( object gadget -- )
|
||||||
|
|
|
@ -38,7 +38,7 @@ TUPLE: tiling < track gadgets tiles first focused ;
|
||||||
|
|
||||||
: tiling-map-gadgets ( tiling -- tiling )
|
: tiling-map-gadgets ( tiling -- tiling )
|
||||||
dup clear-track
|
dup clear-track
|
||||||
dup tiling-gadgets-to-map [ 1 track-add* ] each ;
|
dup tiling-gadgets-to-map [ 1 track-add ] each ;
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ ARTICLE: "ui-track-layout" "Track layouts"
|
||||||
"Creating empty tracks:"
|
"Creating empty tracks:"
|
||||||
{ $subsection <track> }
|
{ $subsection <track> }
|
||||||
"Adding children:"
|
"Adding children:"
|
||||||
{ $subsection track-add* } ;
|
{ $subsection track-add } ;
|
||||||
|
|
||||||
HELP: track
|
HELP: track
|
||||||
{ $class-description "A track is like a " { $link pack } " except each child is resized to a fixed multiple of the track's dimension in the direction of " { $link gadget-orientation } ". Tracks are created by calling " { $link <track> } "." } ;
|
{ $class-description "A track is like a " { $link pack } " except each child is resized to a fixed multiple of the track's dimension in the direction of " { $link gadget-orientation } ". Tracks are created by calling " { $link <track> } "." } ;
|
||||||
|
@ -17,7 +17,7 @@ HELP: <track>
|
||||||
{ $values { "orientation" "an orientation specifier" } { "track" "a new " { $link track } } }
|
{ $values { "orientation" "an orientation specifier" } { "track" "a new " { $link track } } }
|
||||||
{ $description "Creates a new track which lays out children along the given axis. Children are laid out vertically if the orientation is " { $snippet "{ 0 1 }" } " and horizontally if the orientation is " { $snippet "{ 1 0 }" } "." } ;
|
{ $description "Creates a new track which lays out children along the given axis. Children are laid out vertically if the orientation is " { $snippet "{ 0 1 }" } " and horizontally if the orientation is " { $snippet "{ 1 0 }" } "." } ;
|
||||||
|
|
||||||
HELP: track-add*
|
HELP: track-add
|
||||||
{ $values { "gadget" gadget } { "track" track } { "constraint" "a number between 0 and 1, or " { $link f } } }
|
{ $values { "gadget" gadget } { "track" track } { "constraint" "a number between 0 and 1, or " { $link f } } }
|
||||||
{ $description "Adds a new child to a track. If the constraint is " { $link f } ", the child always occupies its preferred size. Otherwise, the constrant is a fraction of the total size which is allocated for the child." } ;
|
{ $description "Adds a new child to a track. If the constraint is " { $link f } ", the child always occupies its preferred size. Otherwise, the constrant is a fraction of the total size which is allocated for the child." } ;
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ IN: ui.gadgets.tracks.tests
|
||||||
|
|
||||||
[ { 100 100 } ] [
|
[ { 100 100 } ] [
|
||||||
{ 0 1 } <track>
|
{ 0 1 } <track>
|
||||||
<gadget> { 100 100 } >>dim 1 track-add*
|
<gadget> { 100 100 } >>dim 1 track-add
|
||||||
pref-dim
|
pref-dim
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ { 100 110 } ] [
|
[ { 100 110 } ] [
|
||||||
{ 0 1 } <track>
|
{ 0 1 } <track>
|
||||||
<gadget> { 10 10 } >>dim f track-add*
|
<gadget> { 10 10 } >>dim f track-add
|
||||||
<gadget> { 100 100 } >>dim 1 track-add*
|
<gadget> { 100 100 } >>dim 1 track-add
|
||||||
pref-dim
|
pref-dim
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
|
@ -50,7 +50,7 @@ M: track pref-dim* ( gadget -- dim )
|
||||||
tri
|
tri
|
||||||
set-axis ;
|
set-axis ;
|
||||||
|
|
||||||
: track-add* ( track gadget constraint -- track )
|
: track-add ( track gadget constraint -- track )
|
||||||
pick sizes>> push add-gadget ;
|
pick sizes>> push add-gadget ;
|
||||||
|
|
||||||
: track-remove ( track gadget -- track )
|
: track-remove ( track gadget -- track )
|
||||||
|
|
|
@ -40,7 +40,7 @@ M: world request-focus-on ( child gadget -- )
|
||||||
{ 0 0 } >>window-loc
|
{ 0 0 } >>window-loc
|
||||||
swap >>status
|
swap >>status
|
||||||
swap >>title
|
swap >>title
|
||||||
swap 1 track-add*
|
swap 1 track-add
|
||||||
dup request-focus ;
|
dup request-focus ;
|
||||||
|
|
||||||
M: world layout*
|
M: world layout*
|
||||||
|
|
|
@ -22,9 +22,9 @@ TUPLE: browser-gadget < track pane history ;
|
||||||
: <browser-gadget> ( -- gadget )
|
: <browser-gadget> ( -- gadget )
|
||||||
{ 0 1 } browser-gadget new-track
|
{ 0 1 } browser-gadget new-track
|
||||||
dup init-history
|
dup init-history
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
dup <help-pane> >>pane
|
dup <help-pane> >>pane
|
||||||
dup pane>> <scroller> 1 track-add* ;
|
dup pane>> <scroller> 1 track-add ;
|
||||||
|
|
||||||
M: browser-gadget call-tool* show-help ;
|
M: browser-gadget call-tool* show-help ;
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ TUPLE: debugger < track restarts ;
|
||||||
|
|
||||||
: <debugger> ( error restarts restart-hook -- gadget )
|
: <debugger> ( error restarts restart-hook -- gadget )
|
||||||
{ 0 1 } debugger new-track
|
{ 0 1 } debugger new-track
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
-rot <restart-list> >>restarts
|
-rot <restart-list> >>restarts
|
||||||
dup restarts>> rot <debugger-display> <scroller> 1 track-add* ;
|
dup restarts>> rot <debugger-display> <scroller> 1 track-add ;
|
||||||
|
|
||||||
M: debugger focusable-child* debugger-restarts ;
|
M: debugger focusable-child* debugger-restarts ;
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ TUPLE: inspector-gadget < track object pane ;
|
||||||
|
|
||||||
: <inspector-gadget> ( -- gadget )
|
: <inspector-gadget> ( -- gadget )
|
||||||
{ 0 1 } inspector-gadget new-track
|
{ 0 1 } inspector-gadget new-track
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
<pane> >>pane
|
<pane> >>pane
|
||||||
dup pane>> <scroller> 1 track-add* ;
|
dup pane>> <scroller> 1 track-add ;
|
||||||
|
|
||||||
: inspect-object ( obj mirror keys inspector -- )
|
: inspect-object ( obj mirror keys inspector -- )
|
||||||
2nip swap >>object refresh ;
|
2nip swap >>object refresh ;
|
||||||
|
|
|
@ -14,7 +14,7 @@ TUPLE: listener-gadget < track input output stack ;
|
||||||
|
|
||||||
: listener-output, ( listener -- listener )
|
: listener-output, ( listener -- listener )
|
||||||
<scrolling-pane> >>output
|
<scrolling-pane> >>output
|
||||||
dup output>> <scroller> "Output" <labelled-gadget> 1 track-add* ;
|
dup output>> <scroller> "Output" <labelled-gadget> 1 track-add ;
|
||||||
|
|
||||||
: listener-streams ( listener -- input output )
|
: listener-streams ( listener -- input output )
|
||||||
[ input>> ] [ output>> <pane-stream> ] bi ;
|
[ input>> ] [ output>> <pane-stream> ] bi ;
|
||||||
|
@ -27,7 +27,7 @@ TUPLE: listener-gadget < track input output stack ;
|
||||||
dup input>>
|
dup input>>
|
||||||
{ 0 100 } <limited-scroller>
|
{ 0 100 } <limited-scroller>
|
||||||
"Input" <labelled-gadget>
|
"Input" <labelled-gadget>
|
||||||
f track-add* ;
|
f track-add ;
|
||||||
|
|
||||||
: welcome. ( -- )
|
: welcome. ( -- )
|
||||||
"If this is your first time with Factor, please read the " print
|
"If this is your first time with Factor, please read the " print
|
||||||
|
@ -125,10 +125,10 @@ TUPLE: stack-display < track ;
|
||||||
: <stack-display> ( workspace -- gadget )
|
: <stack-display> ( workspace -- gadget )
|
||||||
listener>>
|
listener>>
|
||||||
{ 0 1 } stack-display new-track
|
{ 0 1 } stack-display new-track
|
||||||
over <toolbar> f track-add*
|
over <toolbar> f track-add
|
||||||
swap
|
swap
|
||||||
stack>> [ [ stack. ] curry try ] t "Data stack" <labelled-pane>
|
stack>> [ [ stack. ] curry try ] t "Data stack" <labelled-pane>
|
||||||
1 track-add* ;
|
1 track-add ;
|
||||||
|
|
||||||
M: stack-display tool-scroller
|
M: stack-display tool-scroller
|
||||||
find-workspace workspace-listener tool-scroller ;
|
find-workspace workspace-listener tool-scroller ;
|
||||||
|
|
|
@ -9,9 +9,9 @@ TUPLE: profiler-gadget < track pane ;
|
||||||
|
|
||||||
: <profiler-gadget> ( -- gadget )
|
: <profiler-gadget> ( -- gadget )
|
||||||
{ 0 1 } profiler-gadget new-track
|
{ 0 1 } profiler-gadget new-track
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
<pane> >>pane
|
<pane> >>pane
|
||||||
dup pane>> <scroller> 1 track-add* ;
|
dup pane>> <scroller> 1 track-add ;
|
||||||
|
|
||||||
: with-profiler-pane ( gadget quot -- )
|
: with-profiler-pane ( gadget quot -- )
|
||||||
>r profiler-gadget-pane r> with-pane ;
|
>r profiler-gadget-pane r> with-pane ;
|
||||||
|
|
|
@ -62,9 +62,9 @@ search-field H{
|
||||||
: <live-search> ( string seq limited? presenter -- gadget )
|
: <live-search> ( string seq limited? presenter -- gadget )
|
||||||
{ 0 1 } live-search new-track
|
{ 0 1 } live-search new-track
|
||||||
<search-field> >>field
|
<search-field> >>field
|
||||||
dup field>> f track-add*
|
dup field>> f track-add
|
||||||
-roll <search-list> >>list
|
-roll <search-list> >>list
|
||||||
dup list>> <scroller> 1 track-add*
|
dup list>> <scroller> 1 track-add
|
||||||
|
|
||||||
swap
|
swap
|
||||||
over field>> set-editor-string
|
over field>> set-editor-string
|
||||||
|
|
|
@ -38,10 +38,10 @@ IN: ui.tools
|
||||||
<listener-gadget> >>listener
|
<listener-gadget> >>listener
|
||||||
dup <workspace-book> >>book
|
dup <workspace-book> >>book
|
||||||
|
|
||||||
dup <workspace-tabs> f track-add*
|
dup <workspace-tabs> f track-add
|
||||||
dup book>> 1/5 track-add*
|
dup book>> 1/5 track-add
|
||||||
dup listener>> 4/5 track-add*
|
dup listener>> 4/5 track-add
|
||||||
dup <toolbar> f track-add* ;
|
dup <toolbar> f track-add ;
|
||||||
|
|
||||||
: resize-workspace ( workspace -- )
|
: resize-workspace ( workspace -- )
|
||||||
dup track-sizes over control-value zero? [
|
dup track-sizes over control-value zero? [
|
||||||
|
|
|
@ -30,13 +30,13 @@ M: traceback-gadget pref-dim* drop { 550 600 } ;
|
||||||
|
|
||||||
dup model>>
|
dup model>>
|
||||||
{ 1 0 } <track>
|
{ 1 0 } <track>
|
||||||
over <datastack-display> 1/2 track-add*
|
over <datastack-display> 1/2 track-add
|
||||||
swap <retainstack-display> 1/2 track-add*
|
swap <retainstack-display> 1/2 track-add
|
||||||
1/3 track-add*
|
1/3 track-add
|
||||||
|
|
||||||
dup model>> <callstack-display> 2/3 track-add*
|
dup model>> <callstack-display> 2/3 track-add
|
||||||
|
|
||||||
dup <toolbar> f track-add* ;
|
dup <toolbar> f track-add ;
|
||||||
|
|
||||||
: <namestack-display> ( model -- gadget )
|
: <namestack-display> ( model -- gadget )
|
||||||
[ [ continuation-name namestack. ] when* ]
|
[ [ continuation-name namestack. ] when* ]
|
||||||
|
|
|
@ -62,9 +62,9 @@ M: walker-gadget focusable-child*
|
||||||
swap >>status
|
swap >>status
|
||||||
dup continuation>> <traceback-gadget> >>traceback
|
dup continuation>> <traceback-gadget> >>traceback
|
||||||
|
|
||||||
dup <toolbar> f track-add*
|
dup <toolbar> f track-add
|
||||||
dup status>> self <thread-status> f track-add*
|
dup status>> self <thread-status> f track-add
|
||||||
dup traceback>> 1 track-add* ;
|
dup traceback>> 1 track-add ;
|
||||||
|
|
||||||
: walker-help ( -- ) "ui-walker" help-window ;
|
: walker-help ( -- ) "ui-walker" help-window ;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ M: gadget tool-scroller drop f ;
|
||||||
: show-popup ( gadget workspace -- )
|
: show-popup ( gadget workspace -- )
|
||||||
dup hide-popup
|
dup hide-popup
|
||||||
over >>popup
|
over >>popup
|
||||||
over f track-add* drop
|
over f track-add drop
|
||||||
request-focus ;
|
request-focus ;
|
||||||
|
|
||||||
: show-titled-popup ( workspace gadget title -- )
|
: show-titled-popup ( workspace gadget title -- )
|
||||||
|
|
|
@ -26,11 +26,9 @@ M: true-constraint assume
|
||||||
[ \ f class-not <class-info> swap value>> refine-value-info ]
|
[ \ f class-not <class-info> swap value>> refine-value-info ]
|
||||||
bi ;
|
bi ;
|
||||||
|
|
||||||
M: true-constraint satisfied?
|
M: true-constraint satisfied? value>> \ f class-not value-is? ;
|
||||||
value>> value-info class>> \ f class-not class<= ;
|
|
||||||
|
|
||||||
M: true-constraint satisfiable?
|
M: true-constraint satisfiable? value>> \ f class-not value-is? ;
|
||||||
value>> value-info class>> \ f class-not classes-intersect? ;
|
|
||||||
|
|
||||||
TUPLE: false-constraint value ;
|
TUPLE: false-constraint value ;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: assocs classes classes.algebra kernel accessors math
|
USING: assocs classes classes.algebra kernel
|
||||||
math.intervals namespaces sequences words combinators arrays
|
accessors math math.intervals namespaces sequences words
|
||||||
compiler.tree.copy-equiv ;
|
combinators arrays compiler.tree.copy-equiv ;
|
||||||
IN: compiler.tree.propagation.info
|
IN: compiler.tree.propagation.info
|
||||||
|
|
||||||
SYMBOL: +interval+
|
SYMBOL: +interval+
|
||||||
|
@ -17,12 +17,15 @@ M: complex eql? over complex? [ = ] [ 2drop f ] if ;
|
||||||
|
|
||||||
! Value info represents a set of objects. Don't mutate value infos
|
! Value info represents a set of objects. Don't mutate value infos
|
||||||
! you receive, always construct new ones. We don't declare the
|
! you receive, always construct new ones. We don't declare the
|
||||||
! slots read-only to allow cloning followed by writing.
|
! slots read-only to allow cloning followed by writing, and to
|
||||||
|
! simplify constructors.
|
||||||
TUPLE: value-info
|
TUPLE: value-info
|
||||||
{ class initial: null }
|
class
|
||||||
{ interval initial: empty-interval }
|
interval
|
||||||
literal
|
literal
|
||||||
literal? ;
|
literal?
|
||||||
|
length
|
||||||
|
slots ;
|
||||||
|
|
||||||
: class-interval ( class -- interval )
|
: class-interval ( class -- interval )
|
||||||
dup real class<=
|
dup real class<=
|
||||||
|
@ -45,36 +48,60 @@ literal? ;
|
||||||
} cond
|
} cond
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: <value-info> ( class interval literal literal? -- info )
|
: <value-info> ( -- info ) \ value-info new ;
|
||||||
[
|
|
||||||
2nip
|
: init-value-info ( info -- info )
|
||||||
[ class ] [ dup real? [ [a,a] ] [ drop [-inf,inf] ] if ] [ ] tri
|
dup literal?>> [
|
||||||
t
|
dup literal>> class >>class
|
||||||
|
dup literal>> dup real? [ [a,a] ] [ drop [-inf,inf] ] if >>interval
|
||||||
] [
|
] [
|
||||||
drop
|
dup [ class>> null class<= ] [ interval>> empty-interval eq? ] bi or [
|
||||||
2dup [ null class<= ] [ empty-interval eq? ] bi* or [
|
null >>class
|
||||||
2drop null empty-interval f f
|
empty-interval >>interval
|
||||||
] [
|
] [
|
||||||
over integer class<= [ integral-closure ] when
|
[ [-inf,inf] or ] change-interval
|
||||||
2dup interval>literal
|
dup class>> integer class<= [ [ integral-closure ] change-interval ] when
|
||||||
|
dup [ class>> ] [ interval>> ] bi interval>literal
|
||||||
|
[ >>literal ] [ >>literal? ] bi*
|
||||||
] if
|
] if
|
||||||
] if
|
] if ;
|
||||||
\ value-info boa ; foldable
|
|
||||||
|
|
||||||
: <class/interval-info> ( class interval -- info )
|
: <class/interval-info> ( class interval -- info )
|
||||||
f f <value-info> ; foldable
|
<value-info>
|
||||||
|
swap >>interval
|
||||||
|
swap >>class
|
||||||
|
init-value-info ; foldable
|
||||||
|
|
||||||
: <class-info> ( class -- info )
|
: <class-info> ( class -- info )
|
||||||
dup word? [ dup +interval+ word-prop ] [ f ] if [-inf,inf] or
|
dup word? [ dup +interval+ word-prop ] [ f ] if [-inf,inf] or
|
||||||
<class/interval-info> ; foldable
|
<class/interval-info> ; foldable
|
||||||
|
|
||||||
: <interval-info> ( interval -- info )
|
: <interval-info> ( interval -- info )
|
||||||
real swap <class/interval-info> ; foldable
|
<value-info>
|
||||||
|
real >>class
|
||||||
|
swap >>interval
|
||||||
|
init-value-info ; foldable
|
||||||
|
|
||||||
: <literal-info> ( literal -- info )
|
: <literal-info> ( literal -- info )
|
||||||
f f rot t <value-info> ; foldable
|
<value-info>
|
||||||
|
swap >>literal
|
||||||
|
t >>literal?
|
||||||
|
init-value-info ; foldable
|
||||||
|
|
||||||
: >literal< ( info -- literal literal? ) [ literal>> ] [ literal?>> ] bi ;
|
: <sequence-info> ( value -- info )
|
||||||
|
<value-info>
|
||||||
|
object >>class
|
||||||
|
swap value-info >>length
|
||||||
|
init-value-info ; foldable
|
||||||
|
|
||||||
|
: <tuple-info> ( slots class -- info )
|
||||||
|
<value-info>
|
||||||
|
swap >>class
|
||||||
|
swap >>slots
|
||||||
|
init-value-info ;
|
||||||
|
|
||||||
|
: >literal< ( info -- literal literal? )
|
||||||
|
[ literal>> ] [ literal?>> ] bi ;
|
||||||
|
|
||||||
: intersect-literals ( info1 info2 -- literal literal? )
|
: intersect-literals ( info1 info2 -- literal literal? )
|
||||||
{
|
{
|
||||||
|
@ -84,11 +111,30 @@ literal? ;
|
||||||
[ drop >literal< ]
|
[ drop >literal< ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
DEFER: value-info-intersect
|
||||||
|
|
||||||
|
: intersect-lengths ( info1 info2 -- length )
|
||||||
|
[ length>> ] bi@ {
|
||||||
|
{ [ dup not ] [ drop ] }
|
||||||
|
{ [ over not ] [ nip ] }
|
||||||
|
[ value-info-intersect ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: intersect-slots ( info1 info2 -- slots )
|
||||||
|
[ slots>> ] bi@
|
||||||
|
2dup [ length ] bi@ =
|
||||||
|
[ [ value-info-intersect ] 2map ] [ 2drop f ] if ;
|
||||||
|
|
||||||
: (value-info-intersect) ( info1 info2 -- info )
|
: (value-info-intersect) ( info1 info2 -- info )
|
||||||
[ [ class>> ] bi@ class-and ]
|
[ <value-info> ] 2dip
|
||||||
[ [ interval>> ] bi@ interval-intersect ]
|
{
|
||||||
[ intersect-literals ]
|
[ [ class>> ] bi@ class-and >>class ]
|
||||||
2tri <value-info> ;
|
[ [ interval>> ] bi@ interval-intersect >>interval ]
|
||||||
|
[ intersect-literals [ >>literal ] [ >>literal? ] bi* ]
|
||||||
|
[ intersect-lengths >>length ]
|
||||||
|
[ intersect-slots >>slots ]
|
||||||
|
} 2cleave
|
||||||
|
init-value-info ;
|
||||||
|
|
||||||
: value-info-intersect ( info1 info2 -- info )
|
: value-info-intersect ( info1 info2 -- info )
|
||||||
{
|
{
|
||||||
|
@ -102,11 +148,30 @@ literal? ;
|
||||||
[ literal>> ] bi@ 2dup eql? [ drop t ] [ 2drop f f ] if
|
[ literal>> ] bi@ 2dup eql? [ drop t ] [ 2drop f f ] if
|
||||||
] [ 2drop f f ] if ;
|
] [ 2drop f f ] if ;
|
||||||
|
|
||||||
|
DEFER: value-info-union
|
||||||
|
|
||||||
|
: union-lengths ( info1 info2 -- length )
|
||||||
|
[ length>> ] bi@ {
|
||||||
|
{ [ dup not ] [ nip ] }
|
||||||
|
{ [ over not ] [ drop ] }
|
||||||
|
[ value-info-union ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: union-slots ( info1 info2 -- slots )
|
||||||
|
[ slots>> ] bi@
|
||||||
|
2dup [ length ] bi@ =
|
||||||
|
[ [ value-info-union ] 2map ] [ 2drop f ] if ;
|
||||||
|
|
||||||
: (value-info-union) ( info1 info2 -- info )
|
: (value-info-union) ( info1 info2 -- info )
|
||||||
[ [ class>> ] bi@ class-or ]
|
[ <value-info> ] 2dip
|
||||||
[ [ interval>> ] bi@ interval-union ]
|
{
|
||||||
[ union-literals ]
|
[ [ class>> ] bi@ class-or >>class ]
|
||||||
2tri <value-info> ;
|
[ [ interval>> ] bi@ interval-union >>interval ]
|
||||||
|
[ union-literals [ >>literal ] [ >>literal? ] bi* ]
|
||||||
|
[ union-lengths >>length ]
|
||||||
|
[ union-slots >>slots ]
|
||||||
|
} 2cleave
|
||||||
|
init-value-info ;
|
||||||
|
|
||||||
: value-info-union ( info1 info2 -- info )
|
: value-info-union ( info1 info2 -- info )
|
||||||
{
|
{
|
||||||
|
@ -122,7 +187,8 @@ literal? ;
|
||||||
SYMBOL: value-infos
|
SYMBOL: value-infos
|
||||||
|
|
||||||
: value-info ( value -- info )
|
: value-info ( value -- info )
|
||||||
resolve-copy value-infos get at T{ value-info } or ;
|
resolve-copy value-infos get at
|
||||||
|
T{ value-info f null empty-interval } or ;
|
||||||
|
|
||||||
: set-value-info ( info value -- )
|
: set-value-info ( info value -- )
|
||||||
resolve-copy value-infos get set-at ;
|
resolve-copy value-infos get set-at ;
|
||||||
|
@ -144,3 +210,6 @@ SYMBOL: value-infos
|
||||||
[ { t f } ]
|
[ { t f } ]
|
||||||
} cond nip
|
} cond nip
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
|
: value-is? ( value class -- ? )
|
||||||
|
[ value-info class>> ] dip class<= ;
|
||||||
|
|
|
@ -185,6 +185,27 @@ generic-comparison-ops [
|
||||||
'[ , fold-comparison ] +outputs+ set-word-prop
|
'[ , fold-comparison ] +outputs+ set-word-prop
|
||||||
] each
|
] each
|
||||||
|
|
||||||
|
: maybe-or-never ( ? -- info )
|
||||||
|
[ object <class-info> ] [ \ f <class-info> ] if ;
|
||||||
|
|
||||||
|
: info-intervals-intersect? ( info1 info2 -- ? )
|
||||||
|
[ interval>> ] bi@ intervals-intersect? ;
|
||||||
|
|
||||||
|
{ number= bignum= float= } [
|
||||||
|
[
|
||||||
|
info-intervals-intersect? maybe-or-never
|
||||||
|
] +outputs+ set-word-prop
|
||||||
|
] each
|
||||||
|
|
||||||
|
: info-classes-intersect? ( info1 info2 -- ? )
|
||||||
|
[ class>> ] bi@ classes-intersect? ;
|
||||||
|
|
||||||
|
\ eq? [
|
||||||
|
[ info-intervals-intersect? ]
|
||||||
|
[ info-classes-intersect? ]
|
||||||
|
bi or maybe-or-never
|
||||||
|
] +outputs+ set-word-prop
|
||||||
|
|
||||||
{
|
{
|
||||||
{ >fixnum fixnum }
|
{ >fixnum fixnum }
|
||||||
{ >bignum bignum }
|
{ >bignum bignum }
|
||||||
|
|
|
@ -2,7 +2,9 @@ USING: kernel compiler.tree.builder compiler.tree
|
||||||
compiler.tree.propagation compiler.tree.copy-equiv
|
compiler.tree.propagation compiler.tree.copy-equiv
|
||||||
compiler.tree.def-use tools.test math math.order
|
compiler.tree.def-use tools.test math math.order
|
||||||
accessors sequences arrays kernel.private vectors
|
accessors sequences arrays kernel.private vectors
|
||||||
alien.accessors alien.c-types sequences.private ;
|
alien.accessors alien.c-types sequences.private
|
||||||
|
byte-arrays classes.algebra math.functions math.private
|
||||||
|
strings ;
|
||||||
IN: compiler.tree.propagation.tests
|
IN: compiler.tree.propagation.tests
|
||||||
|
|
||||||
\ propagate must-infer
|
\ propagate must-infer
|
||||||
|
@ -232,3 +234,101 @@ IN: compiler.tree.propagation.tests
|
||||||
[ V{ 2 } ] [
|
[ V{ 2 } ] [
|
||||||
[ [ 1 ] [ 1 ] if 1 + ] final-literals
|
[ [ 1 ] [ 1 ] if 1 + ] final-literals
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ string string } ] [
|
||||||
|
[
|
||||||
|
2dup [ dup string? [ "Oops" throw ] unless ] bi@ 2drop
|
||||||
|
] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Array length propagation
|
||||||
|
[ V{ t } ] [ [ 10 f <array> length 10 = ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ t } ] [ [ [ 10 f <array> ] [ 10 <byte-array> ] if length 10 = ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ t } ] [ [ [ 1 f <array> ] [ 2 f <array> ] if length 3 < ] final-literals ] unit-test
|
||||||
|
|
||||||
|
! Slot propagation
|
||||||
|
TUPLE: prop-test-tuple { x integer } ;
|
||||||
|
|
||||||
|
[ V{ integer } ] [ [ { prop-test-tuple } declare x>> ] final-classes ] unit-test
|
||||||
|
|
||||||
|
TUPLE: another-prop-test-tuple { x ratio initial: 1/2 } ;
|
||||||
|
|
||||||
|
UNION: prop-test-union prop-test-tuple another-prop-test-tuple ;
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
[ { prop-test-union } declare x>> ] final-classes first
|
||||||
|
rational class=
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
TUPLE: fold-boa-test-tuple { x read-only } { y read-only } { z read-only } ;
|
||||||
|
|
||||||
|
[ V{ T{ fold-boa-test-tuple f 1 2 3 } } ]
|
||||||
|
[ [ 1 2 3 fold-boa-test-tuple boa ] final-literals ]
|
||||||
|
unit-test
|
||||||
|
|
||||||
|
TUPLE: immutable-prop-test-tuple { x sequence read-only } ;
|
||||||
|
|
||||||
|
[ V{ T{ immutable-prop-test-tuple f "hey" } } ] [
|
||||||
|
[ "hey" immutable-prop-test-tuple boa ] final-literals
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ { 1 2 } } ] [
|
||||||
|
[ { 1 2 } immutable-prop-test-tuple boa x>> ] final-literals
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ array } ] [
|
||||||
|
[ { array } declare immutable-prop-test-tuple boa x>> ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ complex } ] [
|
||||||
|
[ <complex> ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ complex } ] [
|
||||||
|
[ { float float } declare dup 0.0 <= [ "Oops" throw ] [ rect> ] if ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ float float } ] [
|
||||||
|
[
|
||||||
|
{ float float } declare
|
||||||
|
dup 0.0 <= [ "Oops" throw ] when rect>
|
||||||
|
[ real>> ] [ imaginary>> ] bi
|
||||||
|
] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ complex } ] [
|
||||||
|
[
|
||||||
|
{ float float object } declare
|
||||||
|
[ "Oops" throw ] [ <complex> ] if
|
||||||
|
] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ number } ] [ [ [ "Oops" throw ] [ 2 + ] if ] final-classes ] unit-test
|
||||||
|
[ V{ number } ] [ [ [ 2 + ] [ "Oops" throw ] if ] final-classes ] unit-test
|
||||||
|
|
||||||
|
[ V{ POSTPONE: f } ] [
|
||||||
|
[ dup 1.0 <= [ drop f ] [ 0 number= ] if ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Don't fold this
|
||||||
|
TUPLE: mutable-tuple-test { x sequence } ;
|
||||||
|
|
||||||
|
[ V{ sequence } ] [
|
||||||
|
[ "hey" mutable-tuple-test boa x>> ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ sequence } ] [
|
||||||
|
[ T{ mutable-tuple-test f "hey" } x>> ] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Mixed mutable and immutable slots
|
||||||
|
TUPLE: mixed-mutable-immutable { x integer } { y sequence read-only } ;
|
||||||
|
|
||||||
|
[ V{ integer array } ] [
|
||||||
|
[
|
||||||
|
3 { 2 1 } mixed-mutable-immutable boa
|
||||||
|
[ x>> ] [ y>> ] bi
|
||||||
|
] final-classes
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: fry accessors kernel sequences assocs words namespaces
|
USING: fry accessors kernel sequences sequences.private assocs
|
||||||
classes.algebra combinators classes continuations
|
words namespaces classes.algebra combinators classes
|
||||||
|
classes.tuple classes.tuple.private continuations arrays
|
||||||
|
byte-arrays strings math math.private slots
|
||||||
compiler.tree
|
compiler.tree
|
||||||
compiler.tree.def-use
|
compiler.tree.def-use
|
||||||
compiler.tree.propagation.info
|
compiler.tree.propagation.info
|
||||||
compiler.tree.propagation.nodes
|
compiler.tree.propagation.nodes
|
||||||
|
compiler.tree.propagation.slots
|
||||||
compiler.tree.propagation.constraints ;
|
compiler.tree.propagation.constraints ;
|
||||||
IN: compiler.tree.propagation.simple
|
IN: compiler.tree.propagation.simple
|
||||||
|
|
||||||
|
@ -52,6 +55,17 @@ M: #declare propagate-before
|
||||||
[ word>> +outputs+ word-prop ]
|
[ word>> +outputs+ word-prop ]
|
||||||
bi with-datastack ;
|
bi with-datastack ;
|
||||||
|
|
||||||
|
: foldable-word? ( #call -- ? )
|
||||||
|
dup word>> "foldable" word-prop [
|
||||||
|
drop t
|
||||||
|
] [
|
||||||
|
dup word>> \ <tuple-boa> eq? [
|
||||||
|
in-d>> peek value-info literal>> immutable-tuple-class?
|
||||||
|
] [
|
||||||
|
drop f
|
||||||
|
] if
|
||||||
|
] if ;
|
||||||
|
|
||||||
: foldable-call? ( #call -- ? )
|
: foldable-call? ( #call -- ? )
|
||||||
dup word>> "foldable" word-prop [
|
dup word>> "foldable" word-prop [
|
||||||
in-d>> [ value-info literal?>> ] all?
|
in-d>> [ value-info literal?>> ] all?
|
||||||
|
@ -75,6 +89,10 @@ M: #declare propagate-before
|
||||||
: output-value-infos ( node -- infos )
|
: output-value-infos ( node -- infos )
|
||||||
{
|
{
|
||||||
{ [ dup foldable-call? ] [ fold-call ] }
|
{ [ dup foldable-call? ] [ fold-call ] }
|
||||||
|
{ [ dup tuple-constructor? ] [ propagate-tuple-constructor ] }
|
||||||
|
{ [ dup word>> reader? ] [ reader-word-outputs ] }
|
||||||
|
{ [ dup sequence-constructor? ] [ propagate-sequence-constructor ] }
|
||||||
|
{ [ dup length-accessor? ] [ propagate-length ] }
|
||||||
{ [ dup word>> +outputs+ word-prop ] [ call-outputs-quot ] }
|
{ [ dup word>> +outputs+ word-prop ] [ call-outputs-quot ] }
|
||||||
[ default-output-value-infos ]
|
[ default-output-value-infos ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
@ -86,12 +104,16 @@ M: #call propagate-before
|
||||||
|
|
||||||
M: node propagate-before drop ;
|
M: node propagate-before drop ;
|
||||||
|
|
||||||
|
: propagate-input-classes ( node -- )
|
||||||
|
[ word>> "input-classes" word-prop class-infos ] [ in-d>> ] bi
|
||||||
|
refine-value-infos ;
|
||||||
|
|
||||||
M: #call propagate-after
|
M: #call propagate-after
|
||||||
dup word>> "input-classes" word-prop dup [
|
{
|
||||||
class-infos swap in-d>> refine-value-infos
|
{ [ dup reader? ] [ reader-word-inputs ] }
|
||||||
] [
|
{ [ dup word>> "input-classes" word-prop ] [ propagate-input-classes ] }
|
||||||
2drop
|
[ drop ]
|
||||||
] if ;
|
} cond ;
|
||||||
|
|
||||||
M: node propagate-after drop ;
|
M: node propagate-after drop ;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: fry assocs arrays byte-arrays strings accessors sequences
|
||||||
|
kernel slots classes.algebra classes.tuple classes.tuple.private
|
||||||
|
words math math.private combinators sequences.private namespaces
|
||||||
|
compiler.tree.propagation.info ;
|
||||||
|
IN: compiler.tree.propagation.slots
|
||||||
|
|
||||||
|
! Propagation of immutable slots and array lengths
|
||||||
|
|
||||||
|
! Revisit this code when delegation is removed and when complex
|
||||||
|
! numbers become tuples.
|
||||||
|
|
||||||
|
UNION: fixed-length-sequence array byte-array string ;
|
||||||
|
|
||||||
|
: sequence-constructor? ( node -- ? )
|
||||||
|
word>> { <array> <byte-array> <string> } memq? ;
|
||||||
|
|
||||||
|
: constructor-output-class ( word -- class )
|
||||||
|
{
|
||||||
|
{ <array> array }
|
||||||
|
{ <byte-array> byte-array }
|
||||||
|
{ <string> string }
|
||||||
|
} at ;
|
||||||
|
|
||||||
|
: propagate-sequence-constructor ( node -- infos )
|
||||||
|
[ word>> constructor-output-class <class-info> ]
|
||||||
|
[ in-d>> first <sequence-info> ]
|
||||||
|
bi value-info-intersect 1array ;
|
||||||
|
|
||||||
|
: length-accessor? ( node -- ? )
|
||||||
|
dup in-d>> first fixed-length-sequence value-is?
|
||||||
|
[ word>> \ length eq? ] [ drop f ] if ;
|
||||||
|
|
||||||
|
: propagate-length ( node -- infos )
|
||||||
|
in-d>> first value-info length>>
|
||||||
|
[ array-capacity <class-info> ] unless* 1array ;
|
||||||
|
|
||||||
|
: tuple-constructor? ( node -- ? )
|
||||||
|
word>> { <tuple-boa> <complex> } memq? ;
|
||||||
|
|
||||||
|
: propagate-<tuple-boa> ( node -- info )
|
||||||
|
#! Delegation
|
||||||
|
in-d>> [ value-info ] map unclip-last
|
||||||
|
literal>> class>> dup immutable-tuple-class? [
|
||||||
|
over [ literal?>> ] all?
|
||||||
|
[ [ , f , [ literal>> ] map % ] { } make >tuple <literal-info> ]
|
||||||
|
[ <tuple-info> ]
|
||||||
|
if
|
||||||
|
] [ nip <class-info> ] if ;
|
||||||
|
|
||||||
|
: propagate-<complex> ( node -- info )
|
||||||
|
in-d>> [ value-info ] map complex <tuple-info> ;
|
||||||
|
|
||||||
|
: propagate-tuple-constructor ( node -- infos )
|
||||||
|
dup word>> {
|
||||||
|
{ \ <tuple-boa> [ propagate-<tuple-boa> ] }
|
||||||
|
{ \ <complex> [ propagate-<complex> ] }
|
||||||
|
} case 1array ;
|
||||||
|
|
||||||
|
: relevant-methods ( node -- methods )
|
||||||
|
[ word>> "methods" word-prop ]
|
||||||
|
[ in-d>> first value-info class>> ] bi
|
||||||
|
'[ drop , classes-intersect? ] assoc-filter ;
|
||||||
|
|
||||||
|
: relevant-slots ( node -- slots )
|
||||||
|
relevant-methods [ nip "reading" word-prop ] { } assoc>map ;
|
||||||
|
|
||||||
|
: no-reader-methods ( input slots -- info )
|
||||||
|
2drop null <class-info> ;
|
||||||
|
|
||||||
|
: same-offset ( slots -- slot/f )
|
||||||
|
dup [ dup [ read-only>> ] when ] all? [
|
||||||
|
[ offset>> ] map dup all-equal? [ first ] [ drop f ] if
|
||||||
|
] [ drop f ] if ;
|
||||||
|
|
||||||
|
: (reader-word-outputs) ( reader -- info )
|
||||||
|
null
|
||||||
|
[ [ class>> ] [ object ] if* class-or ] reduce
|
||||||
|
<class-info> ;
|
||||||
|
|
||||||
|
: value-info-slot ( slot info -- info' )
|
||||||
|
#! Delegation.
|
||||||
|
[ class>> complex class<= 1 3 ? - ] keep
|
||||||
|
dup literal?>> [
|
||||||
|
literal>> {
|
||||||
|
{ [ dup tuple? ] [
|
||||||
|
tuple-slots 1 tail-slice nth <literal-info>
|
||||||
|
] }
|
||||||
|
{ [ dup complex? ] [
|
||||||
|
[ real-part ] [ imaginary-part ] bi
|
||||||
|
2array nth <literal-info>
|
||||||
|
] }
|
||||||
|
} cond
|
||||||
|
] [ slots>> ?nth ] if ;
|
||||||
|
|
||||||
|
: reader-word-outputs ( node -- infos )
|
||||||
|
[ relevant-slots ] [ in-d>> first ] bi
|
||||||
|
over empty? [ no-reader-methods ] [
|
||||||
|
over same-offset dup
|
||||||
|
[ swap value-info value-info-slot ] [ 2drop f ] if
|
||||||
|
[ ] [ (reader-word-outputs) ] ?if
|
||||||
|
] if 1array ;
|
||||||
|
|
||||||
|
: reader-word-inputs ( node -- )
|
||||||
|
[ in-d>> first ] [
|
||||||
|
relevant-slots keys
|
||||||
|
object [ class>> [ class-and ] when* ] reduce
|
||||||
|
<class-info>
|
||||||
|
] bi
|
||||||
|
refine-value-info ;
|
|
@ -7,7 +7,7 @@ stack-checker.backend stack-checker.errors stack-checker.visitor
|
||||||
IN: stack-checker.branches
|
IN: stack-checker.branches
|
||||||
|
|
||||||
: balanced? ( seq -- ? )
|
: balanced? ( seq -- ? )
|
||||||
[ first2 length - ] map all-equal? ;
|
[ second ] filter [ first2 length - ] map all-equal? ;
|
||||||
|
|
||||||
: phi-inputs ( seq -- newseq )
|
: phi-inputs ( seq -- newseq )
|
||||||
dup empty? [
|
dup empty? [
|
||||||
|
@ -16,7 +16,7 @@ IN: stack-checker.branches
|
||||||
] unless ;
|
] unless ;
|
||||||
|
|
||||||
: unify-values ( values -- phi-out )
|
: unify-values ( values -- phi-out )
|
||||||
dup [ known ] map dup all-eq?
|
dup sift [ known ] map dup all-eq?
|
||||||
[ nip first make-known ] [ 2drop <value> ] if ;
|
[ nip first make-known ] [ 2drop <value> ] if ;
|
||||||
|
|
||||||
: phi-outputs ( phi-in -- stack )
|
: phi-outputs ( phi-in -- stack )
|
||||||
|
@ -25,7 +25,7 @@ IN: stack-checker.branches
|
||||||
SYMBOL: quotations
|
SYMBOL: quotations
|
||||||
|
|
||||||
: unify-branches ( ins stacks -- in phi-in phi-out )
|
: unify-branches ( ins stacks -- in phi-in phi-out )
|
||||||
zip [ second ] filter dup empty? [ drop 0 { } { } ] [
|
zip dup empty? [ drop 0 { } { } ] [
|
||||||
dup balanced?
|
dup balanced?
|
||||||
[ [ keys supremum ] [ values phi-inputs dup phi-outputs ] bi ]
|
[ [ keys supremum ] [ values phi-inputs dup phi-outputs ] bi ]
|
||||||
[ quotations get unbalanced-branches-error ]
|
[ quotations get unbalanced-branches-error ]
|
||||||
|
|
Loading…
Reference in New Issue