]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 20 Jul 2008 09:19:16 +0000 (04:19 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 20 Jul 2008 09:19:16 +0000 (04:19 -0500)
75 files changed:
core/arrays/arrays.factor
core/assocs/assocs.factor
core/binary-search/binary-search.factor
core/bootstrap/compiler/compiler.factor
core/bootstrap/primitives.factor
core/bootstrap/stage1.factor
core/bootstrap/stage2.factor
core/bootstrap/syntax.factor
core/byte-arrays/byte-arrays.factor
core/classes/tuple/tuple.factor
core/combinators/combinators.factor
core/dequeues/dequeues.factor
core/dlists/dlists.factor
core/effects/effects.factor
core/effects/parser/parser.factor
core/generic/generic.factor
core/generic/standard/engines/tuple/tuple.factor
core/graphs/graphs.factor
core/hashtables/hashtables.factor
core/inference/backend/backend.factor
core/inference/class/class-tests.factor
core/inference/dataflow/dataflow.factor
core/inference/transforms/transforms.factor
core/io/encodings/encodings.factor
core/kernel/kernel.factor
core/listener/listener.factor
core/math/bitfields/bitfields-tests.factor
core/math/bitfields/bitfields.factor
core/math/integers/integers.factor
core/math/math.factor
core/math/parser/parser-tests.factor
core/math/parser/parser.factor
core/memory/memory.factor
core/optimizer/control/control.factor
core/quotations/quotations.factor
core/sequences/sequences.factor
core/sorting/sorting.factor
core/splitting/splitting.factor
core/syntax/syntax.factor
core/threads/threads.factor
core/words/words.factor
extra/backtrack/backtrack.factor
extra/benchmark/backtrack/backtrack.factor [changed mode: 0644->0755]
extra/cocoa/enumeration/enumeration.factor
extra/concurrency/mailboxes/mailboxes.factor
extra/concurrency/messaging/messaging-tests.factor
extra/disjoint-set/authors.txt [deleted file]
extra/disjoint-set/disjoint-set.factor [deleted file]
extra/disjoint-set/summary.txt [deleted file]
extra/disjoint-set/tags.txt [deleted file]
extra/disjoint-sets/authors.txt [new file with mode: 0644]
extra/disjoint-sets/disjoint-sets.factor [new file with mode: 0644]
extra/disjoint-sets/summary.txt [new file with mode: 0644]
extra/disjoint-sets/tags.txt [new file with mode: 0644]
extra/fry/fry-docs.factor
extra/help/handbook/handbook.factor
extra/help/lint/lint.factor
extra/io/monitors/monitors-tests.factor
extra/irc/client/client-tests.factor
extra/irc/client/client.factor
extra/irc/messages/messages-tests.factor [new file with mode: 0644]
extra/irc/messages/messages.factor
extra/irc/ui/load/load.factor
extra/irc/ui/ui.factor
extra/koszul/koszul.factor
extra/locals/locals.factor
extra/math/functions/functions.factor
extra/optimizer/debugger/debugger.factor
extra/project-euler/079/079.factor
extra/project-euler/186/186.factor
extra/reports/optimizer/optimizer.factor
extra/sequences/deep/deep.factor
extra/sorting/insertion/insertion.factor
extra/ui/cocoa/cocoa.factor
extra/ui/freetype/freetype.factor

index 9c5f40d88327f3d2fc4d1686cfca22e207a45694..02e0e45544169faa504d6f09d57ad2ff6233c066 100755 (executable)
@@ -1,11 +1,11 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel kernel.private math math.private sequences
-sequences.private ;
+USING: accessors kernel kernel.private math math.private
+sequences sequences.private ;
 IN: arrays
 
 M: array clone (clone) ;
-M: array length array-capacity ;
+M: array length length>> ;
 M: array nth-unsafe >r >fixnum r> array-nth ;
 M: array set-nth-unsafe >r >fixnum r> set-array-nth ;
 M: array resize resize-array ;
index 6cb89582987820dbe8b163e5cda5db06a676d666..b613147f29591eeff90ae58ecb443f823459b697 100755 (executable)
@@ -84,7 +84,7 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     ] [
         3dup nth-unsafe at*
         [ >r 3drop r> ] [ drop >r 1- r> (assoc-stack) ] if
-    ] if ; inline
+    ] if ; inline recursive
 
 : assoc-stack ( key seq -- value )
     dup length 1- swap (assoc-stack) ;
@@ -158,6 +158,9 @@ M: assoc value-at* swap [ = nip ] curry assoc-find nip ;
 : zip ( keys values -- alist )
     2array flip ; inline
 
+: unzip ( assoc -- keys values )
+    dup assoc-empty? [ drop { } { } ] [ >alist flip first2 ] if ;
+
 : search-alist ( key alist -- pair i )
     [ first = ] with find swap ; inline
 
index 87a4e0f5036a14932c8866fa32c17aced4f6ed51..2863944c8b04b730882fc5e161e0d42f8d11b5dc 100644 (file)
@@ -16,7 +16,7 @@ IN: binary-search
     [ [ from>> ] [ midpoint@ ] bi + ] [ seq>> ] bi
     [ drop ] [ dup ] [ ] tri* nth ; inline
 
-: (search) ( quot seq -- i elt )
+: (search) ( quot: ( elt -- <=> ) seq -- i elt )
     dup length 1 <= [
         finish
     ] [
@@ -25,7 +25,7 @@ IN: binary-search
             { +lt+ [ dup midpoint@ head-slice (search) ] }
             { +gt+ [ dup midpoint@ tail-slice (search) ] }
         } case
-    ] if ; inline
+    ] if ; inline recursive
 
 PRIVATE>
 
index 04e53046fe5eca2bae455b380fbfcd7fdc37f92a..f25eafeb17d79c2ccae7f795fdb87857f018a734 100755 (executable)
@@ -37,7 +37,7 @@ nl
     array? hashtable? vector?
     tuple? sbuf? node? tombstone?
 
-    array-capacity array-nth set-array-nth
+    array-nth set-array-nth
 
     wrap probe
 
index b2b6dc4e59087131ee7d53ff54a8782956387a2a..df1d7dfd1d9fa2a91b23954b7b9661b9ce984035 100755 (executable)
@@ -6,7 +6,8 @@ sequences strings vectors words quotations assocs layouts
 classes classes.builtin classes.tuple classes.tuple.private
 kernel.private vocabs vocabs.loader source-files definitions
 slots classes.union classes.intersection classes.predicate
-compiler.units bootstrap.image.private io.files accessors combinators ;
+compiler.units bootstrap.image.private io.files accessors
+combinators ;
 IN: bootstrap.primitives
 
 "Creating primitives and basic runtime structures..." print flush
@@ -225,7 +226,9 @@ bi
     { "imaginary" { "real" "math" } read-only }
 } define-builtin
 
-"array" "arrays" create { } define-builtin
+"array" "arrays" create {
+    { "length" { "array-capacity" "sequences.private" } read-only }
+} define-builtin
 
 "wrapper" "kernel" create {
     { "wrapped" read-only }
@@ -261,7 +264,9 @@ bi
     { "sub-primitive" read-only }
 } define-builtin
 
-"byte-array" "byte-arrays" create { } define-builtin
+"byte-array" "byte-arrays" create {
+    { "length" { "array-capacity" "sequences.private" } read-only }
+} define-builtin
 
 "callstack" "kernel" create { } define-builtin
 
@@ -306,9 +311,12 @@ tuple
 } prepare-slots define-tuple-class
 
 "curry" "kernel" lookup
-[ f "inline" set-word-prop ]
-[ ]
-[ tuple-layout [ <tuple-boa> ] curry ] tri
+{
+    [ f "inline" set-word-prop ]
+    [ make-flushable ]
+    [ ]
+    [ tuple-layout [ <tuple-boa> ] curry ] tri
+} cleave
 (( obj quot -- curry )) define-declared
 
 "compose" "kernel" create
@@ -319,9 +327,12 @@ tuple
 } prepare-slots define-tuple-class
 
 "compose" "kernel" lookup
-[ f "inline" set-word-prop ]
-[ ]
-[ tuple-layout [ <tuple-boa> ] curry ] tri
+{
+    [ f "inline" set-word-prop ]
+    [ make-flushable ]
+    [ ]
+    [ tuple-layout [ <tuple-boa> ] curry ] tri
+} cleave
 (( quot1 quot2 -- compose )) define-declared
 
 ! Sub-primitive words
index 64402ca2e198ad850ffb1c91412204ecfd9b7842..5c55bb15ca2e9cecab4a94f8eea128e7aac09c41 100755 (executable)
@@ -32,7 +32,6 @@ load-help? off
     "libc" require
 
     "io.streams.c" require
-    "io.thread" require
     "vocabs.loader" require
     
     "syntax" require
index 3b98e8909597272288b7888e58865cc6850a0f0a..c6afdfe749e3aec687132afdb79b6ebbadbabed4 100755 (executable)
@@ -56,6 +56,8 @@ parse-command-line
 
 "-no-crossref" cli-args member? [ do-crossref ] unless
 
+"io.thread" require
+
 ! Set dll paths
 os wince? [ "windows.ce" require ] when
 os winnt? [ "windows.nt" require ] when
index 940b8ba57d1a5df1be7652f63061025a31473615..e7dd333ed8e90e03592d5c520d5237904b0fb963 100755 (executable)
@@ -59,6 +59,7 @@ IN: bootstrap.syntax
     "flushable"
     "foldable"
     "inline"
+    "recursive"
     "parsing"
     "t"
     "{"
index d6034708102abf55812b929702621822f7e42615..5461da2b84f307eb98af8c2697eb677e71a951d0 100755 (executable)
@@ -1,11 +1,11 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel kernel.private alien.accessors sequences
+USING: accessors kernel kernel.private alien.accessors sequences
 sequences.private math ;
 IN: byte-arrays
 
 M: byte-array clone (clone) ;
-M: byte-array length array-capacity ;
+M: byte-array length length>> ;
 M: byte-array nth-unsafe swap >fixnum alien-unsigned-1 ;
 M: byte-array set-nth-unsafe swap >fixnum set-alien-unsigned-1 ;
 : >byte-array ( seq -- byte-array ) B{ } clone-like ; inline
index 17d8e3693527722aa7510f98500161ed8b725769..4216a5dc3d672928e01eb462cf51a5382b603bdf 100755 (executable)
@@ -91,7 +91,7 @@ ERROR: bad-superclass class ;
     #! 4 slot == superclasses>>
     rot dup tuple? [
         layout-of 4 slot
-        2dup array-capacity fixnum<
+        2dup 1 slot fixnum<
         [ array-nth eq? ] [ 3drop f ] if
     ] [ 3drop f ] if ; inline
 
index 0e04042beac5e019ef1206d3ed2190fec92ebf3f..10324224b6336ff53b36aaf427971b189be01e51 100755 (executable)
@@ -90,10 +90,10 @@ ERROR: no-case ;
 : <buckets> ( initial length -- array )
     next-power-of-2 swap [ nip clone ] curry map ;
 
-: distribute-buckets ( assoc initial quot -- buckets )
-    spin [ length <buckets> ] keep
-    [ >r 2dup r> dup first roll call (distribute-buckets) ] each
-    nip ; inline
+: distribute-buckets ( alist initial quot -- buckets )
+    swapd [ >r dup first r> call 2array ] curry map
+    [ length <buckets> dup ] keep
+    [ first2 (distribute-buckets) ] with each ; inline
 
 : hash-case-table ( default assoc -- array )
     V{ } [ 1array ] distribute-buckets
index 67c87d79c3aa668029a207c527668d25a5fec5c9..ae55c57fe5c484c1669dc1ecf8995b4fe3a531d9 100644 (file)
@@ -37,8 +37,7 @@ GENERIC: node-value ( node -- value )
     [ peek-back ] [ pop-back* ] bi ;
 
 : slurp-dequeue ( dequeue quot -- )
