Merge branch 'master' of git://factorcode.org/git/factor

db4
Joe Groff 2008-12-04 13:41:30 -08:00
commit ef0bc65039
106 changed files with 541 additions and 261 deletions

View File

@ -29,7 +29,7 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
writer>> swap "writing" set-word-prop ; writer>> swap "writing" set-word-prop ;
: reader-word ( class name vocab -- word ) : reader-word ( class name vocab -- word )
[ "-" swap 3append ] dip create ; [ "-" glue ] dip create ;
: writer-word ( class name vocab -- word ) : writer-word ( class name vocab -- word )
[ [ swap "set-" % % "-" % % ] "" make ] dip create ; [ [ swap "set-" % % "-" % % ] "" make ] dip create ;

View File

@ -21,7 +21,7 @@ IN: compiler.tree.builder
: build-tree-with ( in-stack quot -- nodes out-stack ) : build-tree-with ( in-stack quot -- nodes out-stack )
#! Not safe to call from inference transforms. #! Not safe to call from inference transforms.
[ [
[ >vector meta-d set ] [ >vector \ meta-d set ]
[ f initial-recursive-state infer-quot ] bi* [ f initial-recursive-state infer-quot ] bi*
] with-tree-builder nip ] with-tree-builder nip
unclip-last in-d>> ; unclip-last in-d>> ;

View File

