]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorDaniel Ehrenberg <littledan@Macintosh-122.local>
Tue, 18 Aug 2009 05:02:29 +0000 (00:02 -0500)
committerDaniel Ehrenberg <littledan@Macintosh-122.local>
Tue, 18 Aug 2009 05:02:29 +0000 (00:02 -0500)
79 files changed:
basis/bit-arrays/bit-arrays.factor
basis/compiler/compiler.factor [changed mode: 0644->0755]
basis/compiler/tree/cleanup/cleanup-tests.factor
basis/compiler/tree/debugger/debugger.factor
basis/compiler/tree/def-use/def-use.factor
basis/compiler/tree/def-use/simplified/simplified-tests.factor
basis/compiler/tree/def-use/simplified/simplified.factor
basis/compiler/tree/finalization/finalization.factor [changed mode: 0644->0755]
basis/compiler/tree/modular-arithmetic/modular-arithmetic-tests.factor
basis/compiler/tree/modular-arithmetic/modular-arithmetic.factor
basis/compiler/tree/propagation/call-effect/call-effect.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/propagation/propagation.factor
basis/grouping/grouping.factor
basis/io/encodings/ascii/ascii.factor
basis/math/bits/bits.factor
basis/math/complex/complex.factor
basis/math/functions/functions.factor
basis/math/ranges/ranges.factor
basis/math/ratios/ratios.factor
basis/multiline/multiline-docs.factor
basis/multiline/multiline-tests.factor
basis/multiline/multiline.factor
basis/sorting/functor/functor.factor
basis/specialized-arrays/functor/functor.factor
basis/stack-checker/known-words/known-words.factor
basis/tuple-arrays/tuple-arrays.factor
basis/vectors/functor/functor.factor
basis/windows/ole32/ole32.factor
build-support/factor.sh
core/alien/alien.factor
core/arrays/arrays.factor
core/assocs/assocs.factor
core/byte-arrays/byte-arrays-tests.factor
core/byte-arrays/byte-arrays.factor
core/byte-vectors/byte-vectors.factor
core/classes/builtin/builtin.factor
core/classes/tuple/tuple.factor
core/growable/growable.factor
core/hashtables/hashtables.factor
core/io/encodings/utf8/utf8.factor
core/io/streams/byte-array/byte-array-tests.factor
core/kernel/kernel.factor
core/layouts/layouts.factor
core/math/floats/floats.factor
core/math/integers/integers.factor
core/math/math.factor
core/math/order/order.factor
core/sbufs/sbufs.factor
core/sequences/sequences-docs.factor
core/sequences/sequences.factor
core/slots/slots.factor
core/strings/strings.factor
core/vectors/vectors.factor
core/words/words.factor
extra/benchmark/yuv-to-rgb/yuv-to-rgb.factor
extra/multi-methods/authors.txt [new file with mode: 0755]
extra/multi-methods/multi-methods.factor [new file with mode: 0755]
extra/multi-methods/summary.txt [new file with mode: 0755]
extra/multi-methods/tags.txt [new file with mode: 0644]
extra/multi-methods/tests/canonicalize.factor [new file with mode: 0644]
extra/multi-methods/tests/definitions.factor [new file with mode: 0644]
extra/multi-methods/tests/legacy.factor [new file with mode: 0644]
extra/multi-methods/tests/syntax.factor [new file with mode: 0644]
extra/multi-methods/tests/topological-sort.factor [new file with mode: 0644]
extra/rpn/authors.txt [new file with mode: 0644]
extra/rpn/rpn.factor [new file with mode: 0644]
extra/rpn/summary.txt [new file with mode: 0644]
extra/rpn/tags.txt [new file with mode: 0644]
unmaintained/multi-methods/authors.txt [deleted file]
unmaintained/multi-methods/multi-methods.factor [deleted file]
unmaintained/multi-methods/summary.txt [deleted file]
unmaintained/multi-methods/tags.txt [deleted file]
unmaintained/multi-methods/tests/canonicalize.factor [deleted file]
unmaintained/multi-methods/tests/definitions.factor [deleted file]
unmaintained/multi-methods/tests/legacy.factor [deleted file]
unmaintained/multi-methods/tests/syntax.factor [deleted file]
unmaintained/multi-methods/tests/topological-sort.factor [deleted file]

index 7aea3c458ae297b67103ac316f14ddfb371571d0..0b5a63a9068ebf78311d88485677e97c9fcb0734 100644 (file)
@@ -44,33 +44,33 @@ PRIVATE>
 : <bit-array> ( n -- bit-array )
     dup bits>bytes <byte-array> bit-array boa ; inline
 
-M: bit-array length length>> ;
+M: bit-array length length>> ; inline
 
 M: bit-array nth-unsafe
-    [ >fixnum ] [ underlying>> ] bi* byte/bit bit? ;
+    [ >fixnum ] [ underlying>> ] bi* byte/bit bit? ; inline
 
 M: bit-array set-nth-unsafe
     [ >fixnum ] [ underlying>> ] bi*
     [ byte/bit set-bit ] 2keep
-    swap n>byte set-alien-unsigned-1 ;
+    swap n>byte set-alien-unsigned-1 ; inline
 
 GENERIC: clear-bits ( bit-array -- )
 
-M: bit-array clear-bits 0 (set-bits) ;
+M: bit-array clear-bits 0 (set-bits) ; inline
 
 GENERIC: set-bits ( bit-array -- )
 
-M: bit-array set-bits -1 (set-bits) ;
+M: bit-array set-bits -1 (set-bits) ; inline
 
 M: bit-array clone
-    [ length>> ] [ underlying>> clone ] bi bit-array boa ;
+    [ length>> ] [ underlying>> clone ] bi bit-array boa ; inline
 
 : >bit-array ( seq -- bit-array )
     T{ bit-array f 0 B{ } } clone-like ; inline
 
-M: bit-array like drop dup bit-array? [ >bit-array ] unless ;
+M: bit-array like drop dup bit-array? [ >bit-array ] unless ; inline
 
-M: bit-array new-sequence drop <bit-array> ;
+M: bit-array new-sequence drop <bit-array> ; inline
 
 M: bit-array equal?
     over bit-array? [ [ underlying>> ] bi@ sequence= ] [ 2drop f ] if ;
@@ -81,7 +81,7 @@ M: bit-array resize
         resize-byte-array
     ] 2bi
     bit-array boa
-    dup clean-up ;
+    dup clean-up ; inline
 
 M: bit-array byte-length length 7 + -3 shift ;
 
old mode 100644 (file)
new mode 100755 (executable)
index 3b8d996..504acc7
@@ -120,7 +120,7 @@ M: predicate-engine-word no-compile? "owner-generic" word-prop no-compile? ;
     } cond ;
 
 : optimize? ( word -- ? )
-    { [ predicate-engine-word? ] [ single-generic? ] } 1|| not ;
+    single-generic? not ;
 
 : contains-breakpoints? ( -- ? )
     dependencies get keys [ "break?" word-prop ] any? ;
index 73ff49259a079d17a66d84b33ee5f9ae10029b5f..faf69686702c78adec3493422e10c30a42b252e4 100755 (executable)
@@ -41,13 +41,13 @@ IN: compiler.tree.cleanup.tests
 
 GENERIC: mynot ( x -- y )
 
-M: f mynot drop t ;
+M: f mynot drop t ; inline
 
-M: object mynot drop f ;
+M: object mynot drop f ; inline
 
 GENERIC: detect-f ( x -- y )
 