-    over dequeue-empty? [ 2drop ] [
-        [ [ pop-back ] dip call ] [ slurp-dequeue ] 2bi
-    ] if ; inline
+    [ drop [ dequeue-empty? not ] curry ]
+    [ [ pop-back ] prepose curry ] 2bi [ ] while ; inline
 
 MIXIN: dequeue
index 0095734e63a29d1d906ef240ebb8b2315c5ada98..370ec4042f181d1e76d9818610dce8deff3259a4 100755 (executable)
@@ -48,11 +48,11 @@ M: dlist-node node-value obj>> ;
 : set-front-to-back ( dlist -- )
     dup front>> [ dup back>> >>front ] unless drop ;
 
-: (dlist-find-node) ( dlist-node quot -- node/f ? )
+: (dlist-find-node) ( dlist-node quot: ( node -- ? ) -- node/f ? )
     over [
         [ call ] 2keep rot
         [ drop t ] [ >r next>> r> (dlist-find-node) ] if
-    ] [ 2drop f f ] if ; inline
+    ] [ 2drop f f ] if ; inline recursive
 
 : dlist-find-node ( dlist quot -- node/f ? )
     >r front>> r> (dlist-find-node) ; inline
index 6aee6fbcb231756a4bc58c208e35ac44b0a4bb63..c221ad073b27418649b40d17bf860494658b338f 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math namespaces sequences strings words assocs
-combinators accessors ;
+combinators accessors arrays ;
 IN: effects
 
 TUPLE: effect in out terminated? ;
@@ -22,15 +22,16 @@ TUPLE: effect in out terminated? ;
         [ t ]
     } cond 2nip ;
 
-GENERIC: (stack-picture) ( obj -- str )
-M: string (stack-picture) ;
-M: word (stack-picture) name>> ;
-M: integer (stack-picture) drop "object" ;
+GENERIC: effect>string ( obj -- str )
+M: string effect>string ;
+M: word effect>string name>> ;
+M: integer effect>string drop "object" ;
+M: pair effect>string first2 [ effect>string ] bi@ ": " swap 3append ;
 
 : stack-picture ( seq -- string )
-    [ [ (stack-picture) % CHAR: \s , ] each ] "" make ;
+    [ [ effect>string % CHAR: \s , ] each ] "" make ;
 
-: effect>string ( effect -- string )
+M: effect effect>string ( effect -- string )
     [
         "( " %
         [ in>> stack-picture % "-- " % ]
@@ -51,6 +52,9 @@ M: word stack-effect
 M: effect clone
     [ in>> clone ] [ out>> clone ] bi <effect> ;
 
+: stack-height ( word -- n )
+    stack-effect effect-height ;
+
 : split-shuffle ( stack shuffle -- stack1 stack2 )
     in>> length cut* ;
 
index 8f28450de78cd4237f43f79234a7a1dd015d0264..93401d321c73ba4585ea1fb97aebb15b33cef801 100644 (file)
@@ -1,15 +1,31 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lexer sets sequences kernel splitting effects ;
+USING: lexer sets sequences kernel splitting effects summary
+combinators debugger arrays parser ;
 IN: effects.parser
 
-: parse-effect ( end -- effect )
-    parse-tokens dup { "(" "((" } intersect empty? [
-        { "--" } split1 dup [
-            <effect>
-        ] [
-            "Stack effect declaration must contain --" throw
+DEFER: parse-effect
+
+ERROR: bad-effect ;
+
+M: bad-effect summary
+    drop "Bad stack effect declaration" ;
+
+: parse-effect-token ( end -- token/f )
+    scan tuck = [ drop f ] [
+        dup { f "(" "((" } member? [ bad-effect ] [
+            ":" ?tail [
+                scan-word {
+                    { \ ( [ ")" parse-effect ] }
+                    [ ]
+                } case 2array
+            ] when
         ] if
-    ] [
-        "Stack effect declaration must not contain ( or ((" throw
     ] if ;
+
+: parse-effect-tokens ( end -- tokens )
+    [ parse-effect-token dup ] curry [ ] [ drop ] produce ;
+
+: parse-effect ( end -- effect )
+    parse-effect-tokens { "--" } split1 dup
+    [ <effect> ] [ "Stack effect declaration must contain --" throw ] if ;
index 3aecd4825e344b272174290fe136c7305910dfc1..a621c7fa91fde16b10928887209541178a534cb4 100755 (executable)
@@ -77,6 +77,9 @@ TUPLE: check-method class generic ;
 PREDICATE: method-body < word
     "method-generic" word-prop >boolean ;
 
+M: method-body inline?
+    "method-generic" word-prop inline? ;
+
 M: method-body stack-effect
     "method-generic" word-prop stack-effect ;
 
index 6f1773a21f34d33036b9e1cadd8be0b2a23a7a2e..325f2ebb394bc8754d925b78a81c9b692a662805 100644 (file)
@@ -64,6 +64,9 @@ M: engine-word stack-effect
     [ extra-values ] [ stack-effect ] bi
     dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
 
+M: engine-word inline?
+    "tuple-dispatch-generic" word-prop inline? ;
+
 M: engine-word crossref? "forgotten" word-prop not ;
 
 M: engine-word irrelevant? drop t ;
index 792b2ab340a6051c565aaafd62dc8b4fd8860ced..f2003641de3408d9b5da2e3dda840fd15a454c5c 100644 (file)
@@ -37,14 +37,14 @@ SYMBOL: graph
 
 SYMBOL: previous
 
-: (closure) ( obj quot -- )
+: (closure) ( obj quot: ( elt -- assoc ) -- )
     over previous get key? [
         2drop
     ] [
         over previous get conjoin
         dup slip
         [ nip (closure) ] curry assoc-each
-    ] if ; inline
+    ] if ; inline recursive
 
 : closure ( obj quot -- assoc )
     H{ } clone [
index e804bb76fab665e3315c9af4bf2c3a8fa192d336..32fda7d2fb02a8d329f2a742a3a0f5c5618d19d5 100755 (executable)
@@ -12,7 +12,7 @@ TUPLE: hashtable
 <PRIVATE
 
 : wrap ( i array -- n )
-    array-capacity 1 fixnum-fast fixnum-bitand ; inline
+    length>> 1 fixnum-fast fixnum-bitand ; inline
 
 : hash@ ( key array -- i )
     >r hashcode >fixnum dup fixnum+fast r> wrap ; inline
@@ -27,10 +27,10 @@ TUPLE: hashtable
     dup ((empty)) eq?
     [ 3drop no-key ] [
         = [ rot drop t ] [ probe (key@) ] if
-    ] if ; inline
+    ] if ; inline recursive
 
 : key@ ( key hash -- array n ? )
-    array>> dup array-capacity 0 eq?
+    array>> dup length>> 0 eq?
     [ no-key ] [ 2dup hash@ (key@) ] if ; inline
 
 : <hash-array> ( n -- array )
@@ -51,7 +51,7 @@ TUPLE: hashtable
         ] [
             probe (new-key@)
         ] if
-    ] if ; inline
+    ] if ; inline recursive
 
 : new-key@ ( key hash -- array n empty? )
     array>> 2dup hash@ (new-key@) ; inline
@@ -71,7 +71,7 @@ TUPLE: hashtable
 
 : hash-large? ( hash -- ? )
     [ count>> 3 fixnum*fast 1 fixnum+fast ]
-    [ array>> array-capacity ] bi fixnum> ; inline
+    [ array>> length>> ] bi fixnum> ; inline
 
 : hash-stale? ( hash -- ? )
     [ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ; inline
index b4a533597cecb0726724938ccd3d4cf8de7fac5c..054315990313077774f7bdb1aae780cc55c99899 100755 (executable)
@@ -365,7 +365,8 @@ TUPLE: unbalanced-branches-error quots in out ;
     [ unify-effects ] [ unify-dataflow ] bi ; inline
 
 : infer-branches ( last branches node -- )
-    #! last is a quotation which provides a #return or a #values
+    #! last -> #return or #values
+    #! node -> #if or #dispatch
     1 reify-curries
     call dup node,
     pop-d drop
index 7be70f1ad4bae1ccdfcc7bdcb3e9723912fba8ba..a133f008e4ca3c229900b9335b04ae36542b6619 100755 (executable)
@@ -620,6 +620,8 @@ TUPLE: declared-fixnum { x fixnum } ;
     [ { ascii } declare decode-char ] \ decode-char inlined?
 ] unit-test
 
+[ t ] [ [ { 1 2 } length ] { length length>> slot } inlined? ] unit-test
+
 ! Later
 
 ! [ t ] [
index 734c1c551cc171155f061574fa0eadac04b858a8..14383538939a066bcae261cf3c8ecc51ff321da9 100755 (executable)
@@ -144,7 +144,8 @@ TUPLE: #dispatch < #branch ;
 
 : #dispatch ( -- node ) peek-d 1array \ #dispatch in-node ;
 
-TUPLE: #merge < node ;
+! Phi node: merging is a sequence of sequences of values
+TUPLE: #merge < node merging ;
 
 : #merge ( -- node ) \ #merge all-out-node ;
 
@@ -191,7 +192,7 @@ TUPLE: #declare < node ;
 : #drop ( n -- #shuffle )
     d-tail flatten-curries \ #shuffle in-node ;
 
-: node-exists? ( node quot -- ? )
+: node-exists? ( node quot: ( node -- ? ) -- ? )
     over [
         2dup 2slip rot [
             2drop t
@@ -201,7 +202,7 @@ TUPLE: #declare < node ;
         ] if
     ] [
         2drop f
-    ] if ; inline
+    ] if ; inline recursive
 
 GENERIC: calls-label* ( label node -- ? )
 
@@ -223,21 +224,21 @@ SYMBOL: node-stack
 
 : iterate-next ( -- node ) node@ successor>> ;
 
-: iterate-nodes ( node quot -- )
+: iterate-nodes ( node quot: ( -- ) -- )
     over [
         [ swap >node call node> drop ] keep iterate-nodes
     ] [
         2drop
-    ] if ; inline
+    ] if ; inline recursive
 
-: (each-node) ( quot -- next )
+: (each-node) ( quot: ( node -- ) -- next )
     node@ [ swap call ] 2keep
     node-children [
         [
             [ (each-node) ] keep swap
         ] iterate-nodes
     ] each drop
-    iterate-next ; inline
+    iterate-next ; inline recursive
 
 : with-node-iterator ( quot -- )
     >r V{ } clone node-stack r> with-variable ; inline
@@ -260,14 +261,14 @@ SYMBOL: node-stack
         2drop
     ] if ; inline
 
-: (transform-nodes) ( prev node quot -- )
+: (transform-nodes) ( prev node quot: ( node -- newnode ) -- )
     dup >r call dup [
         >>successor
         successor>> dup successor>>
         r> (transform-nodes)
     ] [
         r> 2drop f >>successor drop
-    ] if ; inline
+    ] if ; inline recursive
 
 : transform-nodes ( node quot -- new-node )
     over [
index c56c8ed080a4d00c3cbe9e9804f81c7b9248a703..c757ff4e96f30b6e1a35cdc64ddf73adb7db5341 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel words sequences generic math
-namespaces quotations assocs combinators math.bitfields
+namespaces quotations assocs combinators
 inference.backend inference.dataflow inference.state
 classes.tuple classes.tuple.private effects summary hashtables
 classes generic sets definitions generic.standard slots.private ;
@@ -48,25 +48,6 @@ IN: inference.transforms
 
 \ spread [ spread>quot ] 1 define-transform
 
-! Bitfields
-GENERIC: (bitfield-quot) ( spec -- quot )
-
-M: integer (bitfield-quot) ( spec -- quot )
-    [ swapd shift bitor ] curry ;
-
-M: pair (bitfield-quot) ( spec -- quot )
-    first2 over word? [ >r swapd execute r> ] [ ] ?
-    [ shift bitor ] append 2curry ;
-
-: bitfield-quot ( spec -- quot )
-    [ (bitfield-quot) ] map [ 0 ] prefix concat ;
-
-\ bitfield [ bitfield-quot ] 1 define-transform
-
-\ flags [
-    [ 0 , [ , \ bitor , ] each ] [ ] make
-] 1 define-transform
-
 ! Tuple operations
 : [get-slots] ( slots -- quot )
     [ [ 1quotation , \ keep , ] each \ drop , ] [ ] make ;
index 0181f80af444999c5c52743d3fda5c14253c4d89..fc02d880f157725e295c88b8bdb2755b41005b43 100755 (executable)
@@ -93,11 +93,10 @@ M: decoder stream-read-partial stream-read ;
         { CHAR: \n [ line-ends\n ] }
     } case ; inline
 