@ -20,6 +20,10 @@ SYMBOL: node-count
: count-nodes ( nodes -- ) : count-nodes ( nodes -- )
0 swap [ drop 1+ ] each-node node-count set ; 0 swap [ drop 1+ ] each-node node-count set ;
! We try not to inline the same word too many times, to avoid
! combinatorial explosion
SYMBOL: inlining-count
! Splicing nodes ! Splicing nodes
GENERIC: splicing-nodes ( #call word/quot/f -- nodes ) GENERIC: splicing-nodes ( #call word/quot/f -- nodes )
@ -120,17 +124,25 @@ DEFER: (flat-length)
bi and bi and
] contains? ; ] contains? ;
: node-count-bias ( -- n )
45 node-count get [-] 8 /i ;
: body-length-bias ( word -- n )
[ flat-length ] [ inlining-count get at 0 or 2/ 1+ ] bi *
24 swap [-] 4 /i ;
: inlining-rank ( #call word -- n ) : inlining-rank ( #call word -- n )
[ classes-known? 2 0 ? ] [ classes-known? 2 0 ? ]
[ [
{ {
[ drop node-count get 45 swap [-] 8 /i ] [ body-length-bias ]
[ flat-length 24 swap [-] 4 /i ]
[ "default" word-prop -4 0 ? ] [ "default" word-prop -4 0 ? ]
[ "specializer" word-prop 1 0 ? ] [ "specializer" word-prop 1 0 ? ]
[ method-body? 1 0 ? ] [ method-body? 1 0 ? ]
} cleave } cleave
] bi* + + + + + ; node-count-bias
loop-nesting get 0 or 2 *
] bi* + + + + + + ;
: should-inline? ( #call word -- ? ) : should-inline? ( #call word -- ? )
dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ; dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ;
@ -138,12 +150,12 @@ DEFER: (flat-length)
SYMBOL: history SYMBOL: history
: remember-inlining ( word -- ) : remember-inlining ( word -- )
history [ swap suffix ] change ; [ [ 1 ] dip inlining-count get at+ ]
[ history [ swap suffix ] change ]
bi ;
: inline-word-def ( #call word quot -- ? ) : inline-word-def ( #call word quot -- ? )
over history get memq? [ over history get memq? [ 3drop f ] [
3drop f
] [
[ [
swap remember-inlining swap remember-inlining
dupd splicing-nodes >>body dupd splicing-nodes >>body

View File

@ -6,6 +6,8 @@ compiler.tree.propagation.copy
compiler.tree.propagation.info ; compiler.tree.propagation.info ;
IN: compiler.tree.propagation.nodes IN: compiler.tree.propagation.nodes
SYMBOL: loop-nesting
GENERIC: propagate-before ( node -- ) GENERIC: propagate-before ( node -- )
GENERIC: propagate-after ( node -- ) GENERIC: propagate-after ( node -- )

View File

@ -19,5 +19,6 @@ IN: compiler.tree.propagation
H{ } clone copies set H{ } clone copies set
H{ } clone 1array value-infos set H{ } clone 1array value-infos set
H{ } clone 1array constraints set H{ } clone 1array constraints set
H{ } clone inlining-count set
dup count-nodes dup count-nodes
dup (propagate) ; dup (propagate) ;

View File

@ -55,6 +55,8 @@ IN: compiler.tree.propagation.recursive
M: #recursive propagate-around ( #recursive -- ) M: #recursive propagate-around ( #recursive -- )
constraints [ H{ } clone suffix ] change constraints [ H{ } clone suffix ] change
[ [
loop-nesting inc
constraints [ but-last H{ } clone suffix ] change constraints [ but-last H{ } clone suffix ] change
child>> child>>
@ -62,6 +64,8 @@ M: #recursive propagate-around ( #recursive -- )
[ first propagate-recursive-phi ] [ first propagate-recursive-phi ]
[ (propagate) ] [ (propagate) ]
tri tri
loop-nesting dec
] until-fixed-point ; ] until-fixed-point ;
: recursive-phi-infos ( node -- infos ) : recursive-phi-infos ( node -- infos )

View File

@ -266,8 +266,8 @@ M: postgresql-db persistent-table ( -- hashtable )
ERROR: no-compound-found string object ; ERROR: no-compound-found string object ;
M: postgresql-db compound ( string object -- string' ) M: postgresql-db compound ( string object -- string' )
over { over {
{ "default" [ first number>string join-space ] } { "default" [ first number>string " " glue ] }
{ "varchar" [ first number>string paren append ] } { "varchar" [ first number>string "(" ")" surround append ] }
{ "references" [ >reference-string ] } { "references" [ >reference-string ] }
[ drop no-compound-found ] [ drop no-compound-found ]
} case ; } case ;

View File

@ -162,22 +162,19 @@ M: db <select-by-slots-statement> ( tuple class -- statement )
where-clause where-clause
] query-make ; ] query-make ;
: splice ( string1 string2 string3 -- string )
swap 3append ;
: do-group ( tuple groups -- ) : do-group ( tuple groups -- )
dup string? [ 1array ] when dup string? [ 1array ] when
[ ", " join " group by " splice ] curry change-sql drop ; [ ", " join " group by " glue ] curry change-sql drop ;
: do-order ( tuple order -- ) : do-order ( tuple order -- )
dup string? [ 1array ] when dup string? [ 1array ] when
[ ", " join " order by " splice ] curry change-sql drop ; [ ", " join " order by " glue ] curry change-sql drop ;
: do-offset ( tuple n -- ) : do-offset ( tuple n -- )
[ number>string " offset " splice ] curry change-sql drop ; [ number>string " offset " glue ] curry change-sql drop ;
: do-limit ( tuple n -- ) : do-limit ( tuple n -- )
[ number>string " limit " splice ] curry change-sql drop ; [ number>string " limit " glue ] curry change-sql drop ;
: make-query* ( tuple query -- tuple' ) : make-query* ( tuple query -- tuple' )
dupd dupd

View File

@ -308,7 +308,7 @@ M: sqlite-db persistent-table ( -- assoc )
M: sqlite-db compound ( string seq -- new-string ) M: sqlite-db compound ( string seq -- new-string )
over { over {
{ "default" [ first number>string join-space ] } { "default" [ first number>string " " glue ] }
{ "references" [ { "references" [
[ >reference-string ] keep [ >reference-string ] keep
first2 [ "foreign-table" set ] first2 [ "foreign-table" set ]

View File

@ -147,12 +147,6 @@ HELP: get-slot-named
{ "value" "the value stored in the slot" } } { "value" "the value stored in the slot" } }
{ $description "Returns the value stored in a tuple slot, where the tuple slot is a string." } ; { $description "Returns the value stored in a tuple slot, where the tuple slot is a string." } ;
HELP: join-space
{ $values
{ "string1" string } { "string2" string }
{ "new-string" null } }
{ $description "" } ;
HELP: literal-bind HELP: literal-bind
{ $description "" } ; { $description "" } ;

View File

@ -158,12 +158,6 @@ ERROR: no-sql-type type ;
modifiers>> [ lookup-modifier ] map " " join modifiers>> [ lookup-modifier ] map " " join
[ "" ] [ " " prepend ] if-empty ; [ "" ] [ " " prepend ] if-empty ;
: join-space ( string1 string2 -- new-string )
" " swap 3append ;
: paren ( string -- new-string )
"(" swap ")" 3append ;
HOOK: bind% db ( spec -- ) HOOK: bind% db ( spec -- )
HOOK: bind# db ( spec obj -- ) HOOK: bind# db ( spec obj -- )
@ -171,7 +165,7 @@ ERROR: no-column column ;
: >reference-string ( string pair -- string ) : >reference-string ( string pair -- string )
first2 first2
[ [ unparse join-space ] [ db-columns ] bi ] dip [ [ unparse " " glue ] [ db-columns ] bi ] dip
swap [ column-name>> = ] with find nip swap [ column-name>> = ] with find nip
[ no-column ] unless* [ no-column ] unless*
column-name>> paren append ; column-name>> "(" ")" surround append ;

View File

@ -14,7 +14,10 @@ IN: editors.scite
: scite-path ( -- path ) : scite-path ( -- path )
\ scite-path get-global [ \ scite-path get-global [
program-files "wscite\\SciTE.exe" append-path program-files "ScITE Source Code Editor\\SciTE.exe" append-path
dup exists? [
drop program-files "wscite\\SciTE.exe" append-path
] unless
] unless* ; ] unless* ;
: scite-command ( file line -- cmd ) : scite-command ( file line -- cmd )

View File

@ -18,7 +18,7 @@ HOOK: (set-os-envs) os ( seq -- )
(os-envs) [ "=" split1 ] H{ } map>assoc ; (os-envs) [ "=" split1 ] H{ } map>assoc ;
: set-os-envs ( assoc -- ) : set-os-envs ( assoc -- )
[ "=" swap 3append ] { } assoc>map (set-os-envs) ; [ "=" glue ] { } assoc>map (set-os-envs) ;
{ {
{ [ os unix? ] [ "environment.unix" require ] } { [ os unix? ] [ "environment.unix" require ] }

View File

@ -7,8 +7,7 @@ namespaces make sequences ftp io.unix.launcher.parser
unicode.case splitting assocs classes io.servers.connection unicode.case splitting assocs classes io.servers.connection
destructors calendar io.timeouts io.streams.duplex threads destructors calendar io.timeouts io.streams.duplex threads
continuations math concurrency.promises byte-arrays continuations math concurrency.promises byte-arrays
io.backend sequences.lib tools.hexdump tools.files io.backend tools.hexdump tools.files io.streams.string ;
io.streams.string ;
IN: ftp.server IN: ftp.server
TUPLE: ftp-client url mode state command-promise user password ; TUPLE: ftp-client url mode state command-promise user password ;
@ -231,7 +230,7 @@ M: ftp-put service-command ( stream obj -- )
expect-connection expect-connection
[ [
"Entering Passive Mode (127,0,0,1," % "Entering Passive Mode (127,0,0,1," %
port>bytes [ number>string ] bi@ "," splice % port>bytes [ number>string ] bi@ "," glue %
")" % ")" %
] "" make 227 swap server-response ; ] "" make 227 swap server-response ;

View File

@ -7,7 +7,7 @@ http.server.redirection http.server.remapping ;
IN: furnace.utilities IN: furnace.utilities
: word>string ( word -- string ) : word>string ( word -- string )
[ vocabulary>> ] [ name>> ] bi ":" swap 3append ; [ vocabulary>> ] [ name>> ] bi ":" glue ;
: words>strings ( seq -- seq' ) : words>strings ( seq -- seq' )
[ word>string ] map ; [ word>string ] map ;

View File

@ -111,7 +111,7 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s
{ [ dup real? ] [ number>string ] } { [ dup real? ] [ number>string ] }
[ ] [ ]
} cond } cond
[ check-cookie-string ] bi@ "=" swap 3append , [ check-cookie-string ] bi@ "=" glue ,
] ]
} case ; } case ;

View File

@ -1,4 +1,22 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: tools.test interpolate ; USING: interpolate io.streams.string namespaces tools.test locals ;
IN: interpolate.tests IN: interpolate.tests
[ "Hello, Jane." ] [
"Jane" "name" set
[ "Hello, ${name}." interpolate ] with-string-writer
] unit-test
[ "Sup Dawg, we heard you liked rims, so we put rims on your rims so you can roll while you roll." ] [
"Dawg" "name" set
"rims" "noun" set
"roll" "verb" set
[ "Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your ${noun} so you can ${verb} while you ${verb}." interpolate ] with-string-writer
] unit-test
[ "Oops, I accidentally the whole economy..." ] [
[let | noun [ "economy" ] |
[ I[ Oops, I accidentally the whole ${noun}...]I ] with-string-writer
]
] unit-test

View File

@ -1,21 +1,40 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: io kernel macros make multiline namespaces parser USING: io kernel macros make multiline namespaces parser
peg.ebnf present sequences strings ; present sequences strings splitting fry accessors ;
IN: interpolate IN: interpolate
MACRO: interpolate ( string -- ) TUPLE: interpolate-var name ;
[EBNF
var = "${" [^}]+ "}" => [[ second >string [ get present write ] curry ]]
text = [^$]+ => [[ >string [ write ] curry ]]
interpolate = (var|text)* => [[ [ ] join ]]
EBNF] ;
EBNF: interpolate-locals : (parse-interpolate) ( string -- )
var = "${" [^}]+ "}" => [[ [ second >string search , [ present write ] % ] [ ] make ]] [
text = [^$]+ => [[ [ >string , [ write ] % ] [ ] make ]] "${" split1-slice [ >string , ] [
interpolate = (var|text)* => [[ [ ] join ]] [
;EBNF "}" split1-slice
[ >string interpolate-var boa , ]
[ (parse-interpolate) ] bi*
] when*
] bi*
] unless-empty ;
: parse-interpolate ( string -- seq )
[ (parse-interpolate) ] { } make ;
MACRO: interpolate ( string -- )
parse-interpolate [
dup interpolate-var?
[ name>> '[ _ get present write ] ]
[ '[ _ write ] ]
if
] map [ ] join ;
: interpolate-locals ( string -- quot )
parse-interpolate [
dup interpolate-var?
[ name>> search '[ _ present write ] ]
[ '[ _ write ] ]
if
] map [ ] join ;
: I[ "]I" parse-multiline-string : I[ "]I" parse-multiline-string
interpolate-locals parsed \ call parsed ; parsing interpolate-locals parsed \ call parsed ; parsing

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel math math.bitwise combinators.lib math.parser USING: kernel math math.bitwise math.parser
random sequences sequences.lib continuations namespaces random sequences continuations namespaces
io.files io arrays io.files.unique.backend system io.files io arrays io.files.unique.backend system
combinators vocabs.loader fry ; combinators vocabs.loader fry ;
IN: io.files.unique IN: io.files.unique
@ -29,7 +29,7 @@ PRIVATE>
: make-unique-file ( prefix suffix -- path ) : make-unique-file ( prefix suffix -- path )
temporary-path -rot temporary-path -rot
[ [
unique-length get random-name swap 3append append-path unique-length get random-name glue append-path
dup (make-unique-file) dup (make-unique-file)
] 3curry unique-retries get retry ; ] 3curry unique-retries get retry ;

View File

@ -1,4 +1,4 @@
USE: specialized-arrays.functor USING: io.mmap.functor specialized-arrays.direct.ushort ;
IN: specialized-arrays.ushort IN: io.mmap.ushort
<< "ushort" define-array >> << "ushort" define-mapped-array >>

View File

@ -79,7 +79,7 @@ M: threaded-server handle-client* handler>> call ;
\ handle-client ERROR add-error-logging \ handle-client ERROR add-error-logging
: thread-name ( server-name addrspec -- string ) : thread-name ( server-name addrspec -- string )
unparse-short " connection from " swap 3append ; unparse-short " connection from " glue ;
: accept-connection ( threaded-server -- ) : accept-connection ( threaded-server -- )
[ accept ] [ addr>> ] bi [ accept ] [ addr>> ] bi

View File

@ -115,7 +115,7 @@ M: invalid-inet6 summary drop "Invalid IPv6 address" ;
: pad-inet6 ( string1 string2 -- seq ) : pad-inet6 ( string1 string2 -- seq )
2dup [ length ] bi@ + 8 swap - 2dup [ length ] bi@ + 8 swap -
dup 0 < [ "More than 8 components" throw ] when dup 0 < [ "More than 8 components" throw ] when
<byte-array> swap 3append ; <byte-array> glue ;
: inet6-bytes ( seq -- bytes ) : inet6-bytes ( seq -- bytes )
[ 2 >be ] { } map-as concat >byte-array ; [ 2 >be ] { } map-as concat >byte-array ;

View File

@ -4,7 +4,7 @@ USING: alien.syntax kernel unix.stat math unix
combinators system io.backend accessors alien.c-types combinators system io.backend accessors alien.c-types
io.encodings.utf8 alien.strings unix.types io.unix.files io.encodings.utf8 alien.strings unix.types io.unix.files
io.files unix.statvfs.netbsd unix.getfsstat.netbsd io.files unix.statvfs.netbsd unix.getfsstat.netbsd
grouping sequences ; grouping sequences io.encodings.utf8 ;
IN: io.unix.files.netbsd IN: io.unix.files.netbsd
TUPLE: netbsd-file-system-info < unix-file-system-info TUPLE: netbsd-file-system-info < unix-file-system-info
@ -40,13 +40,13 @@ M: netbsd statvfs>file-system-info ( file-system-info statvfs -- file-system-inf
[ statvfs-f_namemax >>name-max ] [ statvfs-f_namemax >>name-max ]
[ statvfs-f_owner >>owner ] [ statvfs-f_owner >>owner ]
! [ statvfs-f_spare >>spare ] ! [ statvfs-f_spare >>spare ]
[ statvfs-f_fstypename alien>native-string >>type ] [ statvfs-f_fstypename utf8 alien>string >>type ]
[ statvfs-f_mntonname alien>native-string >>mount-point ] [ statvfs-f_mntonname utf8 alien>string >>mount-point ]
[ statvfs-f_mntfromname alien>native-string >>device-name ] [ statvfs-f_mntfromname utf8 alien>string >>device-name ]
} cleave ; } cleave ;
M: netbsd file-systems ( -- array ) M: netbsd file-systems ( -- array )
f 0 0 getvfsstat dup io-error f 0 0 getvfsstat dup io-error
"statvfs" <c-array> dup dup length 0 getvfsstat io-error "statvfs" <c-array> dup dup length 0 getvfsstat io-error
"statvfs" heap-size group "statvfs" heap-size group
[ statvfs-f_mntonname alien>native-string file-system-info ] map ; [ statvfs-f_mntonname utf8 alien>string file-system-info ] map ;

View File

@ -16,7 +16,7 @@ USE: unix
command>> dup string? [ tokenize-command ] when ; command>> dup string? [ tokenize-command ] when ;
: assoc>env ( assoc -- env ) : assoc>env ( assoc -- env )
[ "=" swap 3append ] { } assoc>map ; [ "=" glue ] { } assoc>map ;
: setup-priority ( process -- process ) : setup-priority ( process -- process )
dup priority>> [ dup priority>> [

View File

@ -1,8 +0,0 @@
USING: io io.mmap io.files kernel tools.test continuations
sequences io.encodings.ascii accessors ;
IN: io.windows.mmap.tests
[ ] [ "a" "mmap-grow-test.txt" temp-file ascii set-file-contents ] unit-test
[ 1 ] [ "mmap-grow-test.txt" temp-file file-info size>> ] unit-test
[ ] [ "mmap-grow-test.txt" temp-file 100 [ [ ] change-each ] with-mapped-file ] unit-test
[ 100 ] [ "mmap-grow-test.txt" temp-file file-info size>> ] unit-test

View File

@ -10,6 +10,7 @@ HELP: geometric-mean
HELP: harmonic-mean HELP: harmonic-mean
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} } { $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
{ $description "Computes the harmonic mean of the elements in " { $snippet "seq" } ". The harmonic mean is appropriate when the average of rates is desired." } { $description "Computes the harmonic mean of the elements in " { $snippet "seq" } ". The harmonic mean is appropriate when the average of rates is desired." }
{ $notes "Positive reals only." }
{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } harmonic-mean ." "6/11" } } { $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } harmonic-mean ." "6/11" } }
{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ; { $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
@ -36,7 +37,7 @@ HELP: range
HELP: std HELP: std
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} } { $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
{ $description "Computes the standard deviation of " { $snippet "seq" } " by squaring the variance of the sequence. It measures how widely spread the values in a sequence are about the mean." } { $description "Computes the standard deviation of " { $snippet "seq" } ", which is the square root of the variance. It measures how widely spread the values in a sequence are about the mean." }
{ $examples { $examples
{ $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } std ." "1.0" } { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } std ." "1.0" }
{ $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } std ." "1.290994448735806" } } ; { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } std ." "1.290994448735806" } } ;

View File

@ -5,20 +5,15 @@ USING: arrays combinators kernel math math.analysis math.functions sequences
IN: math.statistics IN: math.statistics
: mean ( seq -- n ) : mean ( seq -- n )
#! arithmetic mean, sum divided by length
[ sum ] [ length ] bi / ; [ sum ] [ length ] bi / ;
: geometric-mean ( seq -- n ) : geometric-mean ( seq -- n )
#! geometric mean, nth root of product
[ length ] [ product ] bi nth-root ; [ length ] [ product ] bi nth-root ;
: harmonic-mean ( seq -- n ) : harmonic-mean ( seq -- n )
#! harmonic mean, reciprocal of sum of reciprocals.
#! positive reals only
[ recip ] sigma recip ; [ recip ] sigma recip ;
: median ( seq -- n ) : median ( seq -- n )
#! middle number if odd, avg of two middle numbers if even
natural-sort dup length even? [ natural-sort dup length even? [
[ midpoint@ dup 1- 2array ] keep nths mean [ midpoint@ dup 1- 2array ] keep nths mean
] [ ] [
@ -26,11 +21,10 @@ IN: math.statistics
] if ; ] if ;
: range ( seq -- n ) : range ( seq -- n )
#! max - min
minmax swap - ; minmax swap - ;
: var ( seq -- x ) : var ( seq -- x )
#! variance, normalize by N-1 #! normalize by N-1
dup length 1 <= [ dup length 1 <= [
drop 0 drop 0
] [ ] [
@ -39,11 +33,9 @@ IN: math.statistics
] if ; ] if ;
: std ( seq -- x ) : std ( seq -- x )
#! standard deviation, sqrt of variance
var sqrt ; var sqrt ;
: ste ( seq -- x ) : ste ( seq -- x )
#! standard error, standard deviation / sqrt ( length of sequence )
[ std ] [ length ] bi sqrt / ; [ std ] [ length ] bi sqrt / ;
: ((r)) ( mean(x) mean(y) {x} {y} -- (r) ) : ((r)) ( mean(x) mean(y) {x} {y} -- (r) )

View File

@ -129,7 +129,7 @@ SYMBOL: ->
: remove-breakpoints ( quot pos -- quot' ) : remove-breakpoints ( quot pos -- quot' )
over quotation? [ over quotation? [
1+ cut [ (remove-breakpoints) ] bi@ 1+ cut [ (remove-breakpoints) ] bi@
[ -> ] swap 3append [ -> ] glue
] [ ] [
drop drop
] if ; ] if ;

View File

@ -15,11 +15,14 @@ TUPLE: mersenne-twister { seq uint-array } { i fixnum } ;
: mt-m 397 ; inline : mt-m 397 ; inline
: mt-a HEX: 9908b0df ; inline : mt-a HEX: 9908b0df ; inline
: mersenne-wrap ( n -- n' )
dup mt-n > [ mt-n - ] when ; inline
: wrap-nth ( n seq -- obj ) : wrap-nth ( n seq -- obj )
[ length mod ] keep nth-unsafe ; inline [ mersenne-wrap ] dip nth-unsafe ; inline
: set-wrap-nth ( obj n seq -- ) : set-wrap-nth ( obj n seq -- )
[ length mod ] keep set-nth-unsafe ; inline [ mersenne-wrap ] dip set-nth-unsafe ; inline
: calculate-y ( n seq -- y ) : calculate-y ( n seq -- y )
[ wrap-nth 31 mask-bit ] [ wrap-nth 31 mask-bit ]
@ -50,7 +53,7 @@ TUPLE: mersenne-twister { seq uint-array } { i fixnum } ;
: init-mt-seq ( seed -- seq ) : init-mt-seq ( seed -- seq )
32 bits mt-n <uint-array> 32 bits mt-n <uint-array>
[ set-first ] [ init-mt-rest ] [ ] tri ; [ set-first ] [ init-mt-rest ] [ ] tri ; inline
: mt-temper ( y -- yt ) : mt-temper ( y -- yt )
dup -11 shift bitxor dup -11 shift bitxor

View File

@ -20,7 +20,7 @@ SET-NTH [ T dup c-setter array-accessor ]
WHERE WHERE
TUPLE: A TUPLE: A
{ underlying alien read-only } { underlying c-ptr read-only }
{ length fixnum read-only } ; { length fixnum read-only } ;
: <A> ( alien len -- direct-array ) A boa ; inline : <A> ( alien len -- direct-array ) A boa ; inline

View File

@ -3,20 +3,21 @@ stack-checker.state sequences ;
IN: stack-checker.backend.tests IN: stack-checker.backend.tests
[ ] [ [ ] [
V{ } clone meta-d set V{ } clone \ meta-d set
V{ } clone meta-r set V{ } clone \ meta-r set
V{ } clone \ literals set
0 d-in set 0 d-in set
] unit-test ] unit-test
[ 0 ] [ 0 ensure-d length ] unit-test [ 0 ] [ 0 ensure-d length ] unit-test
[ 2 ] [ 2 ensure-d length ] unit-test [ 2 ] [ 2 ensure-d length ] unit-test
[ 2 ] [ meta-d get length ] unit-test [ 2 ] [ meta-d length ] unit-test
[ 3 ] [ 3 ensure-d length ] unit-test [ 3 ] [ 3 ensure-d length ] unit-test
[ 3 ] [ meta-d get length ] unit-test [ 3 ] [ meta-d length ] unit-test
[ 1 ] [ 1 ensure-d length ] unit-test [ 1 ] [ 1 ensure-d length ] unit-test
[ 3 ] [ meta-d get length ] unit-test [ 3 ] [ meta-d length ] unit-test
[ ] [ 1 consume-d drop ] unit-test [ ] [ 1 consume-d drop ] unit-test

View File

@ -9,10 +9,10 @@ stack-checker.visitor stack-checker.errors
stack-checker.values stack-checker.recursive-state ; stack-checker.values stack-checker.recursive-state ;
IN: stack-checker.backend IN: stack-checker.backend
: push-d ( obj -- ) meta-d get push ; : push-d ( obj -- ) meta-d push ;
: pop-d ( -- obj ) : pop-d ( -- obj )
meta-d get [ meta-d [
<value> dup 1array #introduce, d-in inc <value> dup 1array #introduce, d-in inc
] [ pop ] if-empty ; ] [ pop ] if-empty ;
@ -22,46 +22,52 @@ IN: stack-checker.backend
[ <value> ] replicate ; [ <value> ] replicate ;
: ensure-d ( n -- values ) : ensure-d ( n -- values )
meta-d get 2dup length > [ meta-d 2dup length > [
2dup 2dup
[ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri [ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
[ length d-in +@ ] [ #introduce, ] [ meta-d get push-all ] tri [ length d-in +@ ] [ #introduce, ] [ meta-d push-all ] tri
meta-d get push-all meta-d push-all
] when swap tail* ; ] when swap tail* ;
: shorten-by ( n seq -- ) : shorten-by ( n seq -- )
[ length swap - ] keep shorten ; inline [ length swap - ] keep shorten ; inline
: consume-d ( n -- seq ) : consume-d ( n -- seq )
[ ensure-d ] [ meta-d get shorten-by ] bi ; [ ensure-d ] [ meta-d shorten-by ] bi ;
: output-d ( values -- ) meta-d get push-all ; : output-d ( values -- ) meta-d push-all ;
: produce-d ( n -- values ) : produce-d ( n -- values )
make-values dup meta-d get push-all ; make-values dup meta-d push-all ;
: push-r ( obj -- ) meta-r get push ; : push-r ( obj -- ) meta-r push ;
: pop-r ( -- obj ) : pop-r ( -- obj )
meta-r get dup empty? meta-r dup empty?
[ too-many-r> inference-error ] [ pop ] if ; [ too-many-r> inference-error ] [ pop ] if ;
: consume-r ( n -- seq ) : consume-r ( n -- seq )
meta-r get 2dup length > meta-r 2dup length >
[ too-many-r> inference-error ] when [ too-many-r> inference-error ] when
[ swap tail* ] [ shorten-by ] 2bi ; [ swap tail* ] [ shorten-by ] 2bi ;
: output-r ( seq -- ) meta-r get push-all ; : output-r ( seq -- ) meta-r push-all ;
: pop-literal ( -- rstate obj )
pop-d
[ 1array #drop, ]
[ literal [ recursion>> ] [ value>> ] bi ] bi ;
GENERIC: apply-object ( obj -- )
: push-literal ( obj -- ) : push-literal ( obj -- )
dup <literal> make-known [ nip push-d ] [ #push, ] 2bi ; literals get push ;
: pop-literal ( -- rstate obj )
literals get [
pop-d
[ 1array #drop, ]
[ literal [ recursion>> ] [ value>> ] bi ] bi
] [ pop recursive-state get swap ] if-empty ;
: literals-available? ( n -- literals ? )
literals get 2dup length <=
[ [ swap tail* ] [ shorten-by ] 2bi t ] [ 2drop f f ] if ;
GENERIC: apply-object ( obj -- )
M: wrapper apply-object M: wrapper apply-object
wrapped>> wrapped>>
@ -72,10 +78,17 @@ M: wrapper apply-object
M: object apply-object push-literal ; M: object apply-object push-literal ;
: terminate ( -- ) : terminate ( -- )
terminated? on meta-d get clone meta-r get clone #terminate, ; terminated? on meta-d clone meta-r clone #terminate, ;
: check->r ( -- )
meta-r empty? [ \ too-many->r inference-error ] unless ;
: infer-quot-here ( quot -- ) : infer-quot-here ( quot -- )
[ apply-object terminated? get not ] all? drop ; meta-r [
V{ } clone \ meta-r set
[ apply-object terminated? get not ] all?
[ commit-literals check->r ] [ literals get delete-all ] if
] dip \ meta-r set ;
: infer-quot ( quot rstate -- ) : infer-quot ( quot rstate -- )
recursive-state get [ recursive-state get [
@ -103,10 +116,10 @@ M: object apply-object push-literal ;
] if ; ] if ;
: infer->r ( n -- ) : infer->r ( n -- )
consume-d dup copy-values [ #>r, ] [ nip output-r ] 2bi ; consume-d dup copy-values [ nip output-r ] [ #>r, ] 2bi ;
: infer-r> ( n -- ) : infer-r> ( n -- )
consume-r dup copy-values [ #r>, ] [ nip output-d ] 2bi ; consume-r dup copy-values [ nip output-d ] [ #r>, ] 2bi ;
: undo-infer ( -- ) : undo-infer ( -- )
recorded get [ f "inferred-effect" set-word-prop ] each ; recorded get [ f "inferred-effect" set-word-prop ] each ;
@ -127,13 +140,8 @@ M: object apply-object push-literal ;
: infer-word-def ( word -- ) : infer-word-def ( word -- )
[ specialized-def ] [ add-recursive-state ] bi infer-quot ; [ specialized-def ] [ add-recursive-state ] bi infer-quot ;
: check->r ( -- )
meta-r get empty? terminated? get or
[ \ too-many->r inference-error ] unless ;
: end-infer ( -- ) : end-infer ( -- )
check->r meta-d clone #return, ;
meta-d get clone #return, ;
: effect-required? ( word -- ? ) : effect-required? ( word -- ? )
{ {

View File

@ -57,9 +57,9 @@ SYMBOL: quotations
branch-variable ; branch-variable ;
: datastack-phi ( seq -- phi-in phi-out ) : datastack-phi ( seq -- phi-in phi-out )
[ d-in branch-variable ] [ meta-d active-variable ] bi [ d-in branch-variable ] [ \ meta-d active-variable ] bi
unify-branches unify-branches
[ d-in set ] [ ] [ dup >vector meta-d set ] tri* ; [ d-in set ] [ ] [ dup >vector \ meta-d set ] tri* ;
: terminated-phi ( seq -- terminated ) : terminated-phi ( seq -- terminated )
terminated? branch-variable ; terminated? branch-variable ;
@ -74,17 +74,25 @@ SYMBOL: quotations
tri ; tri ;
: copy-inference ( -- ) : copy-inference ( -- )
meta-d [ clone ] change \ meta-d [ clone ] change
V{ } clone meta-r set literals [ clone ] change
d-in [ ] change ; d-in [ ] change ;
: infer-branch ( literal -- namespace ) GENERIC: infer-branch ( literal -- namespace )
M: literal infer-branch
[ [
copy-inference copy-inference
nest-visitor nest-visitor
[ value>> quotation set ] [ infer-literal-quot ] bi [ value>> quotation set ] [ infer-literal-quot ] bi
check->r ] H{ } make-assoc ;
] H{ } make-assoc ; inline
M: callable infer-branch
[
copy-inference
nest-visitor
[ quotation set ] [ infer-quot-here ] bi
] H{ } make-assoc ;
: infer-branches ( branches -- input children data ) : infer-branches ( branches -- input children data )
[ pop-d ] dip [ pop-d ] dip
@ -96,16 +104,19 @@ SYMBOL: quotations
[ first2 #if, ] dip compute-phi-function ; [ first2 #if, ] dip compute-phi-function ;
: infer-if ( -- ) : infer-if ( -- )
2 consume-d 2 literals-available? [
(infer-if)
] [
drop 2 consume-d
dup [ known [ curried? ] [ composed? ] bi or ] contains? [ dup [ known [ curried? ] [ composed? ] bi or ] contains? [
output-d output-d
[ rot [ drop call ] [ nip call ] if ] [ rot [ drop call ] [ nip call ] if ]
infer-quot-here infer-quot-here
] [ ] [
[ #drop, ] [ [ literal ] map (infer-if) ] bi [ #drop, ] [ [ literal ] map (infer-if) ] bi
] if
] if ; ] if ;
: infer-dispatch ( -- ) : infer-dispatch ( -- )
pop-literal nip [ <literal> ] map pop-literal nip infer-branches
infer-branches
[ #dispatch, ] dip compute-phi-function ; [ #dispatch, ] dip compute-phi-function ;

View File

@ -51,14 +51,14 @@ SYMBOL: enter-out
: prepare-stack ( word -- ) : prepare-stack ( word -- )
required-stack-effect in>> required-stack-effect in>>
[ length ensure-d drop ] [ [ length ensure-d drop ] [
meta-d get clone enter-in set meta-d clone enter-in set
meta-d get swap make-copies enter-out set meta-d swap make-copies enter-out set
] bi ; ] bi ;
: emit-enter-recursive ( label -- ) : emit-enter-recursive ( label -- )
enter-out get >>enter-out enter-out get >>enter-out
enter-in get enter-out get #enter-recursive, enter-in get enter-out get #enter-recursive,
enter-out get >vector meta-d set ; enter-out get >vector \ meta-d set ;
: entry-stack-height ( label -- stack ) : entry-stack-height ( label -- stack )
enter-out>> length ; enter-out>> length ;
@ -77,7 +77,7 @@ SYMBOL: enter-out
: end-recursive-word ( word label -- ) : end-recursive-word ( word label -- )
[ check-return ] [ check-return ]
[ meta-d get dup copy-values dup meta-d set #return-recursive, ] [ meta-d dup copy-values dup \ meta-d set #return-recursive, ]
bi ; bi ;
: recursive-word-inputs ( label -- n ) : recursive-word-inputs ( label -- n )
@ -95,10 +95,8 @@ SYMBOL: enter-out
[ nip ] [ nip ]
2tri 2tri
check->r
dup recursive-word-inputs dup recursive-word-inputs
meta-d get meta-d
stack-visitor get stack-visitor get
terminated? get terminated? get
] with-scope ; ] with-scope ;
@ -116,7 +114,7 @@ SYMBOL: enter-out
swap word>> required-stack-effect in>> length tail* ; swap word>> required-stack-effect in>> length tail* ;
: call-site-stack ( label -- stack ) : call-site-stack ( label -- stack )
meta-d get trim-stack ; meta-d trim-stack ;
: trimmed-enter-out ( label -- stack ) : trimmed-enter-out ( label -- stack )
dup enter-out>> trim-stack ; dup enter-out>> trim-stack ;
@ -131,7 +129,7 @@ SYMBOL: enter-out
: adjust-stack-effect ( effect -- effect' ) : adjust-stack-effect ( effect -- effect' )
[ in>> ] [ out>> ] bi [ in>> ] [ out>> ] bi
meta-d get length pick length [-] meta-d length pick length [-]
object <repetition> '[ _ prepend ] bi@ object <repetition> '[ _ prepend ] bi@
<effect> ; <effect> ;
@ -142,6 +140,7 @@ SYMBOL: enter-out
] [ drop undeclared-recursion-error inference-error ] if ; ] [ drop undeclared-recursion-error inference-error ] if ;
: inline-word ( word -- ) : inline-word ( word -- )
commit-literals
[ inlined-dependency depends-on ] [ inlined-dependency depends-on ]
[ [
dup inline-recursive-label [ dup inline-recursive-label [

View File

@ -63,7 +63,9 @@ IN: stack-checker.known-words
GENERIC: infer-call* ( value known -- ) GENERIC: infer-call* ( value known -- )
: infer-call ( value -- ) dup known infer-call* ; : (infer-call) ( value -- ) dup known infer-call* ;
: infer-call ( -- ) pop-d (infer-call) ;
M: literal infer-call* M: literal infer-call*
[ 1array #drop, ] [ infer-literal-quot ] bi* ; [ 1array #drop, ] [ infer-literal-quot ] bi* ;
@ -73,7 +75,7 @@ M: curried infer-call*
[ uncurry ] infer-quot-here [ uncurry ] infer-quot-here
[ quot>> known pop-d [ set-known ] keep ] [ quot>> known pop-d [ set-known ] keep ]
[ obj>> known pop-d [ set-known ] keep ] bi [ obj>> known pop-d [ set-known ] keep ] bi
push-d infer-call ; push-d (infer-call) ;
M: composed infer-call* M: composed infer-call*
swap push-d swap push-d
@ -81,20 +83,41 @@ M: composed infer-call*
[ quot2>> known pop-d [ set-known ] keep ] [ quot2>> known pop-d [ set-known ] keep ]
[ quot1>> known pop-d [ set-known ] keep ] bi [ quot1>> known pop-d [ set-known ] keep ] bi
push-d push-d push-d push-d
1 infer->r pop-d infer-call 1 infer->r infer-call
terminated? get [ 1 infer-r> pop-d infer-call ] unless ; terminated? get [ 1 infer-r> infer-call ] unless ;
M: object infer-call* M: object infer-call*
\ literal-expected inference-warning ; \ literal-expected inference-warning ;
: infer-slip ( -- ) : infer-slip ( -- )
1 infer->r pop-d infer-call 1 infer-r> ; 1 infer->r infer-call 1 infer-r> ;
: infer-2slip ( -- ) : infer-2slip ( -- )
2 infer->r pop-d infer-call 2 infer-r> ; 2 infer->r infer-call 2 infer-r> ;
: infer-3slip ( -- ) : infer-3slip ( -- )
3 infer->r pop-d infer-call 3 infer-r> ; 3 infer->r infer-call 3 infer-r> ;
: infer-dip ( -- )
commit-literals
literals get
[ \ dip def>> infer-quot-here ]
[ pop 1 infer->r infer-quot-here 1 infer-r> ]
if-empty ;
: infer-2dip ( -- )
commit-literals
literals get
[ \ 2dip def>> infer-quot-here ]
[ pop 2 infer->r infer-quot-here 2 infer-r> ]
if-empty ;
: infer-3dip ( -- )
commit-literals
literals get
[ \ 3dip def>> infer-quot-here ]
[ pop 3 infer->r infer-quot-here 3 infer-r> ]
if-empty ;
: infer-curry ( -- ) : infer-curry ( -- )
2 consume-d 2 consume-d
@ -157,11 +180,14 @@ M: object infer-call*
{ \ >r [ 1 infer->r ] } { \ >r [ 1 infer->r ] }
{ \ r> [ 1 infer-r> ] } { \ r> [ 1 infer-r> ] }
{ \ declare [ infer-declare ] } { \ declare [ infer-declare ] }
{ \ call [ pop-d infer-call ] } { \ call [ infer-call ] }
{ \ (call) [ pop-d infer-call ] } { \ (call) [ infer-call ] }
{ \ slip [ infer-slip ] } { \ slip [ infer-slip ] }
{ \ 2slip [ infer-2slip ] } { \ 2slip [ infer-2slip ] }
{ \ 3slip [ infer-3slip ] } { \ 3slip [ infer-3slip ] }
{ \ dip [ infer-dip ] }
{ \ 2dip [ infer-2dip ] }
{ \ 3dip [ infer-3dip ] }
{ \ curry [ infer-curry ] } { \ curry [ infer-curry ] }
{ \ compose [ infer-compose ] } { \ compose [ infer-compose ] }
{ \ execute [ infer-execute ] } { \ execute [ infer-execute ] }
@ -190,10 +216,10 @@ M: object infer-call*
"local-word-def" word-prop infer-quot-here ; "local-word-def" word-prop infer-quot-here ;
{ {
>r r> declare call (call) slip 2slip 3slip curry compose >r r> declare call (call) slip 2slip 3slip dip 2dip 3dip
execute (execute) if dispatch <tuple-boa> (throw) curry compose execute (execute) if dispatch <tuple-boa>
load-locals get-local drop-locals do-primitive alien-invoke (throw) load-locals get-local drop-locals do-primitive
alien-indirect alien-callback alien-invoke alien-indirect alien-callback
} [ t "special" set-word-prop ] each } [ t "special" set-word-prop ] each
{ call execute dispatch load-locals get-local drop-locals } { call execute dispatch load-locals get-local drop-locals }

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs arrays namespaces sequences kernel definitions USING: assocs arrays namespaces sequences kernel definitions
math effects accessors words fry classes.algebra math effects accessors words fry classes.algebra
compiler.units ; compiler.units stack-checker.values stack-checker.visitor ;
IN: stack-checker.state IN: stack-checker.state
! Did the current control-flow path throw an error? ! Did the current control-flow path throw an error?
@ -11,23 +11,40 @@ SYMBOL: terminated?
! Number of inputs current word expects from the stack ! Number of inputs current word expects from the stack
SYMBOL: d-in SYMBOL: d-in
DEFER: commit-literals
! Compile-time data stack ! Compile-time data stack
SYMBOL: meta-d : meta-d ( -- stack ) commit-literals \ meta-d get ;
! Compile-time retain stack ! Compile-time retain stack
SYMBOL: meta-r : meta-r ( -- stack ) \ meta-r get ;
: current-stack-height ( -- n ) meta-d get length d-in get - ; ! Uncommitted literals. This is a form of local dead-code
! elimination; the goal is to reduce the number of IR nodes
! which get constructed. Technically it is redundant since
! we do global DCE later, but it speeds up compile time.
SYMBOL: literals
: (push-literal) ( obj -- )
dup <literal> make-known
[ nip \ meta-d get push ] [ #push, ] 2bi ;
: commit-literals ( -- )
literals get [
[ [ (push-literal) ] each ] [ delete-all ] bi
] unless-empty ;
: current-stack-height ( -- n ) meta-d length d-in get - ;
: current-effect ( -- effect ) : current-effect ( -- effect )
d-in get d-in get
meta-d get length <effect> meta-d length <effect>
terminated? get >>terminated? ; terminated? get >>terminated? ;
: init-inference ( -- ) : init-inference ( -- )
terminated? off terminated? off
V{ } clone meta-d set V{ } clone \ meta-d set
V{ } clone meta-r set V{ } clone literals set
0 d-in set ; 0 d-in set ;
! Words that the current quotation depends on ! Words that the current quotation depends on

View File

@ -19,11 +19,8 @@ IN: stack-checker.transforms
rot with-datastack first2 rot with-datastack first2
dup [ dup [
[ [
[ drop ] [ [ drop ]
[ length meta-d get '[ _ pop* ] times ] [ [ length meta-d shorten-by ] [ #drop, ] bi ] bi*
[ #drop, ]
bi
] bi*
] 2dip ] 2dip
swap infer-quot swap infer-quot
] [ ] [

View File

@ -7,11 +7,11 @@ $nl
"The " { $slot "underlying" } " slot holds a " { $link c-ptr } " with the raw data. This pointer can be passed to C functions." } ; "The " { $slot "underlying" } " slot holds a " { $link c-ptr } " with the raw data. This pointer can be passed to C functions." } ;
HELP: <struct-array> HELP: <struct-array>
{ $values { "length" integer } { "c-type" string } } { $values { "length" integer } { "c-type" string } { "struct-array" struct-array } }
{ $description "Creates a new array for holding values of the specified C type." } ; { $description "Creates a new array for holding values of the specified C type." } ;
HELP: <direct-struct-array> HELP: <direct-struct-array>
{ $values { "alien" c-ptr } { "length" integer } { "c-type" string } } { $values { "alien" c-ptr } { "length" integer } { "c-type" string } { "struct-array" struct-array } }
{ $description "Creates a new array for holding values of the specified C type, backed by the memory at " { $snippet "alien" } "." } ; { $description "Creates a new array for holding values of the specified C type, backed by the memory at " { $snippet "alien" } "." } ;
ARTICLE: "struct-arrays" "C struct and union arrays" ARTICLE: "struct-arrays" "C struct and union arrays"

View File

@ -10,7 +10,7 @@ IN: tools.memory
: write-size ( n -- ) : write-size ( n -- )
number>string number>string
dup length 4 > [ 3 cut* "," swap 3append ] when dup length 4 > [ 3 cut* "," glue ] when
" KB" append write-cell ; " KB" append write-cell ;
: write-total/used/free ( free total str -- ) : write-total/used/free ( free total str -- )

View File

@ -238,7 +238,7 @@ M: vocab-link summary vocab-summary ;
vocab-dir append-path dup exists? vocab-dir append-path dup exists?
[ subdirs ] [ drop { } ] if [ subdirs ] [ drop { } ] if
] keep [ ] keep [
swap [ "." swap 3append ] with map swap [ "." glue ] with map
] unless-empty ; ] unless-empty ;
: vocabs-in-dir ( root name -- ) : vocabs-in-dir ( root name -- )

View File

@ -126,7 +126,7 @@ SYMBOL: +stopped+
[ [
2dup length = [ nip [ break ] append ] [ 2dup length = [ nip [ break ] append ] [
2dup nth \ break = [ nip ] [ 2dup nth \ break = [ nip ] [
swap 1+ cut [ break ] swap 3append swap 1+ cut [ break ] glue
] if ] if
] if ] if
] change-frame ; ] change-frame ;

View File

@ -72,7 +72,7 @@ VALUE: grapheme-table
grapheme-table nth nth not ; grapheme-table nth nth not ;
: chars ( i str n -- str[i] str[i+n] ) : chars ( i str n -- str[i] str[i+n] )
swap >r dupd + r> [ ?nth ] curry bi@ ; swap [ dupd + ] dip [ ?nth ] curry bi@ ;
: find-index ( seq quot -- i ) find drop ; inline : find-index ( seq quot -- i ) find drop ; inline
: find-last-index ( seq quot -- i ) find-last drop ; inline : find-last-index ( seq quot -- i ) find-last drop ; inline

View File

@ -124,7 +124,7 @@ PRIVATE>
[ zero? ] tri@ and and ; [ zero? ] tri@ and and ;
: filter-ignorable ( weights -- weights' ) : filter-ignorable ( weights -- weights' )
>r f r> [ f swap [
tuck primary>> zero? and tuck primary>> zero? and
[ swap ignorable?>> or ] [ swap ignorable?>> or ]
[ swap completely-ignorable? or not ] 2bi [ swap completely-ignorable? or not ] 2bi

View File

@ -91,6 +91,6 @@ PRIVATE>
[ [
[ [
[ url-encode ] dip [ url-encode ] dip
[ url-encode "=" swap 3append , ] with each [ url-encode "=" glue , ] with each
] assoc-each ] assoc-each
] { } make "&" join ; ] { } make "&" join ;

View File

@ -79,6 +79,7 @@ $nl
{ $subsection continue-with } { $subsection continue-with }
"Continuations as control-flow:" "Continuations as control-flow:"
{ $subsection attempt-all } { $subsection attempt-all }
{ $subsection retry }
{ $subsection with-return } { $subsection with-return }
"Reflecting the datastack:" "Reflecting the datastack:"
{ $subsection with-datastack } { $subsection with-datastack }
@ -237,6 +238,20 @@ HELP: attempt-all
} }
} ; } ;
HELP: retry
{ $values
{ "quot" quotation } { "n" null }
}
{ $description "Tries the quotation up to " { $snippet "n" } " times until it returns true. Retries the quotation if an exception is thrown or if the quotation returns " { $link f } ". The quotation is expected to have side effects that may fail, such as generating a random name for a new file until successful." }
{ $examples
{ $unchecked-example "USING: continuations math prettyprint ;"
"[ 5 random 0 = ] retry t"
"t"
}
} ;
{ attempt-all retry } related-words
HELP: return HELP: return
{ $description "Returns early from a quotation by reifying the continuation captured by " { $link with-return } " ; execution is resumed starting immediately after " { $link with-return } "." } ; { $description "Returns early from a quotation by reifying the continuation captured by " { $link with-return } " ; execution is resumed starting immediately after " { $link with-return } "." } ;

View File

@ -154,6 +154,8 @@ ERROR: attempt-all-error ;
] { } make peek swap [ rethrow ] when ] { } make peek swap [ rethrow ] when
] if ; inline ] if ; inline
: retry ( quot: ( -- ? ) n -- ) swap [ drop ] prepose attempt-all ; inline
TUPLE: condition error restarts continuation ; TUPLE: condition error restarts continuation ;
C: <condition> condition ( error restarts cc -- condition ) C: <condition> condition ( error restarts cc -- condition )

View File

@ -26,7 +26,7 @@ GENERIC: effect>string ( obj -- str )
M: string effect>string ; M: string effect>string ;
M: word effect>string name>> ; M: word effect>string name>> ;
M: integer effect>string number>string ; M: integer effect>string number>string ;
M: pair effect>string first2 [ effect>string ] bi@ ": " swap 3append ; M: pair effect>string first2 [ effect>string ] bi@ ": " glue ;
: stack-picture ( seq -- string ) : stack-picture ( seq -- string )
dup integer? [ "object" <repetition> ] when dup integer? [ "object" <repetition> ] when

View File

@ -77,7 +77,7 @@ TUPLE: check-method class generic ;
3tri ; inline 3tri ; inline
: method-word-name ( class word -- string ) : method-word-name ( class word -- string )
[ name>> ] bi@ "=>" swap 3append ; [ name>> ] bi@ "=>" glue ;
PREDICATE: method-body < word PREDICATE: method-body < word
"method-generic" word-prop >boolean ; "method-generic" word-prop >boolean ;

View File

@ -758,12 +758,10 @@ $nl
"Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:" "Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:"
{ $code { $code
"! First alternative; uses dip" "! First alternative; uses dip"
"[ [ 1 + ] dip 1 - dip ] 2 *" "[ [ 1 + ] dip 1 - ] dip 2 *"
"! Second alternative: uses tri*" "! Second alternative: uses tri*"
"[ 1 + ] [ 1 - ] [ 2 * ] tri*" "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
} }
$nl
"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "." "A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
{ $subsection "spread-shuffle-equivalence" } ; { $subsection "spread-shuffle-equivalence" } ;

View File

@ -52,7 +52,9 @@ DEFER: if
: ?if ( default cond true false -- ) : ?if ( default cond true false -- )
pick [ roll 2drop call ] [ 2nip call ] if ; inline pick [ roll 2drop call ] [ 2nip call ] if ; inline
! Slippers ! Slippers and dippers.
! Not declared inline because the compiler special-cases them
: slip ( quot x -- x ) : slip ( quot x -- x )
#! 'slip' and 'dip' can be defined in terms of each other #! 'slip' and 'dip' can be defined in terms of each other
#! because the JIT special-cases a 'dip' preceeded by #! because the JIT special-cases a 'dip' preceeded by
@ -71,11 +73,11 @@ DEFER: if
#! a literal quotation. #! a literal quotation.
[ call ] 3dip ; [ call ] 3dip ;
: dip ( x quot -- x ) swap slip ; inline : dip ( x quot -- x ) swap slip ;
: 2dip ( x y quot -- x y ) -rot 2slip ; inline : 2dip ( x y quot -- x y ) -rot 2slip ;
: 3dip ( x y z quot -- x y z ) -roll 3slip ; inline : 3dip ( x y z quot -- x y z ) -roll 3slip ;
! Keepers ! Keepers
: keep ( x quot -- x ) over slip ; inline : keep ( x quot -- x ) over slip ; inline

View File

@ -6,7 +6,7 @@ ARTICLE: "floats" "Floats"
"Rational numbers represent " { $emphasis "exact" } " quantities. On the other hand, a floating point number is an " { $emphasis "approximation" } ". While rationals can grow to any required precision, floating point numbers are fixed-width, and manipulating them is usually faster than manipulating ratios or bignums (but slower than manipulating fixnums). Floating point numbers are often used to represent irrational numbers, which have no exact representation as a ratio of two integers." "Rational numbers represent " { $emphasis "exact" } " quantities. On the other hand, a floating point number is an " { $emphasis "approximation" } ". While rationals can grow to any required precision, floating point numbers are fixed-width, and manipulating them is usually faster than manipulating ratios or bignums (but slower than manipulating fixnums). Floating point numbers are often used to represent irrational numbers, which have no exact representation as a ratio of two integers."
$nl $nl
"Introducing a floating point number in a computation forces the result to be expressed in floating point." "Introducing a floating point number in a computation forces the result to be expressed in floating point."
{ $example "5/4 1/2 + ." "7/4" } { $example "5/4 1/2 + ." "1+3/4" }
{ $example "5/4 0.5 + ." "1.75" } { $example "5/4 0.5 + ." "1.75" }
"Integers and rationals can be converted to floats:" "Integers and rationals can be converted to floats:"
{ $subsection >float } { $subsection >float }

View File

@ -128,7 +128,7 @@ M: ratio >base
[ [
[ numerator (>base) ] [ numerator (>base) ]
[ denominator (>base) ] bi [ denominator (>base) ] bi
"/" swap 3append "/" glue
] bi* append ] bi* append
negative? get [ CHAR: - prefix ] when negative? get [ CHAR: - prefix ] when
] with-radix ; ] with-radix ;

View File

@ -714,6 +714,26 @@ HELP: 3append
} }
} ; } ;
HELP: surround
{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "newseq" sequence } }
{ $description "Outputs a new sequence with " { $snippet "seq1" } " inserted between " { $snippet "seq2" } " and " { $snippet "seq3" } "." }
{ $examples
{ $example "USING: sequences prettyprint ;"
"\"sssssh\" \"(\" \")\" surround ."
"\"(sssssh)\""
}
} ;
HELP: glue
{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "newseq" sequence } }
{ $description "Outputs a new sequence with " { $snippet "seq3" } " inserted between " { $snippet "seq1" } " and " { $snippet "seq2" } "." }
{ $examples
{ $example "USING: sequences prettyprint ;"
"\"a\" \"b\" \",\" glue ."
"\"a,b\""
}
} ;
HELP: subseq HELP: subseq
{ $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } { "subseq" "a new sequence" } } { $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } { "subseq" "a new sequence" } }
{ $description "Outputs a new sequence consisting of all elements starting from and including " { $snippet "from" } ", and up to but not including " { $snippet "to" } "." } { $description "Outputs a new sequence consisting of all elements starting from and including " { $snippet "from" } ", and up to but not including " { $snippet "to" } "." }
@ -1348,6 +1368,8 @@ ARTICLE: "sequences-appending" "Appending sequences"
{ $subsection append } { $subsection append }
{ $subsection prepend } { $subsection prepend }
{ $subsection 3append } { $subsection 3append }
{ $subsection surround }
{ $subsection glue }
{ $subsection concat } { $subsection concat }
{ $subsection join } { $subsection join }
"A pair of words useful for aligning strings:" "A pair of words useful for aligning strings:"

View File

@ -268,3 +268,6 @@ M: bogus-hashcode hashcode* 2drop 0 >bignum ;
[ { 1 3 "X" 5 7 } ] [ "X" 2 { 1 3 5 7 } insert-nth ] unit-test [ { 1 3 "X" 5 7 } ] [ "X" 2 { 1 3 5 7 } insert-nth ] unit-test
[ V{ 0 2 } ] [ "a" { "a" "b" "a" } indices ] unit-test [ V{ 0 2 } ] [ "a" { "a" "b" "a" } indices ] unit-test
[ "a,b" ] [ "a" "b" "," glue ] unit-test
[ "(abc)" ] [ "abc" "(" ")" surround ] unit-test

View File

@ -317,6 +317,10 @@ PRIVATE>
: 3append ( seq1 seq2 seq3 -- newseq ) pick 3append-as ; : 3append ( seq1 seq2 seq3 -- newseq ) pick 3append-as ;
: surround ( seq1 seq2 seq3 -- newseq ) swapd 3append ; inline
: glue ( seq1 seq2 seq3 -- newseq ) swap 3append ; inline
: change-nth ( i seq quot -- ) : change-nth ( i seq quot -- )
[ [ nth ] dip call ] 3keep drop set-nth ; inline [ [ nth ] dip call ] 3keep drop set-nth ; inline

View File

@ -9,7 +9,7 @@ IN: benchmark.knucleotide
"." split1 rot "." split1 rot
over length over < over length over <
[ CHAR: 0 pad-right ] [ CHAR: 0 pad-right ]
[ head ] if "." swap 3append ; [ head ] if "." glue ;
: discard-lines ( -- ) : discard-lines ( -- )
readln readln

View File

@ -80,7 +80,7 @@ M: check< summary drop "Number exceeds upper bound" ;
[ ":" split1 string>number [ dup length ] unless* ] { } map>assoc ; [ ":" split1 string>number [ dup length ] unless* ] { } map>assoc ;
: define-slots ( prefix names quots -- ) : define-slots ( prefix names quots -- )
>r [ "-" swap 3append create-in ] with map r> >r [ "-" glue create-in ] with map r>
[ define ] 2each ; [ define ] 2each ;
: define-accessors ( classname slots -- ) : define-accessors ( classname slots -- )

View File

@ -135,9 +135,6 @@ MACRO: multikeep ( word out-indexes -- ... )
r> [ drop \ r> , ] each r> [ drop \ r> , ] each
] [ ] make ; ] [ ] make ;
: retry ( quot n -- )
[ drop ] rot compose attempt-all ; inline
: do-while ( pred body tail -- ) : do-while ( pred body tail -- )
[ tuck 2slip ] dip while ; inline [ tuck 2slip ] dip while ; inline

View File

@ -285,7 +285,7 @@ SYMBOLS: NO-ERROR FORMAT-ERROR SERVER-FAILURE NAME-ERROR NOT-IMPLEMENTED
[ get-label ] [ get-label ]
[ skip-label get-name ] [ skip-label get-name ]
2bi 2bi
"." swap 3append "." glue
] ]
} }
} }

