From 0fd34b4a4b8050a9f0d62ecf7c89205a3d6ceed4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jul 2008 21:47:09 -0500 Subject: [PATCH 01/15] Fix and --- extra/io/launcher/launcher.factor | 4 ++-- extra/io/unix/launcher/launcher-tests.factor | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/extra/io/launcher/launcher.factor b/extra/io/launcher/launcher.factor index f556bac35c..09f240c53a 100755 --- a/extra/io/launcher/launcher.factor +++ b/extra/io/launcher/launcher.factor @@ -183,7 +183,7 @@ M: object run-pipeline-element [ |dispose drop ] [ swap >process - [ swap in>> or ] change-stdout + [ swap in>> or ] change-stdin run-detached ] [ in>> dispose ] @@ -200,8 +200,8 @@ M: object run-pipeline-element [ [ |dispose drop ] bi@ ] [ rot >process - [ swap out>> or ] change-stdout [ swap in>> or ] change-stdin + [ swap out>> or ] change-stdout run-detached ] [ [ out>> dispose ] [ in>> dispose ] bi* ] diff --git a/extra/io/unix/launcher/launcher-tests.factor b/extra/io/unix/launcher/launcher-tests.factor index 6d1f7f1796..33988c273b 100755 --- a/extra/io/unix/launcher/launcher-tests.factor +++ b/extra/io/unix/launcher/launcher-tests.factor @@ -1,7 +1,8 @@ IN: io.unix.launcher.tests USING: io.files tools.test io.launcher arrays io namespaces 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 @@ -111,4 +112,12 @@ accessors kernel sequences io.encodings.utf8 destructors ; "append-test" temp-file utf8 file-contents ] unit-test -[ ] [ "ls" utf8 contents drop ] unit-test +[ t ] [ "ls" utf8 contents >boolean ] unit-test + +[ "Hello world.\n" ] [ + "cat" utf8 [ + "Hello world.\n" write + output-stream get dispose + input-stream get contents + ] with-stream +] unit-test From c6915b10231f6291dcf388c86d34106f9e1c3d50 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 25 Jul 2008 02:07:45 -0500 Subject: [PATCH 02/15] Working on tuple slot propagation --- core/classes/tuple/tuple.factor | 4 + core/kernel/kernel.factor | 8 +- core/math/intervals/intervals.factor | 3 + core/slots/slots.factor | 26 +++- core/words/words.factor | 1 + .../tree/propagation/info/info.factor | 39 ++++-- .../known-words/known-words.factor | 21 ++++ .../tree/propagation/propagation-tests.factor | 95 ++++++++++++++- .../tree/propagation/simple/simple.factor | 49 ++++---- .../tree/propagation/slots/slots.factor | 111 ++++++++++++++++++ .../stack-checker/branches/branches.factor | 6 +- 11 files changed, 314 insertions(+), 49 deletions(-) create mode 100644 unfinished/compiler/tree/propagation/slots/slots.factor diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor index 4216a5dc3d..42b5826e95 100755 --- a/core/classes/tuple/tuple.factor +++ b/core/classes/tuple/tuple.factor @@ -20,6 +20,10 @@ ERROR: not-a-tuple object ; : all-slots ( class -- slots ) superclasses [ "slots" word-prop ] map concat ; +PREDICATE: immutable-tuple-class < tuple-class ( class -- ? ) + #! Delegation + all-slots rest-slice [ read-only>> ] all? ; + boolean ( obj -- ? ) t f ? ; inline diff --git a/core/math/intervals/intervals.factor b/core/math/intervals/intervals.factor index 1896943a71..8afbee3478 100755 --- a/core/math/intervals/intervals.factor +++ b/core/math/intervals/intervals.factor @@ -135,6 +135,9 @@ TUPLE: interval { from read-only } { to read-only } ; ] } cond ; +: intervals-intersect? ( i1 i2 -- ? ) + interval-intersect empty-interval eq? not ; + : interval-union ( i1 i2 -- i3 ) { { [ dup empty-interval eq? ] [ drop ] } diff --git a/core/slots/slots.factor b/core/slots/slots.factor index 73d674782d..8754444ce0 100755 --- a/core/slots/slots.factor +++ b/core/slots/slots.factor @@ -8,13 +8,17 @@ IN: slots 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 new object bootstrap-word >>class ; : define-typecheck ( class generic quot props -- ) [ dup define-simple-generic create-method ] 2dip - [ [ props>> ] [ drop ] [ [ t ] H{ } map>assoc ] tri* update ] + [ [ props>> ] [ drop ] [ ] tri* update ] [ drop define ] 3bi ; @@ -31,17 +35,23 @@ TUPLE: slot-spec name offset class initial read-only reader writer ; ] [ ] make ; : 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 ) - read-only>> { "foldable" "flushable" } { "flushable" } ? ; +: reader-props ( slot-spec -- assoc ) + [ + [ "reading" set ] + [ read-only>> [ t "foldable" set ] when ] bi + t "flushable" set + ] H{ } make-assoc ; : define-reader ( class slot-spec -- ) [ name>> reader-word ] [ reader-quot ] [ reader-props ] tri define-typecheck ; : 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 ; @@ -77,8 +87,12 @@ ERROR: bad-slot-value value class ; } cond ] [ ] make ; +: writer-props ( slot-spec -- assoc ) + [ "writing" set ] H{ } make-assoc ; + : 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 ) ">>" prepend (( object value -- object )) create-accessor ; diff --git a/core/words/words.factor b/core/words/words.factor index 5cf15abfa4..535295007e 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -187,6 +187,7 @@ M: word reset-word "parsing" "inline" "recursive" "foldable" "flushable" "predicating" "reading" "writing" + "reader" "writer" "constructing" "declared-effect" "constructor-quot" "delimiter" } reset-props ; diff --git a/unfinished/compiler/tree/propagation/info/info.factor b/unfinished/compiler/tree/propagation/info/info.factor index 2572e167a1..dc24b58bce 100644 --- a/unfinished/compiler/tree/propagation/info/info.factor +++ b/unfinished/compiler/tree/propagation/info/info.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs classes classes.algebra kernel accessors math -math.intervals namespaces sequences words combinators arrays -compiler.tree.copy-equiv ; +USING: assocs classes classes.algebra kernel +accessors math math.intervals namespaces sequences words +combinators arrays compiler.tree.copy-equiv ; IN: compiler.tree.propagation.info SYMBOL: +interval+ @@ -17,13 +17,15 @@ M: complex eql? over complex? [ = ] [ 2drop f ] if ; ! Value info represents a set of objects. Don't mutate value infos ! 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 -{ class initial: null } -{ interval initial: empty-interval } +class +interval literal literal? -length ; +length +slots ; : class-interval ( class -- interval ) dup real class<= @@ -57,6 +59,7 @@ length ; null >>class empty-interval >>interval ] [ + [ [-inf,inf] or ] change-interval dup class>> integer class<= [ [ integral-closure ] change-interval ] when dup [ class>> ] [ interval>> ] bi interval>literal [ >>literal ] [ >>literal? ] bi* @@ -88,10 +91,15 @@ length ; : ( value -- info ) object >>class - [-inf,inf] >>interval swap value-info >>length init-value-info ; foldable +: ( slots class -- info ) + + swap >>class + swap >>slots + init-value-info ; + : >literal< ( info -- literal literal? ) [ literal>> ] [ literal?>> ] bi ; @@ -112,6 +120,11 @@ DEFER: value-info-intersect [ 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 ) [ ] 2dip { @@ -119,6 +132,7 @@ DEFER: value-info-intersect [ [ interval>> ] bi@ interval-intersect >>interval ] [ intersect-literals [ >>literal ] [ >>literal? ] bi* ] [ intersect-lengths >>length ] + [ intersect-slots >>slots ] } 2cleave init-value-info ; @@ -143,6 +157,11 @@ DEFER: value-info-union [ 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 ) [ ] 2dip { @@ -150,6 +169,7 @@ DEFER: value-info-union [ [ interval>> ] bi@ interval-union >>interval ] [ union-literals [ >>literal ] [ >>literal? ] bi* ] [ union-lengths >>length ] + [ union-slots >>slots ] } 2cleave init-value-info ; @@ -167,7 +187,8 @@ DEFER: value-info-union SYMBOL: value-infos : 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 -- ) resolve-copy value-infos get set-at ; diff --git a/unfinished/compiler/tree/propagation/known-words/known-words.factor b/unfinished/compiler/tree/propagation/known-words/known-words.factor index e358dd5be1..bfdcff51c5 100644 --- a/unfinished/compiler/tree/propagation/known-words/known-words.factor +++ b/unfinished/compiler/tree/propagation/known-words/known-words.factor @@ -185,6 +185,27 @@ generic-comparison-ops [ '[ , fold-comparison ] +outputs+ set-word-prop ] each +: maybe-or-never ( ? -- info ) + [ object ] [ \ f ] 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 } { >bignum bignum } diff --git a/unfinished/compiler/tree/propagation/propagation-tests.factor b/unfinished/compiler/tree/propagation/propagation-tests.factor index 5d278b27b0..82f8ce1e4d 100644 --- a/unfinished/compiler/tree/propagation/propagation-tests.factor +++ b/unfinished/compiler/tree/propagation/propagation-tests.factor @@ -3,7 +3,8 @@ compiler.tree.propagation compiler.tree.copy-equiv compiler.tree.def-use tools.test math math.order accessors sequences arrays kernel.private vectors alien.accessors alien.c-types sequences.private -byte-arrays ; +byte-arrays classes.algebra math.functions math.private +strings ; IN: compiler.tree.propagation.tests \ propagate must-infer @@ -234,8 +235,100 @@ IN: compiler.tree.propagation.tests [ [ 1 ] [ 1 ] if 1 + ] final-literals ] unit-test +[ V{ string string } ] [ + [ + 2dup [ dup string? [ "Oops" throw ] unless ] bi@ 2drop + ] final-classes +] unit-test + +! Array length propagation [ V{ t } ] [ [ 10 f length 10 = ] final-literals ] unit-test [ V{ t } ] [ [ [ 10 f ] [ 10 ] if length 10 = ] final-literals ] unit-test [ V{ t } ] [ [ [ 1 f ] [ 2 f ] 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 } ] [ + [ ] 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 ] [ ] 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 diff --git a/unfinished/compiler/tree/propagation/simple/simple.factor b/unfinished/compiler/tree/propagation/simple/simple.factor index 6b8efd77e9..10beb6f6e0 100644 --- a/unfinished/compiler/tree/propagation/simple/simple.factor +++ b/unfinished/compiler/tree/propagation/simple/simple.factor @@ -2,11 +2,13 @@ ! See http://factorcode.org/license.txt for BSD license. USING: fry accessors kernel sequences sequences.private assocs words namespaces classes.algebra combinators classes -continuations arrays byte-arrays strings +classes.tuple classes.tuple.private continuations arrays +byte-arrays strings math math.private slots compiler.tree compiler.tree.def-use compiler.tree.propagation.info compiler.tree.propagation.nodes +compiler.tree.propagation.slots compiler.tree.propagation.constraints ; IN: compiler.tree.propagation.simple @@ -53,6 +55,17 @@ M: #declare propagate-before [ word>> +outputs+ word-prop ] bi with-datastack ; +: foldable-word? ( #call -- ? ) + dup word>> "foldable" word-prop [ + drop t + ] [ + dup word>> \ eq? [ + in-d>> peek value-info literal>> immutable-tuple-class? + ] [ + drop f + ] if + ] if ; + : foldable-call? ( #call -- ? ) dup word>> "foldable" word-prop [ in-d>> [ value-info literal?>> ] all? @@ -73,27 +86,11 @@ M: #declare propagate-before out-d>> length object ] ?if ; -UNION: fixed-length-sequence array byte-array string ; - -: sequence-constructor? ( node -- ? ) - word>> { } memq? ; - -: propagate-sequence-constructor ( node -- infos ) - [ default-output-value-infos first ] - [ in-d>> first ] - 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 ] unless* 1array ; - : output-value-infos ( node -- infos ) { { [ 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 ] } @@ -107,12 +104,16 @@ M: #call propagate-before 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 - dup word>> "input-classes" word-prop dup [ - class-infos swap in-d>> refine-value-infos - ] [ - 2drop - ] if ; + { + { [ dup reader? ] [ reader-word-inputs ] } + { [ dup word>> "input-classes" word-prop ] [ propagate-input-classes ] } + [ drop ] + } cond ; M: node propagate-after drop ; diff --git a/unfinished/compiler/tree/propagation/slots/slots.factor b/unfinished/compiler/tree/propagation/slots/slots.factor new file mode 100644 index 0000000000..df10626967 --- /dev/null +++ b/unfinished/compiler/tree/propagation/slots/slots.factor @@ -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>> { } memq? ; + +: constructor-output-class ( word -- class ) + { + { array } + { byte-array } + { string } + } at ; + +: propagate-sequence-constructor ( node -- infos ) + [ word>> constructor-output-class ] + [ in-d>> first ] + 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 ] unless* 1array ; + +: tuple-constructor? ( node -- ? ) + word>> { } memq? ; + +: propagate- ( node -- info ) + #! Delegation + in-d>> [ value-info ] map unclip-last + literal>> class>> dup immutable-tuple-class? [ + over [ literal?>> ] all? + [ [ , f , [ literal>> ] map % ] { } make >tuple ] + [ ] + if + ] [ nip ] if ; + +: propagate- ( node -- info ) + in-d>> [ value-info ] map complex ; + +: propagate-tuple-constructor ( node -- infos ) + dup word>> { + { \ [ propagate- ] } + { \ [ propagate- ] } + } 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 ; + +: 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 + ; + +: value-info-slot ( slot info -- info' ) + #! Delegation. + [ class>> complex class<= 1 3 ? - ] keep + dup literal?>> [ + literal>> { + { [ dup tuple? ] [ + tuple-slots 1 tail-slice nth + ] } + { [ dup complex? ] [ + [ real-part ] [ imaginary-part ] bi + 2array nth + ] } + } 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 + + ] bi + refine-value-info ; diff --git a/unfinished/stack-checker/branches/branches.factor b/unfinished/stack-checker/branches/branches.factor index 613cf31161..711fb3f151 100644 --- a/unfinished/stack-checker/branches/branches.factor +++ b/unfinished/stack-checker/branches/branches.factor @@ -7,7 +7,7 @@ stack-checker.backend stack-checker.errors stack-checker.visitor IN: stack-checker.branches : balanced? ( seq -- ? ) - [ first2 length - ] map all-equal? ; + [ second ] filter [ first2 length - ] map all-equal? ; : phi-inputs ( seq -- newseq ) dup empty? [ @@ -16,7 +16,7 @@ IN: stack-checker.branches ] unless ; : unify-values ( values -- phi-out ) - dup [ known ] map dup all-eq? + dup sift [ known ] map dup all-eq? [ nip first make-known ] [ 2drop ] if ; : phi-outputs ( phi-in -- stack ) @@ -25,7 +25,7 @@ IN: stack-checker.branches SYMBOL: quotations : unify-branches ( ins stacks -- in phi-in phi-out ) - zip [ second ] filter dup empty? [ drop 0 { } { } ] [ + zip dup empty? [ drop 0 { } { } ] [ dup balanced? [ [ keys supremum ] [ values phi-inputs dup phi-outputs ] bi ] [ quotations get unbalanced-branches-error ] From ef44191e86417b47d4e9b5773fcac6afe59c365a Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:24:43 -0500 Subject: [PATCH 03/15] ui.gadgets.grids: Add 'grid-add' --- extra/ui/gadgets/grids/grids.factor | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extra/ui/gadgets/grids/grids.factor b/extra/ui/gadgets/grids/grids.factor index fcc1f691e9..cd2433f3eb 100644 --- a/extra/ui/gadgets/grids/grids.factor +++ b/extra/ui/gadgets/grids/grids.factor @@ -25,6 +25,11 @@ grid >r >r 2dup swap add-gadget drop r> r> 3dup grid-child unparent rot grid>> nth set-nth ; +: grid-add ( grid child i j -- grid ) + >r >r dupd swap r> r> + >r >r 2dup swap add-gadget drop r> r> + 3dup grid-child unparent rot grid>> nth set-nth ; + : grid-remove ( grid i j -- grid ) -rot grid-add* ; : pref-dim-grid ( grid -- dims ) From de3b36fb6b11140773ee16e0e0a93246cc4e5597 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:29:29 -0500 Subject: [PATCH 04/15] Convert calls to 'grid-add*' to 'grid-add' --- extra/ui/gadgets/frames/frames-docs.factor | 6 +++--- extra/ui/gadgets/labelled/labelled.factor | 8 ++++---- extra/ui/gadgets/scrollers/scrollers.factor | 6 +++--- extra/ui/gadgets/sliders/sliders.factor | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/extra/ui/gadgets/frames/frames-docs.factor b/extra/ui/gadgets/frames/frames-docs.factor index 890836dcaa..36c7feed97 100755 --- a/extra/ui/gadgets/frames/frames-docs.factor +++ b/extra/ui/gadgets/frames/frames-docs.factor @@ -7,7 +7,7 @@ ARTICLE: "ui-frame-layout" "Frame layouts" { $subsection frame } "Creating empty frames:" { $subsection } -"A set of mnemonic words for the positions on a frame's 3x3 grid; these words push values which may be passed to " { $link grid-add* } ":" +"A set of mnemonic words for the positions on a frame's 3x3 grid; these words push values which may be passed to " { $link grid-add } ":" { $subsection @center } { $subsection @left } { $subsection @right } @@ -20,7 +20,7 @@ ARTICLE: "ui-frame-layout" "Frame layouts" : $ui-frame-constant ( element -- ) drop - { $description "Symbolic constant for a common input to " { $link grid-add* } "." } print-element ; + { $description "Symbolic constant for a common input to " { $link grid-add } "." } print-element ; HELP: @center $ui-frame-constant ; HELP: @left $ui-frame-constant ; @@ -35,7 +35,7 @@ HELP: @bottom-right $ui-frame-constant ; HELP: frame { $class-description "A frame is a gadget which lays out its children in a 3x3 grid. If the frame is enlarged past its preferred size, the center gadget fills up available room." $nl -"Frames are constructed by calling " { $link } " and since they inherit from " { $link grid } ", children can be managed with " { $link grid-add* } " and " { $link grid-remove } "." } ; +"Frames are constructed by calling " { $link } " and since they inherit from " { $link grid } ", children can be managed with " { $link grid-add } " and " { $link grid-remove } "." } ; HELP: { $values { "frame" frame } } diff --git a/extra/ui/gadgets/labelled/labelled.factor b/extra/ui/gadgets/labelled/labelled.factor index 831ac1b1d8..bd775a2d39 100755 --- a/extra/ui/gadgets/labelled/labelled.factor +++ b/extra/ui/gadgets/labelled/labelled.factor @@ -39,8 +39,8 @@ M: labelled-gadget focusable-child* labelled-gadget-content ; : ( title quot -- gadget ) - swap dup [ @left grid-add* ] [ drop ] if - swap @center grid-add* ; + swap dup [ @left grid-add ] [ drop ] if + swap @center grid-add ; TUPLE: closable-gadget < frame content ; @@ -49,8 +49,8 @@ TUPLE: closable-gadget < frame content ; : ( gadget title quot -- gadget ) closable-gadget new-frame - -rot @top grid-add* + -rot @top grid-add swap >>content - dup content>> @center grid-add* ; + dup content>> @center grid-add ; M: closable-gadget focusable-child* closable-gadget-content ; diff --git a/extra/ui/gadgets/scrollers/scrollers.factor b/extra/ui/gadgets/scrollers/scrollers.factor index f45f40c805..ed825824ef 100755 --- a/extra/ui/gadgets/scrollers/scrollers.factor +++ b/extra/ui/gadgets/scrollers/scrollers.factor @@ -38,11 +38,11 @@ scroller H{ >>model faint-boundary - dup model>> dependencies>> first >>x dup x>> @bottom grid-add* - dup model>> dependencies>> second >>y dup y>> @right grid-add* + dup model>> dependencies>> first >>x dup x>> @bottom grid-add + dup model>> dependencies>> second >>y dup y>> @right grid-add swap over model>> >>viewport - dup viewport>> @center grid-add* ; + dup viewport>> @center grid-add ; : ( gadget -- scroller ) scroller new-scroller ; diff --git a/extra/ui/gadgets/sliders/sliders.factor b/extra/ui/gadgets/sliders/sliders.factor index fba5f5df48..b67edeaea3 100755 --- a/extra/ui/gadgets/sliders/sliders.factor +++ b/extra/ui/gadgets/sliders/sliders.factor @@ -130,7 +130,7 @@ M: elevator layout* tuck >>elevator swap >>thumb dup elevator>> over thumb>> add-gadget - @center grid-add* ; + @center grid-add ; : ( -- button ) { 0 1 } arrow-left -1 ; : ( -- button ) { 0 1 } arrow-right 1 ; @@ -145,15 +145,15 @@ M: elevator layout* : ( range -- slider ) { 1 0 } - @left grid-add* + @left grid-add { 0 1 } elevator, - @right grid-add* ; + @right grid-add ; : ( range -- slider ) { 0 1 } - @top grid-add* + @top grid-add { 1 0 } elevator, - @bottom grid-add* ; + @bottom grid-add ; M: slider pref-dim* dup call-next-method From ddbab9cdd2354ce586b92738e45f3c84985528d9 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:34:41 -0500 Subject: [PATCH 05/15] Update code in extra to use 'grid-add' --- extra/automata/ui/ui.factor | 4 ++-- extra/boids/ui/ui.factor | 4 ++-- extra/color-picker/color-picker.factor | 6 +++--- extra/irc/ui/ui.factor | 6 +++--- extra/ui/gadgets/tabs/tabs.factor | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extra/automata/ui/ui.factor b/extra/automata/ui/ui.factor index 8dd3c7ece5..cfb0462877 100644 --- a/extra/automata/ui/ui.factor +++ b/extra/automata/ui/ui.factor @@ -72,13 +72,13 @@ DEFER: automata-window "5 - Random Rule" [ random-rule ] view-button add-gadget "n - New" [ automata-window ] view-button add-gadget - @top grid-add* + @top grid-add C[ display ] { 400 400 } >>pdim dup >slate - @center grid-add* + @center grid-add diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index 6d57bb32ac..4639a0b58d 100755 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -143,9 +143,9 @@ VARS: population-label cohesion-label alignment-label separation-label ; } [ call ] map [ add-gadget ] each 1 over set-pack-fill - @top grid-add* + @top grid-add - slate> @center grid-add* + slate> @center grid-add diff --git a/extra/color-picker/color-picker.factor b/extra/color-picker/color-picker.factor index 15c4e7c733..c3214f5bf2 100755 --- a/extra/color-picker/color-picker.factor +++ b/extra/color-picker/color-picker.factor @@ -37,11 +37,11 @@ M: color-preview model-changed swap dup - [ @top grid-add* ] - [ @center grid-add* ] + [ @top grid-add ] + [ @center grid-add ] [ [ [ truncate number>string ] map " " join ] - @bottom grid-add* + @bottom grid-add ] tri* ; diff --git a/extra/irc/ui/ui.factor b/extra/irc/ui/ui.factor index a79920efe5..9b8d1a4d11 100755 --- a/extra/irc/ui/ui.factor +++ b/extra/irc/ui/ui.factor @@ -155,12 +155,12 @@ irc-editor "general" f { : ( listener client -- irc-tab ) irc-tab new-frame swap client>> >>client swap >>listener - [ @center grid-add* ] keep - @bottom grid-add* ; + [ @center grid-add ] keep + @bottom grid-add ; : ( listener client -- irc-tab ) - [ @right grid-add* ] dip >>listmodel + [ @right grid-add ] dip >>listmodel [ update-participants ] keep ; : ( listener client -- irc-tab ) diff --git a/extra/ui/gadgets/tabs/tabs.factor b/extra/ui/gadgets/tabs/tabs.factor index 5688bb5a2e..12031e5911 100755 --- a/extra/ui/gadgets/tabs/tabs.factor +++ b/extra/ui/gadgets/tabs/tabs.factor @@ -15,8 +15,8 @@ DEFER: (del-page) :: add-toggle ( model n name toggler -- ) n name toggler parent>> '[ , , , (del-page) ] "X" swap - @right grid-add* - n model name @center grid-add* + @right grid-add + n model name @center grid-add toggler swap add-gadget drop ; : redo-toggler ( tabbed -- ) @@ -52,10 +52,10 @@ DEFER: (del-page) tabbed new-frame 0 >>model 1 >>fill >>toggler - dup toggler>> @left grid-add* + dup toggler>> @left grid-add swap [ keys >vector >>names ] - [ values over model>> >>content dup content>> @center grid-add* ] + [ values over model>> >>content dup content>> @center grid-add ] bi dup redo-toggler ; From f4809d92d925e2bf146ce0284d12b3ea60f04b0e Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:36:02 -0500 Subject: [PATCH 06/15] ui.gadgets.grids-docs: update help for 'grid-add' --- extra/ui/gadgets/grids/grids-docs.factor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extra/ui/gadgets/grids/grids-docs.factor b/extra/ui/gadgets/grids/grids-docs.factor index 31f85e4784..eb7affdb80 100755 --- a/extra/ui/gadgets/grids/grids-docs.factor +++ b/extra/ui/gadgets/grids/grids-docs.factor @@ -7,7 +7,7 @@ ARTICLE: "ui-grid-layout" "Grid layouts" "Creating grids from a fixed set of gadgets:" { $subsection } "Managing chidren:" -{ $subsection grid-add* } +{ $subsection grid-add } { $subsection grid-remove } { $subsection grid-child } ; @@ -18,7 +18,7 @@ $nl $nl "The " { $link grid-fill? } " slot stores a boolean, indicating if grid cells should assume their preferred size, or if they should fill the dimensions of the cell. The default is " { $link t } "." $nl -"Grids are created by calling " { $link } " and children are managed with " { $link grid-add* } " and " { $link grid-remove } "." +"Grids are created by calling " { $link } " and children are managed with " { $link grid-add } " and " { $link grid-remove } "." $nl "The " { $link add-gadget } ", " { $link unparent } " and " { $link clear-gadget } " words should not be used to manage child gadgets of grids." } ; @@ -31,7 +31,7 @@ HELP: grid-child { $description "Outputs the child gadget at the " { $snippet "i" } "," { $snippet "j" } "th position of the grid." } { $errors "Throws an error if the indices are out of bounds." } ; -HELP: grid-add* +HELP: grid-add { $values { "gadget" gadget } { "grid" grid } { "i" "non-negative integer" } { "j" "non-negative integer" } } { $description "Adds a child gadget at the specified location." } { $side-effects "grid" } ; From 8a90325f67da100de73e37b77d16615a69efbcca Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:37:09 -0500 Subject: [PATCH 07/15] ui.gadgets.grids: Update 'grid-remove' --- extra/ui/gadgets/grids/grids.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/ui/gadgets/grids/grids.factor b/extra/ui/gadgets/grids/grids.factor index cd2433f3eb..5e4af7fcb3 100644 --- a/extra/ui/gadgets/grids/grids.factor +++ b/extra/ui/gadgets/grids/grids.factor @@ -30,7 +30,7 @@ grid >r >r 2dup swap add-gadget drop r> r> 3dup grid-child unparent rot grid>> nth set-nth ; -: grid-remove ( grid i j -- grid ) -rot grid-add* ; +: grid-remove ( grid i j -- grid ) -rot grid-add ; : pref-dim-grid ( grid -- dims ) grid>> [ [ pref-dim ] map ] map ; From 2291c2d18a479303e0ccd56c08c8db27ee09080a Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 12:48:08 -0500 Subject: [PATCH 08/15] Remove 'grid-add*' --- extra/ui/gadgets/grids/grids.factor | 5 ----- 1 file changed, 5 deletions(-) diff --git a/extra/ui/gadgets/grids/grids.factor b/extra/ui/gadgets/grids/grids.factor index 5e4af7fcb3..eb2cdad801 100644 --- a/extra/ui/gadgets/grids/grids.factor +++ b/extra/ui/gadgets/grids/grids.factor @@ -20,11 +20,6 @@ grid : grid-child ( grid i j -- gadget ) rot grid>> nth nth ; -: grid-add* ( grid child i j -- grid ) - >r >r dupd swap r> r> - >r >r 2dup swap add-gadget drop r> r> - 3dup grid-child unparent rot grid>> nth set-nth ; - : grid-add ( grid child i j -- grid ) >r >r dupd swap r> r> >r >r 2dup swap add-gadget drop r> r> From cbf5fccb69f5a1eb60c3e1b04fad58ee5d6c99b1 Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Fri, 25 Jul 2008 22:02:07 +0100 Subject: [PATCH 09/15] Added write-csv word --- extra/csv/csv-docs.factor | 11 +++++++++-- extra/csv/csv-tests.factor | 10 +++++++++- extra/csv/csv.factor | 25 +++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/extra/csv/csv-docs.factor b/extra/csv/csv-docs.factor index c9f39900ab..e4741f4810 100644 --- a/extra/csv/csv-docs.factor +++ b/extra/csv/csv-docs.factor @@ -2,20 +2,27 @@ USING: help.syntax help.markup kernel prettyprint sequences ; IN: csv HELP: csv -{ $values { "stream" "a stream" } +{ $values { "stream" "an input stream" } { "rows" "an array of arrays of fields" } } { $description "parses a csv stream into an array of row arrays" } ; HELP: csv-row -{ $values { "stream" "a stream" } +{ $values { "stream" "an input stream" } { "row" "an array of fields" } } { $description "parses a row from a csv stream" } ; +HELP: write-csv +{ $values { "rows" "an sequence of sequences of strings" } + { "stream" "an output stream" } } +{ $description "writes csv to the output stream, escaping where necessary" +} ; + HELP: with-delimiter { $values { "char" "field delimiter (e.g. CHAR: \t)" } { "quot" "a quotation" } } { $description "Sets the field delimiter for csv or csv-row words " } ; + diff --git a/extra/csv/csv-tests.factor b/extra/csv/csv-tests.factor index 7e96dbc0a6..8261ae104a 100644 --- a/extra/csv/csv-tests.factor +++ b/extra/csv/csv-tests.factor @@ -1,5 +1,5 @@ -USING: io.streams.string csv tools.test shuffle ; IN: csv.tests +USING: io.streams.string csv tools.test shuffle kernel strings ; ! I like to name my unit tests : named-unit-test ( name output input -- ) @@ -68,3 +68,11 @@ IN: csv.tests [ { { "foo" "bar" } { "1" "2" } } ] [ "foo,\"bar\"\n1,2" csv ] named-unit-test + +"can write csv too!" +[ "foo1,bar1\nfoo2,bar2\n" ] +[ { { "foo1" "bar1" } { "foo2" "bar2" } } tuck write-csv >string ] named-unit-test + +"escapes quotes commas and newlines when writing" +[ "\"fo\"\"o1\",bar1\n\"fo\no2\",\"b,ar2\"\n" ] +[ { { "fo\"o1" "bar1" } { "fo\no2" "b,ar2" } } tuck write-csv >string ] named-unit-test ! " diff --git a/extra/csv/csv.factor b/extra/csv/csv.factor index 8ba0832b29..3d1fb64492 100644 --- a/extra/csv/csv.factor +++ b/extra/csv/csv.factor @@ -10,7 +10,7 @@ IN: csv DEFER: quoted-field VAR: delimiter - + ! trims whitespace from either end of string : trim-whitespace ( str -- str ) [ blank? ] trim ; inline @@ -57,7 +57,7 @@ VAR: delimiter [ (csv) ] when ; : init-vars ( -- ) - delimiter> [ CHAR: , >delimiter ] unless ; inline + delimiter> [ CHAR: , >delimiter ] unless ; inline : csv-row ( stream -- row ) init-vars @@ -69,3 +69,24 @@ VAR: delimiter : with-delimiter ( char quot -- ) delimiter swap with-variable ; inline + + + +: needs-escaping? ( cell -- ? ) + [ "\n\"" delimiter> suffix member? ] contains? ; inline ! " + +: escape-quotes ( cell -- cell' ) + [ [ dup , CHAR: " = [ CHAR: " , ] when ] each ] "" make ; inline + +: enclose-in-quotes ( cell -- cell' ) + CHAR: " [ prefix ] [ suffix ] bi ; inline ! " + +: escape-if-required ( cell -- cell' ) + dup needs-escaping? [ escape-quotes enclose-in-quotes ] when ; inline + +: write-row ( row -- ) + [ delimiter> write1 ] [ escape-if-required write ] interleave nl ; inline + +: write-csv ( rows outstream -- ) + init-vars + [ [ write-row ] each ] with-output-stream ; From d2894204ea9e767dc6534a88fc7dba4ca6e9bd1f Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 16:41:03 -0500 Subject: [PATCH 10/15] boids.ui: Clean up shelf code --- extra/boids/ui/ui.factor | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index 4639a0b58d..3d0916d835 100755 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -116,34 +116,36 @@ VARS: population-label cohesion-label alignment-label separation-label ; - { - [ "ESC - Pause" [ drop toggle-loop ] button* ] - - [ "1 - Randomize" [ drop randomize ] button* ] - - [ 1 over set-pack-fill + "ESC - Pause" [ drop toggle-loop ] button* add-gadget + + "1 - Randomize" [ drop randomize ] button* add-gadget + + 1 over set-pack-fill population-label> add-gadget "3 - Add 10" [ drop add-10-boids ] button* add-gadget - "2 - Sub 10" [ drop sub-10-boids ] button* add-gadget ] - - [ 1 over set-pack-fill + "2 - Sub 10" [ drop sub-10-boids ] button* add-gadget + add-gadget + + 1 over set-pack-fill cohesion-label> add-gadget "q - +0.1" [ drop inc-cohesion-weight ] button* add-gadget - "a - -0.1" [ drop dec-cohesion-weight ] button* add-gadget ] + "a - -0.1" [ drop dec-cohesion-weight ] button* add-gadget + add-gadget - [ 1 over set-pack-fill + 1 over set-pack-fill alignment-label> add-gadget "w - +0.1" [ drop inc-alignment-weight ] button* add-gadget - "s - -0.1" [ drop dec-alignment-weight ] button* add-gadget ] + "s - -0.1" [ drop dec-alignment-weight ] button* add-gadget + add-gadget - [ 1 over set-pack-fill + 1 over set-pack-fill separation-label> add-gadget "e - +0.1" [ drop inc-separation-weight ] button* add-gadget - "d - -0.1" [ drop dec-separation-weight ] button* add-gadget ] + "d - -0.1" [ drop dec-separation-weight ] button* add-gadget + add-gadget - } [ call ] map [ add-gadget ] each - 1 over set-pack-fill - @top grid-add + 1 over set-pack-fill + @top grid-add slate> @center grid-add From 8ad22154e5db31939f28fa6c6f80222fc72011c2 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 25 Jul 2008 16:55:10 -0500 Subject: [PATCH 11/15] boids.ui: Rearrange 'boids-window*' --- extra/boids/ui/ui.factor | 96 +++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index 3d0916d835..064eda841b 100755 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -100,74 +100,68 @@ VARS: population-label cohesion-label alignment-label separation-label ; : boids-window* ( -- ) init-variables init-world-size init-boids loop on - C[ display ] >slate - t slate> set-gadget-clipped? - { 600 400 } slate> set-slate-pdim - C[ [ run ] in-thread ] slate> set-slate-graft - C[ loop off ] slate> set-slate-ungraft - ""