-: ((read-until)) ( buf quot -- string/f sep/f )
-    ! quot: -- char stop?
+: ((read-until)) ( buf quot: ( -- char stop? ) -- string/f sep/f )
     dup call
     [ >r drop "" like r> ]
-    [ pick push ((read-until)) ] if ; inline
+    [ pick push ((read-until)) ] if ; inline recursive
 
 : (read-until) ( quot -- string/f sep/f )
     100 <sbuf> swap ((read-until)) ; inline
index 6b785a61ba5db03e0999d6ce46c513bc20a3a522..2540ee39cdcf2f89243c1043a40a2fa2a42a356d 100755 (executable)
@@ -109,10 +109,13 @@ DEFER: if
 : 2bi@ ( w x y z quot -- )
     dup 2bi* ; inline
 
-: while ( pred body tail -- )
+: loop ( pred: ( -- ? ) -- )
+    dup slip swap [ loop ] [ drop ] if ; inline recursive
+
+: while ( pred: ( -- ? ) body: ( -- ) tail: ( -- ) -- )
     >r >r dup slip r> r> roll
     [ >r tuck 2slip r> while ]
-    [ 2nip call ] if ; inline
+    [ 2nip call ] if ; inline recursive
 
 ! Object protocol
 GENERIC: hashcode* ( depth obj -- code )
index 4e2a8c768e347d18c3606b4cd0000c5e69f3bd20..5ff5830e7a359cd56fad2e8dc631c78d1a2e9118 100755 (executable)
@@ -59,9 +59,7 @@ SYMBOL: error-hook
     ] recover ;
 
 : until-quit ( -- )
-    quit-flag get
-    [ quit-flag off ]
-    [ listen until-quit ] if ; inline
+    quit-flag get [ quit-flag off ] [ listen until-quit ] if ;
 
 : listener ( -- )
     [ until-quit ] with-interactive-vocabs ;
index 248001277371f55ee57a4e0c22ce2e22c8a8d0d2..8864b645327243a78b31657f976aa6eb62cb28f8 100755 (executable)
@@ -15,3 +15,13 @@ IN: math.bitfields.tests
 [ 3 ] [ foo ] unit-test
 [ 3 ] [ { a b } flags ] unit-test
 \ foo must-infer
+
+[ 0 ] [ { } bitfield-quot call ] unit-test
+
+[ 256 ] [ 1 { 8 } bitfield-quot call ] unit-test
+
+[ 268 ] [ 3 1 { 8 2 } bitfield-quot call ] unit-test
+
+[ 268 ] [ 1 { 8 { 3 2 } } bitfield-quot call ] unit-test
+
+[ 512 ] [ 1 { { 1+ 8 } } bitfield-quot call ] unit-test
index a0fb17ef4882402ced25a101befab4259e07a7ae..64ae60d5b3882597d54b351c1efce56c33aa821b 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math sequences words ;
+USING: arrays kernel math sequences words
+namespaces inference.transforms ;
 IN: math.bitfields
 
 GENERIC: (bitfield) ( value accum shift -- newaccum )
@@ -16,3 +17,21 @@ M: pair (bitfield) ( value accum pair -- newaccum )
 
 : flags ( values -- n )
     0 [ dup word? [ execute ] when bitor ] reduce ;
+
+GENERIC: (bitfield-quot) ( spec -- quot )
+
+M: integer (bitfield-quot) ( spec -- quot )
+    [ swapd shift bitor ] curry ;
+
+M: pair (bitfield-quot) ( spec -- quot )
+    first2 over word? [ >r swapd execute r> ] [ ] ?
+    [ shift bitor ] append 2curry ;
+
+: bitfield-quot ( spec -- quot )
+    [ (bitfield-quot) ] map [ 0 ] prefix concat ;
+
+\ bitfield [ bitfield-quot ] 1 define-transform
+
+\ flags [
+    [ 0 , [ , \ bitor , ] each ] [ ] make
+] 1 define-transform
index 6563a1cd11745fe0a5041ca2a0d35b5168cf33fc..1e27d5f16c5255a148e84842ee631359f0140ad7 100755 (executable)
@@ -40,7 +40,7 @@ M: fixnum bit? neg shift 1 bitand 0 > ;
 
 : (fixnum-log2) ( accum n -- accum )
     dup 1 number= [ drop ] [ >r 1+ r> 2/ (fixnum-log2) ] if ;
-    inline
+    inline recursive
 
 M: fixnum (log2) 0 swap (fixnum-log2) ;
 
index 859d0f6f29717b91e0e4d68f4c28cfb1cee92315..457dddceeb49940caf78275e64cdb6876be03dcd 100755 (executable)
@@ -124,21 +124,21 @@ M: float fp-nan?
 
 PRIVATE>
 
-: (each-integer) ( i n quot -- )
+: (each-integer) ( i n quot: ( i -- ) -- )
     [ iterate-step iterate-next (each-integer) ]
-    [ 3drop ] if-iterate? ; inline
+    [ 3drop ] if-iterate? ; inline recursive
 
-: (find-integer) ( i n quot -- i )
+: (find-integer) ( i n quot: ( i -- ? ) -- i )
     [
         iterate-step roll
         [ 2drop ] [ iterate-next (find-integer) ] if
-    ] [ 3drop f ] if-iterate? ; inline
+    ] [ 3drop f ] if-iterate? ; inline recursive
 
-: (all-integers?) ( i n quot -- ? )
+: (all-integers?) ( i n quot: ( i -- ? ) -- ? )
     [
         iterate-step roll
         [ iterate-next (all-integers?) ] [ 3drop f ] if
-    ] [ 3drop t ] if-iterate? ; inline
+    ] [ 3drop t ] if-iterate? ; inline recursive
 
 : each-integer ( n quot -- )
     iterate-prep (each-integer) ; inline
@@ -152,7 +152,7 @@ PRIVATE>
 : all-integers? ( n quot -- ? )
     iterate-prep (all-integers?) ; inline
 
-: find-last-integer ( n quot -- i )
+: find-last-integer ( n quot: ( i -- ? ) -- i )
     over 0 < [
         2drop f
     ] [
@@ -161,4 +161,4 @@ PRIVATE>
         ] [
             >r 1- r> find-last-integer
         ] if
-    ] if ; inline
+    ] if ; inline recursive
index 15234ee3108b60c7f8aaae478f1909e57fdedca8..c16a0316900a89c66ebcbd8b06def0a196ac0950 100755 (executable)
@@ -77,10 +77,6 @@ unit-test
 [ "-101.0e-2" string>number number>string ]
 unit-test
 
-[ 5.0 ]
-[ "10.0/2" string>number ]
-unit-test
-
 [ f ]
 [ "1e1/2" string>number ]
 unit-test
@@ -104,3 +100,11 @@ unit-test
 [ "1.0/0.0" ] [ 1.0 0.0 / number>string ] unit-test
 
 [ "-1.0/0.0" ] [ -1.0 0.0 / number>string ] unit-test
+
+[ 0.0/0.0 ] [ "0/0." string>number ] unit-test
+
+[ 1.0/0.0 ] [ "1/0." string>number ] unit-test
+
+[ -1.0/0.0 ] [ "-1/0." string>number ] unit-test
+
+[ "-0.0" ] [ -0.0 number>string ] unit-test
index 5d048f0b8e2125959642fefed7726b1a78e0a7e7..1cb2ae6cdf31a23ab76210efbe9b84df01f52b27 100755 (executable)
@@ -55,8 +55,9 @@ SYMBOL: negative?
     dup [ (base>) ] [ drop 0 swap ] if ;
 
 : string>ratio ( str -- a/b )
+    "-" ?head dup negative? set swap
     "/" split1 (base>) >r whole-part r>
-    3dup and and [ / + ] [ 3drop f ] if ;
+    3dup and and [ / + swap [ neg ] when ] [ 2drop 2drop f ] if ;
 
 : valid-digits? ( seq -- ? )
     {
@@ -66,20 +67,23 @@ SYMBOL: negative?
     } cond ;
 
 : string>integer ( str -- n/f )
+    "-" ?head swap
     string>digits dup valid-digits?
-    [ radix get digits>integer ] [ drop f ] if ;
+    [ radix get digits>integer swap [ neg ] when ] [ 2drop f ] if ;
 
 PRIVATE>
 
 : base> ( str radix -- n/f )
     [
-        "-" ?head dup negative? set >r
-        {
-            { [ CHAR: / over member? ] [ string>ratio ] }
-            { [ CHAR: . over member? ] [ string>float ] }
-            [ string>integer ]
-        } cond
-        r> [ dup [ neg ] when ] when
+        CHAR: / over member? [
+            string>ratio
+        ] [
+            CHAR: . over member? [
+                string>float
+            ] [
+                string>integer
+            ] if
+        ] if
     ] with-radix ;
 
 : string>number ( str -- n/f ) 10 base> ;
index 0d684c3261de5b797f1ad3569384f59723467718..227aa1f9dcb2f5fb5c39cc2ab485986b472e722f 100644 (file)
@@ -5,9 +5,8 @@ USING: arrays kernel sequences vectors system hashtables
 kernel.private sbufs growable assocs namespaces quotations
 math strings combinators ;
 
-: (each-object) ( quot -- )
-    next-object dup
-    [ swap [ call ] keep (each-object) ] [ 2drop ] if ; inline
+: (each-object) ( quot: ( obj -- ) -- )
+    [ next-object dup ] swap [ drop ] while ; inline
 
 : each-object ( quot -- )
     begin-scan (each-object) end-scan ; inline
index f3f9f519911c96d24e215df289c5c28c1534eee5..feb5706d97aa2f2708d7f774d37857d3a0dd9883 100755 (executable)
@@ -70,8 +70,6 @@ M: #label collect-label-info*
     [ V{ } clone node-stack get length 3array ] keep
     node-param label-info get set-at ;
 
-USE: prettyprint
-
 M: #call-label collect-label-info*
     node-param label-info get at
     node-stack get over third tail
index 9e7ded1836336177c03bfab1908032434af634bb..617dac33236e4bd6a96c2032ea084b3a7cc7e957 100755 (executable)
@@ -5,11 +5,19 @@ kernel kernel.private math assocs quotations.private
 slots.private ;
 IN: quotations
 
+<PRIVATE
+
+: uncurry dup 3 slot swap 4 slot ; inline
+
+: uncompose dup 3 slot swap 4 slot ; inline
+
+PRIVATE>
+
 M: quotation call (call) ;
 
-M: curry call dup 3 slot swap 4 slot call ;
+M: curry call uncurry call ;
 
-M: compose call dup 3 slot swap 4 slot slip call ;
+M: compose call uncompose slip call ;
 
 M: wrapper equal?
     over wrapper? [ [ wrapped>> ] bi@ = ] [ 2drop f ] if ;
index 11cfb975df0e37bb6c444d0774799d74a4e3558c..349d68adc551a03bc351b81550bff7aa1765d272 100755 (executable)
@@ -60,9 +60,6 @@ INSTANCE: immutable-sequence sequence
 
 <PRIVATE
 
-: array-capacity ( array -- n )
-    1 slot { array-capacity } declare ; inline
-
 : array-nth ( n array -- elt )
     swap 2 fixnum+fast slot ; inline
 
@@ -241,7 +238,8 @@ INSTANCE: repetition immutable-sequence
     ] 3keep ; inline
 
 : (copy) ( dst i src j n -- dst )