View File

@ -5,7 +5,7 @@ IN: hardware-info.windows.ce
: memory-status ( -- MEMORYSTATUS ) : memory-status ( -- MEMORYSTATUS )
"MEMORYSTATUS" <c-object> "MEMORYSTATUS" <c-object>
"MEMORYSTATUS" heap-size over set-MEMORYSTATUS-dwLength "MEMORYSTATUS" heap-size over set-MEMORYSTATUS-dwLength
[ GlobalMemoryStatus ] keep ; dup GlobalMemoryStatus ;
M: wince cpus ( -- n ) 1 ; M: wince cpus ( -- n ) 1 ;

View File

@ -1,18 +1,16 @@
USING: alien alien.c-types alien.strings USING: alien alien.c-types alien.strings
kernel libc math namespaces hardware-info.backend kernel libc math namespaces hardware-info.backend
windows windows.advapi32 windows.kernel32 system ; hardware-info.windows windows windows.advapi32
windows.kernel32 system byte-arrays ;
IN: hardware-info.windows.nt IN: hardware-info.windows.nt
: system-info ( -- SYSTEM_INFO )
"SYSTEM_INFO" <c-object> [ GetSystemInfo ] keep ;
M: winnt cpus ( -- n ) M: winnt cpus ( -- n )
system-info SYSTEM_INFO-dwNumberOfProcessors ; system-info SYSTEM_INFO-dwNumberOfProcessors ;
: memory-status ( -- MEMORYSTATUSEX ) : memory-status ( -- MEMORYSTATUSEX )
"MEMORYSTATUSEX" <c-object> "MEMORYSTATUSEX" <c-object>
"MEMORYSTATUSEX" heap-size over set-MEMORYSTATUSEX-dwLength "MEMORYSTATUSEX" heap-size over set-MEMORYSTATUSEX-dwLength
[ GlobalMemoryStatusEx ] keep swap zero? [ win32-error ] when ; dup GlobalMemoryStatusEx win32-error=0/f ;
M: winnt memory-load ( -- n ) M: winnt memory-load ( -- n )
memory-status MEMORYSTATUSEX-dwMemoryLoad ; memory-status MEMORYSTATUSEX-dwMemoryLoad ;
@ -35,21 +33,12 @@ M: winnt total-virtual-mem ( -- n )
M: winnt available-virtual-mem ( -- n ) M: winnt available-virtual-mem ( -- n )
memory-status MEMORYSTATUSEX-ullAvailVirtual ; memory-status MEMORYSTATUSEX-ullAvailVirtual ;
: pull-win32-string ( alien -- string )
[ utf16n alien>string ] keep free ;
: computer-name ( -- string ) : computer-name ( -- string )
MAX_COMPUTERNAME_LENGTH 1+ [ malloc ] keep MAX_COMPUTERNAME_LENGTH 1+
<int> dupd GetComputerName zero? [ [ <byte-array> dup ] keep <uint>
free win32-error f GetComputerName win32-error=0/f alien>native-string ;
] [
pull-win32-string
] if ;
: username ( -- string ) : username ( -- string )
UNLEN 1+ [ malloc ] keep UNLEN 1+
<int> dupd GetUserName zero? [ [ <byte-array> dup ] keep <uint>
free win32-error f GetUserName win32-error=0/f alien>native-string ;
] [
pull-win32-string
] if ;