-M: f detect-f ;
+M: f detect-f ; inline
 
 [ t ] [
     [ dup [ mynot ] [ ] if detect-f ] \ detect-f inlined?
@@ -55,9 +55,9 @@ M: f detect-f ;
 
 GENERIC: xyz ( n -- n )
 
-M: integer xyz ;
+M: integer xyz ; inline
 
-M: object xyz ;
+M: object xyz ; inline
 
 [ t ] [
     [ { integer } declare xyz ] \ xyz inlined?
index a99e547b31f1affef730e3843c902660e2ea3fb9..4bf4cf88f02bb4efb92c0cd341d9977c12dff984 100644 (file)
@@ -11,6 +11,8 @@ compiler.tree.normalization
 compiler.tree.cleanup
 compiler.tree.propagation
 compiler.tree.propagation.info
+compiler.tree.escape-analysis
+compiler.tree.tuple-unboxing
 compiler.tree.def-use
 compiler.tree.builder
 compiler.tree.optimizer
@@ -209,6 +211,8 @@ SYMBOL: node-count
         normalize
         propagate
         cleanup
+        escape-analysis
+        unbox-tuples
         apply-identities
         compute-def-use
         remove-dead-code
index 21e79eb6c4cda2e9adf84bc717c83f38291123a4..872b6131c9bd453a9efa315aef58726f288adb7b 100644 (file)
@@ -21,7 +21,7 @@ TUPLE: definition value node uses ;
 ERROR: no-def-error value ;
 
 : def-of ( value -- definition )
-    dup def-use get at* [ nip ] [ no-def-error ] if ;
+    def-use get ?at [ no-def-error ] unless ;
 
 ERROR: multiple-defs-error ;
 
index a1a768d42956870e6d3eb29aa4f62876d7d78e5f..72c7e4c60c61f240ff3276c725aac7e6c0d05689 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel tools.test compiler.tree compiler.tree.builder
-compiler.tree.def-use compiler.tree.def-use.simplified accessors
-sequences sorting classes ;
+compiler.tree.recursive compiler.tree.def-use
+compiler.tree.def-use.simplified accessors sequences sorting classes ;
 IN: compiler.tree.def-use.simplified
 
 [ { #call #return } ] [
@@ -8,3 +8,17 @@ IN: compiler.tree.def-use.simplified
     first out-d>> first actually-used-by
     [ node>> class ] map natural-sort
 ] unit-test
+
+: word-1 ( a -- b ) dup [ word-1 ] when ; inline recursive
+
+[ { #introduce } ] [
+    [ word-1 ] build-tree analyze-recursive compute-def-use
+    last in-d>> first actually-defined-by
+    [ node>> class ] map natural-sort
+] unit-test
+
+[ { #if #return } ] [
+    [ word-1 ] build-tree analyze-recursive compute-def-use
+    first out-d>> first actually-used-by
+    [ node>> class ] map natural-sort
+] unit-test
\ No newline at end of file
index 9b2a2038da5a26512cce9a56aa09183fb7aaffba..c2fb74c97e285d2616414e67740fb082c23a85ee 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences kernel fry vectors
-compiler.tree compiler.tree.def-use ;
+USING: sequences kernel fry vectors accessors namespaces assocs sets
+stack-checker.branches compiler.tree compiler.tree.def-use ;
 IN: compiler.tree.def-use.simplified
 
 ! Simplified def-use follows chains of copies.
@@ -9,32 +9,85 @@ IN: compiler.tree.def-use.simplified
 ! A 'real' usage is a usage of a value that is not a #renaming.
 TUPLE: real-usage value node ;
 
+<PRIVATE
+
+SYMBOLS: visited accum ;
+
+: if-not-visited ( value quot -- )
+    over visited get key?
+    [ 2drop ] [ over visited get conjoin call ] if ; inline
+
+: with-simplified-def-use ( quot -- real-usages )
+    [
+        H{ } clone visited set
+        H{ } clone accum set
+        call
+        accum get keys
+    ] with-scope ; inline
+
+PRIVATE>
+
 ! Def
-GENERIC: actually-defined-by* ( value node -- real-usage )
+GENERIC: actually-defined-by* ( value node -- )
 
-: actually-defined-by ( value -- real-usage )
-    dup defined-by actually-defined-by* ;
+: (actually-defined-by) ( value -- )
+    [ dup defined-by actually-defined-by* ] if-not-visited ;
 
 M: #renaming actually-defined-by*
-    inputs/outputs swap [ index ] dip nth actually-defined-by ;
+    inputs/outputs swap [ index ] dip nth (actually-defined-by) ;
+
+M: #call-recursive actually-defined-by*
+    [ out-d>> index ] [ label>> return>> in-d>> nth ] bi
+    (actually-defined-by) ;
 
-M: #return-recursive actually-defined-by* real-usage boa ;
+M: #enter-recursive actually-defined-by*
+    [ out-d>> index ] keep
+    [ in-d>> nth (actually-defined-by) ]
+    [ label>> calls>> [ node>> in-d>> nth (actually-defined-by) ] with each ] 2bi ;
 
-M: node actually-defined-by* real-usage boa ;
+M: #phi actually-defined-by*
+    [ out-d>> index ] [ phi-in-d>> ] bi
+    [
+        nth dup +bottom+ eq?
+        [ drop ] [ (actually-defined-by) ] if
+    ] with each ;
+
+M: node actually-defined-by*
+    real-usage boa accum get conjoin ;
+
+: actually-defined-by ( value -- real-usages )
+    [ (actually-defined-by) ] with-simplified-def-use ;
 
 ! Use
-GENERIC# actually-used-by* 1 ( value node accum -- )
+GENERIC: actually-used-by* ( value node -- )
 
-: (actually-used-by) ( value accum -- )
-    [ [ used-by ] keep ] dip '[ _ swap _ actually-used-by* ] each ;
+: (actually-used-by) ( value -- )
+    [ dup used-by [ actually-used-by* ] with each ] if-not-visited ;
 
 M: #renaming actually-used-by*
-    [ inputs/outputs [ indices ] dip nths ] dip
-    '[ _ (actually-used-by) ] each ;
+    inputs/outputs [ indices ] dip nths
+    [ (actually-used-by) ] each ;
+
+M: #return-recursive actually-used-by*
+    [ in-d>> index ] keep
+    [ out-d>> nth (actually-used-by) ]
+    [ label>> calls>> [ node>> out-d>> nth (actually-used-by) ] with each ] 2bi ;
+
+M: #call-recursive actually-used-by*
+    [ in-d>> index ] [ label>> enter-out>> nth ] bi
+    (actually-used-by) ;
+
+M: #enter-recursive actually-used-by*
+    [ in-d>> index ] [ out-d>> nth ] bi (actually-used-by) ;
+
+M: #phi actually-used-by*
+    [ phi-in-d>> [ index ] with map-find drop ] [ out-d>> nth ] bi
+    (actually-used-by) ;
 
-M: #return-recursive actually-used-by* [ real-usage boa ] dip push ;
+M: #recursive actually-used-by* 2drop ;
 
-M: node actually-used-by* [ real-usage boa ] dip push ;
+M: node actually-used-by*
+    real-usage boa accum get conjoin ;
 
 : actually-used-by ( value -- real-usages )
-    10 <vector> [ (actually-used-by) ] keep ;
+    [ (actually-used-by) ] with-simplified-def-use ;
old mode 100644 (file)
new mode 100755 (executable)
index 9b278dd..fca35a5
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences words memoize combinators
-classes classes.builtin classes.tuple math.partial-dispatch
-fry assocs combinators.short-circuit
+classes classes.builtin classes.tuple classes.singleton
+math.partial-dispatch fry assocs combinators.short-circuit
 compiler.tree
 compiler.tree.combinators
 compiler.tree.propagation.info
@@ -45,6 +45,7 @@ M: predicate finalize-word
     "predicating" word-prop {
         { [ dup builtin-class? ] [ drop word>> cached-expansion ] }
         { [ dup tuple-class? ] [ drop word>> def>> splice-final ] }
+        { [ dup singleton-class? ] [ drop word>> def>> splice-final ] }
         [ drop ]
     } cond ;
 
index 7d40bf3fc16c7ee123646c0fbeef2e710cfc9362..7b972c516076680f44e7e5e1f4e398f751bfdf8f 100644 (file)
@@ -1,11 +1,10 @@
 ! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel kernel.private tools.test math math.partial-dispatch
-math.private accessors slots.private sequences sequences.private strings sbufs
-compiler.tree.builder
-compiler.tree.normalization
-compiler.tree.debugger
-alien.accessors layouts combinators byte-arrays ;
+prettyprint math.private accessors slots.private sequences
+sequences.private strings sbufs compiler.tree.builder
+compiler.tree.normalization compiler.tree.debugger alien.accessors
+layouts combinators byte-arrays ;
 IN: compiler.tree.modular-arithmetic.tests
 
 : test-modular-arithmetic ( quot -- quot' )
@@ -93,8 +92,6 @@ TUPLE: declared-fixnum { x fixnum } ;
     [ { string sbuf } declare ] \ push-all def>> append \ >fixnum inlined?
 ] unit-test
 
-
-
 [ t ] [
     [
         { integer } declare [ 256 mod ] map
@@ -140,6 +137,11 @@ TUPLE: declared-fixnum { x fixnum } ;
 [ [ >fixnum 255 fixnum-bitand ] ]
 [ [ >integer 256 rem ] test-modular-arithmetic ] unit-test
 
+[ t ] [
+    [ { fixnum fixnum } declare + [ 1 + >fixnum ] [ 2 + >fixnum ] bi ]
+    { >fixnum } inlined?
+] unit-test
+
 [ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-unsigned-1 ] ]
 [ [ [ { fixnum fixnum } declare + ] 2dip set-alien-unsigned-1 ] test-modular-arithmetic ] unit-test
 
@@ -176,3 +178,83 @@ cell {
     [ 0 10 <byte-array> 10 [ 1 pick 0 + >fixnum pick set-nth-unsafe [ 1 + >fixnum ] dip ] times ]
     { >fixnum } inlined?
 ] unit-test
+
+[ f ] [ [ + >fixnum ] { >fixnum } inlined? ] unit-test
+
+[ t ] [
+    [ >integer [ >fixnum ] [ >fixnum ] bi ]
+    { >integer } inlined?
+] unit-test
+
+[ f ] [
+    [ >integer [ >fixnum ] [ >fixnum ] bi ]
+    { >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ >integer [ 2 + >fixnum ] [ 3 + >fixnum ] bi ]
+    { >integer } inlined?
+] unit-test
+
+[ f ] [
+    [ >integer [ 2 + >fixnum ] [ 3 + >fixnum ] bi ]
+    { >fixnum } inlined?
+] unit-test
+
+[ f ] [
+    [ [ { fixnum } declare 2 fixnum+ ] dip [ >fixnum 2 - ] [ ] if ]
+    { fixnum+ } inlined?
+] unit-test
+
+[ t ] [
+    [ { fixnum boolean } declare [ 1 + ] [ "HI" throw ] if >fixnum ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ { fixnum boolean } declare [ 1 + ] [ drop 5 ] if >fixnum ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ { fixnum boolean } declare [ 1 + ] [ 2 + ] if >fixnum ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ [ [ 1 ] [ 4 ] if ] ] [
+    [ [ 1.5 ] [ 4 ] if >fixnum ] test-modular-arithmetic
+] unit-test
+
+[ [ [ 1 ] [ 2 ] if ] ] [
+    [ [ 1.5 ] [ 2.3 ] if >fixnum ] test-modular-arithmetic
+] unit-test
+
+[ f ] [
+    [ { fixnum fixnum boolean } declare [ [ 3 * ] [ 1 + ] dip ] [ [ 4 - ] [ 2 + ] dip ] if >fixnum ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ 0 1000 [ 1 + dup >fixnum . ] times drop ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ { fixnum } declare 3 + [ 1000 ] dip [ >fixnum . ] curry times ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ t ] [
+    [ 0 1000 [ 1 + ] times >fixnum ]
+    { fixnum+ >fixnum } inlined?
+] unit-test
+
+[ f ] [
+    [ f >fixnum ]
+    { >fixnum } inlined?
+] unit-test
+
+[ f ] [
+    [ [ >fixnum ] 2dip set-alien-unsigned-1 ]
+    { >fixnum } inlined?
+] unit-test
\ No newline at end of file
index 148286faba029fe7dd80ee10320a690e14ff12bd..d97295d0f17daca03522b7b419e8ef3540cefa21 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math math.partial-dispatch namespaces sequences sets
-accessors assocs words kernel memoize fry combinators
+USING: math math.private math.partial-dispatch namespaces sequences
+sets accessors assocs words kernel memoize fry combinators
 combinators.short-circuit layouts alien.accessors
 compiler.tree
 compiler.tree.combinators
+compiler.tree.propagation.info
 compiler.tree.def-use
 compiler.tree.def-use.simplified
 compiler.tree.late-optimizations ;
@@ -19,17 +20,24 @@ IN: compiler.tree.modular-arithmetic
 !    ==>
 !        [ >fixnum ] bi@ fixnum+fast
 
+! Words where the low-order bits of the output only depends on the
+! low-order bits of the input. If the output is only used for its
+! low-order bits, then the word can be converted into a form that is
+! cheaper to compute.
 { + - * bitand bitor bitxor } [
     [
         t "modular-arithmetic" set-word-prop
     ] each-integer-derived-op
 ] each
 
-{ bitand bitor bitxor bitnot }
+{ bitand bitor bitxor bitnot >integer }
 [ t "modular-arithmetic" set-word-prop ] each
 
+! Words that only use the low-order bits of their input. If the input
+! is a modular arithmetic word, then the input can be converted into
+! a form that is cheaper to compute.
 {
-    >fixnum
+    >fixnum bignum>fixnum float>fixnum
     set-alien-unsigned-1 set-alien-signed-1
     set-alien-unsigned-2 set-alien-signed-2
 }
@@ -38,80 +46,138 @@ cell 8 = [
 ] when
 [ t "low-order" set-word-prop ] each
 
-SYMBOL: modularize-values
+! Values which only have their low-order bits used. This set starts out
+! big and is gradually refined.
+SYMBOL: modular-values
 
 : modular-value? ( value -- ? )
-    modularize-values get key? ;
+    modular-values get key? ;
 
-: modularize-value ( value -- ) modularize-values get conjoin ;
+: modular-value ( value -- )
+    modular-values get conjoin ;
 
-GENERIC: maybe-modularize* ( value node -- )
+! Values which are known to be fixnums.
+SYMBOL: fixnum-values
 
-: maybe-modularize ( value -- )
-    actually-defined-by [ value>> ] [ node>> ] bi
-    over actually-used-by length 1 = [
-        maybe-modularize*
-    ] [ 2drop ] if ;
+: fixnum-value? ( value -- ? )
+    fixnum-values get key? ;
 
-M: #call maybe-modularize*
-    dup word>> "modular-arithmetic" word-prop [
-        [ modularize-value ]
-        [ in-d>> [ maybe-modularize ] each ] bi*
-    ] [ 2drop ] if ;
+: fixnum-value ( value -- )
+    fixnum-values get conjoin ;
 
-M: node maybe-modularize* 2drop ;
+GENERIC: compute-modular-candidates* ( node -- )
 
-GENERIC: compute-modularized-values* ( node -- )
+M: #push compute-modular-candidates*
+    [ out-d>> first ] [ literal>> ] bi
+    real? [ [ modular-value ] [ fixnum-value ] bi ] [ drop ] if ;
 
-M: #call compute-modularized-values*
-    dup word>> "low-order" word-prop
-    [ in-d>> first maybe-modularize ] [ drop ] if ;
+M: #call compute-modular-candidates*
+    {
+        {
+            [ dup word>> "modular-arithmetic" word-prop ]
+            [ out-d>> first [ modular-value ] [ fixnum-value ] bi ]
+        }
+        {
+            [ dup word>> "low-order" word-prop ]
+            [ in-d>> first modular-value ]
+        }
+        [ drop ]
+    } cond ;
+
+M: node compute-modular-candidates*
+    drop ;
+
+: compute-modular-candidates ( nodes -- )
+    H{ } clone modular-values set
+    H{ } clone fixnum-values set
+    [ compute-modular-candidates* ] each-node ;
+
+GENERIC: only-reads-low-order? ( node -- ? )
+
+M: #call only-reads-low-order?
+    {
+        [ word>> "low-order" word-prop ]
+        [
+            {
+                [ word>> "modular-arithmetic" word-prop ]
+                [ out-d>> first modular-values get key? ]
+            } 1&&
+        ]
+    } 1|| ;
+
+M: node only-reads-low-order? drop f ;
 
-M: node compute-modularized-values* drop ;
+SYMBOL: changed?
 
-: compute-modularized-values ( nodes -- )
-    [ compute-modularized-values* ] each-node ;
+: only-used-as-low-order? ( value -- ? )
+    actually-used-by [ node>> only-reads-low-order? ] all? ;
+
+: (compute-modular-values) ( -- )
+    modular-values get keys [
+        dup only-used-as-low-order?
+        [ drop ] [ modular-values get delete-at changed? on ] if
+    ] each ;
+
+: compute-modular-values ( -- )
+    [ changed? off (compute-modular-values) changed? get ] loop ;
 
 GENERIC: optimize-modular-arithmetic* ( node -- nodes )
 
+M: #push optimize-modular-arithmetic*
+    dup [ out-d>> first modular-value? ] [ literal>> real? ] bi and
+    [ [ >fixnum ] change-literal ] when ;
+
 : redundant->fixnum? ( #call -- ? )
-    in-d>> first actually-defined-by value>> modular-value? ;
+    in-d>> first actually-defined-by
+    [ value>> { [ modular-value? ] [ fixnum-value? ] } 1&& ] all? ;
 
 : optimize->fixnum ( #call -- nodes )
     dup redundant->fixnum? [ drop f ] when ;
 
+: should-be->fixnum? ( #call -- ? )
+    out-d>> first modular-value? ;
+
 : optimize->integer ( #call -- nodes )
-    dup out-d>> first actually-used-by dup length 1 = [
-        first node>> { [ #call? ] [ word>> \ >fixnum eq? ] } 1&&
-        [ drop { } ] when
-    ] [ drop ] if ;
+    dup should-be->fixnum? [ \ >fixnum >>word ] when ;
 
 MEMO: fixnum-coercion ( flags -- nodes )
+    ! flags indicate which input parameters are already known to be fixnums,
+    ! and don't need a coercion as a result.
     [ [ ] [ >fixnum ] ? ] map '[ _ spread ] splice-quot ;
 
+: modular-value-info ( #call -- alist )
+    [ in-d>> ] [ out-d>> ] bi append
+    fixnum <class-info> '[ _ ] { } map>assoc ;
+
 : optimize-modular-op ( #call -- nodes )
     dup out-d>> first modular-value? [
         [ in-d>> ] [ word>> integer-op-input-classes ] [ ] tri
         [
             [
-                [ actually-defined-by value>> modular-value? ]
+                [ actually-defined-by [ value>> modular-value? ] all? ]
                 [ fixnum eq? ]
                 bi* or
             ] 2map fixnum-coercion
         ] [ [ modular-variant ] change-word ] bi* suffix
     ] when ;
 
+: optimize-low-order-op ( #call -- nodes )
+    dup in-d>> first fixnum-value? [
+        [ ] [ in-d>> first ] [ info>> ] tri
+        [ drop fixnum <class-info> ] change-at
+    ] when ;
+
 M: #call optimize-modular-arithmetic*
     dup word>> {
-        { [ dup \ >fixnum eq? ] [ drop optimize->fixnum ] }
+        { [ dup { >fixnum bignum>fixnum float>fixnum } memq? ] [ drop optimize->fixnum ] }
         { [ dup \ >integer eq? ] [ drop optimize->integer ] }
         { [ dup "modular-arithmetic" word-prop ] [ drop optimize-modular-op ] }
+        { [ dup "low-order" word-prop ] [ drop optimize-low-order-op ] }
         [ drop ]
     } cond ;
 
 M: node optimize-modular-arithmetic* ;
 
 : optimize-modular-arithmetic ( nodes -- nodes' )
-    H{ } clone modularize-values set
-    dup compute-modularized-values
+    dup compute-modular-candidates compute-modular-values
     [ optimize-modular-arithmetic* ] map-nodes ;
index a667ea727f69cfc371f3ced4ba3e6cb0511a0f25..cdbeabe532d6b3920bdcd3ac0e8586be2f8c86af 100644 (file)
@@ -153,7 +153,7 @@ ERROR: uninferable ;
 
 : (value>quot) ( value-info -- quot )
     dup class>> {
-        { \ quotation [ literal>> dup remember-inlining '[ drop @ ] ] }
+        { \ quotation [ literal>> dup add-to-history '[ drop @ ] ] }
         { \ curry [
             slots>> third (value>quot)
             '[ [ obj>> ] [ quot>> @ ] bi ]
index 1586f2ca0b98b911604d26a9c25d5cadc7ffd35a..3836e0f3ba78451045326c50967eed41c914bda6 100755 (executable)
@@ -3,8 +3,8 @@
 USING: accessors kernel arrays sequences math math.order
 math.partial-dispatch generic generic.standard generic.single generic.math
 classes.algebra classes.union sets quotations assocs combinators
-words namespaces continuations classes fry combinators.smart hints
-locals
+combinators.short-circuit words namespaces continuations classes
+fry hints locals
 compiler.tree
 compiler.tree.builder
 compiler.tree.recursive
@@ -14,19 +14,6 @@ compiler.tree.propagation.info
 compiler.tree.propagation.nodes ;
 IN: compiler.tree.propagation.inlining
 
-! We count nodes up-front; if there are relatively few nodes,
-! we are more eager to inline
-SYMBOL: node-count
-
-: count-nodes ( nodes -- n )
-    0 swap [ drop 1 + ] each-node ;
-
-: compute-node-count ( nodes -- ) count-nodes node-count set ;
-
-! We try not to inline the same word too many times, to avoid
-! combinatorial explosion
-SYMBOL: inlining-count
-
 ! Splicing nodes
 : splicing-call ( #call word -- nodes )
     [ [ in-d>> ] [ out-d>> ] bi ] dip #call 1array ;
@@ -101,99 +88,28 @@ M: callable splicing-nodes splicing-body ;
     dupd inlining-math-partial eliminate-dispatch ;
 
 ! Method body inlining
-SYMBOL: recursive-calls
-DEFER: (flat-length)
-
-: word-flat-length ( word -- n )
-    {
-        ! special-case
-        { [ dup { dip 2dip 3dip } memq? ] [ drop 1 ] }
-        ! not inline
-        { [ dup inline? not ] [ drop 1 ] }
-        ! recursive and inline
-        { [ dup recursive-calls get key? ] [ drop 10 ] }
-        ! inline
-        [ [ recursive-calls get conjoin ] [ def>> (flat-length) ] bi ]
-    } cond ;
-
-: (flat-length) ( seq -- n )
-    [
-        {
-            { [ dup quotation? ] [ (flat-length) 2 + ] }
-            { [ dup array? ] [ (flat-length) ] }
-            { [ dup word? ] [ word-flat-length ] }
-            [ drop 0 ]
-        } cond
-    ] sigma ;
-
-: flat-length ( word -- n )
-    H{ } clone recursive-calls [
-        [ recursive-calls get conjoin ]
-        [ def>> (flat-length) 5 /i ]
-        bi
-    ] with-variable ;
-
-: classes-known? ( #call -- ? )
-    in-d>> [
-        value-info class>>
-        [ class-types length 1 = ]
-        [ union-class? not ]
-        bi and
-    ] any? ;
-
-: node-count-bias ( -- n )
-    45 node-count get [-] 8 /i ;
-
-: body-length-bias ( word -- n )
-    [ flat-length ] [ inlining-count get at 0 or ] bi
-    over 2 <= [ drop ] [ 2/ 1 + * ] if 24 swap [-] 4 /i ;
-
-: inlining-rank ( #call word -- n )
-    [
-        [ classes-known? 2 0 ? ]
-        [
-            [ body-length-bias ]
-            [ "specializer" word-prop 1 0 ? ]
-            [ method-body? 1 0 ? ]
-            tri
-            node-count-bias
-            loop-nesting get 0 or 2 *
-        ] bi*
-    ] sum-outputs ;
-
-: should-inline? ( #call word -- ? )
-    dup inline? [ 2drop t ] [ inlining-rank 5 >= ] if ;
-
 SYMBOL: history
 
 : already-inlined? ( obj -- ? ) history get memq? ;
 
 : add-to-history ( obj -- ) history [ swap suffix ] change ;
 
-: remember-inlining ( word -- )
-    [ inlining-count get inc-at ]
-    [ add-to-history ]
-    bi ;
-
 :: inline-word ( #call word -- ? )
     word already-inlined? [ f ] [
         #call word splicing-body [
             [
-                word remember-inlining
-                [ ] [ count-nodes ] [ (propagate) ] tri
+                word add-to-history
+                dup (propagate)
             ] with-scope
-            [ #call (>>body) ] [ node-count +@ ] bi* t
+            #call (>>body) t
         ] [ f ] if*
     ] if ;
 
-: inline-method-body ( #call word -- ? )
-    2dup should-inline? [ inline-word ] [ 2drop f ] if ;
-
 : always-inline-word? ( word -- ? )
     { curry compose } memq? ;
 
 : never-inline-word? ( word -- ? )
-    [ deferred? ] [ "default" word-prop ] [ \ call eq? ] tri or or ;
+    { [ deferred? ] [ "default" word-prop ] [ \ call eq? ] } 1|| ;
 
 : custom-inlining? ( word -- ? )
     "custom-inlining" word-prop ;
@@ -217,7 +133,7 @@ SYMBOL: history
         { [ dup always-inline-word? ] [ inline-word ] }
         { [ dup standard-generic? ] [ inline-standard-method ] }
         { [ dup math-generic? ] [ inline-math-method ] }
-        { [ dup method-body? ] [ inline-method-body ] }
+        { [ dup inline? ] [ inline-word ] }
         [ 2drop f ]
     } cond ;
 
index eb9591c40cc96751b4824ed0891032d01769a1bd..1c9b27dfbcf662d2aee71ec4e2ef66449eeb6178 100644 (file)
@@ -56,9 +56,9 @@ IN: compiler.tree.propagation.tests
 
 [ float ] [ [ { float real } declare + ] final-math-class ] unit-test
 
-[ rational ] [ [ { ratio ratio } declare + ] final-math-class ] unit-test
+[ rational ] [ [ { ratio ratio } declare + ] final-math-class ] unit-test
 
-[ rational ] [ [ { rational ratio } declare + ] final-math-class ] unit-test
+[ rational ] [ [ { rational ratio } declare + ] final-math-class ] unit-test
 
 [ number ] [ [ { complex complex } declare + ] final-math-class ] unit-test
 
@@ -444,6 +444,13 @@ TUPLE: mixed-mutable-immutable { x integer } { y sequence read-only } ;
     ] final-classes
 ] unit-test
 
+[ V{ f { } } ] [
+    [
+        T{ mixed-mutable-immutable f 3 { } }
+        [ x>> ] [ y>> ] bi
+    ] final-literals
+] unit-test
+
 ! Recursive propagation
 : recursive-test-1 ( a -- b ) recursive-test-1 ; inline recursive
 
@@ -502,8 +509,8 @@ TUPLE: mixed-mutable-immutable { x integer } { y sequence read-only } ;
 ] unit-test
 
 GENERIC: iterate ( obj -- next-obj ? )
-M: fixnum iterate f ;
-M: array iterate first t ;
+M: fixnum iterate f ; inline
+M: array iterate first t ; inline
 
 : dead-loop ( obj -- final-obj )
     iterate [ dead-loop ] when ; inline recursive
@@ -567,7 +574,7 @@ M: array iterate first t ;
 ] unit-test
 
 GENERIC: bad-generic ( a -- b )
-M: fixnum bad-generic 1 fixnum+fast ;
+M: fixnum bad-generic 1 fixnum+fast ; inline
 : bad-behavior ( -- b ) 4 bad-generic ; inline recursive
 
 [ V{ fixnum } ] [ [ bad-behavior ] final-classes ] unit-test
@@ -740,7 +747,7 @@ TUPLE: foo bar ;
 [ t ] [ [ foo new ] { new } inlined? ] unit-test
 
 GENERIC: whatever ( x -- y )
-M: number whatever drop foo ;
+M: number whatever drop foo ; inline
 
 [ t ] [ [ 1 whatever new ] { new } inlined? ] unit-test
 
@@ -749,8 +756,8 @@ M: number whatever drop foo ;
 [ f ] [ [ that-thing new ] { new } inlined? ] unit-test
 
 GENERIC: whatever2 ( x -- y )
-M: number whatever2 drop H{ { 1 1 } { 2 2 } { 3 3 } { 4 4 } { 5 6 } } ;
-M: f whatever2 ;
+M: number whatever2 drop H{ { 1 1 } { 2 2 } { 3 3 } { 4 4 } { 5 6 } } ; inline
+M: f whatever2 ; inline
 
 [ t ] [ [ 1 whatever2 at ] { at* hashcode* } inlined? ] unit-test
 [ f ] [ [ whatever2 at ] { at* hashcode* } inlined? ] unit-test
index 3dd2c4998af257ccdfdce2cad8d341a7fdc79068..a11264fb7ff9cf1bf64823c10a4e82227a15cb0d 100644 (file)
@@ -19,6 +19,4 @@ IN: compiler.tree.propagation
     H{ } clone copies set
     H{ } clone 1array value-infos set
     H{ } clone 1array constraints set
-    H{ } clone inlining-count set
-    dup compute-node-count
     dup (propagate) ;
index f68760a4e18e881d08d80507edd2223a90a7d99d..83579d2beb518bc00433992d1b79bff0b543a0a6 100644 (file)
@@ -18,41 +18,41 @@ GENERIC: group@ ( n groups -- from to seq )
 
 M: chunking-seq set-nth group@ <slice> 0 swap copy ;
 
-M: chunking-seq like drop { } like ;
+M: chunking-seq like drop { } like ; inline
 
 INSTANCE: chunking-seq sequence
 
 MIXIN: subseq-chunking
 
-M: subseq-chunking nth group@ subseq ;
+M: subseq-chunking nth group@ subseq ; inline
 
 MIXIN: slice-chunking
 
-M: slice-chunking nth group@ <slice> ;
+M: slice-chunking nth group@ <slice> ; inline
 
-M: slice-chunking nth-unsafe group@ slice boa ;
+M: slice-chunking nth-unsafe group@ slice boa ; inline
 
 TUPLE: abstract-groups < chunking-seq ;
 
 M: abstract-groups length
-    [ seq>> length ] [ n>> ] bi [ + 1 - ] keep /i ;
+    [ seq>> length ] [ n>> ] bi [ + 1 - ] keep /i ; inline
 
 M: abstract-groups set-length
-    [ n>> * ] [ seq>> ] bi set-length ;
+    [ n>> * ] [ seq>> ] bi set-length ; inline
 
 M: abstract-groups group@
-    [ n>> [ * dup ] keep + ] [ seq>> ] bi [ length min ] keep ;
+    [ n>> [ * dup ] keep + ] [ seq>> ] bi [ length min ] keep ; inline
 
 TUPLE: abstract-clumps < chunking-seq ;
 
 M: abstract-clumps length
-    [ seq>> length ] [ n>> ] bi - 1 + ;
+    [ seq>> length ] [ n>> ] bi - 1 + ; inline
 
 M: abstract-clumps set-length
-    [ n>> + 1 - ] [ seq>> ] bi set-length ;
+    [ n>> + 1 - ] [ seq>> ] bi set-length ; inline
 
 M: abstract-clumps group@
-    [ n>> over + ] [ seq>> ] bi ;
+    [ n>> over + ] [ seq>> ] bi ; inline
 
 PRIVATE>
 
index 16132ca810d814299bcc184c12637776130d56cf..00d3bc7509052385481bda70c98b2c7fb3f8c760 100644 (file)
@@ -16,7 +16,7 @@ PRIVATE>
 SINGLETON: ascii
 
 M: ascii encode-char
-    128 encode-if< ;
+    128 encode-if< ; inline
 
 M: ascii decode-char
-    128 decode-if< ;
+    128 decode-if< ; inline
index e469140ff423a0ea710eced35f54da536f74e684..4de49c06a7b1455fc25fb6d22a5368dfbd5a8eb0 100644 (file)
@@ -9,9 +9,9 @@ C: <bits> bits
 : make-bits ( number -- bits )
     [ T{ bits f 0 0 } ] [ dup abs log2 1 + <bits> ] if-zero ; inline
 
-M: bits length length>> ;
+M: bits length length>> ; inline
 
-M: bits nth-unsafe number>> swap bit? ;
+M: bits nth-unsafe number>> swap bit? ; inline
 
 INSTANCE: bits immutable-sequence
 
index 832a9e64baf9db08cf7921f8aaafc1c3661160d2..ce94dfaca886a0c4e87699bc6c7defee2c2a747e 100644 (file)
@@ -5,29 +5,29 @@ math.libm math.functions arrays math.functions.private sequences
 parser ;
 IN: math.complex.private
 
-M: real real-part ;
-M: real imaginary-part drop 0 ;
-M: complex real-part real>> ;
-M: complex imaginary-part imaginary>> ;
-M: complex absq >rect [ sq ] bi@ + ;
-M: complex hashcode* nip >rect [ hashcode ] bi@ bitxor ;
+M: real real-part ; inline
+M: real imaginary-part drop 0 ; inline
+M: complex real-part real>> ; inline
+M: complex imaginary-part imaginary>> ; inline
+M: complex absq >rect [ sq ] bi@ + ; inline
+M: complex hashcode* nip >rect [ hashcode ] bi@ bitxor ; inline
 : componentwise ( x y quot -- a b ) [ [ >rect ] bi@ ] dip bi-curry@ bi* ; inline
 : complex= ( x y quot -- ? ) componentwise and ; inline
-M: complex equal? over complex? [ [ = ] complex= ] [ 2drop f ] if ;
-M: complex number= [ number= ] complex= ;
+M: complex equal? over complex? [ [ = ] complex= ] [ 2drop f ] if ; inline
+M: complex number= [ number= ] complex= ; inline
 : complex-op ( x y quot -- z ) componentwise rect> ; inline
-M: complex + [ + ] complex-op ;
-M: complex - [ - ] complex-op ;
+M: complex + [ + ] complex-op ; inline
+M: complex - [ - ] complex-op ; inline
 : *re ( x y -- xr*yr xi*yi ) [ >rect ] bi@ [ * ] bi-curry@ bi* ; inline
 : *im ( x y -- xi*yr xr*yi ) swap [ >rect ] bi@ swap [ * ] bi-curry@ bi* ; inline
-M: complex * [ *re - ] [ *im + ] 2bi rect> ;
+M: complex * [ *re - ] [ *im + ] 2bi rect> ; inline
 : (complex/) ( x y -- r i m ) [ [ *re + ] [ *im - ] 2bi ] keep absq ; inline
 : complex/ ( x y quot -- z ) [ (complex/) ] dip curry bi@ rect> ; inline
-M: complex / [ / ] complex/ ;
-M: complex /f [ /f ] complex/ ;
-M: complex /i [ /i ] complex/ ;
-M: complex abs absq >float fsqrt ;
-M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ;
+M: complex / [ / ] complex/ ; inline
+M: complex /f [ /f ] complex/ ; inline
+M: complex /i [ /i ] complex/ ; inline
+M: complex abs absq >float fsqrt ; inline
+M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ; inline
 
 IN: syntax
 
index 801522b37634a89dba9c31a3c0a7d94de5809082..0daea7f706664cdb1c29263312012cd75d568138 100644 (file)
@@ -13,7 +13,7 @@ IN: math.functions
 GENERIC: sqrt ( x -- y ) foldable
 
 M: real sqrt
-    >float dup 0.0 < [ neg fsqrt 0.0 swap rect> ] [ fsqrt ] if ;
+    >float dup 0.0 < [ neg fsqrt 0.0 swap rect> ] [ fsqrt ] if ; inline
 
 : factor-2s ( n -- r s )
     #! factor an integer into 2^r * s
@@ -120,7 +120,7 @@ ERROR: non-trivial-divisor n ;
 
 GENERIC: absq ( x -- y ) foldable
 
-M: real absq sq ;
+M: real absq sq ; inline
 
 : ~abs ( x y epsilon -- ? )
     [ - abs ] dip < ;
@@ -148,13 +148,13 @@ M: real absq sq ;
 
 GENERIC: exp ( x -- y )
 
-M: real exp fexp ;
+M: real exp fexp ; inline
 
 M: complex exp >rect swap fexp swap polar> ;
 
 GENERIC: log ( x -- y )
 
-M: real log dup 0.0 >= [ flog ] [ 0.0 rect> log ] if ;
+M: real log dup 0.0 >= [ flog ] [ 0.0 rect> log ] if ; inline
 
 M: complex log >polar swap flog swap rect> ;
 
@@ -169,7 +169,7 @@ M: complex cos
     [ [ fcos ] [ fcosh ] bi* * ]
     [ [ fsin neg ] [ fsinh ] bi* * ] 2bi rect> ;
 
-M: real cos fcos ;
+M: real cos fcos ; inline
 
 : sec ( x -- y ) cos recip ; inline
 
@@ -180,7 +180,7 @@ M: complex cosh
     [ [ fcosh ] [ fcos ] bi* * ]
     [ [ fsinh ] [ fsin ] bi* * ] 2bi rect> ;
 
-M: real cosh fcosh ;
+M: real cosh fcosh ; inline
 
 : sech ( x -- y ) cosh recip ; inline
 
@@ -191,7 +191,7 @@ M: complex sin
     [ [ fsin ] [ fcosh ] bi* * ]
     [ [ fcos ] [ fsinh ] bi* * ] 2bi rect> ;
 
-M: real sin fsin ;
+M: real sin fsin ; inline
 
 : cosec ( x -- y ) sin recip ; inline
 
@@ -202,7 +202,7 @@ M: complex sinh
     [ [ fsinh ] [ fcos ] bi* * ]
     [ [ fcosh ] [ fsin ] bi* * ] 2bi rect> ;
 
-M: real sinh fsinh ;
+M: real sinh fsinh ; inline
 
 : cosech ( x -- y ) sinh recip ; inline
 
@@ -210,13 +210,13 @@ GENERIC: tan ( x -- y ) foldable
 
 M: complex tan [ sin ] [ cos ] bi / ;
 
-M: real tan ftan ;
+M: real tan ftan ; inline
 
 GENERIC: tanh ( x -- y ) foldable
 
 M: complex tanh [ sinh ] [ cosh ] bi / ;
 
-M: real tanh ftanh ;
+M: real tanh ftanh ; inline
 
 : cot ( x -- y ) tan recip ; inline
 
@@ -252,7 +252,7 @@ GENERIC: atan ( x -- y ) foldable
 
 M: complex atan i* atanh i* ;
 
-M: real atan fatan ;
+M: real atan fatan ; inline
 
 : asec ( x -- y ) recip acos ; inline
 
index d28afa14130e3e9a5875fc3244493bf990768990..58cb2b09db226b887ce995fdaaf992c05903cefc 100644 (file)
@@ -12,11 +12,9 @@ TUPLE: range
 : <range> ( a b step -- range )
     [ over - ] dip [ /i 1 + 0 max ] keep range boa ; inline
 
-M: range length ( seq -- n )
-    length>> ;
+M: range length ( seq -- n ) length>> ; inline
 
-M: range nth-unsafe ( n range -- obj )
-    [ step>> * ] keep from>> + ;
+M: range nth-unsafe ( n range -- obj ) [ step>> * ] keep from>> + ; inline
 
 ! For ranges with many elements, the default element-wise methods
 ! sequences define are unsuitable because they're O(n)
index 7da92cd1545ee596c8cf68a2a56462cfbc403b1b..dcb8e87e7c85ee1b874d783829e7e63a0806fd0d 100644 (file)
@@ -48,8 +48,8 @@ M: ratio >fixnum >fraction /i >fixnum ;
 M: ratio >bignum >fraction /i >bignum ;
 M: ratio >float >fraction /f ;
 
-M: ratio numerator numerator>> ;
-M: ratio denominator denominator>> ;
+M: ratio numerator numerator>> ; inline
+M: ratio denominator denominator>> ; inline
 
 M: ratio < scale < ;
 M: ratio <= scale <= ;
index 4782571d4aa82e9cfe6fdd491a1154a031312bb7..0977acd1cd1a214283c48308f8be88bb2dda456b 100644 (file)
@@ -18,6 +18,25 @@ HELP: /*
            ""
 } ;
 
+HELP: HEREDOC:
+{ $syntax "HEREDOC: marker\n...text...marker" }
+{ $values { "marker" "a word (token)" } { "text" "arbitrary text" } { "" "a string" } }
+{ $description "A multiline string syntax with a user-specified terminating delimiter.  HEREDOC: reads the next word, and uses it as the 'close quote'.  All input from the beginning of the HEREDOC:'s next line, until the first appearance of the word's name, becomes a string.  The terminating word does not need to be at the beginning of a line.\n\nThe HEREDOC: line should not have anything after the delimiting word.  The delimiting word should be an alphanumeric token.  It should not be, as in some other languages, a \"quoted string\"." }
+{ $examples
+    { $example "USING: multiline prettyprint ;"
+               "HEREDOC: END\nx\nEND ."
+               "\"x\\n\""
+    }
+    { $example "USING: multiline prettyprint ;"
+               "HEREDOC: END\nxEND ."
+               "\"x\""
+    }
+    { $example "USING: multiline prettyprint sequences ;"
+               "2 5 HEREDOC: zap\nfoo\nbarzap subseq ."
+               "\"o\\nb\""
+    }
+} ;
+
 { POSTPONE: <" POSTPONE: STRING: } related-words
 
 HELP: parse-multiline-string
@@ -29,6 +48,7 @@ ARTICLE: "multiline" "Multiline"
 "Multiline strings:"
 { $subsection POSTPONE: STRING: }
 { $subsection POSTPONE: <" }
+{ $subsection POSTPONE: HEREDOC: }
 "Multiline comments:"
 { $subsection POSTPONE: /* }
 "Writing new multiline parsing words:"
index 153b6cedbe7b3709bd0c999bfb535725b7915e18..2458589d27d5c2484aad2b5ed7dc3e6f01d33bb7 100644 (file)
@@ -19,3 +19,43 @@ world"> ] unit-test
 
 [ "\nhi" ] [ <"
 hi"> ] unit-test
+
+
+! HEREDOC:
+
+[ "foo\nbar\n" ] [ HEREDOC: END
+foo
+bar
+END ] unit-test
+
+[ "foo\nbar" ] [ HEREDOC: END
+foo
+barEND ] unit-test
+
+[ "" ] [ HEREDOC: END
+END ] unit-test
+
+[ " " ] [ HEREDOC: END
+ END ] unit-test
+
+[ "\n" ] [ HEREDOC: END
+
+END ] unit-test
+
+[ "x" ] [ HEREDOC: END
+xEND ] unit-test
+
+[ "xyz " ] [ HEREDOC: END
+xyz END ] unit-test
+
+[ "} ! * # \" Â«\n" ] [ HEREDOC: END
+} ! * # " Â«
+END ] unit-test
+
+[ 21 "foo\nbar" " HEREDOC: FOO\n FOO\n" 22 ] [ 21 HEREDOC: X
+foo
+barX HEREDOC: END ! mumble
+ HEREDOC: FOO
+ FOO
+END 22 ] unit-test
+
index c0d109e3c5a0e4286f0e018a1072f5c3f6b13913..e4334f1201101ca93bbc9c77cf879472e71d6ed0 100644 (file)
@@ -27,7 +27,7 @@ SYNTAX: STRING:
 
 <PRIVATE
 
-:: (parse-multiline-string) ( i end -- j )
+:: (scan-multiline-string) ( i end -- j )
     lexer get line-text>> :> text
     text [
         end text i start* [| j |
@@ -35,19 +35,22 @@ SYNTAX: STRING:
         ] [
             text i short tail % CHAR: \n ,
             lexer get next-line
-            0 end (parse-multiline-string)
+            0 end (scan-multiline-string)
         ] if*
     ] [ end unexpected-eof ] if ;
         
-PRIVATE>
-
-: parse-multiline-string ( end-text -- str )
+:: (parse-multiline-string) ( end-text skip-n-chars -- str )
     [
         lexer get
-        [ 1 + swap (parse-multiline-string) ]
+        [ skip-n-chars + end-text (scan-multiline-string) ]
         change-column drop
     ] "" make ;
 
+PRIVATE>
+
+: parse-multiline-string ( end-text -- str )
+    1 (parse-multiline-string) ;
+
 SYNTAX: <"
     "\">" parse-multiline-string parsed ;
 
@@ -61,3 +64,9 @@ SYNTAX: {"
     "\"}" parse-multiline-string parsed ;
 
 SYNTAX: /* "*/" parse-multiline-string drop ;
+
+SYNTAX: HEREDOC:
+    scan
+    lexer get next-line
+    0 (parse-multiline-string)
+    parsed ;
index 7f46af4c9274ee9d8b4d7659e89a510170bc682c..8e9ea6a9ea88003c0346636fbf074e9e219f0d2d 100644 (file)
@@ -10,7 +10,7 @@ NAME>=< DEFINES ${NAME}>=<
 
 WHERE
 
-: NAME<=> ( obj1 obj2 -- <=> ) QUOT bi@ <=> ;
+: NAME<=> ( obj1 obj2 -- <=> ) QUOT compare ;
 : NAME>=< ( obj1 obj2 -- >=< ) NAME<=> invert-comparison ;
 
 ;FUNCTOR
index 1c855be1a485c84144538cdcc51eea63d683e04e..06b9aef17dc22d8ccebfe2d1fe33a780293a73af 100644 (file)
@@ -39,19 +39,19 @@ TUPLE: A
     dup length T heap-size /mod 0 = [ drop T bad-byte-array-length ] unless
     swap A boa ; inline
 
-M: A clone [ length>> ] [ underlying>> clone ] bi A boa ;
+M: A clone [ length>> ] [ underlying>> clone ] bi A boa ; inline
 
-M: A length length>> ;
+M: A length length>> ; inline
 
-M: A nth-unsafe underlying>> NTH call ;
+M: A nth-unsafe underlying>> NTH call ; inline
 
-M: A set-nth-unsafe underlying>> SET-NTH call ;
+M: A set-nth-unsafe underlying>> SET-NTH call ; inline
 
-: >A ( seq -- specialized-array ) A new clone-like ; inline
+: >A ( seq -- specialized-array ) A new clone-like ;
 
-M: A like drop dup A instance? [ >A ] unless ;
+M: A like drop dup A instance? [ >A ] unless ; inline
 
-M: A new-sequence drop (A) ;
+M: A new-sequence drop (A) ; inline
 
 M: A equal? over A instance? [ sequence= ] [ 2drop f ] if ;
 
@@ -60,9 +60,9 @@ M: A resize
         [ T heap-size * ] [ underlying>> ] bi*
         resize-byte-array
     ] 2bi
-    A boa ;
+    A boa ; inline
 
-M: A byte-length underlying>> length ;
+M: A byte-length underlying>> length ; inline
 
 M: A pprint-delims drop \ A{ \ } ;
 
index 0edbe5e53dc87a5e0a22f6223cd1bd6051bd962c..ea8f6f5f49ccaf5568632a9965498e8237a5c599 100644 (file)
@@ -158,6 +158,8 @@ M: bad-executable summary
 
 \ <tuple-boa> [ infer-<tuple-boa> ] "special" set-word-prop
 
+\ <tuple-boa> t "flushable" set-word-prop
+
 : infer-effect-unsafe ( word -- )
     pop-literal nip
     add-effect-input
index 761dbd816a8c77c66bc9a4863953a25fb25c1fa8..92e7541616f3507d05075fa5a7ec5d04d38db358 100644 (file)
@@ -54,17 +54,17 @@ TUPLE: CLASS-array
     [ \ CLASS [ tuple-prototype <repetition> concat ] [ tuple-arity ] bi ] keep
     \ CLASS-array boa ; inline
 
-M: CLASS-array length length>> ;
+M: CLASS-array length length>> ; inline
 
-M: CLASS-array nth-unsafe tuple-slice \ CLASS read-tuple ;
+M: CLASS-array nth-unsafe tuple-slice \ CLASS read-tuple ; inline
 
-M: CLASS-array set-nth-unsafe tuple-slice \ CLASS write-tuple ;
+M: CLASS-array set-nth-unsafe tuple-slice \ CLASS write-tuple ; inline
 
-M: CLASS-array new-sequence drop <CLASS-array> ;
+M: CLASS-array new-sequence drop <CLASS-array> ; inline
 
 : >CLASS-array ( seq -- tuple-array ) 0 <CLASS-array> clone-like ;
 
-M: CLASS-array like drop dup CLASS-array? [ >CLASS-array ] unless ;
+M: CLASS-array like drop dup CLASS-array? [ >CLASS-array ] unless ; inline
 
 INSTANCE: CLASS-array sequence
 
index 47a6c2090ae57e49fbeba3a46ea0fe64bf07ab6b..b70c7c50509a1ed6b4571447b85913e3b0d650ed 100644 (file)
@@ -18,11 +18,11 @@ TUPLE: V { underlying A } { length array-capacity } ;
 M: V like
     drop dup V instance? [
         dup A instance? [ dup length V boa ] [ >V ] if
-    ] unless ;
+    ] unless ; inline
 
-M: V new-sequence drop [ <A> ] [ >fixnum ] bi V boa ;
+M: V new-sequence drop [ <A> ] [ >fixnum ] bi V boa ; inline
 
-M: A new-resizable drop <V> ;
+M: A new-resizable drop <V> ; inline
 
 M: V equal? over V instance? [ sequence= ] [ 2drop f ] if ;
 
index 864700cb0fa6afe362c6490daac0bd45550b8f00..d6a08325d964c994b8cf38b5012791ccf6a18f2f 100755 (executable)
@@ -1,5 +1,5 @@
 USING: alien alien.syntax alien.c-types alien.strings math
-kernel sequences windows.errors windows.types debugger io
+kernel sequences windows.errors windows.types io
 accessors math.order namespaces make math.parser windows.kernel32
 combinators locals specialized-arrays.direct.uchar ;
 IN: windows.ole32
@@ -116,11 +116,10 @@ FUNCTION: void ReleaseStgMedium ( LPSTGMEDIUM pmedium ) ;
 : succeeded? ( hresult -- ? )
     0 HEX: 7FFFFFFF between? ;
 
-TUPLE: ole32-error error-code ;
-C: <ole32-error> ole32-error
+TUPLE: ole32-error code message ;
 
-M: ole32-error error.
-    "COM method failed: " print error-code>> n>win32-error-string print ;
+: <ole32-error> ( code -- error )
+    dup n>win32-error-string \ ole32-error boa ;
 
 : ole32-error ( hresult -- )
     dup succeeded? [ drop ] [ <ole32-error> throw ] if ;
index d5b8bd5411c7e3c10b4c6bacb3a378174d640507..b179811bda31dbbc2bccd0e717aa4e8270ac4560 100755 (executable)
@@ -487,12 +487,12 @@ update_bootstrap() {
 }
 
 refresh_image() {
-    ./$FACTOR_BINARY -script -e="USE: vocabs.loader USE: system refresh-all USE: memory save 0 exit"
+    ./$FACTOR_BINARY -script -e="USING: vocabs.loader system memory ; refresh-all USE: memory save 0 exit"
     check_ret factor
 }
 
 make_boot_image() {
-    ./$FACTOR_BINARY -script -e="\"$MAKE_IMAGE_TARGET\" USE: system USE: bootstrap.image make-image save 0 exit"
+    ./$FACTOR_BINARY -script -e="\"$MAKE_IMAGE_TARGET\" USING: system bootstrap.image memory ; make-image save 0 exit"
     check_ret factor
 
 }
index ec38e3be5b8b5b9ff821339012ff6af25414a446..d98ea3d1032a019d7367aba509fa88e9c07e99c0 100644 (file)
@@ -20,11 +20,11 @@ UNION: pinned-c-ptr
 
 GENERIC: >c-ptr ( obj -- c-ptr )
 
-M: c-ptr >c-ptr ;
+M: c-ptr >c-ptr ; inline
 
 SLOT: underlying
 
-M: object >c-ptr underlying>> ;
+M: object >c-ptr underlying>> ; inline
 
 GENERIC: expired? ( c-ptr -- ? ) flushable
 
index dd70e45b6b15eb485dacb804bad7e5c88fb8ac65..fa4d4b2f6951d0938d557edd49ae89899a4246e0 100644 (file)
@@ -4,17 +4,17 @@ USING: accessors kernel kernel.private math math.private
 sequences sequences.private ;
 IN: arrays
 
-M: array clone (clone) ;
-M: array length length>> ;
-M: array nth-unsafe [ >fixnum ] dip array-nth ;
-M: array set-nth-unsafe [ >fixnum ] dip set-array-nth ;
-M: array resize resize-array ;
+M: array clone (clone) ; inline
+M: array length length>> ; inline
+M: array nth-unsafe [ >fixnum ] dip array-nth ; inline
+M: array set-nth-unsafe [ >fixnum ] dip set-array-nth ; inline
+M: array resize resize-array ; inline
 
 : >array ( seq -- array ) { } clone-like ;
 
-M: object new-sequence drop 0 <array> ;
+M: object new-sequence drop 0 <array> ; inline
 
-M: f new-sequence drop [ f ] [ 0 <array> ] if-zero ;
+M: f new-sequence drop [ f ] [ 0 <array> ] if-zero ; inline
 
 M: array equal?
     over array? [ sequence= ] [ 2drop f ] if ;
index 8b6809236c4368a1301ad215721481f7e386dc4f..e633a54843a6dc1e7c70ba10453ef1cf95a9866e 100755 (executable)
@@ -17,7 +17,7 @@ GENERIC: assoc-like ( assoc exemplar -- newassoc )
 GENERIC: assoc-clone-like ( assoc exemplar -- newassoc )
 GENERIC: >alist ( assoc -- newassoc )
 
-M: assoc assoc-like drop ;
+M: assoc assoc-like drop ; inline
 
 : ?at ( key assoc -- value/key ? )
     2dup at* [ 2nip t ] [ 2drop f ] if ; inline
@@ -87,7 +87,7 @@ PRIVATE>
 
 M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     [ dup assoc-size ] dip new-assoc
-    [ [ set-at ] with-assoc assoc-each ] keep ;
+    [ [ set-at ] with-assoc assoc-each ] keep ; inline
 
 : keys ( assoc -- keys )
     [ drop ] { } assoc>map ;
@@ -189,48 +189,48 @@ M: sequence set-at
     [ 2nip set-second ]
     [ drop [ swap 2array ] dip push ] if ;
 
-M: sequence new-assoc drop <vector> ;
+M: sequence new-assoc drop <vector> ; inline
 
-M: sequence clear-assoc delete-all ;
+M: sequence clear-assoc delete-all ; inline
 
 M: sequence delete-at
     [ nip ] [ search-alist nip ] 2bi
     [ swap delete-nth ] [ drop ] if* ;
 
-M: sequence assoc-size length ;
+M: sequence assoc-size length ; inline
 
 M: sequence assoc-clone-like
-    [ >alist ] dip clone-like ;
+    [ >alist ] dip clone-like ; inline
 
 M: sequence assoc-like
-    [ >alist ] dip like ;
+    [ >alist ] dip like ; inline
 
-M: sequence >alist ;
+M: sequence >alist ; inline
 
 ! Override sequence => assoc instance for f
-M: f clear-assoc drop ;
+M: f clear-assoc drop ; inline
 
-M: f assoc-like drop dup assoc-empty? [ drop f ] when ;
+M: f assoc-like drop dup assoc-empty? [ drop f ] when ; inline
 
 INSTANCE: sequence assoc
 
-TUPLE: enum seq ;
+TUPLE: enum { seq read-only } ;
 
 C: <enum> enum
 
 M: enum at*
     seq>> 2dup bounds-check?
-    [ nth t ] [ 2drop f f ] if ;
+    [ nth t ] [ 2drop f f ] if ; inline
 
-M: enum set-at seq>> set-nth ;
+M: enum set-at seq>> set-nth ; inline
 
-M: enum delete-at seq>> delete-nth ;
+M: enum delete-at seq>> delete-nth ; inline
 
 M: enum >alist ( enum -- alist )
-    seq>> [ length ] keep zip ;
+    seq>> [ length ] keep zip ; inline
 
-M: enum assoc-size seq>> length ;
+M: enum assoc-size seq>> length ; inline
 
-M: enum clear-assoc seq>> delete-all ;
+M: enum clear-assoc seq>> delete-all ; inline
 
 INSTANCE: enum assoc
index a23e4ecd745fc3222fb8f9e82258b34e8c10ba44..e28083b2dbf5a21a39f089224e261994479bcd13 100644 (file)
@@ -1,4 +1,4 @@
-USING: tools.test byte-arrays sequences kernel ;\r
+USING: tools.test byte-arrays sequences kernel math ;\r
 IN: byte-arrays.tests\r
 \r
 [ 6 B{ 1 2 3 } ] [\r
@@ -11,3 +11,7 @@ IN: byte-arrays.tests
 [ -10 B{ } resize-byte-array ] must-fail\r
 \r
 [ B{ 123 } ] [ 123 1byte-array ] unit-test\r
+\r
+[ B{ 123 } ] [ 123 0 B{ 0 } [ set-nth ] keep ] unit-test\r
+\r
+[ B{ 123 } ] [ 123 >bignum 0 B{ 0 } [ set-nth ] keep ] unit-test
\ No newline at end of file
index 72989ac447069d04fd48c9460b1136010589bca4..3c89a5f63e777dc9a28854fa9ee0b761e151d68c 100644 (file)
@@ -4,18 +4,18 @@ USING: accessors kernel kernel.private alien.accessors sequences
 sequences.private math ;
 IN: byte-arrays
 
-M: byte-array clone (clone) ;
-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 ;
+M: byte-array clone (clone) ; inline
+M: byte-array length length>> ; inline
+M: byte-array nth-unsafe swap >fixnum alien-unsigned-1 ; inline
+M: byte-array set-nth-unsafe swap >fixnum set-alien-unsigned-1 ; inline
 : >byte-array ( seq -- byte-array ) B{ } clone-like ; inline
-M: byte-array new-sequence drop (byte-array) ;
+M: byte-array new-sequence drop (byte-array) ; inline
 
 M: byte-array equal?
     over byte-array? [ sequence= ] [ 2drop f ] if ;
 
 M: byte-array resize
-    resize-byte-array ;
+    resize-byte-array ; inline
 
 INSTANCE: byte-array sequence
 
index fc3d9501c777cd1463509ce3adaad37b4c3f01a2..287e9724051a91ead34cad6453cafce3cefdd36d 100644 (file)
@@ -18,15 +18,15 @@ M: byte-vector like
     drop dup byte-vector? [\r
         dup byte-array?\r
         [ dup length byte-vector boa ] [ >byte-vector ] if\r
-    ] unless ;\r
+    ] unless ; inline\r
 \r
 M: byte-vector new-sequence\r
-    drop [ (byte-array) ] [ >fixnum ] bi byte-vector boa ;\r
+    drop [ (byte-array) ] [ >fixnum ] bi byte-vector boa ; inline\r
 \r
 M: byte-vector equal?\r
     over byte-vector? [ sequence= ] [ 2drop f ] if ;\r
 \r
-M: byte-vector contract 2drop ;\r
+M: byte-vector contract 2drop ; inline\r
 \r
 M: byte-array like\r
     #! If we have an byte-array, we're done.\r
@@ -39,8 +39,8 @@ M: byte-array like
             2dup length eq?\r
             [ nip ] [ resize-byte-array ] if\r
         ] [ >byte-array ] if\r
-    ] unless ;\r
+    ] unless ; inline\r
 \r
-M: byte-array new-resizable drop <byte-vector> ;\r
+M: byte-array new-resizable drop <byte-vector> ; inline\r
 \r
 INSTANCE: byte-vector growable\r
index c74c8f3b503ef83f108948f356e34c5b8659f9eb..8eeb4ce3575e3884e149cc3aebe3282c4b9ccf6b 100644 (file)
@@ -20,9 +20,9 @@ PREDICATE: hi-tag-class < builtin-class class>type 7 > ;
 
 : bootstrap-type>class ( n -- class ) builtins get nth ;
 
-M: hi-tag class hi-tag type>class ;
+M: hi-tag class hi-tag type>class ; inline
 
-M: object class tag type>class ;
+M: object class tag type>class ; inline
 
 M: builtin-class rank-class drop 0 ;
 
index 8e49e2f5f44990db37bfba9a42cf61dd95690111..0a437a3d6968918670a40cd91ebc7e5f4dae8fe5 100755 (executable)
@@ -29,7 +29,7 @@ PREDICATE: immutable-tuple-class < tuple-class ( class -- ? )
 : layout-of ( tuple -- layout )
     1 slot { array } declare ; inline
 
-M: tuple class layout-of 2 slot { word } declare ;
+M: tuple class layout-of 2 slot { word } declare ; inline
 
 : tuple-size ( tuple -- size )
     layout-of 3 slot { fixnum } declare ; inline
@@ -323,7 +323,7 @@ M: tuple-class (classes-intersect?)
         [ swap classes-intersect? ]
     } cond ;
 
-M: tuple clone (clone) ;
+M: tuple clone (clone) ; inline
 
 M: tuple equal? over tuple? [ tuple= ] [ 2drop f ] if ;
 
index 754a3293d1dada28cf8fee3d51d9890f7cf96d7d..68a8de3d43072c0913164aa78de6912da4a4490d 100644 (file)
@@ -9,9 +9,9 @@ MIXIN: growable
 SLOT: length
 SLOT: underlying
 
-M: growable length length>> ;
-M: growable nth-unsafe underlying>> nth-unsafe ;
-M: growable set-nth-unsafe underlying>> set-nth-unsafe ;
+M: growable length length>> ; inline
+M: growable nth-unsafe underlying>> nth-unsafe ; inline
+M: growable set-nth-unsafe underlying>> set-nth-unsafe ; inline
 
 : capacity ( seq -- n ) underlying>> length ; inline
 
@@ -49,21 +49,21 @@ M: growable set-length ( n seq -- )
         [ >fixnum ] dip
     ] if ; inline
 
-M: growable set-nth ensure set-nth-unsafe ;
+M: growable set-nth ensure set-nth-unsafe ; inline
 
-M: growable clone (clone) [ clone ] change-underlying ;
+M: growable clone (clone) [ clone ] change-underlying ; inline
 
 M: growable lengthen ( n seq -- )
     2dup length > [
         2dup capacity > [ over new-size over expand ] when
         2dup (>>length)
-    ] when 2drop ;
+    ] when 2drop ; inline
 
 M: growable shorten ( n seq -- )
     growable-check
     2dup length < [
         2dup contract
         2dup (>>length)
-    ] when 2drop ;
+    ] when 2drop ; inline
 
 INSTANCE: growable sequence
index 03bc3e01fd0d3a4a34488ffec18a6ac17ca60a4b..8547f53a0efb7c2a7e186dc1ab98b508a26e2063 100644 (file)
@@ -112,7 +112,7 @@ M: hashtable delete-at ( key hash -- )
     ] if ;
 
 M: hashtable assoc-size ( hash -- n )
-    [ count>> ] [ deleted>> ] bi - ;
+    [ count>> ] [ deleted>> ] bi - ; inline
 
 : rehash ( hash -- )
     dup >alist [
@@ -150,7 +150,7 @@ M: hashtable >alist
     ] keep { } like ;
 
 M: hashtable clone
-    (clone) [ clone ] change-array ;
+    (clone) [ clone ] change-array ; inline
 
 M: hashtable equal?
     over hashtable? [
@@ -159,15 +159,15 @@ M: hashtable equal?
     ] [ 2drop f ] if ;
 
 ! Default method
-M: assoc new-assoc drop <hashtable> ;
+M: assoc new-assoc drop <hashtable> ; inline
 
-M: f new-assoc drop <hashtable> ;
+M: f new-assoc drop <hashtable> ; inline
 
 : >hashtable ( assoc -- hashtable )
     H{ } assoc-clone-like ;
 
 M: hashtable assoc-like
-    drop dup hashtable? [ >hashtable ] unless ;
+    drop dup hashtable? [ >hashtable ] unless ; inline
 
 : ?set-at ( value key assoc/f -- assoc )
     [ [ set-at ] keep ] [ associate ] if* ;
index a722655cad4a81dfcecf2e094bab0ae2a23392ad..2911385c0990afd1f832108ba0282e5260d0bfe7 100755 (executable)
@@ -40,7 +40,7 @@ SINGLETON: utf8
     dup stream-read1 dup [ begin-utf8 ] when nip ; inline
 
 M: utf8 decode-char
-    drop decode-utf8 ;
+    drop decode-utf8 ; inline
 
 ! Encoding UTF-8
 
index 43a8373232d9c9c397d32db00a0e3f466c8ff220..3a08dd10d97907caa3365e628ccc18b5efcd508e 100644 (file)
@@ -1,5 +1,5 @@
 USING: tools.test io.streams.byte-array io.encodings.binary
-io.encodings.utf8 io kernel arrays strings namespaces ;
+io.encodings.utf8 io kernel arrays strings namespaces math ;
 
 [ B{ } ] [ B{ } binary [ contents ] with-byte-reader ] unit-test
 [ B{ 1 2 3 } ] [ binary [ B{ 1 2 3 } write ] with-byte-writer ] unit-test
@@ -28,3 +28,8 @@ io.encodings.utf8 io kernel arrays strings namespaces ;
         read1
     ] with-byte-reader
 ] unit-test
+
+! Overly aggressive compiler optimizations
+[ B{ 123 } ] [
+    binary [ 123 >bignum write1 ] with-byte-writer
+] unit-test
\ No newline at end of file
index d6350e0420241ffbd5d2001f3c75f9d1805db265..838d877a40e71403264fcbe5a130206d4322203b 100644 (file)
@@ -192,19 +192,19 @@ UNION: boolean POSTPONE: t POSTPONE: f ;
 ! Object protocol
 GENERIC: hashcode* ( depth obj -- code )
 
-M: object hashcode* 2drop 0 ;
+M: object hashcode* 2drop 0 ; inline
 
-M: f hashcode* 2drop 31337 ;
+M: f hashcode* 2drop 31337 ; inline
 
 : hashcode ( obj -- code ) 3 swap hashcode* ; inline
 
 GENERIC: equal? ( obj1 obj2 -- ? )
 
-M: object equal? 2drop f ;
+M: object equal? 2drop f ; inline
 
 TUPLE: identity-tuple ;
 
-M: identity-tuple equal? 2drop f ;
+M: identity-tuple equal? 2drop f ; inline
 
 : = ( obj1 obj2 -- ? )
     2dup eq? [ 2drop t ] [
@@ -213,9 +213,9 @@ M: identity-tuple equal? 2drop f ;
 
 GENERIC: clone ( obj -- cloned )
 
-M: object clone ;
+M: object clone ; inline
 
-M: callstack clone (clone) ;
+M: callstack clone (clone) ; inline
 
 ! Tuple construction
 GENERIC: new ( class -- tuple )
index 42898fc085dba73c2d64e54df916ca6ba855a972..5738c2ec99ac0089964d335192af95f8b51ecff5 100644 (file)
@@ -78,6 +78,6 @@ M: bignum >integer
 
 M: real >integer
     dup most-negative-fixnum most-positive-fixnum between?
-    [ >fixnum ] [ >bignum ] if ;
+    [ >fixnum ] [ >bignum ] if ; inline
 
 UNION: immediate fixnum POSTPONE: f ;
index 2a22dc4330c12ebebe3b6c5cbc040401c6d59d51..160b220173b7391319e2a179826974a9c33cb2c4 100644 (file)
@@ -3,28 +3,28 @@
 USING: kernel math math.private ;
 IN: math.floats.private
 
-M: fixnum >float fixnum>float ;
-M: bignum >float bignum>float ;
+M: fixnum >float fixnum>float ; inline
+M: bignum >float bignum>float ; inline
 
-M: float >fixnum float>fixnum ;
-M: float >bignum float>bignum ;
-M: float >float ;
+M: float >fixnum float>fixnum ; inline
+M: float >bignum float>bignum ; inline
+M: float >float ; inline
 
-M: float hashcode* nip float>bits ;
-M: float equal? over float? [ float= ] [ 2drop f ] if ;
-M: float number= float= ;
+M: float hashcode* nip float>bits ; inline
+M: float equal? over float? [ float= ] [ 2drop f ] if ; inline
+M: float number= float= ; inline
 
-M: float < float< ;
-M: float <= float<= ;
-M: float > float> ;
-M: float >= float>= ;
+M: float < float< ; inline
+M: float <= float<= ; inline
+M: float > float> ; inline
+M: float >= float>= ; inline
 
-M: float + float+ ;
-M: float - float- ;
-M: float * float* ;
-M: float / float/f ;
-M: float /f float/f ;
-M: float /i float/f >integer ;
-M: float mod float-mod ;
+M: float + float+ ; inline
+M: float - float- ; inline
+M: float * float* ; inline
+M: float / float/f ; inline
+M: float /f float/f ; inline
+M: float /i float/f >integer ; inline
+M: float mod float-mod ; inline
 
-M: real abs dup 0 < [ neg ] when ;
+M: real abs dup 0 < [ neg ] when ; inline
index 2b35ef76fd72a75edde2cb855a90b57f521f52a2..75abd8087e3cccf0edc9fd22af5fb2468077b1cb 100644 (file)
@@ -5,79 +5,79 @@ USING: kernel kernel.private sequences
 sequences.private math math.private combinators ;
 IN: math.integers.private
 
-M: integer numerator ;
-M: integer denominator drop 1 ;
+M: integer numerator ; inline
+M: integer denominator drop 1 ; inline
 
-M: fixnum >fixnum ;
-M: fixnum >bignum fixnum>bignum ;
-M: fixnum >integer ;
+M: fixnum >fixnum ; inline
+M: fixnum >bignum fixnum>bignum ; inline
+M: fixnum >integer ; inline
 
-M: fixnum hashcode* nip ;
-M: fixnum equal? over bignum? [ >bignum bignum= ] [ 2drop f ] if ;
-M: fixnum number= eq? ;
+M: fixnum hashcode* nip ; inline
+M: fixnum equal? over bignum? [ >bignum bignum= ] [ 2drop f ] if ; inline
+M: fixnum number= eq? ; inline
 
-M: fixnum < fixnum< ;
-M: fixnum <= fixnum<= ;
-M: fixnum > fixnum> ;
-M: fixnum >= fixnum>= ;
+M: fixnum < fixnum< ; inline
+M: fixnum <= fixnum<= ; inline
+M: fixnum > fixnum> ; inline
+M: fixnum >= fixnum>= ; inline
 
-M: fixnum + fixnum+ ;
-M: fixnum - fixnum- ;
-M: fixnum * fixnum* ;
-M: fixnum /i fixnum/i ;
-M: fixnum /f [ >float ] dip >float float/f ;
+M: fixnum + fixnum+ ; inline
+M: fixnum - fixnum- ; inline
+M: fixnum * fixnum* ; inline
+M: fixnum /i fixnum/i ; inline
+M: fixnum /f [ >float ] dip >float float/f ; inline
 
-M: fixnum mod fixnum-mod ;
+M: fixnum mod fixnum-mod ; inline
 
-M: fixnum /mod fixnum/mod ;
+M: fixnum /mod fixnum/mod ; inline
 
-M: fixnum bitand fixnum-bitand ;
-M: fixnum bitor fixnum-bitor ;
-M: fixnum bitxor fixnum-bitxor ;
-M: fixnum shift >fixnum fixnum-shift ;
+M: fixnum bitand fixnum-bitand ; inline
+M: fixnum bitor fixnum-bitor ; inline
+M: fixnum bitxor fixnum-bitxor ; inline
+M: fixnum shift >fixnum fixnum-shift ; inline
 
-M: fixnum bitnot fixnum-bitnot ;
+M: fixnum bitnot fixnum-bitnot ; inline
 
-M: fixnum bit? neg shift 1 bitand 0 > ;
+M: fixnum bit? neg shift 1 bitand 0 > ; inline
 
 : fixnum-log2 ( x -- n )
     0 swap [ dup 1 eq? ] [ [ 1 + ] [ 2/ ] bi* ] until drop ;
 
-M: fixnum (log2) fixnum-log2 ;
+M: fixnum (log2) fixnum-log2 ; inline
 
-M: bignum >fixnum bignum>fixnum ;
-M: bignum >bignum ;
+M: bignum >fixnum bignum>fixnum ; inline
+M: bignum >bignum ; inline
 
 M: bignum hashcode* nip >fixnum ;
 
 M: bignum equal?
     over bignum? [ bignum= ] [
         swap dup fixnum? [ >bignum bignum= ] [ 2drop f ] if
-    ] if ;
+    ] if ; inline
 
-M: bignum number= bignum= ;
+M: bignum number= bignum= ; inline
 
-M: bignum < bignum< ;
-M: bignum <= bignum<= ;
-M: bignum > bignum> ;
-M: bignum >= bignum>= ;
+M: bignum < bignum< ; inline
+M: bignum <= bignum<= ; inline
+M: bignum > bignum> ; inline
+M: bignum >= bignum>= ; inline
 
-M: bignum + bignum+ ;
-M: bignum - bignum- ;
-M: bignum * bignum* ;
-M: bignum /i bignum/i ;
-M: bignum mod bignum-mod ;
+M: bignum + bignum+ ; inline
+M: bignum - bignum- ; inline
+M: bignum * bignum* ; inline
+M: bignum /i bignum/i ; inline
+M: bignum mod bignum-mod ; inline
 
-M: bignum /mod bignum/mod ;
+M: bignum /mod bignum/mod ; inline
 
-M: bignum bitand bignum-bitand ;
-M: bignum bitor bignum-bitor ;
-M: bignum bitxor bignum-bitxor ;
-M: bignum shift >fixnum bignum-shift ;
+M: bignum bitand bignum-bitand ; inline
+M: bignum bitor bignum-bitor ; inline
+M: bignum bitxor bignum-bitxor ; inline
+M: bignum shift >fixnum bignum-shift ; inline
 
-M: bignum bitnot bignum-bitnot ;
-M: bignum bit? bignum-bit? ;
-M: bignum (log2) bignum-log2 ;
+M: bignum bitnot bignum-bitnot ; inline
+M: bignum bit? bignum-bit? ; inline
+M: bignum (log2) bignum-log2 ; inline
 
 ! Converting ratios to floats. Based on FLOAT-RATIO from
 ! sbcl/src/code/float.lisp, which has the following license:
index a00f2240e1297daf0a82bededdf3ddf6b514da84..1213e13a1f493803664b971b75d17a9a80e2f78b 100755 (executable)
@@ -98,38 +98,38 @@ GENERIC: fp-infinity? ( x -- ? )
 GENERIC: fp-nan-payload ( x -- bits )
 
 M: object fp-special?
-    drop f ;
+    drop f ; inline
 M: object fp-nan?
-    drop f ;
+    drop f ; inline
 M: object fp-qnan?
-    drop f ;
+    drop f ; inline
 M: object fp-snan?
-    drop f ;
+    drop f ; inline
 M: object fp-infinity?
-    drop f ;
+    drop f ; inline
 M: object fp-nan-payload
-    drop f ;
+    drop f ; inline
 
 M: float fp-special?
-    double>bits -52 shift HEX: 7ff [ bitand ] keep = ;
+    double>bits -52 shift HEX: 7ff [ bitand ] keep = ; inline
 
 M: float fp-nan-payload
-    double>bits HEX: fffffffffffff bitand ; foldable flushable
+    double>bits HEX: fffffffffffff bitand ; inline
 
 M: float fp-nan?
-    dup fp-special? [ fp-nan-payload zero? not ] [ drop f ] if ;
+    dup fp-special? [ fp-nan-payload zero? not ] [ drop f ] if ; inline
 
 M: float fp-qnan?
-    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? not ] [ drop f ] if ;
+    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? not ] [ drop f ] if ; inline
 
 M: float fp-snan?
-    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? ] [ drop f ] if ;
+    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? ] [ drop f ] if ; inline
 
 M: float fp-infinity?
-    dup fp-special? [ fp-nan-payload zero? ] [ drop f ] if ;
+    dup fp-special? [ fp-nan-payload zero? ] [ drop f ] if ; inline
 
 : <fp-nan> ( payload -- nan )
-    HEX: 7ff0000000000000 bitor bits>double ; foldable flushable
+    HEX: 7ff0000000000000 bitor bits>double ; inline
 
 : next-float ( m -- n )
     double>bits
@@ -137,7 +137,7 @@ M: float fp-infinity?
         dup -0.0 double>bits = [ drop 0.0 ] [ ! negative zero
             1 + bits>double ! positive
         ] if
-    ] if ; foldable flushable
+    ] if ; inline
 
 : prev-float ( m -- n )
     double>bits
@@ -145,7 +145,7 @@ M: float fp-infinity?
         dup 0.0 double>bits = [ drop -0.0 ] [ ! positive zero
             1 - bits>double ! positive non-zero
         ] if
-    ] if ; foldable flushable
+    ] if ; inline
 
 : next-power-of-2 ( m -- n )
     dup 2 <= [ drop 2 ] [ 1 - log2 1 + 2^ ] if ; inline
index 435eec9b96102af3922ad6b492ada0bbe04568d6..707dc02af217c4f6e232a45ddca1eb0a1a231a55 100644 (file)
@@ -15,24 +15,24 @@ GENERIC: <=> ( obj1 obj2 -- <=> )
 
 : >=< ( obj1 obj2 -- >=< ) <=> invert-comparison ; inline
 
-M: real <=> 2dup < [ 2drop +lt+ ] [ number= +eq+ +gt+ ? ] if ;
+M: real <=> 2dup < [ 2drop +lt+ ] [ number= +eq+ +gt+ ? ] if ; inline
 
 GENERIC: before? ( obj1 obj2 -- ? )
 GENERIC: after? ( obj1 obj2 -- ? )
 GENERIC: before=? ( obj1 obj2 -- ? )
 GENERIC: after=? ( obj1 obj2 -- ? )
 
-M: object before? ( obj1 obj2 -- ? ) <=> +lt+ eq? ;
-M: object after? ( obj1 obj2 -- ? ) <=> +gt+ eq? ;
-M: object before=? ( obj1 obj2 -- ? ) <=> +gt+ eq? not ;
-M: object after=? ( obj1 obj2 -- ? ) <=> +lt+ eq? not ;
+M: object before? ( obj1 obj2 -- ? ) <=> +lt+ eq? ; inline
+M: object after? ( obj1 obj2 -- ? ) <=> +gt+ eq? ; inline
+M: object before=? ( obj1 obj2 -- ? ) <=> +gt+ eq? not ; inline
+M: object after=? ( obj1 obj2 -- ? ) <=> +lt+ eq? not ; inline
 
-M: real before? ( obj1 obj2 -- ? ) < ;
-M: real after? ( obj1 obj2 -- ? ) > ;
-M: real before=? ( obj1 obj2 -- ? ) <= ;
-M: real after=? ( obj1 obj2 -- ? ) >= ;
+M: real before? ( obj1 obj2 -- ? ) < ; inline
+M: real after? ( obj1 obj2 -- ? ) > ; inline
+M: real before=? ( obj1 obj2 -- ? ) <= ; inline
+M: real after=? ( obj1 obj2 -- ? ) >= ; inline
 
-: min ( x y -- z ) [ before? ] most ; inline 
+: min ( x y -- z ) [ before? ] most ; inline
 : max ( x y -- z ) [ after? ] most ; inline
 : clamp ( x min max -- y ) [ max ] dip min ; inline
 
index 0b2c170c1e6dacb46f29af1afae00b77256b4942..49b6ec137406cccc9901231e0bcdcc914f4b47a0 100644 (file)
@@ -11,24 +11,24 @@ TUPLE: sbuf
 : <sbuf> ( n -- sbuf ) 0 <string> 0 sbuf boa ; inline
 
 M: sbuf set-nth-unsafe
-    [ >fixnum ] [ >fixnum ] [ underlying>> ] tri* set-string-nth ;
+    [ >fixnum ] [ >fixnum ] [ underlying>> ] tri* set-string-nth ; inline
 
 M: sbuf new-sequence
-    drop [ 0 <string> ] [ >fixnum ] bi sbuf boa ;
+    drop [ 0 <string> ] [ >fixnum ] bi sbuf boa ; inline
 
 : >sbuf ( seq -- sbuf ) SBUF" " clone-like ; inline
 
 M: sbuf like
     drop dup sbuf? [
         dup string? [ dup length sbuf boa ] [ >sbuf ] if
-    ] unless ;
+    ] unless ; inline
 
-M: sbuf new-resizable drop <sbuf> ;
+M: sbuf new-resizable drop <sbuf> ; inline
 
 M: sbuf equal?
     over sbuf? [ sequence= ] [ 2drop f ] if ;
 
-M: string new-resizable drop <sbuf> ;
+M: string new-resizable drop <sbuf> ; inline
 
 M: string like
     #! If we have a string, we're done.
@@ -41,6 +41,6 @@ M: string like
             2dup length eq?
             [ nip dup reset-string-hashcode ] [ resize-string ] if
         ] [ >string ] if
-    ] unless ;
+    ] unless ; inline
 
 INSTANCE: sbuf growable
index 2a52384180d39e16c45d6b8c963c89665917751c..258b484764bffc04b4466d20b66d4657d76b176d 100755 (executable)
@@ -1392,7 +1392,7 @@ $nl
 "More elaborate counted loops can be performed with " { $link "math.ranges" } "." ;
 
 ARTICLE: "sequences-if" "Control flow with sequences"
-"To reduce the boilerplate of checking if a sequence is empty or a number is zero, several combinators are provided."
+"To reduce the boilerplate of checking if a sequence is empty, several combinators are provided."
 $nl
 "Checking if a sequence is empty:"
 { $subsection if-empty }
index 84b80794a30ec2c4eda2b4596c4d3e8a0e6426ab..031d5f7b4a2ce8102987ea1a8c02bc0ea2a94542 100755 (executable)
@@ -18,14 +18,14 @@ GENERIC: clone-like ( seq exemplar -- newseq ) flushable
 : new-like ( len exemplar quot -- seq )
     over [ [ new-sequence ] dip call ] dip like ; inline
 
-M: sequence like drop ;
+M: sequence like drop ; inline
 
 GENERIC: lengthen ( n seq -- )
 GENERIC: shorten ( n seq -- )
 
-M: sequence lengthen 2dup length > [ set-length ] [ 2drop ] if ;
+M: sequence lengthen 2dup length > [ set-length ] [ 2drop ] if ; inline
 
-M: sequence shorten 2dup length < [ set-length ] [ 2drop ] if ;
+M: sequence shorten 2dup length < [ set-length ] [ 2drop ] if ; inline
 
 : empty? ( seq -- ? ) length 0 = ; inline
 
@@ -82,25 +82,25 @@ GENERIC: resize ( n seq -- newseq ) flushable
 GENERIC: nth-unsafe ( n seq -- elt ) flushable
 GENERIC: set-nth-unsafe ( elt n seq -- )
 
-M: sequence nth bounds-check nth-unsafe ;
-M: sequence set-nth bounds-check set-nth-unsafe ;
+M: sequence nth bounds-check nth-unsafe ; inline
+M: sequence set-nth bounds-check set-nth-unsafe ; inline
 
-M: sequence nth-unsafe nth ;
-M: sequence set-nth-unsafe set-nth ;
+M: sequence nth-unsafe nth ; inline
+M: sequence set-nth-unsafe set-nth ; inline
 
 : change-nth-unsafe ( i seq quot -- )
     [ [ nth-unsafe ] dip call ] 3keep drop set-nth-unsafe ; inline
 
 ! The f object supports the sequence protocol trivially
-M: f length drop 0 ;
-M: f nth-unsafe nip ;
-M: f like drop [ f ] when-empty ;
+M: f length drop 0 ; inline
+M: f nth-unsafe nip ; inline
+M: f like drop [ f ] when-empty ; inline
 
 INSTANCE: f immutable-sequence
 
 ! Integers support the sequence protocol
-M: integer length ;
-M: integer nth-unsafe drop ;
+M: integer length ; inline
+M: integer nth-unsafe drop ; inline
 
 INSTANCE: integer immutable-sequence
 
@@ -113,8 +113,8 @@ TUPLE: iota { n integer read-only } ;
 
 <PRIVATE
 
-M: iota length n>> ;
-M: iota nth-unsafe drop ;
+M: iota length n>> ; inline
+M: iota nth-unsafe drop ; inline
 
 INSTANCE: iota immutable-sequence
 
@@ -185,12 +185,12 @@ MIXIN: virtual-sequence
 GENERIC: virtual-seq ( seq -- seq' )
 GENERIC: virtual@ ( n seq -- n' seq' )
 
-M: virtual-sequence nth virtual@ nth ;
-M: virtual-sequence set-nth virtual@ set-nth ;
-M: virtual-sequence nth-unsafe virtual@ nth-unsafe ;
-M: virtual-sequence set-nth-unsafe virtual@ set-nth-unsafe ;
-M: virtual-sequence like virtual-seq like ;
-M: virtual-sequence new-sequence virtual-seq new-sequence ;
+M: virtual-sequence nth virtual@ nth ; inline
+M: virtual-sequence set-nth virtual@ set-nth ; inline
+M: virtual-sequence nth-unsafe virtual@ nth-unsafe ; inline
+M: virtual-sequence set-nth-unsafe virtual@ set-nth-unsafe ; inline
+M: virtual-sequence like virtual-seq like ; inline
+M: virtual-sequence new-sequence virtual-seq new-sequence ; inline
 
 INSTANCE: virtual-sequence sequence
 
@@ -199,11 +199,9 @@ TUPLE: reversed { seq read-only } ;
 
 C: <reversed> reversed
 
-M: reversed virtual-seq seq>> ;
-
-M: reversed virtual@ seq>> [ length swap - 1 - ] keep ;
-
-M: reversed length seq>> length ;
+M: reversed virtual-seq seq>> ; inline
+M: reversed virtual@ seq>> [ length swap - 1 - ] keep ; inline
+M: reversed length seq>> length ; inline
 
 INSTANCE: reversed virtual-sequence
 
@@ -233,11 +231,11 @@ TUPLE: slice-error from to seq reason ;
     check-slice
     slice boa ; inline
 
-M: slice virtual-seq seq>> ;
+M: slice virtual-seq seq>> ; inline
 
-M: slice virtual@ [ from>> + ] [ seq>> ] bi ;
+M: slice virtual@ [ from>> + ] [ seq>> ] bi ; inline
 
-M: slice length [ to>> ] [ from>> ] bi - ;
+M: slice length [ to>> ] [ from>> ] bi - ; inline
 
 : short ( seq n -- seq n' ) over length min ; inline
 
@@ -260,8 +258,8 @@ TUPLE: repetition { len read-only } { elt read-only } ;
 
 C: <repetition> repetition
 
-M: repetition length len>> ;
-M: repetition nth-unsafe nip elt>> ;
+M: repetition length len>> ; inline
+M: repetition nth-unsafe nip elt>> ; inline
 
 INSTANCE: repetition immutable-sequence
 
@@ -316,9 +314,9 @@ PRIVATE>
     (copy) drop ; inline
 
 M: sequence clone-like
-    [ dup length ] dip new-sequence [ 0 swap copy ] keep ;
+    [ dup length ] dip new-sequence [ 0 swap copy ] keep ; inline
 
-M: immutable-sequence clone-like like ;
+M: immutable-sequence clone-like like ; inline
 
 : push-all ( src dest -- ) [ length ] [ copy ] bi ;
 
index 9215857018e4e375c36e58773deab61f6a912777..e2d75d636243a546f44c65031ccbf48bc8650b19 100755 (executable)
@@ -24,7 +24,8 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
     [ create-method ] 2dip
     [ [ props>> ] [ drop ] [ ] tri* update ]
     [ drop define ]
-    3bi ;
+    [ 2drop make-inline ]
+    3tri ;
 
 GENERIC# reader-quot 1 ( class slot-spec -- quot )
 
@@ -41,11 +42,7 @@ M: object reader-quot
     dup t "reader" set-word-prop ;
 
 : reader-props ( slot-spec -- assoc )
-    [
-        [ "reading" set ]
-        [ read-only>> [ t "foldable" set ] when ] bi
-        t "flushable" set
-    ] H{ } make-assoc ;
+    "reading" associate ;
 
 : define-reader-generic ( name -- )
     reader-word (( object -- value )) define-simple-generic ;
index ffcefab78be4604309064e86112f9f9848b6f51f..8ab0409318d34c4ad98fa7a7800b55bf0289e91b 100644 (file)
@@ -37,24 +37,24 @@ M: string hashcode*
     [ ] [ dup rehash-string string-hashcode ] ?if ;
 
 M: string length
-    length>> ;
+    length>> ; inline
 
 M: string nth-unsafe
-    [ >fixnum ] dip string-nth ;
+    [ >fixnum ] dip string-nth ; inline
 
 M: string set-nth-unsafe
     dup reset-string-hashcode
-    [ >fixnum ] [ >fixnum ] [ ] tri* set-string-nth ;
+    [ >fixnum ] [ >fixnum ] [ ] tri* set-string-nth ; inline
 
 M: string clone
-    (clone) [ clone ] change-aux ;
+    (clone) [ clone ] change-aux ; inline
 
-M: string resize resize-string ;
+M: string resize resize-string ; inline
 
 : 1string ( ch -- str ) 1 swap <string> ;
 
 : >string ( seq -- str ) "" clone-like ;
 
-M: string new-sequence drop 0 <string> ;
+M: string new-sequence drop 0 <string> ; inline
 
 INSTANCE: string sequence
index 1bdda7b69da91567ffdfc642df421faa8a0917cd..4bbc787294b721c26265deb2c77c995e90ab9f64 100644 (file)
@@ -15,10 +15,10 @@ TUPLE: vector
 M: vector like
     drop dup vector? [
         dup array? [ dup length vector boa ] [ >vector ] if
-    ] unless ;
+    ] unless ; inline
 
 M: vector new-sequence
-    drop [ f <array> ] [ >fixnum ] bi vector boa ;
+    drop [ f <array> ] [ >fixnum ] bi vector boa ; inline
 
 M: vector equal?
     over vector? [ sequence= ] [ 2drop f ] if ;
@@ -34,9 +34,9 @@ M: array like
             2dup length eq?
             [ nip ] [ resize-array ] if
         ] [ >array ] if
-    ] unless ;
+    ] unless ; inline
 