-    dup 0 <= [ 2drop 2drop ] [ 1- ((copy)) (copy) ] if ; inline
+    dup 0 <= [ 2drop 2drop ] [ 1- ((copy)) (copy) ] if ;
+    inline recursive
 
 : prepare-subseq ( from to seq -- dst i src j n )
     [ >r swap - r> new-sequence dup 0 ] 3keep
@@ -653,7 +651,7 @@ M: slice equal? over slice? [ sequence= ] [ 2drop f ] if ;
 : halves ( seq -- first second )
     dup midpoint@ cut-slice ;
 
-: binary-reduce ( seq start quot -- value )
+: binary-reduce ( seq start quot: ( elt1 elt2 -- newelt ) -- value )
     #! We can't use case here since combinators depends on
     #! sequences
     pick length dup 0 3 between? [
@@ -668,7 +666,7 @@ M: slice equal? over slice? [ sequence= ] [ 2drop f ] if ;
         >r >r halves r> r>
         [ [ binary-reduce ] 2curry bi@ ] keep
         call
-    ] if ; inline
+    ] if ; inline recursive
 
 : cut ( seq n -- before after )
     [ head ] [ tail ] 2bi ;
index 8b84ea8fe0d9ad517d499e671ca31ac439e99b4f..b7bb71f6021546ff97a8efb225868c00ab1eca0d 100755 (executable)
@@ -52,14 +52,14 @@ TUPLE: merge
 : r-next  [ [ r-elt ] [ [ 1+ ] change-from2 drop ] bi ] [ accum>> ] bi push ; inline
 : decide  [ [ l-elt ] [ r-elt ] bi ] dip call +gt+ eq? ; inline
 
-: (merge) ( merge quot -- )
+: (merge) ( merge quot: ( elt1 elt2 -- <=> ) -- )
     over r-done? [ drop dump-l ] [
         over l-done? [ drop dump-r ] [
             2dup decide
             [ over r-next ] [ over l-next ] if
             (merge)
         ] if
-    ] if ; inline
+    ] if ; inline recursive
 
 : flip-accum ( merge -- )
     dup [ accum>> ] [ accum1>> ] bi eq? [
@@ -111,10 +111,9 @@ TUPLE: merge
     [ merge ] 2curry each-chunk ; inline
 
 : sort-loop ( merge quot -- )
-    2 swap
-    [ pick seq>> length pick > ]
-    [ [ dup ] [ 1 shift ] [ ] tri* [ sort-pass ] 2keep ]
-    [ ] while 3drop ; inline
+    [ 2 [ over seq>> length over > ] ] dip
+    [ [ 1 shift 2dup ] dip sort-pass ] curry
+    [ ] while 2drop ; inline
 
 : each-pair ( seq quot -- )
     [ [ length 1+ 2/ ] keep ] dip
index c30ea462c10f751aa10b879f94fa9e8d6aa27450..38f5ae08912111b7e60c5ce1edad8be9d31e9f85 100755 (executable)
@@ -30,7 +30,7 @@ IN: splitting
 : (split) ( separators n seq -- )
     3dup rot [ member? ] curry find-from drop
     [ [ swap subseq , ] 2keep 1+ swap (split) ]
-    [ swap dup zero? [ drop ] [ tail ] if , drop ] if* ; inline
+    [ swap dup zero? [ drop ] [ tail ] if , drop ] if* ; inline recursive
 
 : split, ( seq separators -- ) 0 rot (split) ;
 
index e8ee8578777d8cc82992523ab6004fac33f186f5..54df692895df007147f79cf4de2f7a8a31bce58a 100755 (executable)
@@ -89,6 +89,7 @@ IN: bootstrap.syntax
     "POSTPONE:" [ scan-word parsed ] define-syntax
     "\\" [ scan-word literalize parsed ] define-syntax
     "inline" [ word make-inline ] define-syntax
+    "recursive" [ word make-recursive ] define-syntax
     "foldable" [ word make-foldable ] define-syntax
     "flushable" [ word make-flushable ] define-syntax
     "delimiter" [ word t "delimiter" set-word-prop ] define-syntax
index 552d64cfe77302977e086a0997f34d9af82fc602..4b32f4519d92745382aea32e597d91a861b6f811 100755 (executable)
@@ -195,7 +195,7 @@ M: real sleep
     <thread> [ (spawn) ] keep ;
 
 : spawn-server ( quot name -- thread )
-    >r [ [ ] [ ] while ] curry r> spawn ;
+    >r [ loop ] curry r> spawn ;
 
 : in-thread ( quot -- )
     >r datastack r>
index 1d84acbc1404ce0b9ff56f21960db4615cb81d99..5cf15abfa4d1a91fdc83c33a6ed4d1e5f595082a 100755 (executable)
@@ -164,6 +164,9 @@ M: object redefined drop ;
 : make-inline ( word -- )
     t "inline" set-word-prop ;
 
+: make-recursive ( word -- )
+    t "recursive" set-word-prop ;
+
 : make-flushable ( word -- )
     t "flushable" set-word-prop ;
 
@@ -181,7 +184,7 @@ GENERIC: reset-word ( word -- )
 M: word reset-word
     {
         "unannotated-def"
-        "parsing" "inline" "foldable" "flushable"
+        "parsing" "inline" "recursive" "foldable" "flushable"
         "predicating"
         "reading" "writing"
         "constructing"
@@ -222,6 +225,10 @@ ERROR: bad-create name vocab ;
 : constructor-word ( name vocab -- word )
     >r "<" swap ">" 3append r> create ;
 
+GENERIC: inline? ( word -- ? )
+
+M: word inline? "inline" word-prop ;
+
 PREDICATE: parsing-word < word "parsing" word-prop ;
 
 : delimiter? ( obj -- ? )
index 7ab11abd6dc508ab6348556b3ca1e6201a10c208..3c1a79412118bd5891a2fab0b58da82e0c3e2b0a 100755 (executable)
@@ -1,20 +1,68 @@
 ! Copyright (C) 2008 William Schlieper\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 \r
-USING: kernel continuations sequences namespaces fry ;\r
+USING: kernel continuations combinators sequences quotations arrays namespaces\r
+       fry summary assocs math math.order macros ;\r
 \r
 IN: backtrack\r
 \r
 SYMBOL: failure\r
 \r
-: amb ( seq -- elt )\r
-    failure get\r
-    '[ , _ '[ , '[ failure set , , continue-with ] callcc0 ] each\r
-       , continue ] callcc1 ;\r
+ERROR: amb-failure ;\r
+\r
+M: amb-failure summary drop "Backtracking failure" ;\r
 \r
 : fail ( -- )\r
-    f amb drop ;\r
+    failure get [ continue ]\r
+    [ amb-failure ] if* ;\r
 \r
 : require ( ? -- )\r
     [ fail ] unless ;\r
 \r
+MACRO: checkpoint ( quot -- quot' )\r
+    '[ failure get ,\r
+       '[ '[ failure set , continue ] callcc0\r
+          , failure set @ ] callcc0 ] ;\r
+\r
+: number-from ( from -- from+n )\r
+    [ 1 + number-from ] checkpoint ;\r
+\r
+<PRIVATE\r
+\r
+: unsafe-number-from-to ( to from -- to from+n )\r
+    2dup = [ [ 1 + unsafe-number-from-to ] checkpoint ] unless ;\r
+\r
+: number-from-to ( to from -- to from+n )\r
+    2dup < [ fail ] when unsafe-number-from-to ;\r
+\r
+: amb-integer ( seq -- int )\r
+    length 1 - 0 number-from-to nip ;\r
+\r
+MACRO: unsafe-amb ( seq -- quot )\r
+    dup length 1 =\r
+    [ first 1quotation ]\r
+    [ [ first ] [ rest ] bi\r
+      '[ , [ drop , unsafe-amb ] checkpoint ] ] if ;\r
+\r
+PRIVATE> \r
+\r
+: amb-lazy ( seq -- elt )\r
+    [ amb-integer ] [ nth ] bi ;\r
+\r
+: amb ( seq -- elt )\r
+    dup empty?\r
+    [ drop fail f ]\r
+    [ unsafe-amb ] if ; inline\r
+\r
+MACRO: amb-execute ( seq -- quot )\r
+    [ length 1 - ] [ <enum> [ 1quotation ] assoc-map ] bi\r
+    '[ , 0 unsafe-number-from-to nip , case ] ;\r
+\r
+: if-amb ( true false -- )\r
+    [\r
+        [ { t f } amb ]\r
+        [ '[ @ require t ] ]\r
+        [ '[ @ f ] ]\r
+        tri* if\r
+    ] with-scope ; inline\r
+\r
old mode 100644 (file)
new mode 100755 (executable)
index 0ffaaa4..df67872
@@ -12,18 +12,6 @@ IN: benchmark.backtrack
 
 : nop ;
 
-MACRO: amb-execute ( seq -- quot )
-    [ length ] [ <enum> [ 1quotation ] assoc-map ] bi
-    '[ , amb , case ] ;
-
-: if-amb ( true false -- )
-    [
-        [ { t f } amb ]
-        [ '[ @ require t ] ]
-        [ '[ @ f ] ]
-        tri* if
-    ] with-scope ; inline
-
 : do-something ( a b -- c )
     { + - * } amb-execute ;
 
index 0cd8e905319cc73204942c928bc3cdeac210de32..765fb65ef2a43c527ebaa13c3075c219d83ad6ae 100644 (file)
@@ -11,13 +11,13 @@ IN: cocoa.enumeration
         ] with-malloc
     ] with-malloc ; inline
 
-:: (NSFastEnumeration-each) ( object quot state stackbuf count -- )
+:: (NSFastEnumeration-each) ( object quot: ( elt -- ) state stackbuf count -- )
     object state stackbuf count -> countByEnumeratingWithState:objects:count:
     dup zero? [ drop ] [
         state NSFastEnumerationState-itemsPtr [ stackbuf ] unless*
         '[ , void*-nth quot call ] each
         object quot state stackbuf count (NSFastEnumeration-each)
-    ] if ; inline
+    ] if ; inline recursive
 
 : NSFastEnumeration-each ( object quot -- )
     [ (NSFastEnumeration-each) ] (with-enumeration-buffers) ; inline
index d0d6afef3f1f6ef51d12d9b7eeaa2e6e9db2e573..b7d9e46aa8273a81a93af7a812797ea06a730bd6 100755 (executable)
@@ -23,13 +23,13 @@ M: mailbox dispose* threads>> notify-all ;
 : wait-for-mailbox ( mailbox timeout -- )\r
     >r threads>> r> "mailbox" wait ;\r
 \r
-: block-unless-pred ( mailbox timeout pred -- )\r
+: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )\r
     pick check-disposed\r
     pick data>> over dlist-contains? [\r
         3drop\r
     ] [\r
         >r 2dup wait-for-mailbox r> block-unless-pred\r
-    ] if ; inline\r
+    ] if ; inline recursive\r
 \r
 : block-if-empty ( mailbox timeout -- mailbox )\r
     over check-disposed\r
@@ -58,11 +58,7 @@ M: mailbox dispose* threads>> notify-all ;
     f mailbox-get-all-timeout ;\r
 \r
 : while-mailbox-empty ( mailbox quot -- )\r
-    over mailbox-empty? [\r
-        dup >r dip r> while-mailbox-empty\r
-    ] [\r
-        2drop\r
-    ] if ; inline\r
+    [ [ mailbox-empty? ] curry ] dip [ ] while ; inline\r
 \r
 : mailbox-get-timeout? ( mailbox timeout pred -- obj )\r
     3dup block-unless-pred\r
index 929c4d44f49611ed3cb45322c5d4560f8e21f34b..f78287078329890dd21a0c49a7439375a5b95bbe 100755 (executable)
@@ -47,7 +47,7 @@ SYMBOL: exit
     } match-cond ;
 
 [ -5 ] [
-    [ 0 [ counter ] [ ] [ ] while ] "Counter" spawn "counter" set
+    [ 0 [ counter ] loop ] "Counter" spawn "counter" set
     { increment 10 } "counter" get send
     { decrement 15 } "counter" get send
     [ value , self , ] { } make "counter" get send
diff --git a/extra/disjoint-set/authors.txt b/extra/disjoint-set/authors.txt
deleted file mode 100644 (file)
index 16e1588..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Eric Mertens
diff --git a/extra/disjoint-set/disjoint-set.factor b/extra/disjoint-set/disjoint-set.factor
deleted file mode 100644 (file)
index 6f3b1e6..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-USING: accessors arrays hints kernel locals math sequences ;
-
-IN: disjoint-set
-
-<PRIVATE
-
-TUPLE: disjoint-set parents ranks counts ;
-
-: count ( a disjoint-set -- n )
-    counts>> nth ; inline
-
-: add-count ( p a disjoint-set -- )
-    [ count [ + ] curry ] keep counts>> swap change-nth ; inline
-
-: parent ( a disjoint-set -- p )
-    parents>> nth ; inline
-
-: set-parent ( p a disjoint-set -- )
-    parents>> set-nth ; inline
-
-: link-sets ( p a disjoint-set -- )
-    [ set-parent ]
-    [ add-count ] 3bi ; inline
-
-: rank ( a disjoint-set -- r )
-    ranks>> nth ; inline
-
-: inc-rank ( a disjoint-set -- )
-    ranks>> [ 1+ ] change-nth ; inline
-
-: representative? ( a disjoint-set -- ? )
-    dupd parent = ; inline
-
-: representative ( a disjoint-set -- p )
-    2dup representative? [ drop ] [
-        [ [ parent ] keep representative dup ] 2keep set-parent
-    ] if ;
-
-: representatives ( a b disjoint-set -- r r )
-    [ representative ] curry bi@ ; inline
-
-: ranks ( a b disjoint-set -- r r )
-    [ rank ] curry bi@ ; inline
-
-:: branch ( a b neg zero pos -- )
-    a b = zero [ a b < neg pos if ] if ; inline
-
-PRIVATE>
-
-: <disjoint-set> ( n -- disjoint-set )
-    [ >array ]
-    [ 0 <array> ]
-    [ 1 <array> ] tri
-    disjoint-set boa ;
-
-: equiv-set-size ( a disjoint-set -- n )
-    [ representative ] keep count ;
-
-: equiv? ( a b disjoint-set -- ? )
-    representatives = ; inline
-
-:: equate ( a b disjoint-set -- )
-    a b disjoint-set representatives
-    2dup = [ 2drop ] [
-        2dup disjoint-set ranks
-        [ swap ] [ over disjoint-set inc-rank ] [ ] branch
-        disjoint-set link-sets
-    ] if ;
-
-HINTS: equate disjoint-set ;
-HINTS: representative disjoint-set ;
-HINTS: equiv-set-size disjoint-set ;
diff --git a/extra/disjoint-set/summary.txt b/extra/disjoint-set/summary.txt
deleted file mode 100644 (file)
index ec7ec73..0000000
+++ /dev/null
@@ -1 +0,0 @@
-An efficient implementation of the disjoint-set data structure
diff --git a/extra/disjoint-set/tags.txt b/extra/disjoint-set/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
diff --git a/extra/disjoint-sets/authors.txt b/extra/disjoint-sets/authors.txt
new file mode 100644 (file)
index 0000000..16e1588
--- /dev/null
@@ -0,0 +1 @@
+Eric Mertens
diff --git a/extra/disjoint-sets/disjoint-sets.factor b/extra/disjoint-sets/disjoint-sets.factor
new file mode 100644 (file)
index 0000000..7879f3f
--- /dev/null
@@ -0,0 +1,88 @@
+! Copyright (C) 2008 Eric Mertens.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays hints kernel locals math hashtables
+assocs ;
+
+IN: disjoint-sets
+
+TUPLE: disjoint-set
+{ parents hashtable read-only }
+{ ranks hashtable read-only }
+{ counts hashtable read-only } ;
+
+<PRIVATE
+
+: count ( a disjoint-set -- n )
+    counts>> at ; inline
+
+: add-count ( p a disjoint-set -- )
+    [ count [ + ] curry ] keep counts>> swap change-at ; inline
+
+: parent ( a disjoint-set -- p )
+    parents>> at ; inline
+
+: set-parent ( p a disjoint-set -- )
+    parents>> set-at ; inline
+
+: link-sets ( p a disjoint-set -- )
+    [ set-parent ] [ add-count ] 3bi ; inline
+
+: rank ( a disjoint-set -- r )
+    ranks>> at ; inline
+
+: inc-rank ( a disjoint-set -- )
+    ranks>> [ 1+ ] change-at ; inline
+
+: representative? ( a disjoint-set -- ? )
+    dupd parent = ; inline
+
+PRIVATE>
+
+GENERIC: representative ( a disjoint-set -- p )
+
+M: disjoint-set representative
+    2dup representative? [ drop ] [
+        [ [ parent ] keep representative dup ] 2keep set-parent
+    ] if ;
+
+<PRIVATE
+
+: representatives ( a b disjoint-set -- r r )
+    [ representative ] curry bi@ ; inline
+
+: ranks ( a b disjoint-set -- r r )
+    [ rank ] curry bi@ ; inline
+
+:: branch ( a b neg zero pos -- )
+    a b = zero [ a b < neg pos if ] if ; inline
+
+PRIVATE>
+
+: <disjoint-set> ( -- disjoint-set )
+    H{ } clone H{ } clone H{ } clone disjoint-set boa ;
+
+GENERIC: add-atom ( a disjoint-set -- )
+
+M: disjoint-set add-atom
+    [ dupd parents>> set-at ]
+    [ 0 -rot ranks>> set-at ]
+    [ 1 -rot counts>> set-at ]
+    2tri ;
+
+GENERIC: equiv-set-size ( a disjoint-set -- n )
+
+M: disjoint-set equiv-set-size [ representative ] keep count ;
+
+GENERIC: equiv? ( a b disjoint-set -- ? )
+
+M: disjoint-set equiv? representatives = ;
+
+GENERIC: equate ( a b disjoint-set -- )
+
+M:: disjoint-set equate ( a b disjoint-set -- )
+    a b disjoint-set representatives
+    2dup = [ 2drop ] [
+        2dup disjoint-set ranks
+        [ swap ] [ over disjoint-set inc-rank ] [ ] branch
+        disjoint-set link-sets
+    ] if ;
diff --git a/extra/disjoint-sets/summary.txt b/extra/disjoint-sets/summary.txt
new file mode 100644 (file)
index 0000000..ec7ec73
--- /dev/null
@@ -0,0 +1 @@
+An efficient implementation of the disjoint-set data structure
diff --git a/extra/disjoint-sets/tags.txt b/extra/disjoint-sets/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index eba2f95727d1dad6ac4650b1c1a0efe172474458..05cde62c1fa6771851b995c4f9f8d463637af384 100755 (executable)
@@ -19,10 +19,11 @@ HELP: fry
 \r
 HELP: '[\r
 { $syntax "code... ]" }\r
-{ $description "Literal fried quotation. Expands into code which takes values from the stack and substituting them in." } ;\r
+{ $description "Literal fried quotation. Expands into code which takes values from the stack and substitutes them in place of the fry specifiers " { $link , } " and " { $link @ } "." }\r
+{ $examples "See " { $link "fry.examples" } "." } ;\r
 \r
 ARTICLE: "fry.examples" "Examples of fried quotations"\r
-"Conceptually, " { $link fry } " is tricky however the general idea is easy to grasp once presented with examples."\r
+"The easiest way to understand fried quotations is to look at some examples."\r
 $nl\r
 "If a quotation does not contain any fry specifiers, then " { $link POSTPONE: '[ } " behaves just like " { $link POSTPONE: [ } ":"\r
 { $code "{ 10 20 30 } '[ . ] each" }\r
@@ -38,9 +39,10 @@ $nl
     "{ 10 20 30 } 5 [ 3 ] swap [ / ] curry compose map"\r
     "{ 10 20 30 } [ 3 5 / ] map"\r
 }\r
-"Occurrences of " { $link @ } " are simply syntax sugar for " { $snippet ", call" } ". The following three lines are equivalent:"\r
+"Occurrences of " { $link @ } " are simply syntax sugar for " { $snippet ", call" } ". The following four lines are equivalent:"\r
 { $code \r
     "{ 10 20 30 } [ sq ] '[ @ . ] each"\r
+    "{ 10 20 30 } [ sq ] [ call . ] curry each"\r
     "{ 10 20 30 } [ sq ] [ . ] compose each"\r
     "{ 10 20 30 } [ sq . ] each"\r
 }\r
@@ -50,16 +52,17 @@ $nl
     "{ 8 13 14 27 } [ even? ] 5 [ dup ] swap [ ? ] curry 3compose map"\r
     "{ 8 13 14 27 } [ even? dup 5 ? ] map"\r
 }\r