View File

@ -21,7 +21,7 @@ IN: hardware-info.windows
: os-version ( -- os-version ) : os-version ( -- os-version )
"OSVERSIONINFO" <c-object> "OSVERSIONINFO" <c-object>
"OSVERSIONINFO" heap-size over set-OSVERSIONINFO-dwOSVersionInfoSize "OSVERSIONINFO" heap-size over set-OSVERSIONINFO-dwOSVersionInfoSize
[ GetVersionEx ] keep swap zero? [ win32-error ] when ; dup GetVersionEx win32-error=0/f ;
: windows-major ( -- n ) : windows-major ( -- n )
os-version OSVERSIONINFO-dwMajorVersion ; os-version OSVERSIONINFO-dwMajorVersion ;
@ -36,7 +36,7 @@ IN: hardware-info.windows
os-version OSVERSIONINFO-dwPlatformId ; os-version OSVERSIONINFO-dwPlatformId ;
: windows-service-pack ( -- string ) : windows-service-pack ( -- string )
os-version OSVERSIONINFO-szCSDVersion utf16n alien>string ; os-version OSVERSIONINFO-szCSDVersion alien>native-string ;
: feature-present? ( n -- ? ) : feature-present? ( n -- ? )
IsProcessorFeaturePresent zero? not ; IsProcessorFeaturePresent zero? not ;
@ -51,8 +51,8 @@ IN: hardware-info.windows
"ushort" <c-array> ; "ushort" <c-array> ;
: get-directory ( word -- str ) : get-directory ( word -- str )
>r MAX_UNICODE_PATH [ <u16-string-object> ] keep dupd r> [ MAX_UNICODE_PATH [ <u16-string-object> ] keep dupd ] dip
execute win32-error=0/f utf16n alien>string ; inline execute win32-error=0/f alien>native-string ; inline
: windows-directory ( -- str ) : windows-directory ( -- str )
\ GetWindowsDirectory get-directory ; \ GetWindowsDirectory get-directory ;