-M: sequence new-resizable drop <vector> ;
+M: sequence new-resizable drop <vector> ; inline
 
 INSTANCE: vector growable
 
index 2ebdb8b7a8ad0d9433be545d98c84ea3e1f26dd4..19a2ce551d0ee9263d65b3798e09139154c9ddcf 100755 (executable)
@@ -12,7 +12,7 @@ IN: words
 
 M: word execute (execute) ;
 
-M: word ?execute execute( -- value ) ;
+M: word ?execute execute( -- value ) ; inline
 
 M: word <=>
     [ [ name>> ] [ vocabulary>> ] bi 2array ] compare ;
@@ -213,7 +213,7 @@ M: word forget*
     ] if ;
 
 M: word hashcode*
-    nip 1 slot { fixnum } declare ; foldable
+    nip 1 slot { fixnum } declare ; inline foldable
 
 M: word literalize <wrapper> ;
 
index ca57de822f153c495430c7e1d4bf0e7b408a3d12..9562e42c4e8db1d5f9c850e42cf7cea1545cb955 100644 (file)
@@ -36,8 +36,7 @@ C-STRUCT: yuv_buffer
     255 min 0 max ; inline
 
 : stride ( line yuv  -- uvy yy )
-    [ yuv_buffer-uv_stride swap 2/ * >fixnum ]
-    [ yuv_buffer-y_stride * >fixnum ] 2bi ; inline
+    [ yuv_buffer-uv_stride swap 2/ * ] [ yuv_buffer-y_stride * ] 2bi ; inline
 
 : compute-y ( yuv uvy yy x -- y )
     + >fixnum nip swap yuv_buffer-y swap alien-unsigned-1 16 - ; inline