-"Occurrences of " { $link _ } " have the effect of enclosing all code to their left with " { $link >r } " and " { $link r> } ":"\r
+"Occurrences of " { $link _ } " have the effect of enclosing all code to their left in a quotation passed to " { $link dip } ". The following four lines are equivalent:"\r
 { $code \r
     "{ 10 20 30 } 1 '[ , _ / ] map"\r
+    "{ 10 20 30 } 1 [ [ ] curry dip / ] curry map"\r
     "{ 10 20 30 } 1 [ swap / ] curry map"\r
     "{ 10 20 30 } [ 1 swap / ] map"\r
 }\r
 "For any quotation body " { $snippet "X" } ", the following two are equivalent:"\r
 { $code\r
-    "[ >r X r> ]"\r
-    "[ X _ ]"\r
+    "[ [ X ] dip ]"\r
+    "'[ X _ ]"\r
 }\r
 "Here are some built-in combinators rewritten in terms of fried quotations:"\r
 { $table\r
@@ -73,8 +76,11 @@ $nl
 } ;\r
 \r
 ARTICLE: "fry.philosophy" "Fried quotation philosophy"\r
-"Fried quotations generalize quotation-building words such as " { $link curry } " and " { $link compose } "."\r
-$nl\r
+"Fried quotations generalize quotation-building words such as " { $link curry } " and " { $link compose } ". They can clean up code with lots of currying and composition, particularly when quotations are nested:"\r
+{ $code\r
+    "'[ [ , key? ] all? ] filter"\r
+    "[ [ key? ] curry all? ] curry filter"\r
+}\r
 "There is a mapping from fried quotations to lexical closures as defined in the " { $vocab-link "locals" } " vocabulary. Namely, a fried quotation is equivalent to a ``let'' form where each local binding is only used once, and bindings are used in the same order in which they are defined. The following two lines are equivalent:"\r
 { $code\r
     "'[ 3 , + 4 , / ]"\r
@@ -87,7 +93,7 @@ $nl
 } ;\r
 \r
 ARTICLE: "fry.limitations" "Fried quotation limitations"\r
-"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } "." ;\r
+"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead." ;\r
 \r
 ARTICLE: "fry" "Fried quotations"\r
 "A " { $emphasis "fried quotation" } " differs from a literal quotation in that when it is evaluated, instead of just pushing itself on the stack, it consumes zero or more stack values and inserts them into the quotation."\r
index 9ffd2419159aefcd74d530ad2a15049bdcf0fef8..fc0d00e94d9899417c90551bb69d2e330219f9d8 100755 (executable)
@@ -137,7 +137,7 @@ ARTICLE: "collections" "Collections"
 { $subsection "heaps" }
 { $subsection "graphs" }
 { $subsection "buffers" }
-"There are many other collections in " { $snippet "extra/" } ", such as " { $vocab-link "disjoint-set" } ", " { $vocab-link "persistent-vectors" } ", and " { $vocab-link "tuple-arrays" } "." ;
+"There are many other collections in " { $snippet "extra/" } ", such as " { $vocab-link "disjoint-sets" } ", " { $vocab-link "persistent-vectors" } ", and " { $vocab-link "tuple-arrays" } "." ;
 
 USING: io.encodings.utf8 io.encodings.utf16 io.encodings.binary io.encodings.ascii io.files ;
 