View File

@ -31,7 +31,7 @@ M: object handle-message drop ;
"git-log" , "git-log" ,
"--no-merges" , "--no-merges" ,
"--pretty=format:%h %an: %s" , "--pretty=format:%h %an: %s" ,
".." swap 3append , ".." glue ,
] { } make ] { } make
latin1 [ input-stream get lines ] with-process-reader ; latin1 [ input-stream get lines ] with-process-reader ;

View File

@ -1,7 +1,15 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: tools.test math.floating-point math.constants kernel ; USING: tools.test math.floating-point math.constants kernel
math.constants fry sequences kernel math ;
IN: math.floating-point.tests IN: math.floating-point.tests
[ t ] [ pi >double< >double pi = ] unit-test [ t ] [ pi >double< >double pi = ] unit-test
[ t ] [ -1.0 >double< >double -1.0 = ] unit-test [ t ] [ -1.0 >double< >double -1.0 = ] unit-test
[ t ] [ 1/0. infinity? ] unit-test
[ t ] [ -1/0. infinity? ] unit-test
[ f ] [ 0/0. infinity? ] unit-test
[ f ] [ 10. infinity? ] unit-test
[ f ] [ -10. infinity? ] unit-test
[ f ] [ 0. infinity? ] unit-test

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel math sequences prettyprint math.parser io USING: kernel math sequences prettyprint math.parser io
math.functions math.bitwise ; math.functions math.bitwise combinators.short-circuit ;
IN: math.floating-point IN: math.floating-point
: (double-sign) ( bits -- n ) -63 shift ; inline : (double-sign) ( bits -- n ) -63 shift ; inline
@ -37,3 +37,10 @@ IN: math.floating-point
(double-mantissa-bits) >bin 52 CHAR: 0 pad-left (double-mantissa-bits) >bin 52 CHAR: 0 pad-left
11 [ bl ] times print 11 [ bl ] times print
] tri ; ] tri ;
: infinity? ( double -- ? )
double>bits
{
[ (double-exponent-bits) 11 on-bits = ]
[ (double-mantissa-bits) 0 = ]
} 1&& ;