@@ -74,16 +73,16 @@ C-STRUCT: yuv_buffer
     drop ; inline
 
 : yuv>rgb-pixel ( index rgb yuv uvy yy x -- index )
-    compute-yuv compute-rgb store-rgb 3 + >fixnum ; inline
+    compute-yuv compute-rgb store-rgb 3 + ; inline
 
 : yuv>rgb-row ( index rgb yuv y -- index )
     over stride
-    pick yuv_buffer-y_width >fixnum
+    pick yuv_buffer-y_width
     [ yuv>rgb-pixel ] with with with with each ; inline
 
 : yuv>rgb ( rgb yuv -- )
     [ 0 ] 2dip
-    dup yuv_buffer-y_height >fixnum
+    dup yuv_buffer-y_height
     [ yuv>rgb-row ] with with each
     drop ;
 
diff --git a/extra/multi-methods/authors.txt b/extra/multi-methods/authors.txt
new file mode 100755 (executable)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/multi-methods/multi-methods.factor b/extra/multi-methods/multi-methods.factor
new file mode 100755 (executable)
index 0000000..d3e1d44
--- /dev/null
@@ -0,0 +1,281 @@
+! Copyright (C) 2008, 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math sequences vectors classes classes.algebra
+combinators arrays words assocs parser namespaces make
+definitions prettyprint prettyprint.backend prettyprint.custom
+quotations generalizations debugger io compiler.units
+kernel.private effects accessors hashtables sorting shuffle
+math.order sets see effects.parser ;
+IN: multi-methods
+
+! PART I: Converting hook specializers
+: canonicalize-specializer-0 ( specializer -- specializer' )
+    [ \ f or ] map ;
+
+SYMBOL: args
+
+SYMBOL: hooks
+
+SYMBOL: total
+
+: canonicalize-specializer-1 ( specializer -- specializer' )
+    [
+        [ class? ] filter
+        [ length <reversed> [ 1 + neg ] map ] keep zip
+        [ length args [ max ] change ] keep
+    ]
+    [
+        [ pair? ] filter
+        [ keys [ hooks get adjoin ] each ] keep
+    ] bi append ;
+
+: canonicalize-specializer-2 ( specializer -- specializer' )
+    [
+        [
+            {
+                { [ dup integer? ] [ ] }
+                { [ dup word? ] [ hooks get index ] }
+            } cond args get +
+        ] dip
+    ] assoc-map ;
+
+: canonicalize-specializer-3 ( specializer -- specializer' )
+    [ total get object <array> dup <enum> ] dip update ;
+
+: canonicalize-specializers ( methods -- methods' hooks )
+    [
+        [ [ canonicalize-specializer-0 ] dip ] assoc-map
+
+        0 args set
+        V{ } clone hooks set
+
+        [ [ canonicalize-specializer-1 ] dip ] assoc-map
+
+        hooks [ natural-sort ] change
+
+        [ [ canonicalize-specializer-2 ] dip ] assoc-map
+
+        args get hooks get length + total set
+
+        [ [ canonicalize-specializer-3 ] dip ] assoc-map
+
+        hooks get
+    ] with-scope ;
+
+: drop-n-quot ( n -- quot ) \ drop <repetition> >quotation ;
+
+: prepare-method ( method n -- quot )
+    [ 1quotation ] [ drop-n-quot ] bi* prepend ;
+
+: prepare-methods ( methods -- methods' prologue )
+    canonicalize-specializers
+    [ length [ prepare-method ] curry assoc-map ] keep
+    [ [ get ] curry ] map concat [ ] like ;
+
+! Part II: Topologically sorting specializers
+: maximal-element ( seq quot -- n elt )
+    dupd [
+        swapd [ call +lt+ = ] 2curry filter empty?
+    ] 2curry find [ "Topological sort failed" throw ] unless* ;
+    inline
+
+: topological-sort ( seq quot -- newseq )
+    [ >vector [ dup empty? not ] ] dip
+    [ dupd maximal-element [ over delete-nth ] dip ] curry
+    produce nip ; inline
+
+: classes< ( seq1 seq2 -- lt/eq/gt )
+    [
+        {
+            { [ 2dup eq? ] [ +eq+ ] }
+            { [ 2dup [ class<= ] [ swap class<= ] 2bi and ] [ +eq+ ] }
+            { [ 2dup class<= ] [ +lt+ ] }
+            { [ 2dup swap class<= ] [ +gt+ ] }
+            [ +eq+ ]
+        } cond 2nip
+    ] 2map [ +eq+ eq? not ] find nip +eq+ or ;
+
+: sort-methods ( alist -- alist' )
+    [ [ first ] bi@ classes< ] topological-sort ;
+
+! PART III: Creating dispatch quotation
+: picker ( n -- quot )
+    {
+        { 0 [ [ dup ] ] }
+        { 1 [ [ over ] ] }
+        { 2 [ [ pick ] ] }
+        [ 1 - picker [ dip swap ] curry ]
+    } case ;
+
+: (multi-predicate) ( class picker -- quot )
+    swap "predicate" word-prop append ;
+
+: multi-predicate ( classes -- quot )
+    dup length <reversed>
+    [ picker 2array ] 2map
+    [ drop object eq? not ] assoc-filter
+    [ [ t ] ] [
+        [ (multi-predicate) ] { } assoc>map
+        unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
+    ] if-empty ;
+
+: argument-count ( methods -- n )
+    keys 0 [ length max ] reduce ;
+
+ERROR: no-method arguments generic ;
+
+: make-default-method ( methods generic -- quot )
+    [ argument-count ] dip [ [ narray ] dip no-method ] 2curry ;
+
+: multi-dispatch-quot ( methods generic -- quot )
+    [ make-default-method ]
+    [ drop [ [ multi-predicate ] dip ] assoc-map reverse ]
+    2bi alist>quot ;
+
+! Generic words
+PREDICATE: generic < word
+    "multi-methods" word-prop >boolean ;
+
+: methods ( word -- alist )
+    "multi-methods" word-prop >alist ;
+
+: make-generic ( generic -- quot )
+    [
+        [ methods prepare-methods % sort-methods ] keep
+        multi-dispatch-quot %
+    ] [ ] make ;
+
+: update-generic ( word -- )
+    dup make-generic define ;
+
+! Methods
+PREDICATE: method-body < word
+    "multi-method-generic" word-prop >boolean ;
+
+M: method-body stack-effect
+    "multi-method-generic" word-prop stack-effect ;
+
+M: method-body crossref?
+    "forgotten" word-prop not ;
+
+: method-word-name ( specializer generic -- string )
+    [ name>> % "-" % unparse % ] "" make ;
+
+: method-word-props ( specializer generic -- assoc )
+    [
+        "multi-method-generic" set
+        "multi-method-specializer" set
+    ] H{ } make-assoc ;
+
+: <method> ( specializer generic -- word )
+    [ method-word-props ] 2keep
+    method-word-name f <word>
+    swap >>props ;
+
+: with-methods ( word quot -- )
+    over [
+        [ "multi-methods" word-prop ] dip call
+    ] dip update-generic ; inline
+
+: reveal-method ( method classes generic -- )
+    [ set-at ] with-methods ;
+
+: method ( classes word -- method )
+    "multi-methods" word-prop at ;
+
+: create-method ( classes generic -- method )
+    2dup method dup [
+        2nip
+    ] [
+        drop [ <method> dup ] 2keep reveal-method
+    ] if ;
+
+: niceify-method ( seq -- seq )
+    [ dup \ f eq? [ drop f ] when ] map ;
+
+M: no-method error.
+    "Type check error" print
+    nl
+    "Generic word " write dup generic>> pprint
+    " does not have a method applicable to inputs:" print
+    dup arguments>> short.
+    nl
+    "Inputs have signature:" print
+    dup arguments>> [ class ] map niceify-method .
+    nl
+    "Available methods: " print
+    generic>> methods canonicalize-specializers drop sort-methods
+    keys [ niceify-method ] map stack. ;
+
+: forget-method ( specializer generic -- )
+    [ delete-at ] with-methods ;
+
+: method>spec ( method -- spec )
+    [ "multi-method-specializer" word-prop ]
+    [ "multi-method-generic" word-prop ] bi prefix ;
+
+: define-generic ( word effect -- )
+    over set-stack-effect
+    dup "multi-methods" word-prop [ drop ] [
+        [ H{ } clone "multi-methods" set-word-prop ]
+        [ update-generic ]
+        bi
+    ] if ;
+
+! Syntax
+SYNTAX: GENERIC: CREATE-WORD complete-effect define-generic ;
+
+: parse-method ( -- quot classes generic )
+    parse-definition [ 2 tail ] [ second ] [ first ] tri ;
+
+: create-method-in ( specializer generic -- method )
+    create-method dup save-location f set-word ;
+
+: CREATE-METHOD ( -- method )
+    scan-word scan-object swap create-method-in ;
+
+: (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
+
+SYNTAX: METHOD: (METHOD:) define ;
+
+! For compatibility
+SYNTAX: M:
+    scan-word 1array scan-word create-method-in
+    parse-definition
+    define ;
+
+! Definition protocol. We qualify core generics here
+QUALIFIED: syntax
+
+syntax:M: generic definer drop \ GENERIC: f ;
+
+syntax:M: generic definition drop f ;
+
+PREDICATE: method-spec < array
+    unclip generic? [ [ class? ] all? ] dip and ;
+
+syntax:M: method-spec where
+    dup unclip method [ ] [ first ] ?if where ;
+
+syntax:M: method-spec set-where
+    unclip method set-where ;
+
+syntax:M: method-spec definer
+    unclip method definer ;
+
+syntax:M: method-spec definition
+    unclip method definition ;
+
+syntax:M: method-spec synopsis*
+    unclip method synopsis* ;
+
+syntax:M: method-spec forget*
+    unclip method forget* ;
+
+syntax:M: method-body definer
+    drop \ METHOD: \ ; ;
+
+syntax:M: method-body synopsis*
+    dup definer.
+    [ "multi-method-generic" word-prop pprint-word ]
+    [ "multi-method-specializer" word-prop pprint* ] bi ;
diff --git a/extra/multi-methods/summary.txt b/extra/multi-methods/summary.txt
new file mode 100755 (executable)
index 0000000..ec8214b
--- /dev/null
@@ -0,0 +1 @@
+Experimental multiple dispatch implementation
diff --git a/extra/multi-methods/tags.txt b/extra/multi-methods/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/extra/multi-methods/tests/canonicalize.factor b/extra/multi-methods/tests/canonicalize.factor
new file mode 100644 (file)
index 0000000..6ddd5d6
--- /dev/null
@@ -0,0 +1,66 @@
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings ;
+IN: multi-methods.tests
+
+[ { POSTPONE: f integer } ] [ { f integer } canonicalize-specializer-0 ] unit-test
+
+: setup-canon-test ( -- )
+    0 args set
+    V{ } clone hooks set ;
+
+: canon-test-1 ( -- seq )
+    { integer { cpu x86 } sequence } canonicalize-specializer-1 ;
+
+[ { { -2 integer } { -1 sequence } { cpu x86 } } ] [
+    [
+        setup-canon-test
+        canon-test-1
+    ] with-scope
+] unit-test
+
+[ { { 0 integer } { 1 sequence } { 2 x86 } } ] [
+    [
+        setup-canon-test
+        canon-test-1
+        canonicalize-specializer-2
+    ] with-scope
+] unit-test
+
+[ { integer sequence x86 } ] [
+    [
+        setup-canon-test
+        canon-test-1
+        canonicalize-specializer-2
+        args get hooks get length + total set
+        canonicalize-specializer-3
+    ] with-scope
+] unit-test
+
+CONSTANT: example-1
+    {
+        { { { cpu x86 } { os linux } } "a" }
+        { { { cpu ppc } } "b" }
+        { { string { os windows } } "c" }
+    }
+
+[
+    {
+        { { object x86 linux } "a"  }
+        { { object ppc object } "b" }
+        { { string object windows } "c" }
+    }
+    { cpu os }
+] [
+    example-1 canonicalize-specializers
+] unit-test
+
+[
+    {
+        { { object x86 linux } [ drop drop "a" ] }
+        { { object ppc object } [ drop drop "b" ] }
+        { { string object windows } [ drop drop "c" ] }
+    }
+    [ \ cpu get \ os get ]
+] [
+    example-1 prepare-methods
+] unit-test
diff --git a/extra/multi-methods/tests/definitions.factor b/extra/multi-methods/tests/definitions.factor
new file mode 100644 (file)
index 0000000..a483a49
--- /dev/null
@@ -0,0 +1,30 @@
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings words compiler.units quotations ;
+IN: multi-methods.tests
+
+DEFER: fake
+\ fake H{ } clone "multi-methods" set-word-prop
+<< (( -- )) \ fake set-stack-effect >>
+
+[ "fake-{ }" ] [ { } \ fake method-word-name ] unit-test
+
+[ H{ { "multi-method-generic" fake } { "multi-method-specializer" { } } } ]
+[ { } \ fake method-word-props ] unit-test
+
+[ t ] [ { } \ fake <method> method-body? ] unit-test
+
+[
+    [ { } [ ] ] [ \ fake methods prepare-methods [ sort-methods ] dip ] unit-test
+
+    [ t ] [ { } \ fake multi-dispatch-quot callable? ] unit-test
+
+    [ t ] [ \ fake make-generic quotation? ] unit-test
+
+    [ ] [ \ fake update-generic ] unit-test
+
+    DEFER: testing
+
+    [ ] [ \ testing (( -- )) define-generic ] unit-test
+
+    [ t ] [ \ testing generic? ] unit-test
+] with-compilation-unit
diff --git a/extra/multi-methods/tests/legacy.factor b/extra/multi-methods/tests/legacy.factor
new file mode 100644 (file)
index 0000000..28bfa28
--- /dev/null
@@ -0,0 +1,10 @@
+USING: math strings sequences tools.test ;
+IN: multi-methods.tests
+
+GENERIC: legacy-test ( a -- b )
+
+M: integer legacy-test sq ;
+M: string legacy-test " hey" append ;
+
+[ 25 ] [ 5 legacy-test ] unit-test
+[ "hello hey" ] [ "hello" legacy-test ] unit-test
diff --git a/extra/multi-methods/tests/syntax.factor b/extra/multi-methods/tests/syntax.factor
new file mode 100644 (file)
index 0000000..afe6037
--- /dev/null
@@ -0,0 +1,65 @@
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings definitions prettyprint debugger arrays
+hashtables continuations classes assocs accessors see ;
+RENAME: GENERIC: multi-methods => multi-methods:GENERIC:
+IN: multi-methods.tests
+
+multi-methods:GENERIC: first-test ( -- )
+
+[ t ] [ \ first-test generic? ] unit-test
+
+MIXIN: thing
+
+SINGLETON: paper    INSTANCE: paper thing
+SINGLETON: scissors INSTANCE: scissors thing
+SINGLETON: rock     INSTANCE: rock thing
+
+multi-methods:GENERIC: beats? ( obj1 obj2 -- ? )
+
+METHOD: beats? { paper scissors } 2drop t ;
+METHOD: beats? { scissors rock } 2drop t ;
+METHOD: beats? { rock paper } 2drop t ;
+METHOD: beats? { thing thing } 2drop f ;
+
+: play ( obj1 obj2 -- ? ) beats? ;
+
+[ { } 3 play ] must-fail
+[ t ] [ error get no-method? ] unit-test
+[ ] [ error get error. ] unit-test
+[ { { } 3 } ] [ error get arguments>> ] unit-test
+[ t ] [ paper scissors play ] unit-test
+[ f ] [ scissors paper play ] unit-test
+
+[ t ] [ { beats? paper scissors } method-spec? ] unit-test
+[ ] [ { beats? paper scissors } see ] unit-test
+
+SYMBOL: some-var
+
+multi-methods:GENERIC: hook-test ( obj -- obj )
+
+METHOD: hook-test { array { some-var array } } reverse ;
+METHOD: hook-test { { some-var array } } class ;
+METHOD: hook-test { hashtable { some-var number } } assoc-size ;
+
+{ 1 2 3 } some-var set
+[ { f t t } ] [ { t t f } hook-test ] unit-test
+[ fixnum ] [ 3 hook-test ] unit-test
+5.0 some-var set
+[ 0 ] [ H{ } hook-test ] unit-test
+
+"error" some-var set
+[ H{ } hook-test ] must-fail
+[ t ] [ error get no-method? ] unit-test
+[ { H{ } "error" } ] [ error get arguments>> ] unit-test
+
+MIXIN: busted
+
+TUPLE: busted-1 ;
+TUPLE: busted-2 ; INSTANCE: busted-2 busted
+TUPLE: busted-3 ;
+
+multi-methods:GENERIC: busted-sort ( obj1 obj2 -- obj1 obj2 )
+
+METHOD: busted-sort { busted-1 busted-2 } ;
+METHOD: busted-sort { busted-2 busted-3 } ;
+METHOD: busted-sort { busted busted } ;
diff --git a/extra/multi-methods/tests/topological-sort.factor b/extra/multi-methods/tests/topological-sort.factor
new file mode 100644 (file)
index 0000000..f161837
--- /dev/null
@@ -0,0 +1,19 @@
+USING: kernel multi-methods tools.test math arrays sequences
+math.order ;
+IN: multi-methods.tests
+
+[ { 1 2 3 4 5 6 } ] [
+    { 6 4 5 1 3 2 } [ <=> ] topological-sort
+] unit-test
+
+[ +lt+ ] [
+    { fixnum array } { number sequence } classes<
+] unit-test
+
+[ +eq+ ] [
+    { number sequence } { number sequence } classes<
+] unit-test
+
+[ +gt+ ] [
+    { object object } { number sequence } classes<
+] unit-test
diff --git a/extra/rpn/authors.txt b/extra/rpn/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/rpn/rpn.factor b/extra/rpn/rpn.factor
new file mode 100644 (file)
index 0000000..7175746
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2009 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators io kernel lists math math.parser
+sequences splitting ;
+IN: rpn
+
+SINGLETONS: add-insn sub-insn mul-insn div-insn ;
+TUPLE: push-insn value ;
+
+GENERIC: eval-insn ( stack insn -- stack )
+
+: binary-op ( stack quot: ( x y -- z ) -- stack )
+    [ uncons uncons ] dip dip cons ; inline
+
+M: add-insn eval-insn drop [ + ] binary-op ;
+M: sub-insn eval-insn drop [ - ] binary-op ;
+M: mul-insn eval-insn drop [ * ] binary-op ;
+M: div-insn eval-insn drop [ / ] binary-op ;
+M: push-insn eval-insn value>> swons ;
+
+: rpn-tokenize ( string -- string' )
+    " " split harvest sequence>list ;
+
+: rpn-parse ( string -- tokens )
+    rpn-tokenize [
+        {
+            { "+" [ add-insn ] }
+            { "-" [ sub-insn ] }
+            { "*" [ mul-insn ] }
+            { "/" [ div-insn ] }
+            [ string>number push-insn boa ]
+        } case
+    ] lmap ;
+
+: print-stack ( list -- )
+    [ number>string print ] leach ;
+
+: rpn-eval ( tokens -- )
+    nil [ eval-insn ] foldl print-stack ;
+
+: rpn ( -- )
+    "RPN> " write flush
+    readln [ rpn-parse rpn-eval rpn ] when* ;
+
+MAIN: rpn
diff --git a/extra/rpn/summary.txt b/extra/rpn/summary.txt
new file mode 100644 (file)
index 0000000..e6b4fe2
--- /dev/null
@@ -0,0 +1 @@
+Simple RPN calculator
diff --git a/extra/rpn/tags.txt b/extra/rpn/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
diff --git a/unmaintained/multi-methods/authors.txt b/unmaintained/multi-methods/authors.txt
deleted file mode 100755 (executable)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/unmaintained/multi-methods/multi-methods.factor b/unmaintained/multi-methods/multi-methods.factor
deleted file mode 100755 (executable)
index 17f0de1..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math sequences vectors classes classes.algebra
-combinators arrays words assocs parser namespaces make
-definitions prettyprint prettyprint.backend prettyprint.custom
-quotations generalizations debugger io compiler.units
-kernel.private effects accessors hashtables sorting shuffle
-math.order sets see effects.parser ;
-IN: multi-methods
-
-! PART I: Converting hook specializers
-: canonicalize-specializer-0 ( specializer -- specializer' )
-    [ \ f or ] map ;
-
-SYMBOL: args
-
-SYMBOL: hooks
-
-SYMBOL: total
-
-: canonicalize-specializer-1 ( specializer -- specializer' )
-    [
-        [ class? ] filter
-        [ length <reversed> [ 1+ neg ] map ] keep zip
-        [ length args [ max ] change ] keep
-    ]
-    [
-        [ pair? ] filter
-        [ keys [ hooks get adjoin ] each ] keep
-    ] bi append ;
-
-: canonicalize-specializer-2 ( specializer -- specializer' )
-    [
-        [
-            {
-                { [ dup integer? ] [ ] }
-                { [ dup word? ] [ hooks get index ] }
-            } cond args get +
-        ] dip
-    ] assoc-map ;
-
-: canonicalize-specializer-3 ( specializer -- specializer' )
-    [ total get object <array> dup <enum> ] dip update ;
-
-: canonicalize-specializers ( methods -- methods' hooks )
-    [
-        [ [ canonicalize-specializer-0 ] dip ] assoc-map
-
-        0 args set
-        V{ } clone hooks set
-
-        [ [ canonicalize-specializer-1 ] dip ] assoc-map
-
-        hooks [ natural-sort ] change
-
-        [ [ canonicalize-specializer-2 ] dip ] assoc-map
-
-        args get hooks get length + total set
-
-        [ [ canonicalize-specializer-3 ] dip ] assoc-map
-
-        hooks get
-    ] with-scope ;
-
-: drop-n-quot ( n -- quot ) \ drop <repetition> >quotation ;
-
-: prepare-method ( method n -- quot )
-    [ 1quotation ] [ drop-n-quot ] bi* prepend ;
-
-: prepare-methods ( methods -- methods' prologue )
-    canonicalize-specializers
-    [ length [ prepare-method ] curry assoc-map ] keep
-    [ [ get ] curry ] map concat [ ] like ;
-
-! Part II: Topologically sorting specializers
-: maximal-element ( seq quot -- n elt )
-    dupd [
-        swapd [ call +lt+ = ] 2curry filter empty?
-    ] 2curry find [ "Topological sort failed" throw ] unless* ;
-    inline
-
-: topological-sort ( seq quot -- newseq )
-    [ >vector [ dup empty? not ] ] dip
-    [ dupd maximal-element [ over delete-nth ] dip ] curry
-    produce nip ; inline
-
-: classes< ( seq1 seq2 -- lt/eq/gt )
-    [
-        {
-            { [ 2dup eq? ] [ +eq+ ] }
-            { [ 2dup [ class<= ] [ swap class<= ] 2bi and ] [ +eq+ ] }
-            { [ 2dup class<= ] [ +lt+ ] }
-            { [ 2dup swap class<= ] [ +gt+ ] }
-            [ +eq+ ]
-        } cond 2nip
-    ] 2map [ +eq+ eq? not ] find nip +eq+ or ;
-
-: sort-methods ( alist -- alist' )
-    [ [ first ] bi@ classes< ] topological-sort ;
-
-! PART III: Creating dispatch quotation
-: picker ( n -- quot )
-    {
-        { 0 [ [ dup ] ] }
-        { 1 [ [ over ] ] }
-        { 2 [ [ pick ] ] }
-        [ 1- picker [ dip swap ] curry ]
-    } case ;
-
-: (multi-predicate) ( class picker -- quot )
-    swap "predicate" word-prop append ;
-
-: multi-predicate ( classes -- quot )
-    dup length <reversed>
-    [ picker 2array ] 2map
-    [ drop object eq? not ] assoc-filter
-    [ [ t ] ] [
-        [ (multi-predicate) ] { } assoc>map
-        unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
-    ] if-empty ;
-
-: argument-count ( methods -- n )
-    keys 0 [ length max ] reduce ;
-
-ERROR: no-method arguments generic ;
-
-: make-default-method ( methods generic -- quot )
-    [ argument-count ] dip [ [ narray ] dip no-method ] 2curry ;
-
-: multi-dispatch-quot ( methods generic -- quot )
-    [ make-default-method ]
-    [ drop [ [ multi-predicate ] dip ] assoc-map reverse ]
-    2bi alist>quot ;
-
-! Generic words
-PREDICATE: generic < word
-    "multi-methods" word-prop >boolean ;
-
-: methods ( word -- alist )
-    "multi-methods" word-prop >alist ;
-
-: make-generic ( generic -- quot )
-    [
-        [ methods prepare-methods % sort-methods ] keep
-        multi-dispatch-quot %
-    ] [ ] make ;
-
-: update-generic ( word -- )
-    dup make-generic define ;
-
-! Methods
-PREDICATE: method-body < word
-    "multi-method-generic" word-prop >boolean ;
-
-M: method-body stack-effect
-    "multi-method-generic" word-prop stack-effect ;
-
-M: method-body crossref?
-    "forgotten" word-prop not ;
-
-: method-word-name ( specializer generic -- string )
-    [ name>> % "-" % unparse % ] "" make ;
-
-: method-word-props ( specializer generic -- assoc )
-    [
-        "multi-method-generic" set
-        "multi-method-specializer" set
-    ] H{ } make-assoc ;
-
-: <method> ( specializer generic -- word )
-    [ method-word-props ] 2keep
-    method-word-name f <word>
-    swap >>props ;
-
-: with-methods ( word quot -- )
-    over [
-        [ "multi-methods" word-prop ] dip call
-    ] dip update-generic ; inline
-
-: reveal-method ( method classes generic -- )
-    [ set-at ] with-methods ;
-
-: method ( classes word -- method )
-    "multi-methods" word-prop at ;
-
-: create-method ( classes generic -- method )
-    2dup method dup [
-        2nip
-    ] [
-        drop [ <method> dup ] 2keep reveal-method
-    ] if ;
-
-: niceify-method ( seq -- seq )
-    [ dup \ f eq? [ drop f ] when ] map ;
-
-M: no-method error.
-    "Type check error" print
-    nl
-    "Generic word " write dup generic>> pprint
-    " does not have a method applicable to inputs:" print
-    dup arguments>> short.
-    nl
-    "Inputs have signature:" print
-    dup arguments>> [ class ] map niceify-method .
-    nl
-    "Available methods: " print
-    generic>> methods canonicalize-specializers drop sort-methods
-    keys [ niceify-method ] map stack. ;
-
-: forget-method ( specializer generic -- )
-    [ delete-at ] with-methods ;
-
-: method>spec ( method -- spec )
-    [ "multi-method-specializer" word-prop ]
-    [ "multi-method-generic" word-prop ] bi prefix ;
-
-: define-generic ( word effect -- )
-    over set-stack-effect
-    dup "multi-methods" word-prop [ drop ] [
-        [ H{ } clone "multi-methods" set-word-prop ]
-        [ update-generic ]
-        bi
-    ] if ;
-
-! Syntax
-SYNTAX: GENERIC: CREATE-WORD complete-effect define-generic ;
-
-: parse-method ( -- quot classes generic )
-    parse-definition [ 2 tail ] [ second ] [ first ] tri ;
-
-: create-method-in ( specializer generic -- method )
-    create-method dup save-location f set-word ;
-
-: CREATE-METHOD ( -- method )
-    scan-word scan-object swap create-method-in ;
-
-: (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
-
-SYNTAX: METHOD: (METHOD:) define ;
-
-! For compatibility
-SYNTAX: M:
-    scan-word 1array scan-word create-method-in
-    parse-definition
-    define ;
-
-! Definition protocol. We qualify core generics here
-QUALIFIED: syntax
-
-syntax:M: generic definer drop \ GENERIC: f ;
-
-syntax:M: generic definition drop f ;
-
-PREDICATE: method-spec < array
-    unclip generic? [ [ class? ] all? ] dip and ;
-
-syntax:M: method-spec where
-    dup unclip method [ ] [ first ] ?if where ;
-
-syntax:M: method-spec set-where
-    unclip method set-where ;
-
-syntax:M: method-spec definer
-    unclip method definer ;
-
-syntax:M: method-spec definition
-    unclip method definition ;
-
-syntax:M: method-spec synopsis*
-    unclip method synopsis* ;
-
-syntax:M: method-spec forget*
-    unclip method forget* ;
-
-syntax:M: method-body definer
-    drop \ METHOD: \ ; ;
-
-syntax:M: method-body synopsis*
-    dup definer.
-    [ "multi-method-generic" word-prop pprint-word ]
-    [ "multi-method-specializer" word-prop pprint* ] bi ;
diff --git a/unmaintained/multi-methods/summary.txt b/unmaintained/multi-methods/summary.txt
deleted file mode 100755 (executable)
index ec8214b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Experimental multiple dispatch implementation
diff --git a/unmaintained/multi-methods/tags.txt b/unmaintained/multi-methods/tags.txt
deleted file mode 100644 (file)
index f427429..0000000
+++ /dev/null
@@ -1 +0,0 @@
-extensions
diff --git a/unmaintained/multi-methods/tests/canonicalize.factor b/unmaintained/multi-methods/tests/canonicalize.factor
deleted file mode 100644 (file)
index 91982de..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-IN: multi-methods.tests
-USING: multi-methods tools.test math sequences namespaces system
-kernel strings ;
-
-[ { POSTPONE: f integer } ] [ { f integer } canonicalize-specializer-0 ] unit-test
-
-: setup-canon-test ( -- )
-    0 args set
-    V{ } clone hooks set ;
-
-: canon-test-1 ( -- seq )
-    { integer { cpu x86 } sequence } canonicalize-specializer-1 ;
-
-[ { { -2 integer } { -1 sequence } { cpu x86 } } ] [
-    [
-        setup-canon-test
-        canon-test-1
-    ] with-scope
-] unit-test
-
-[ { { 0 integer } { 1 sequence } { 2 x86 } } ] [
-    [
-        setup-canon-test
-        canon-test-1
-        canonicalize-specializer-2
-    ] with-scope
-] unit-test
-
-[ { integer sequence x86 } ] [
-    [
-        setup-canon-test
-        canon-test-1
-        canonicalize-specializer-2
-        args get hooks get length + total set
-        canonicalize-specializer-3
-    ] with-scope
-] unit-test
-
-CONSTANT: example-1
-    {
-        { { { cpu x86 } { os linux } } "a" }
-        { { { cpu ppc } } "b" }
-        { { string { os windows } } "c" }
-    }
-
-[
-    {
-        { { object x86 linux } "a"  }
-        { { object ppc object } "b" }
-        { { string object windows } "c" }
-    }
-    { cpu os }
-] [
-    example-1 canonicalize-specializers
-] unit-test
-
-[
-    {
-        { { object x86 linux } [ drop drop "a" ] }
-        { { object ppc object } [ drop drop "b" ] }
-        { { string object windows } [ drop drop "c" ] }
-    }
-    [ \ cpu get \ os get ]
-] [
-    example-1 prepare-methods
-] unit-test
diff --git a/unmaintained/multi-methods/tests/definitions.factor b/unmaintained/multi-methods/tests/definitions.factor
deleted file mode 100644 (file)
index aa66f41..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-IN: multi-methods.tests
-USING: multi-methods tools.test math sequences namespaces system
-kernel strings words compiler.units quotations ;
-
-DEFER: fake
-\ fake H{ } clone "multi-methods" set-word-prop
-
-[ "fake-{ }" ] [ { } \ fake method-word-name ] unit-test
-
-[ H{ { "multi-method-generic" fake } { "multi-method-specializer" { } } } ]
-[ { } \ fake method-word-props ] unit-test
-
-[ t ] [ { } \ fake <method> method-body? ] unit-test
-
-[
-    [ { } [ ] ] [ \ fake methods prepare-methods [ sort-methods ] dip ] unit-test
-
-    [ t ] [ { } \ fake multi-dispatch-quot callable? ] unit-test
-
-    [ t ] [ \ fake make-generic quotation? ] unit-test
-
-    [ ] [ \ fake update-generic ] unit-test
-
-    DEFER: testing
-
-    [ ] [ \ testing (( -- )) define-generic ] unit-test
-
-    [ t ] [ \ testing generic? ] unit-test
-] with-compilation-unit
diff --git a/unmaintained/multi-methods/tests/legacy.factor b/unmaintained/multi-methods/tests/legacy.factor
deleted file mode 100644 (file)
index b6d7326..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-IN: multi-methods.tests
-USING: math strings sequences tools.test ;
-
-GENERIC: legacy-test ( a -- b )
-
-M: integer legacy-test sq ;
-M: string legacy-test " hey" append ;
-
-[ 25 ] [ 5 legacy-test ] unit-test
-[ "hello hey" ] [ "hello" legacy-test ] unit-test
diff --git a/unmaintained/multi-methods/tests/syntax.factor b/unmaintained/multi-methods/tests/syntax.factor
deleted file mode 100644 (file)
index cc07309..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-IN: multi-methods.tests
-USING: multi-methods tools.test math sequences namespaces system
-kernel strings definitions prettyprint debugger arrays
-hashtables continuations classes assocs accessors see ;
-
-GENERIC: first-test ( -- )
-
-[ t ] [ \ first-test generic? ] unit-test
-
-MIXIN: thing
-
-SINGLETON: paper    INSTANCE: paper thing
-SINGLETON: scissors INSTANCE: scissors thing
-SINGLETON: rock     INSTANCE: rock thing
-
-GENERIC: beats? ( obj1 obj2 -- ? )
-
-METHOD: beats? { paper scissors } t ;
-METHOD: beats? { scissors rock } t ;
-METHOD: beats? { rock paper } t ;
-METHOD: beats? { thing thing } f ;
-
-: play ( obj1 obj2 -- ? ) beats? 2nip ;
-
-[ { } 3 play ] must-fail
-[ t ] [ error get no-method? ] unit-test
-[ ] [ error get error. ] unit-test
-[ { { } 3 } ] [ error get arguments>> ] unit-test
-[ t ] [ paper scissors play ] unit-test
-[ f ] [ scissors paper play ] unit-test
-
-[ t ] [ { beats? paper scissors } method-spec? ] unit-test
-[ ] [ { beats? paper scissors } see ] unit-test
-
-SYMBOL: some-var
-
-GENERIC: hook-test ( -- obj )
-
-METHOD: hook-test { array { some-var array } } reverse ;
-METHOD: hook-test { { some-var array } } class ;
-METHOD: hook-test { hashtable { some-var number } } assoc-size ;
-
-{ 1 2 3 } some-var set
-[ { f t t } ] [ { t t f } hook-test ] unit-test
-[ fixnum ] [ 3 hook-test ] unit-test
-5.0 some-var set
-[ 0 ] [ H{ } hook-test ] unit-test
-
-"error" some-var set
-[ H{ } hook-test ] must-fail
-[ t ] [ error get no-method? ] unit-test
-[ { H{ } "error" } ] [ error get arguments>> ] unit-test
-
-MIXIN: busted
-
-TUPLE: busted-1 ;
-TUPLE: busted-2 ; INSTANCE: busted-2 busted
-TUPLE: busted-3 ;
-
-GENERIC: busted-sort ( obj1 obj2 -- obj1 obj2 )
-
-METHOD: busted-sort { busted-1 busted-2 } ;
-METHOD: busted-sort { busted-2 busted-3 } ;
-METHOD: busted-sort { busted busted } ;
diff --git a/unmaintained/multi-methods/tests/topological-sort.factor b/unmaintained/multi-methods/tests/topological-sort.factor
deleted file mode 100644 (file)
index f161837..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-USING: kernel multi-methods tools.test math arrays sequences
-math.order ;
-IN: multi-methods.tests
-
-[ { 1 2 3 4 5 6 } ] [
-    { 6 4 5 1 3 2 } [ <=> ] topological-sort
-] unit-test
-
-[ +lt+ ] [
-    { fixnum array } { number sequence } classes<
-] unit-test
-
-[ +eq+ ] [
-    { number sequence } { number sequence } classes<
-] unit-test
-
-[ +gt+ ] [
-    { object object } { number sequence } classes<
-] unit-test