index 221dca3c62da9b8e7f8399f7db88e5f6f7a5e171..0926a30adc74c227a176328135fd1496ff279d24 100755 (executable)
@@ -29,7 +29,7 @@ IN: help.lint
 : effect-values ( word -- seq )
     stack-effect
     [ in>> ] [ out>> ] bi append
-    [ (stack-picture) ] map
+    [ dup pair? [ first ] when effect>string ] map
     prune natural-sort ;
 
 : contains-funky-elements? ( element -- ? )
index bd339544363a40c7020ec0288c244bab956bc999..63381811d1d5c7260c3fcb9710e795b604ba802f 100755 (executable)
@@ -55,7 +55,7 @@ os { winnt linux macosx } member? [
                     dup print flush
                     dup parent-directory
                     [ right-trim-separators "xyz" tail? ] either? not
-                ] [ ] [ ] while
+                ] loop
 
                 "c1" get count-down
                 
@@ -64,7 +64,7 @@ os { winnt linux macosx } member? [
                     dup print flush
                     dup parent-directory
                     [ right-trim-separators "yxy" tail? ] either? not
-                ] [ ] [ ] while
+                ] loop
 
                 "c2" get count-down
             ] "Monitor test thread" spawn drop
index 2883e47b81f15f3fe4278f705d10e3232b2adb8a..100724ea58a18c666503885d12fa824dd8342f47 100644 (file)
@@ -1,7 +1,7 @@
 USING: kernel tools.test accessors arrays sequences qualified
        io.streams.string io.streams.duplex namespaces threads
        calendar irc.client.private irc.client irc.messages.private
-       concurrency.mailboxes classes ;
+       concurrency.mailboxes classes assocs ;
 EXCLUDE: irc.messages => join ;
 RENAME: join irc.messages => join_
 IN: irc.client.tests
@@ -20,28 +20,6 @@ IN: irc.client.tests
 : with-dummy-client ( quot -- )
      rot with-variable ; inline
 
-! Parsing tests
-irc-message new
-    ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line
-    "someuser!n=user@some.where" >>prefix
-                       "PRIVMSG" >>command
-               { "#factortest" } >>parameters
-                            "hi" >>trailing
-1array
-[ ":someuser!n=user@some.where PRIVMSG #factortest :hi"
-  string>irc-message f >>timestamp ] unit-test
-
-privmsg new
-    ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line
-    "someuser!n=user@some.where" >>prefix
-                       "PRIVMSG" >>command
-               { "#factortest" } >>parameters
-                            "hi" >>trailing
-                   "#factortest" >>name
-1array
-[ ":someuser!n=user@some.where PRIVMSG #factortest :hi"
-  parse-irc-line f >>timestamp ] unit-test
-
 { "" } make-client dup "factorbot" set-nick current-irc-client [
     { t } [ irc> profile>> nickname>> me? ] unit-test
 
@@ -64,21 +42,29 @@ privmsg new
                     ":some.where 001 factorbot :Welcome factorbot"
                   } make-client
                   [ connect-irc ] keep 1 seconds sleep
-                    profile>> nickname>> ] unit-test
+                  profile>> nickname>> ] unit-test
 
 { join_ "#factortest" } [
-             { ":factorbot!n=factorbo@some.where JOIN :#factortest"
+           { ":factorbot!n=factorbo@some.where JOIN :#factortest"
              ":ircserver.net MODE #factortest +ns"
              ":ircserver.net 353 factorbot @ #factortest :@factorbot "
              ":ircserver.net 366 factorbot #factortest :End of /NAMES list."
              ":ircserver.net 477 factorbot #factortest :[ircserver-info] blah blah"
              } make-client dup "factorbot" set-nick
              [ connect-irc ] keep 1 seconds sleep
-             join-messages>> 5 seconds mailbox-get-timeout
+             join-messages>> 1 seconds mailbox-get-timeout
              [ class ] [ trailing>> ] bi ] unit-test
-! TODO: user join
-! ":somedude!n=user@isp.net JOIN :#factortest"
+
+{ +join+ "somebody" } [
+           { ":somebody!n=somebody@some.where JOIN :#factortest"
+             } make-client dup "factorbot" set-nick
+             [ listeners>> [ "#factortest" [ <irc-channel-listener> ] keep ] dip set-at ]
+             [ connect-irc ]
+             [ listeners>> [ "#factortest" ] dip at
+               [ read-message drop ] [ read-message drop ] [ read-message ] tri ] tri
+             [ action>> ] [ nick>> ] bi
+             ] unit-test
 ! TODO: channel message
-! ":somedude!n=user@isp.net PRIVMSG #factortest :hello"
+! ":somebody!n=somebody@some.where PRIVMSG #factortest :hello"
 ! TODO: direct private message
 ! ":somedude!n=user@isp.net PRIVMSG factorbot2 :hello"
\ No newline at end of file
index 2dbbe8b8f5945b60094219237c26414d17af92e5..405d8ed9ed50fd23d965726daf88e9b047e2773e 100644 (file)
@@ -31,6 +31,20 @@ TUPLE: irc-channel-listener < irc-listener name password timeout participants ;
 TUPLE: irc-nick-listener < irc-listener name ;
 SYMBOL: +server-listener+
 
+! participant modes
+SYMBOL: +operator+
+SYMBOL: +voice+
+SYMBOL: +normal+
+
+: participant-mode ( n -- mode )
+    H{ { 64 +operator+ } { 43 +voice+ } { 0 +normal+ } } at ;
+
+! participant changed actions
+SYMBOL: +join+
+SYMBOL: +part+
+SYMBOL: +mode+
+
+! listener objects
 : <irc-listener> ( -- irc-listener ) <mailbox> <mailbox> irc-listener boa ;
 
 : <irc-server-listener> ( -- irc-server-listener )
@@ -46,6 +60,9 @@ SYMBOL: +server-listener+
 ! Message objects
 ! ======================================
 
+TUPLE: participant-changed nick action ;
+C: <participant-changed> participant-changed
+
 SINGLETON: irc-end          ! sent when the client isn't running anymore
 SINGLETON: irc-disconnected ! sent when connection is lost
 SINGLETON: irc-connected    ! sent when connection is established
@@ -70,19 +87,27 @@ UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ;
 : listener> ( name -- listener/f ) irc> listeners>> at ;
 : unregister-listener ( name -- ) irc> listeners>> delete-at ;
 
-: to-listener ( message name -- )
+GENERIC: to-listener ( message obj -- )
+
+M: string to-listener ( message string -- )
     listener> [ +server-listener+ listener> ] unless*
-    [ in-messages>> mailbox-put ] [ drop ] if* ;
+    [ to-listener ] [ drop ] if* ;
+
+M: irc-listener to-listener ( message irc-listener -- )
+    in-messages>> mailbox-put ;
 
 : remove-participant ( nick channel -- )
     listener> [ participants>> delete-at ] [ drop ] if* ;
 
+: listeners-with-participant ( nick -- seq )
+    irc> listeners>> values
+    [ dup irc-channel-listener? [ participants>> key? ] [ 2drop f ] if ]
+    with filter ;
+
 : remove-participant-from-all ( nick -- )
-    irc> listeners>>
-    [ irc-channel-listener? [ swap remove-participant ] [ 2drop ] if ] with
-    assoc-each ;
+    dup listeners-with-participant [ delete-at ] with each ;
 
-: add-participant ( nick mode channel -- )
+: add-participant ( mode nick channel -- )
     listener> [ participants>> set-at ] [ 2drop ] if* ;
 
 DEFER: me?
@@ -142,12 +167,31 @@ DEFER: me?
     dup name>> me? [ prefix>> parse-name ] [ name>> ] if ;
 
 : broadcast-message-to-listeners ( message -- )
-    irc> listeners>> values [ in-messages>> mailbox-put ] with each ;
+    irc> listeners>> values [ to-listener ] with each ;
+
+GENERIC: handle-participant-change ( irc-message -- )
+
+M: join handle-participant-change ( join -- )
+    [ prefix>> parse-name +join+ <participant-changed> ]
+    [ trailing>> ] bi to-listener ;
+
+M: part handle-participant-change ( part -- )
+    [ prefix>> parse-name +part+ <participant-changed> ]
+    [ channel>> ] bi to-listener ;
+
+M: kick handle-participant-change ( kick -- )
+    [ who>> +part+ <participant-changed> ]
+    [ channel>> ] bi to-listener ;
+
+M: quit handle-participant-change ( quit -- )
+    prefix>> parse-name
+    [ +part+ <participant-changed> ] [ listeners-with-participant ] bi
+    [ to-listener ] with each ;
 
 GENERIC: handle-incoming-irc ( irc-message -- )
 
 M: irc-message handle-incoming-irc ( irc-message -- )
-    +server-listener+ listener> [ in-messages>> mailbox-put ] [ drop ] if* ;
+    +server-listener+ listener> [ to-listener ] [ drop ] if* ;
 
 M: logged-in handle-incoming-irc ( logged-in -- )
     name>> irc> profile>> (>>nickname) ;
@@ -162,34 +206,43 @@ M: privmsg handle-incoming-irc ( privmsg -- )
     dup irc-message-origin to-listener ;
 
 M: join handle-incoming-irc ( join -- )
-    [ maybe-forward-join ]
-    [ dup trailing>> to-listener ]
-    [ [ drop f ] [ prefix>> parse-name ] [ trailing>> ] tri add-participant ]
-    tri ;
+    { [ maybe-forward-join ] ! keep
+      [ dup trailing>> to-listener ]
+      [ [ drop f ] [ prefix>> parse-name ] [ trailing>> ] tri add-participant ]
+      [ handle-participant-change ]
+    } cleave ;
 
 M: part handle-incoming-irc ( part -- )
-    [ dup channel>> to-listener ] keep
-    [ prefix>> parse-name ] [ channel>> ] bi remove-participant ;
+    [ dup channel>> to-listener ]
+    [ [ prefix>> parse-name ] [ channel>> ] bi remove-participant ]
+    [ handle-participant-change ]
+    tri ;
 
 M: kick handle-incoming-irc ( kick -- )
-    [ dup channel>>  to-listener ]
-    [ [ who>> ] [ channel>> ] bi remove-participant ] 
-    [ dup who>> me? [ unregister-listener ] [ drop ] if ]
-    tri ;
+    { [ dup channel>>  to-listener ]
+      [ [ who>> ] [ channel>> ] bi remove-participant ]
+      [ handle-participant-change ]
+      [ dup who>> me? [ unregister-listener ] [ drop ] if ]
+    } cleave ;
 
 M: quit handle-incoming-irc ( quit -- )
-    [ prefix>> parse-name remove-participant-from-all ] keep
-    call-next-method ;
+    { [ dup prefix>> parse-name listeners-with-participant
+        [ to-listener ] with each ]
+      [ handle-participant-change ]
+      [ prefix>> parse-name remove-participant-from-all ]
+      [ ]
+    } cleave call-next-method ;
 
 : >nick/mode ( string -- nick mode )
-    dup first "+@" member? [ unclip ] [ f ] if ;
+    dup first "+@" member? [ unclip ] [ 0 ] if participant-mode ;
 
 : names-reply>participants ( names-reply -- participants )
     trailing>> [ blank? ] trim " " split
     [ >nick/mode 2array ] map >hashtable ;
 
 M: names-reply handle-incoming-irc ( names-reply -- )
-    [ names-reply>participants ] [ channel>> listener> ] bi (>>participants) ;
+    [ names-reply>participants ] [ channel>> listener> ] bi
+    [ (>>participants) ] [ drop ] if* ;
 
 M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- )
     broadcast-message-to-listeners ;
@@ -200,8 +253,8 @@ M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- )
 
 GENERIC: handle-outgoing-irc ( obj -- )
 