View File

@ -56,7 +56,7 @@ SYMBOL: and-needed?
: text-with-scale ( index seq -- str ) : text-with-scale ( index seq -- str )
[ nth 3digits>text ] [ drop scale-numbers ] 2bi [ nth 3digits>text ] [ drop scale-numbers ] 2bi
[ " " swap 3append ] unless-empty ; [ " " glue ] unless-empty ;
: append-with-conjunction ( str1 str2 -- newstr ) : append-with-conjunction ( str1 str2 -- newstr )
over length zero? [ over length zero? [

View File

@ -12,7 +12,7 @@ CHAR: $ \ currency-token set-global
: (money>string) ( dollars cents -- string ) : (money>string) ( dollars cents -- string )
[ number>string ] bi@ [ number>string ] bi@
[ <reversed> 3 group "," join <reversed> ] [ <reversed> 3 group "," join <reversed> ]
[ 2 CHAR: 0 pad-left ] bi* "." swap 3append ; [ 2 CHAR: 0 pad-left ] bi* "." glue ;
: money>string ( object -- string ) : money>string ( object -- string )
dollars/cents (money>string) currency-token get prefix ; dollars/cents (money>string) currency-token get prefix ;

View File

@ -28,7 +28,7 @@ IN: printf
[ 0 ] [ string>number ] if-empty ; [ 0 ] [ string>number ] if-empty ;
: pad-digits ( string digits -- string' ) : pad-digits ( string digits -- string' )
[ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." swap 3append ; [ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." glue ;
: max-digits ( n digits -- n' ) : max-digits ( n digits -- n' )
10 swap ^ [ * round ] keep / ; 10 swap ^ [ * round ] keep / ;

View File

@ -3,3 +3,4 @@ IN: project-euler.002.tests
[ 4613732 ] [ euler002 ] unit-test [ 4613732 ] [ euler002 ] unit-test
[ 4613732 ] [ euler002a ] unit-test [ 4613732 ] [ euler002a ] unit-test
[ 4613732 ] [ euler002b ] unit-test

View File

@ -1,4 +1,4 @@
! Copyright (c) 2007 Aaron Schaefer, Alexander Solovyov. ! Copyright (c) 2007, 2008 Aaron Schaefer, Alexander Solovyov, Vishal Talwar.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel math sequences shuffle ; USING: kernel math sequences shuffle ;
IN: project-euler.002 IN: project-euler.002
@ -50,4 +50,31 @@ PRIVATE>
! [ euler002a ] 100 ave-time ! [ euler002a ] 100 ave-time
! 0 ms ave run time - 0.2 SD (100 trials) ! 0 ms ave run time - 0.2 SD (100 trials)
MAIN: euler002a
<PRIVATE
: next-fibs ( x y -- y x+y )
tuck + ;
: ?retotal ( total fib- fib+ -- retotal fib- fib+ )
dup even? [ [ nip + ] 2keep ] when ;
: (sum-even-fibs-below) ( partial fib- fib+ max -- total )
2dup > [
3drop
] [
[ ?retotal next-fibs ] dip (sum-even-fibs-below)
] if ;
PRIVATE>
: sum-even-fibs-below ( max -- sum )
[ 0 0 1 ] dip (sum-even-fibs-below) ;
: euler002b ( -- answer )
4000000 sum-even-fibs-below ;
! [ euler002b ] 100 ave-time
! 0 ms ave run time - 0.0 SD (100 trials)
MAIN: euler002b

View File

@ -0,0 +1,6 @@
USING: project-euler.050 project-euler.050.private tools.test ;
IN: project-euler.050.tests
[ 41 ] [ 100 solve ] unit-test
[ 953 ] [ 1000 solve ] unit-test
[ 997651 ] [ euler050 ] unit-test

Some files were not shown because too many files have changed in this diff Show More