-M: irc-message handle-outgoing-irc ( irc-message -- )
-!    irc-message>string irc-print ;
+M: irc-message handle-outgoing-irc ( irc-message -- )
+    irc-message>client-line irc-print ;
 
 M: privmsg handle-outgoing-irc ( privmsg -- )
     [ name>> ] [ trailing>> ] bi /PRIVMSG ;
@@ -213,11 +266,6 @@ M: part handle-outgoing-irc ( part -- )
 ! Reader/Writer
 ! ======================================
 
-: irc-mailbox-get ( mailbox quot -- )
-    [ 5 seconds ] dip
-    '[ , , ,  [ mailbox-get-timeout ] dip call ]
-    [ drop ] recover ; inline
-
 : handle-reader-message ( irc-message -- )
     irc> in-messages>> mailbox-put ;
 
@@ -225,7 +273,7 @@ DEFER: (connect-irc)
 
 : (handle-disconnect) ( -- )
     irc>
-        [ [ irc-disconnected ] dip in-messages>> mailbox-put ]
+        [ [ irc-disconnected ] dip to-listener ]
         [ dup reconnect-time>> sleep (connect-irc) ]
         [ profile>> nickname>> /LOGIN ]
     tri ;
@@ -247,14 +295,14 @@ DEFER: (connect-irc)
     [ (reader-loop) ] [ handle-disconnect ] recover ;
 
 : writer-loop ( -- )
-    irc> out-messages>> [ handle-outgoing-irc ] irc-mailbox-get ;
+    irc> out-messages>> mailbox-get handle-outgoing-irc ;
 
 ! ======================================
 ! Processing loops
 ! ======================================
 
 : in-multiplexer-loop ( -- )
-    irc> in-messages>> [ handle-incoming-irc ] irc-mailbox-get ;
+    irc> in-messages>> mailbox-get handle-incoming-irc ;
 
 : strings>privmsg ( name string -- privmsg )
     privmsg new [ (>>trailing) ] keep [ (>>name) ] keep ;
@@ -267,9 +315,8 @@ DEFER: (connect-irc)
     } cond ;
 
 : listener-loop ( name listener -- )
-    out-messages>> swap
-    '[ , swap maybe-annotate-with-name irc> out-messages>> mailbox-put ]
-    irc-mailbox-get ;
+    out-messages>> mailbox-get maybe-annotate-with-name
+    irc> out-messages>> mailbox-put ;
 
 : spawn-irc-loop ( quot name -- )
     [ '[ irc> is-running>> [ @ ] when irc> is-running>> ] ] dip
diff --git a/extra/irc/messages/messages-tests.factor b/extra/irc/messages/messages-tests.factor
new file mode 100644 (file)
index 0000000..1bd6088
--- /dev/null
@@ -0,0 +1,37 @@
+USING: kernel tools.test accessors arrays qualified
+       irc.messages irc.messages.private ;
+EXCLUDE: sequences => join ;
+IN: irc.messages.tests
+
+! Parsing tests
+irc-message new
+    ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line
+    "someuser!n=user@some.where" >>prefix
+                       "PRIVMSG" >>command
+               { "#factortest" } >>parameters
+                            "hi" >>trailing
+1array
+[ ":someuser!n=user@some.where PRIVMSG #factortest :hi"
+  string>irc-message f >>timestamp ] unit-test
+
+privmsg new
+    ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line
+    "someuser!n=user@some.where" >>prefix
+                       "PRIVMSG" >>command
+               { "#factortest" } >>parameters
+                            "hi" >>trailing
+                   "#factortest" >>name
+1array
+[ ":someuser!n=user@some.where PRIVMSG #factortest :hi"
+  parse-irc-line f >>timestamp ] unit-test
+
+join new
+    ":someuser!n=user@some.where JOIN :#factortest" >>line
+    "someuser!n=user@some.where" >>prefix
+                          "JOIN" >>command
+                             { } >>parameters
+                   "#factortest" >>trailing
+1array
+[ ":someuser!n=user@some.where JOIN :#factortest"
+  parse-irc-line f >>timestamp ] unit-test
+
index 205630d7903f9d4f1005a085ba98d17e62751409..5813c7272344c030bec71ebac9587037312a97e8 100644 (file)
@@ -21,6 +21,10 @@ TUPLE: mode < irc-message name channel mode ;
 TUPLE: names-reply < irc-message who = channel ;
 TUPLE: unhandled < irc-message ;
 
+: <irc-client-message> ( command parameters trailing -- irc-message )
+    irc-message new now >>timestamp
+    [ [ (>>trailing) ] [ (>>parameters) ] [ (>>command) ] tri ] keep ;
+
 GENERIC: irc-message>client-line ( irc-message -- string )
 
 M: irc-message irc-message>client-line ( irc-message -- string )
@@ -30,6 +34,7 @@ M: irc-message irc-message>client-line ( irc-message -- string )
     tri 3array " " sjoin ;
 
 GENERIC: irc-message>server-line ( irc-message -- string )
+
 M: irc-message irc-message>server-line ( irc-message -- string )
    drop "not implemented yet" ;
 
@@ -58,6 +63,8 @@ M: irc-message irc-message>server-line ( irc-message -- string )
 : split-trailing ( string -- string string/f )
     ":" split1 ;
 
+PRIVATE>
+
 : string>irc-message ( string -- object )
     dup split-prefix split-trailing
     [ [ blank? ] trim " " split unclip swap ] dip
@@ -82,4 +89,3 @@ M: irc-message irc-message>server-line ( irc-message -- string )
     [ [ tuple-slots ] [ parameters>> ] bi append ] dip
     [ all-slots over [ length ] bi@ min head ] keep slots>tuple ;
 
-PRIVATE>
index 6655f310e7f270e3b3e5888a590dacf3760ccc9d..e6f4d07b56492e25bbb8a449cc734fd701d2620e 100755 (executable)
@@ -5,7 +5,7 @@ USING: kernel io.files parser editors sequences ;
 \r
 IN: irc.ui.load\r
 \r
-: file-or ( path path -- path ) over exists? ? ;\r
+: file-or ( path path -- path ) [ [ exists? ] keep ] dip ? ;\r
 \r
 : personal-ui-rc ( -- path ) home ".ircui-rc" append-path ;\r
 \r
index 12f9d0118391b33ab19b03027f39af680f51ea83..a79920efe5698b6f6db99f7f787ff8bb1e87d6f4 100755 (executable)
@@ -5,8 +5,8 @@ USING: accessors kernel threads combinators concurrency.mailboxes
        sequences strings hashtables splitting fry assocs hashtables\r
        ui ui.gadgets ui.gadgets.panes ui.gadgets.editors\r
        ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures\r
-       ui.gadgets.tabs ui.gadgets.grids\r
-       io io.styles namespaces calendar calendar.format\r
+       ui.gadgets.tabs ui.gadgets.grids ui.gadgets.lists ui.gadgets.labels\r
+       io io.styles namespaces calendar calendar.format models\r
        irc.client irc.client.private irc.messages irc.messages.private\r
        irc.ui.commandparser irc.ui.load ;\r
 \r
@@ -18,11 +18,18 @@ SYMBOL: client
 \r
 TUPLE: ui-window client tabs ;\r
 \r
+TUPLE: irc-tab < frame listener client listmodel ;\r
+\r
 : write-color ( str color -- )\r
     foreground associate format ;\r
 : red { 0.5 0 0 1 } ;\r
 : green { 0 0.5 0 1 } ;\r
 : blue { 0 0 1 1 } ;\r
+: black { 0 0 0 1 } ;\r
+\r
+: colors H{ { +operator+ { 0 0.5 0 1 } }\r
+            { +voice+ { 0 0 1 1 } }\r
+            { +normal+ { 0 0 0 1 } } } ;\r
 \r
 : dot-or-parens ( string -- string )\r
     dup empty? [ drop "." ]\r
@@ -64,6 +71,14 @@ M: quit write-irc
     " has left IRC" red write-color\r
     trailing>> dot-or-parens red write-color ;\r
 \r
+M: mode write-irc\r
+    "* " blue write-color\r
+    [ name>> write ] keep\r
+    " has applied mode " blue write-color\r
+    [ mode>> write ] keep\r
+    " to " blue write-color\r
+    channel>> write ;\r
+\r
 M: irc-end write-irc\r
     drop "* You have left IRC" red write-color ;\r
 \r
@@ -84,20 +99,39 @@ M: irc-message write-irc
     [ print-irc ]\r
     [ listener get write-message ] bi ;\r
 \r
-: display ( stream listener -- )\r
+GENERIC: handle-inbox ( tab message -- )\r
+\r
+: filter-participants ( assoc val -- alist )\r
+    [ >alist ] dip\r
+   '[ second , = ] filter ;\r
+\r
+: update-participants ( tab -- )\r
+    [ listmodel>> ] [ listener>> participants>> ] bi\r
+    [ +operator+ filter-participants ]\r
+    [ +voice+ filter-participants ]\r
+    [ +normal+ filter-participants ] tri\r
+    append append swap set-model ;\r
+\r
+M: participant-changed handle-inbox\r
+    drop update-participants ;\r
+\r
+M: object handle-inbox\r
+    nip print-irc ;\r
+\r
+: display ( stream tab -- )\r
     '[ , [ [ t ]\r
-           [ , read-message print-irc ]\r
+           [ , dup listener>> read-message handle-inbox ]\r
            [  ] while ] with-output-stream ] "ircv" spawn drop ;\r
 \r
-: <irc-pane> ( listener -- pane )\r
+: <irc-pane> ( tab -- tab pane )\r
     <scrolling-pane>\r
-    [ <pane-stream> swap display ] keep ;\r
+    [ <pane-stream> swap display ] 2keep ;\r
 \r
 TUPLE: irc-editor < editor outstream listener client ;\r
 \r
-: <irc-editor> ( page pane listener -- client editor )\r
-    irc-editor new-editor\r
-    swap >>listener swap <pane-stream> >>outstream\r
+: <irc-editor> ( tab pane -- tab editor )\r
+    over irc-editor new-editor\r
+    swap listener>> >>listener swap <pane-stream> >>outstream\r
     over client>> >>client ;\r
 \r
 : editor-send ( irc-editor -- )\r
@@ -113,25 +147,36 @@ irc-editor "general" f {
     { T{ key-down f f "ENTER" } editor-send }\r
 } define-command-map\r
 \r
-TUPLE: irc-page < frame listener client ;\r
+: <irc-list> ( -- gadget model )\r
+    [ drop ]\r
+    [ first2 [ <label> ] dip >>color ]\r
+    { } <model> [ <list> ] keep ;\r
+\r
+: <irc-tab> ( listener client -- irc-tab )\r
+    irc-tab new-frame\r
+    swap client>> >>client swap >>listener\r
+    <irc-pane> [ <scroller> @center grid-add* ] keep\r
+    <irc-editor> <scroller> @bottom grid-add* ;\r
+\r
+: <irc-channel-tab> ( listener client -- irc-tab )\r
+    <irc-tab>\r
+    <irc-list> [ <scroller> @right grid-add* ] dip >>listmodel\r
+    [ update-participants ] keep ;\r
 \r
-: <irc-page> ( listener client -- irc-page )\r
-    irc-page new-frame\r
-    swap client>> >>client swap [ >>listener ] keep\r
-    [ <irc-pane> [ <scroller> @center grid-add* ] keep ]\r
-    [ <irc-editor> <scroller> @bottom grid-add* ] bi ;\r
+: <irc-server-tab> ( listener client -- irc-tab )\r
+    <irc-tab> ;\r
 \r
-M: irc-page graft*\r
+M: irc-tab graft*\r
     [ listener>> ] [ client>> ] bi\r
     add-listener ;\r
 \r
-M: irc-page ungraft*\r
+M: irc-tab ungraft*\r
     [ listener>> ] [ client>> ] bi\r
     remove-listener ;\r
 \r
 : join-channel ( name ui-window -- )\r
     [ dup <irc-channel-listener> ] dip\r
-    [ <irc-page> swap ] keep\r
+    [ <irc-channel-tab> swap ] keep\r
     tabs>> add-page ;\r
 \r
 : irc-window ( ui-window -- )\r
@@ -142,12 +187,12 @@ M: irc-page ungraft*
 : ui-connect ( profile -- ui-window )\r
     <irc-client> ui-window new over >>client swap\r
     [ connect-irc ]\r
-    [ listeners>> +server-listener+ swap at <irc-pane> <scroller>\r
+    [ listeners>> +server-listener+ swap at over <irc-tab>\r
       "Server" associate <tabbed> >>tabs ] bi ;\r
 \r
 : server-open ( server port nick password channels -- )\r
     [ <irc-profile> ui-connect [ irc-window ] keep ] dip\r
-    [ over join-channel ] each ;\r
+    [ over join-channel ] each drop ;\r
 \r
 : main-run ( -- ) run-ircui ;\r
 \r
index 37c2137433a4b32892c4c71b77c83361711d1ec3..2b67a3755e23d06901faea9a1165c0dcc69ed534 100755 (executable)
@@ -184,7 +184,7 @@ DEFER: (d)
     [ length ] keep [ (graded-ker/im-d) ] curry map ;
 
 : graded-betti ( generators -- seq )
-    basis graded graded-ker/im-d flip first2 but-last 0 prefix v- ;
+    basis graded graded-ker/im-d unzip but-last 0 prefix v- ;
 
 ! Bi-graded for two-step complexes
 : (bigraded-ker/im-d) ( u-deg z-deg bigraded-basis -- null/rank )
index 8346c2c2c3cd5532dcaa39cd78af6745105a3aa0..f80af233d7f2211f859ea2b893908072ccdc4c0c 100755 (executable)
@@ -64,8 +64,8 @@ C: <quote> quote
     local-index 1+ [ get-local ] curry ;
 
 : localize-writer ( obj args -- quot )
-  >r "local-reader" word-prop r>
-  read-local-quot [ set-local-value ] append ;
+    >r "local-reader" word-prop r>
+    read-local-quot [ set-local-value ] append ;
 
 : localize ( obj args -- quot )
     {
@@ -275,7 +275,7 @@ M: wlet local-rewrite*
 : parse-locals ( -- vars assoc )
     ")" parse-effect
     word [ over "declared-effect" set-word-prop ] when*
-    effect-in make-locals dup push-locals ;
+    in>> [ dup pair? [ first ] when ] map make-locals dup push-locals ;
 
 : parse-locals-definition ( word -- word quot )
     scan "(" assert= parse-locals \ ; (parse-lambda) <lambda>
index 4dcb21513883de5edd415e2420f4c83293641fc2..4d71b25174e40be25c0c093d7619c6aaa7c5185d 100755 (executable)
@@ -23,12 +23,12 @@ GENERIC: sqrt ( x -- y ) foldable
 M: real sqrt
     >float dup 0.0 < [ neg fsqrt 0.0 swap rect> ] [ fsqrt ] if ;
 
-: each-bit ( n quot -- )
+: each-bit ( n quot: ( ? -- ) -- )
     over 0 number= pick -1 number= or [
         2drop
     ] [
         2dup >r >r >r odd? r> call r> 2/ r> each-bit
-    ] if ; inline
+    ] if ; inline recursive
 
 GENERIC: (^) ( x y -- z ) foldable
 
index fdae5388964499dac46f60f0b7861a02b9feac85..7fe317aadd9a51b8e724d98611d5bfebaeea76d8 100755 (executable)
@@ -3,8 +3,8 @@
 USING: classes io kernel kernel.private math.parser namespaces
 optimizer prettyprint prettyprint.backend sequences words arrays
 match macros assocs sequences.private generic combinators
-sorting math quotations accessors inference inference.dataflow
-optimizer.specializers ;
+sorting math quotations accessors inference inference.backend
+inference.dataflow optimizer.specializers generator ;
 IN: optimizer.debugger
 
 ! A simple tool for turning dataflow IR into quotations, for
@@ -135,14 +135,21 @@ M: object node>quot
 
 : optimized-word. ( word ? -- ) >r specialized-def r> optimized-quot. ;
 
+SYMBOL: pass-count
 SYMBOL: words-called
 SYMBOL: generics-called
 SYMBOL: methods-called
 SYMBOL: intrinsics-called
 SYMBOL: node-count
 
-: dataflow>report ( node -- alist )
+: count-optimization-passes ( node n -- node n )
+    >r optimize-1
+    [ r> 1+ count-optimization-passes ] [ r> ] if ;
+
+: make-report ( word -- assoc )
     [
+        word-dataflow nip 1 count-optimization-passes pass-count set
+
         H{ } clone words-called set
         H{ } clone generics-called set
         H{ } clone methods-called set
@@ -164,14 +171,12 @@ SYMBOL: node-count
         node-count set
     ] H{ } make-assoc ;
 
-: quot-optimize-report ( quot -- report )
-    dataflow optimize dataflow>report ;
-
-: word-optimize-report ( word -- report )
-    def>> quot-optimize-report ;
-
 : report. ( report -- )
     [
+        "==== Optimization passes:" print
+        pass-count get .
+        nl
+
         "==== Total number of dataflow nodes:" print
         node-count get .
 
@@ -186,4 +191,4 @@ SYMBOL: node-count
     ] bind ;
 
 : optimizer-report. ( word -- )
-    word-optimize-report report. ;
+    make-report report. ;
index cde4dc079b3401aa1912e6549ab2e78b2988f0e9..f64c345694d5690280d3b1ba548873fd79b22df3 100644 (file)
@@ -35,7 +35,7 @@ IN: project-euler.079
     ] { } make ;
 
 : find-source ( seq -- elt )
-    [ keys ] [ values ] bi diff prune
+    unzip diff prune
     dup empty? [ "Topological sort failed" throw ] [ first ] if ;
 
 : remove-source ( seq elt -- seq )
index acec27c51ff463849afd99089c2c045c69633367..ac846f6064045ccd12d99e4a84b689eb6e51acd6 100644 (file)
@@ -1,4 +1,4 @@
-USING: circular disjoint-set kernel math math.ranges
+USING: circular disjoint-sets kernel math math.ranges
        sequences sequences.lib ;
 IN: project-euler.186
 
@@ -29,7 +29,10 @@ IN: project-euler.186
         drop nip
     ] if ;
 
+: <relation> ( n -- unionfind )
+    <disjoint-set> [ [ add-atom ] curry each ] keep ;
+
 : euler186 ( -- n )
-    <generator> 0 1000000 <disjoint-set> (p186) ;
+    <generator> 0 1000000 <relation> (p186) ;
 
 MAIN: euler186
index ec3668b83b98290273e4126371ede7cfd5ae68aa..b51fa5c8ee8a244ad9857e5c0c7816cee96f48fa 100755 (executable)
@@ -2,13 +2,10 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors assocs words sequences arrays compiler\r
 tools.time io.styles io prettyprint vocabs kernel sorting\r
-generator optimizer math math.order math.statistics combinators ;\r
+generator optimizer math math.order math.statistics combinators\r
+optimizer.debugger ;\r
 IN: report.optimizer\r
 \r
-: count-optimization-passes ( nodes n -- n )\r
-    >r optimize-1\r
-    [ r> 1+ count-optimization-passes ] [ drop r> ] if ;\r
-\r
 : table. ( alist -- )\r
     20 short tail*\r
     standard-table-style\r
@@ -28,13 +25,12 @@ IN: report.optimizer
         tri\r
     ] 2bi ; inline\r
 \r
+: optimization-passes ( word -- n )\r
+    word-dataflow nip 1 count-optimization-passes nip ;\r
+\r
 : optimizer-measurements ( -- alist )\r
     all-words [ compiled>> ] filter\r
-    [\r
-        dup [\r
-            word-dataflow nip 1 count-optimization-passes\r
-        ] benchmark 2array\r
-    ] { } map>assoc ;\r
+    [ dup [ optimization-passes ] benchmark 2array ] { } map>assoc ;\r
 \r
 : optimizer-measurements. ( alist -- )\r
     {\r
index c0e516e47153632566a8680ea0a66d724c5df360..3ec793f458db2762f4099b36db7a7b7ed369f42f 100644 (file)
@@ -10,25 +10,25 @@ IN: sequences.deep
         dup string? swap number? or not
     ] [ drop f ] if ;
 
-: deep-each ( obj quot -- )
+: deep-each ( obj quot: ( elt -- ) -- )
     [ call ] 2keep over branch?
-    [ [ deep-each ] curry each ] [ 2drop ] if ; inline
+    [ [ deep-each ] curry each ] [ 2drop ] if ; inline recursive
 
-: deep-map ( obj quot -- newobj )
+: deep-map ( obj quot: ( elt -- elt' ) -- newobj )
     [ call ] keep over branch?
-    [ [ deep-map ] curry map ] [ drop ] if ; inline
+    [ [ deep-map ] curry map ] [ drop ] if ; inline recursive
 
-: deep-filter ( obj quot -- seq )
+: deep-filter ( obj quot: ( elt -- ? ) -- seq )
     over >r
     pusher >r deep-each r>
-    r> dup branch? [ like ] [ drop ] if ; inline
+    r> dup branch? [ like ] [ drop ] if ; inline recursive
 
-: deep-find-from ( obj quot -- elt ? )
+: deep-find-from ( obj quot: ( elt -- ? ) -- elt ? )
     [ call ] 2keep rot [ drop t ] [
         over branch? [
             f -rot [ >r nip r> deep-find-from ] curry find drop >boolean
         ] [ 2drop f f ] if  
-    ] if ; inline
+    ] if ; inline recursive
 
 : deep-find ( obj quot -- elt ) deep-find-from drop ; inline
 
@@ -37,10 +37,10 @@ IN: sequences.deep
 : deep-all? ( obj quot -- ? )
     [ not ] compose deep-contains? not ; inline
 
-: deep-change-each ( obj quot -- )
+: deep-change-each ( obj quot: ( elt -- elt' ) -- )
     over branch? [ [
         [ call ] keep over >r deep-change-each r>
-    ] curry change-each ] [ 2drop ] if ; inline
+    ] curry change-each ] [ 2drop ] if ; inline recursive
 
 : flatten ( obj -- seq )
     [ branch? not ] deep-filter ;
index 3a46eb83fd898ad4c17838c5893f60abe7f2f76d..8bc12e270441894929fa3300274244e8ca190181 100644 (file)
@@ -2,13 +2,13 @@ USING: locals sequences kernel math ;
 IN: sorting.insertion
 
 <PRIVATE
-:: insert ( seq quot n -- )
+:: insert ( seq quot: ( elt -- elt' ) n -- )
     n zero? [
         n n 1- [ seq nth quot call ] bi@ >= [
             n n 1- seq exchange
             seq quot n 1- insert
         ] unless
-    ] unless ; inline
+    ] unless ; inline recursive
 PRIVATE>
 
 : insertion-sort ( seq quot -- )
index 0085376eaabd8b7936d789743e4699d2f75d5e6c..8d176b9c6308caa23b288c7ba1ee626b0c0a1fe5 100755 (executable)
@@ -16,10 +16,7 @@ SINGLETON: cocoa-ui-backend
 
 M: cocoa-ui-backend do-events ( -- )
     [
-        [
-            NSApp [ dup do-event ] [ ] [ ] while drop
-            ui-wait
-        ] ui-try
+        [ NSApp [ do-event ] curry loop ui-wait ] ui-try
     ] with-autorelease-pool ;
 
 TUPLE: pasteboard handle ;
index 3512bbf67000448202a6af652f298bbb4d687349..85bf5d335e2206341c6697083f7e1d7409adf1ec 100755 (executable)
@@ -142,7 +142,7 @@ M: freetype-renderer string-height ( open-font string -- h )
     i end < [
         i j bitmap texture copy-pixel
             bitmap texture end (copy-row)
-    ] when ; inline
+    ] when ; inline recursive
 
 :: copy-row ( i j bitmap texture width width2 -- i j )
     i j bitmap texture i width + (copy-row)