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

db4
Joe Groff 2009-01-20 14:37:02 -08:00
commit 67081ddff5
445 changed files with 16187 additions and 12950 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ logs
work
build-support/wordsize
*.bak
.#*

View File

@ -32,7 +32,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2003-2008, Slava Pestov and friends</string>
<string>Copyright © 2003-2009, Slava Pestov and friends</string>
<key>NSServices</key>
<array>
<dict>

View File

@ -0,0 +1,44 @@
USING: interpolate multiline
io io.directories io.encodings.ascii io.files
io.files.temp io.launcher io.streams.string kernel locals system
tools.test sequences ;
IN: alien.remote-control.tests
: compile-file ( contents -- )
"test.c" ascii set-file-contents
{ "gcc" "-I../" "-L.." "-lfactor" "test.c" }
os macosx? cpu x86.64? and [ "-m64" suffix ] when
try-process ;
: run-test ( -- line )
os windows? "temp/a.exe" "temp/a.out" ?
ascii [ readln ] with-process-reader ;
:: test-embedding ( code -- line )
image :> image
[
I[
#include <vm/master.h>
#include <stdio.h>
#include <stdbool.h>
int main(int argc, char **argv)
{
F_PARAMETERS p;
default_parameters(&p);
p.image_path = STRING_LITERAL("${image}");
init_factor(&p);
start_embedded_factor(&p);
${code}
printf("Done.\n");
return 0;
}
]I
] with-string-writer
"resource:temp" [ compile-file ] with-directory
"resource:" [ run-test ] with-directory ;
! [ "Done." ] [ "" test-embedding ] unit-test
! [ "Done." ] [ "factor_yield();" test-embedding ] unit-test

View File

@ -37,6 +37,26 @@ HELP: quotable?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Tests for characters which may appear in a Factor string literal without escaping." } ;
HELP: ascii?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Tests for whether a number is an ASCII character." } ;
HELP: ch>lower
{ $values { "ch" "a character" } { "lower" "a character" } }
{ $description "Converts an ASCII character to lower case." } ;
HELP: ch>upper
{ $values { "ch" "a character" } { "upper" "a character" } }
{ $description "Converts an ASCII character to upper case." } ;
HELP: >lower
{ $values { "str" "a string" } { "lower" "a string" } }
{ $description "Converts an ASCII string to lower case." } ;
HELP: >upper
{ $values { "str" "a string" } { "upper" "a string" } }
{ $description "Converts an ASCII string to upper case." } ;
ARTICLE: "ascii" "ASCII character classes"
"The " { $vocab-link "ascii" } " vocabulary implements traditional ASCII character classes:"
{ $subsection blank? }
@ -46,6 +66,12 @@ ARTICLE: "ascii" "ASCII character classes"
{ $subsection printable? }
{ $subsection control? }
{ $subsection quotable? }
"Modern applications should use Unicode 5.0 instead (" { $vocab-link "unicode.categories" } ")." ;
{ $subsection ascii? }
"ASCII case conversion is also implemented:"
{ $subsection ch>lower }
{ $subsection ch>upper }
{ $subsection >lower }
{ $subsection >upper }
"Modern applications should use Unicode 5.1 instead (" { $vocab-link "unicode.categories" } ")." ;
ABOUT: "ascii"

View File

@ -12,3 +12,8 @@ IN: ascii.tests
0 "There are Four Upper Case characters"
[ LETTER? [ 1+ ] when ] each
] unit-test
[ t f ] [ CHAR: \s ascii? 400 ascii? ] unit-test
[ "HELLO HOW ARE YOU?" ] [ "hellO hOw arE YOU?" >upper ] unit-test
[ "i'm good thx bai" ] [ "I'm Good THX bai" >lower ] unit-test

View File

@ -4,6 +4,8 @@ USING: kernel math math.order sequences
combinators.short-circuit ;
IN: ascii
: ascii? ( ch -- ? ) 0 127 between? ; inline
: blank? ( ch -- ? ) " \t\n\r" member? ; inline
: letter? ( ch -- ? ) CHAR: a CHAR: z between? ; inline
@ -25,3 +27,15 @@ IN: ascii
: alpha? ( ch -- ? )
[ [ Letter? ] [ digit? ] ] 1|| ;
: ch>lower ( ch -- lower )
dup CHAR: A CHAR: Z between? [ HEX: 20 + ] when ;
: >lower ( str -- lower )
[ ch>lower ] map ;
: ch>upper ( ch -- upper )
dup CHAR: a CHAR: z between? [ HEX: 20 - ] when ;
: >upper ( str -- upper )
[ ch>upper ] map ;

View File

@ -7,7 +7,13 @@ HELP: >base64
{ $examples
{ $example "USING: prettyprint base64 strings ;" "\"The monorail is a free service.\" >base64 >string ." "\"VGhlIG1vbm9yYWlsIGlzIGEgZnJlZSBzZXJ2aWNlLg==\"" }
}
{ $see-also base64> } ;
{ $see-also base64> >base64-lines } ;
HELP: >base64-lines
{ $values { "seq" sequence } { "base64" "a string of base64 characters" } }
{ $description "Converts a sequence to its base64 representation by taking six bits at a time as an index into a lookup table containing alphanumerics, '+', and '/'. The result is padded with '=' if the input was not a multiple of six bits. A crlf is inserted for every 76 characters of output." }
{ $see-also base64> >base64-lines } ;
HELP: base64>
{ $values { "base64" "a string of base64 characters" } { "seq" sequence } }
@ -16,13 +22,26 @@ HELP: base64>
{ $example "USING: prettyprint base64 strings ;" "\"VGhlIG1vbm9yYWlsIGlzIGEgZnJlZSBzZXJ2aWNlLg==\" base64> >string ." "\"The monorail is a free service.\"" }
}
{ $notes "This word will throw if the input string contains characters other than those allowed in base64 encodings." }
{ $see-also >base64 } ;
{ $see-also >base64 >base64-lines } ;
HELP: encode-base64
{ $description "Reads the standard input and writes it to standard output encoded in base64." } ;
HELP: decode-base64
{ $description "Reads the standard input and decodes it, writing to standard output." } ;
HELP: encode-base64-lines
{ $description "Reads the standard input and writes it to standard output encoded in base64 with a crlf every 76 characters." } ;
ARTICLE: "base64" "Base 64 conversions"
"The " { $vocab-link "base64" } " vocabulary implements conversions of sequences to printable characters in base 64. These plain-text representations of binary data may be passed around and converted back to binary data later." $nl
"Converting to base 64:"
"Converting to and from base64 as strings:"
{ $subsection >base64 }
"Converting back to binary:"
{ $subsection base64> } ;
{ $subsection >base64-lines }
{ $subsection base64> }
"Using base64 from streams:"
{ $subsection encode-base64 }
{ $subsection encode-base64-lines }
{ $subsection decode-base64 } ;
ABOUT: "base64"

View File

@ -1,4 +1,4 @@
USING: kernel tools.test base64 strings ;
USING: kernel tools.test base64 strings sequences ;
IN: base64.tests
[ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" >base64 base64> >string
@ -7,6 +7,7 @@ IN: base64.tests
[ "a" ] [ "a" >base64 base64> >string ] unit-test
[ "ab" ] [ "ab" >base64 base64> >string ] unit-test
[ "abc" ] [ "abc" >base64 base64> >string ] unit-test
[ "abcde" ] [ "abcde" >base64 3 cut "\r\n" swap 3append base64> >string ] unit-test
! From http://en.wikipedia.org/wiki/Base64
[ "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" ]
@ -15,5 +16,11 @@ IN: base64.tests
>base64 >string
] unit-test
[ "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\r\nIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\r\ndGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\r\ndWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\r\nZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" ]
[
"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."
>base64-lines >string
] unit-test
\ >base64 must-infer
\ base64> must-infer

View File

@ -1,16 +1,22 @@
! Copyright (C) 2008 Doug Coleman.
! Copyright (C) 2008 Doug Coleman, Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math sequences io.binary splitting grouping
accessors ;
USING: combinators io io.binary io.encodings.binary
io.streams.byte-array io.streams.string kernel math namespaces
sequences strings ;
IN: base64
<PRIVATE
: count-end ( seq quot -- n )
trim-right-slice [ seq>> length ] [ to>> ] bi - ; inline
: read1-ignoring ( ignoring -- ch )
read1 2dup swap member? [ drop read1-ignoring ] [ nip ] if ;
: read-ignoring ( ignoring n -- str )
[ drop read1-ignoring ] with map harvest
[ f ] [ >string ] if-empty ;
: ch>base64 ( ch -- ch )
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" nth ;
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
nth ; inline
: base64>ch ( ch -- ch )
{
@ -19,32 +25,60 @@ IN: base64
f 0 f f f 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 23 24 25 f f f f f f 26 27 28 29 30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49 50 51
} nth ;
} nth ; inline
: encode3 ( seq -- seq )
SYMBOL: column
: write1-lines ( ch -- )
write1
column get [
1+ [ 76 = [ "\r\n" write ] when ]
[ 76 mod column set ] bi
] when* ;
: write-lines ( str -- )
[ write1-lines ] each ;
: encode3 ( seq -- )
be> 4 <reversed> [
-6 * shift HEX: 3f bitand ch>base64
] with B{ } map-as ;
-6 * shift HEX: 3f bitand ch>base64 write1-lines
] with each ; inline
: decode4 ( str -- str )
0 [ base64>ch swap 6 shift bitor ] reduce 3 >be ;
: encode-pad ( seq n -- )
[ 3 0 pad-right binary [ encode3 ] with-byte-writer ]
[ 1+ ] bi* head-slice 4 CHAR: = pad-right write-lines ; inline
: >base64-rem ( str -- str )
[ 3 0 pad-right encode3 ] [ length 1+ ] bi
head-slice 4 CHAR: = pad-right ;
ERROR: malformed-base64 ;
: decode4 ( seq -- )
[ 0 [ base64>ch swap 6 shift bitor ] reduce 3 >be ]
[ [ CHAR: = = ] count ] bi head-slice*
[ write1 ] each ; inline
PRIVATE>
: encode-base64 ( -- )
3 read dup length {
{ 0 [ drop ] }
{ 3 [ encode3 encode-base64 ] }
[ encode-pad encode-base64 ]
} case ;
: encode-base64-lines ( -- )
0 column [ encode-base64 ] with-variable ;
: decode-base64 ( -- )
"\n\r" 4 read-ignoring dup length {
{ 0 [ drop ] }
{ 4 [ decode4 decode-base64 ] }
[ malformed-base64 ]
} case ;
: >base64 ( seq -- base64 )
#! cut string into two pieces, convert 3 bytes at a time
#! pad string with = when not enough bits
dup length dup 3 mod - cut
[ 3 <groups> [ encode3 ] map concat ]
[ [ "" ] [ >base64-rem ] if-empty ]
bi* append ;
binary [ [ encode-base64 ] with-string-reader ] with-byte-writer ;
: base64> ( base64 -- seq )
#! input length must be a multiple of 4
[ 4 <groups> [ decode4 ] map concat ]
[ [ CHAR: = = ] count-end ]
bi head* ;
[ binary [ decode-base64 ] with-byte-reader ] with-string-writer ;
: >base64-lines ( seq -- base64 )
binary [ [ encode-base64-lines ] with-string-reader ] with-byte-writer ;

View File

@ -76,3 +76,7 @@ IN: bit-arrays.tests
t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t
t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t
} bit-array>integer ] unit-test
[ 49 ] [ 49 <bit-array> dup set-bits [ ] count ] unit-test
[ HEX: 100 ] [ ?{ f f f f f f f f t } bit-array>integer ] unit-test

View File

@ -25,7 +25,7 @@ TUPLE: bit-array
: (set-bits) ( bit-array n -- )
[ [ length bits>cells ] keep ] dip swap underlying>>
'[ [ _ _ ] dip set-alien-unsigned-4 ] each ; inline
'[ 2 shift [ _ _ ] dip set-alien-unsigned-4 ] each ; inline
PRIVATE>
@ -83,7 +83,7 @@ M: bit-array byte-length length 7 + -3 shift ;
] if ;
: bit-array>integer ( bit-array -- n )
0 swap underlying>> dup length [
0 swap underlying>> dup length <reversed> [
alien-unsigned-1 swap 8 shift bitor
] with each ;

View File

@ -4,6 +4,7 @@ parser vocabs.loader vocabs.loader.private accessors assocs ;
IN: bootstrap.help
: load-help ( -- )
"help.lint" require
"alien.syntax" require
"compiler" require

View File

@ -2,6 +2,4 @@ USING: vocabs vocabs.loader kernel ;
"math.ratios" require
"math.floats" require
"math.complex" require
"prettyprint" vocab [ "math.complex.prettyprint" require ] when
"math.complex" require

View File

@ -1,11 +1,11 @@
! Copyright (C) 2008 Slava Pestov.
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: vocabs vocabs.loader kernel ;
USING: vocabs vocabs.loader kernel io.thread threads
compiler.utilities namespaces ;
IN: bootstrap.threads
USE: io.thread
USE: threads
"debugger" vocab [
"debugger.threads" require
] when
[ yield ] yield-hook set-global

View File

@ -1,5 +0,0 @@
USING: strings.parser kernel namespaces unicode.data ;
IN: bootstrap.unicode
[ name>char [ "Invalid character" throw ] unless* ]
name>char-hook set-global

View File

@ -2,9 +2,9 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel io io.binary io.files io.streams.byte-array math
math.functions math.parser namespaces splitting grouping strings
sequences byte-arrays locals sequences.private
sequences byte-arrays locals sequences.private macros fry
io.encodings.binary math.bitwise checksums
checksums.common checksums.stream ;
checksums.common checksums.stream combinators ;
IN: checksums.md5
! See http://www.faqs.org/rfcs/rfc1321.html
@ -29,7 +29,7 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
old-c c update-old-new
old-d d update-old-new ;
:: (ABCD) ( x s i k func a b c d -- )
:: (ABCD) ( x a b c d k s i func -- )
#! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
a [
b get c get d get func call w+
@ -39,11 +39,6 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
b get w+
] change ; inline
: ABCD a b c d (ABCD) ; inline
: BCDA b c d a (ABCD) ; inline
: CDAB c d a b (ABCD) ; inline
: DABC d a b c (ABCD) ; inline
: F ( X Y Z -- FXYZ )
#! F(X,Y,Z) = XY v not(X) Z
pick bitnot bitand [ bitand ] [ bitor ] bi* ;
@ -60,104 +55,113 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
#! I(X,Y,Z) = Y xor (X v not(Z))
rot swap bitnot bitor bitxor ;
: S11 7 ; inline
: S12 12 ; inline
: S13 17 ; inline
: S14 22 ; inline
: S21 5 ; inline
: S22 9 ; inline
: S23 14 ; inline
: S24 20 ; inline
: S31 4 ; inline
: S32 11 ; inline
: S33 16 ; inline
: S34 23 ; inline
: S41 6 ; inline
: S42 10 ; inline
: S43 15 ; inline
: S44 21 ; inline
CONSTANT: S11 7
CONSTANT: S12 12
CONSTANT: S13 17
CONSTANT: S14 22
CONSTANT: S21 5
CONSTANT: S22 9
CONSTANT: S23 14
CONSTANT: S24 20
CONSTANT: S31 4
CONSTANT: S32 11
CONSTANT: S33 16
CONSTANT: S34 23
CONSTANT: S41 6
CONSTANT: S42 10
CONSTANT: S43 15
CONSTANT: S44 21
: (process-md5-block-F) ( block -- block )
dup S11 1 0 [ F ] ABCD
dup S12 2 1 [ F ] DABC
dup S13 3 2 [ F ] CDAB
dup S14 4 3 [ F ] BCDA
dup S11 5 4 [ F ] ABCD
dup S12 6 5 [ F ] DABC
dup S13 7 6 [ F ] CDAB
dup S14 8 7 [ F ] BCDA
dup S11 9 8 [ F ] ABCD
dup S12 10 9 [ F ] DABC
dup S13 11 10 [ F ] CDAB
dup S14 12 11 [ F ] BCDA
dup S11 13 12 [ F ] ABCD
dup S12 14 13 [ F ] DABC
dup S13 15 14 [ F ] CDAB
dup S14 16 15 [ F ] BCDA ;
MACRO: with-md5-round ( ops func -- )
'[ [ _ (ABCD) ] compose ] map '[ _ cleave ] ;
: (process-md5-block-G) ( block -- block )
dup S21 17 1 [ G ] ABCD
dup S22 18 6 [ G ] DABC
dup S23 19 11 [ G ] CDAB
dup S24 20 0 [ G ] BCDA
dup S21 21 5 [ G ] ABCD
dup S22 22 10 [ G ] DABC
dup S23 23 15 [ G ] CDAB
dup S24 24 4 [ G ] BCDA
dup S21 25 9 [ G ] ABCD
dup S22 26 14 [ G ] DABC
dup S23 27 3 [ G ] CDAB
dup S24 28 8 [ G ] BCDA
dup S21 29 13 [ G ] ABCD
dup S22 30 2 [ G ] DABC
dup S23 31 7 [ G ] CDAB
dup S24 32 12 [ G ] BCDA ;
: (process-md5-block-F) ( block -- )
{
[ a b c d 0 S11 1 ]
[ d a b c 1 S12 2 ]
[ c d a b 2 S13 3 ]
[ b c d a 3 S14 4 ]
[ a b c d 4 S11 5 ]
[ d a b c 5 S12 6 ]
[ c d a b 6 S13 7 ]
[ b c d a 7 S14 8 ]
[ a b c d 8 S11 9 ]
[ d a b c 9 S12 10 ]
[ c d a b 10 S13 11 ]
[ b c d a 11 S14 12 ]
[ a b c d 12 S11 13 ]
[ d a b c 13 S12 14 ]
[ c d a b 14 S13 15 ]
[ b c d a 15 S14 16 ]
} [ F ] with-md5-round ;
: (process-md5-block-H) ( block -- block )
dup S31 33 5 [ H ] ABCD
dup S32 34 8 [ H ] DABC
dup S33 35 11 [ H ] CDAB
dup S34 36 14 [ H ] BCDA
dup S31 37 1 [ H ] ABCD
dup S32 38 4 [ H ] DABC
dup S33 39 7 [ H ] CDAB
dup S34 40 10 [ H ] BCDA
dup S31 41 13 [ H ] ABCD
dup S32 42 0 [ H ] DABC
dup S33 43 3 [ H ] CDAB
dup S34 44 6 [ H ] BCDA
dup S31 45 9 [ H ] ABCD
dup S32 46 12 [ H ] DABC
dup S33 47 15 [ H ] CDAB
dup S34 48 2 [ H ] BCDA ;
: (process-md5-block-G) ( block -- )
{
[ a b c d 1 S21 17 ]
[ d a b c 6 S22 18 ]
[ c d a b 11 S23 19 ]
[ b c d a 0 S24 20 ]
[ a b c d 5 S21 21 ]
[ d a b c 10 S22 22 ]
[ c d a b 15 S23 23 ]
[ b c d a 4 S24 24 ]
[ a b c d 9 S21 25 ]
[ d a b c 14 S22 26 ]
[ c d a b 3 S23 27 ]
[ b c d a 8 S24 28 ]
[ a b c d 13 S21 29 ]
[ d a b c 2 S22 30 ]
[ c d a b 7 S23 31 ]
[ b c d a 12 S24 32 ]
} [ G ] with-md5-round ;
: (process-md5-block-I) ( block -- block )
dup S41 49 0 [ I ] ABCD
dup S42 50 7 [ I ] DABC
dup S43 51 14 [ I ] CDAB
dup S44 52 5 [ I ] BCDA
dup S41 53 12 [ I ] ABCD
dup S42 54 3 [ I ] DABC
dup S43 55 10 [ I ] CDAB
dup S44 56 1 [ I ] BCDA
dup S41 57 8 [ I ] ABCD
dup S42 58 15 [ I ] DABC
dup S43 59 6 [ I ] CDAB
dup S44 60 13 [ I ] BCDA
dup S41 61 4 [ I ] ABCD
dup S42 62 11 [ I ] DABC
dup S43 63 2 [ I ] CDAB
dup S44 64 9 [ I ] BCDA ;
: (process-md5-block-H) ( block -- )
{
[ a b c d 5 S31 33 ]
[ d a b c 8 S32 34 ]
[ c d a b 11 S33 35 ]
[ b c d a 14 S34 36 ]
[ a b c d 1 S31 37 ]
[ d a b c 4 S32 38 ]
[ c d a b 7 S33 39 ]
[ b c d a 10 S34 40 ]
[ a b c d 13 S31 41 ]
[ d a b c 0 S32 42 ]
[ c d a b 3 S33 43 ]
[ b c d a 6 S34 44 ]
[ a b c d 9 S31 45 ]
[ d a b c 12 S32 46 ]
[ c d a b 15 S33 47 ]
[ b c d a 2 S34 48 ]
} [ H ] with-md5-round ;
: (process-md5-block-I) ( block -- )
{
[ a b c d 0 S41 49 ]
[ d a b c 7 S42 50 ]
[ c d a b 14 S43 51 ]
[ b c d a 5 S44 52 ]
[ a b c d 12 S41 53 ]
[ d a b c 3 S42 54 ]
[ c d a b 10 S43 55 ]
[ b c d a 1 S44 56 ]
[ a b c d 8 S41 57 ]
[ d a b c 15 S42 58 ]
[ c d a b 6 S43 59 ]
[ b c d a 13 S44 60 ]
[ a b c d 4 S41 61 ]
[ d a b c 11 S42 62 ]
[ c d a b 2 S43 63 ]
[ b c d a 9 S44 64 ]
} [ I ] with-md5-round ;
: (process-md5-block) ( block -- )
4 <groups> [ le> ] map
(process-md5-block-F)
(process-md5-block-G)
(process-md5-block-H)
(process-md5-block-I)
drop
4 <groups> [ le> ] map {
[ (process-md5-block-F) ]
[ (process-md5-block-G) ]
[ (process-md5-block-H) ]
[ (process-md5-block-I) ]
} cleave
update-md ;

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1,125 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel quotations math sequences
multiline ;
IN: combinators.smart
HELP: input<sequence
{ $values
{ "quot" quotation }
{ "newquot" quotation }
}
{ $description "Infers the number of inputs, " { $snippet "n" } ", to " { $snippet "quot" } " and calls the " { $snippet "quot" } " with the first " { $snippet "n" } " values from a sequence." }
{ $examples
{ $example
"USING: combinators.smart math prettyprint ;"
"{ 1 2 3 } [ + + ] input<sequence ."
"6"
}
} ;
HELP: output>array
{ $values
{ "quot" quotation }
{ "newquot" quotation }
}
{ $description "Infers the number or outputs from the quotation and constructs an array from those outputs." }
{ $examples
{ $example
<" USING: combinators combinators.smart math prettyprint ;
9 [
{ [ 1- ] [ 1+ ] [ sq ] } cleave
] output>array .">
"{ 8 10 81 }"
}
} ;
HELP: output>sequence
{ $values
{ "quot" quotation } { "exemplar" "an exemplar" }
{ "newquot" quotation }
}
{ $description "Infers the number of outputs from the quotation and constructs a new sequence from those objects of the same type as the exemplar." }
{ $examples
{ $example
"USING: combinators.smart kernel math prettyprint ;"
"4 [ [ 1 + ] [ 2 + ] [ 3 + ] tri ] V{ } output>sequence ."
"V{ 5 6 7 }"
}
} ;
HELP: reduce-outputs
{ $values
{ "quot" quotation } { "operation" quotation }
{ "newquot" quotation }
}
{ $description "Infers the number of outputs from " { $snippet "quot" } " and reduces them using " { $snippet "operation" } ". The identity for the " { $link reduce } " operation is the first output." }
{ $examples
{ $example
"USING: combinators.smart kernel math prettyprint ;"
"3 [ [ 4 * ] [ 4 / ] [ 4 - ] tri ] [ * ] reduce-outputs ."
"-9"
}
} ;
HELP: sum-outputs
{ $values
{ "quot" quotation }
{ "n" integer }
}
{ $description "Infers the number of outputs from " { $snippet "quot" } " and returns their sum." }
{ $examples
{ $example
"USING: combinators.smart kernel math prettyprint ;"
"10 [ [ 1- ] [ 1+ ] bi ] sum-outputs ."
"20"
}
} ;
HELP: append-outputs
{ $values
{ "quot" quotation }
{ "seq" sequence }
}
{ $description "Infers the number of outputs from " { $snippet "quot" } " and returns a sequence of the outputs appended." }
{ $examples
{ $example
"USING: combinators.smart prettyprint ;"
"[ { 1 2 } { \"A\" \"b\" } ] append-outputs ."
"{ 1 2 \"A\" \"b\" }"
}
} ;
HELP: append-outputs-as
{ $values
{ "quot" quotation } { "exemplar" sequence }
{ "seq" sequence }
}
{ $description "Infers the number of outputs from " { $snippet "quot" } " and returns a sequence of type " { $snippet "exemplar" } " of the outputs appended." }
{ $examples
{ $example
"USING: combinators.smart prettyprint ;"
"[ { 1 2 } { \"A\" \"b\" } ] V{ } append-outputs-as ."
"V{ 1 2 \"A\" \"b\" }"
}
} ;
{ append-outputs append-outputs-as } related-words
ARTICLE: "combinators.smart" "Smart combinators"
"The " { $vocab-link "combinators.smart" } " vocabulary implements " { $emphasis "smart combinators" } ". A smart combinator is one whose behavior depends on the static stack effect of an input quotation." $nl
"Smart inputs from a sequence:"
{ $subsection input<sequence }
"Smart outputs to a sequence:"
{ $subsection output>sequence }
{ $subsection output>array }
"Reducing the output of a quotation:"
{ $subsection reduce-outputs }
"Summing the output of a quotation:"
{ $subsection sum-outputs }
"Appending the results of a quotation:"
{ $subsection append-outputs }
{ $subsection append-outputs-as } ;
ABOUT: "combinators.smart"

View File

@ -0,0 +1,39 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test combinators.smart math kernel ;
IN: combinators.smart.tests
: test-bi ( -- 9 11 )
10 [ 1- ] [ 1+ ] bi ;
[ [ test-bi ] output>array ] must-infer
[ { 9 11 } ] [ [ test-bi ] output>array ] unit-test
[ { 9 11 } [ + ] input<sequence ] must-infer
[ 20 ] [ { 9 11 } [ + ] input<sequence ] unit-test
[ 6 ] [ [ 1 2 3 ] [ + ] reduce-outputs ] unit-test
[ [ 1 2 3 ] [ + ] reduce-outputs ] must-infer
[ 6 ] [ [ 1 2 3 ] sum-outputs ] unit-test
[ "ab" ]
[
[ "a" "b" ] "" append-outputs-as
] unit-test
[ "" ]
[
[ ] "" append-outputs-as
] unit-test
[ { } ]
[
[ ] append-outputs
] unit-test
[ B{ 1 2 3 } ]
[
[ { 1 } { 2 } { 3 } ] B{ } append-outputs-as
] unit-test

View File

@ -0,0 +1,28 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors fry generalizations kernel macros math.order
stack-checker math ;
IN: combinators.smart
MACRO: output>sequence ( quot exemplar -- newquot )
[ dup infer out>> ] dip
'[ @ _ _ nsequence ] ;
: output>array ( quot -- newquot )
{ } output>sequence ; inline
MACRO: input<sequence ( quot -- newquot )
[ infer in>> ] keep
'[ _ firstn @ ] ;
MACRO: reduce-outputs ( quot operation -- newquot )
[ dup infer out>> 1 [-] ] dip n*quot compose ;
: sum-outputs ( quot -- n )
[ + ] reduce-outputs ; inline
MACRO: append-outputs-as ( quot exemplar -- newquot )
[ dup infer out>> ] dip '[ @ _ _ nappend-as ] ;
: append-outputs ( quot -- seq )
{ } append-outputs-as ; inline

View File

@ -1,7 +1,7 @@
IN: compiler.cfg.linear-scan.tests
USING: tools.test random sorting sequences sets hashtables assocs
kernel fry arrays splitting namespaces math accessors vectors
math.order
math.order grouping
cpu.architecture
compiler.cfg.instructions
compiler.cfg.registers

View File

@ -1,9 +1,9 @@
! Copyright (C) 2008 Slava Pestov.
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces make math math.order math.parser sequences accessors
kernel kernel.private layouts assocs words summary arrays
combinators classes.algebra alien alien.c-types alien.structs
alien.strings alien.arrays sets threads libc continuations.private
alien.strings alien.arrays sets libc continuations.private
fry cpu.architecture
compiler.errors
compiler.alien
@ -11,7 +11,8 @@ compiler.cfg
compiler.cfg.instructions
compiler.cfg.registers
compiler.cfg.builder
compiler.codegen.fixup ;
compiler.codegen.fixup
compiler.utilities ;
IN: compiler.codegen
GENERIC: generate-insn ( insn -- )
@ -463,7 +464,7 @@ TUPLE: callback-context ;
dup current-callback eq? [
drop
] [
yield wait-to-return
yield-hook get call wait-to-return
] if ;
: do-callback ( quot token -- )

View File

@ -1,14 +1,14 @@
! Copyright (C) 2004, 2008 Slava Pestov.
! Copyright (C) 2004, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel namespaces arrays sequences io
words fry continuations vocabs assocs dlists definitions math
threads graphs generic combinators deques search-deques io
graphs generic combinators deques search-deques io
stack-checker stack-checker.state stack-checker.inlining
compiler.errors compiler.units compiler.tree.builder
compiler.tree.optimizer compiler.cfg.builder
compiler.cfg.optimizer compiler.cfg.linearization
compiler.cfg.two-operand compiler.cfg.linear-scan
compiler.cfg.stack-frame compiler.codegen ;
compiler.cfg.stack-frame compiler.codegen compiler.utilities ;
IN: compiler
SYMBOL: compile-queue
@ -107,7 +107,7 @@ t compile-dependencies? set-global
] with-return ;
: compile-loop ( deque -- )
[ (compile) yield ] slurp-deque ;
[ (compile) yield-hook get call ] slurp-deque ;
: decompile ( word -- )
f 2array 1array t modify-code-heap ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: sequences kernel sets namespaces accessors assocs
arrays combinators continuations columns math vectors
stack-checker.branches
grouping stack-checker.branches
compiler.tree
compiler.tree.def-use
compiler.tree.combinators ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel namespaces sequences sets fry columns
stack-checker.branches
grouping stack-checker.branches
compiler.tree
compiler.tree.propagation.branches
compiler.tree.escape-analysis.nodes

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces sequences assocs math kernel accessors fry
combinators sets locals columns
combinators sets locals columns grouping
stack-checker.branches
compiler.tree
compiler.tree.def-use

View File

@ -3,7 +3,7 @@
USING: accessors kernel arrays sequences math math.order
math.partial-dispatch generic generic.standard generic.math
classes.algebra classes.union sets quotations assocs combinators
words namespaces continuations classes fry
words namespaces continuations classes fry combinators.smart
compiler.tree
compiler.tree.builder
compiler.tree.recursive
@ -134,17 +134,19 @@ DEFER: (flat-length)
over 2 <= [ drop ] [ 2/ 1+ * ] if 24 swap [-] 4 /i ;
: inlining-rank ( #call word -- n )
[ classes-known? 2 0 ? ]
[
{
[ body-length-bias ]
[ "default" word-prop -4 0 ? ]
[ "specializer" word-prop 1 0 ? ]
[ method-body? 1 0 ? ]
} cleave
node-count-bias
loop-nesting get 0 or 2 *
] bi* + + + + + + ;
[ classes-known? 2 0 ? ]
[
{
[ body-length-bias ]
[ "default" word-prop -4 0 ? ]
[ "specializer" word-prop 1 0 ? ]
[ method-body? 1 0 ? ]
} cleave
node-count-bias
loop-nesting get 0 or 2 *
] bi*
] sum-outputs ;
: should-inline? ( #call word -- ? )
dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ;

View 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: kernel sequences sequences.private arrays vectors fry
math.order ;
math.order namespaces assocs ;
IN: compiler.utilities
: flattener ( seq quot -- seq vector quot' )
@ -22,10 +22,6 @@ IN: compiler.utilities
: 2map-flat ( seq quot -- seq' ) [ 2each ] flattening ; inline
: (3each) ( seq1 seq2 seq3 quot -- n quot' )
[ [ [ length ] tri@ min min ] 3keep ] dip
'[ [ _ nth-unsafe ] [ _ nth-unsafe ] [ _ nth-unsafe ] tri @ ] ; inline
SYMBOL: yield-hook
: 3each ( seq1 seq2 seq3 quot -- seq ) (3each) each ; inline
: 3map ( seq1 seq2 seq3 quot -- seq ) (3each) map ; inline
yield-hook global [ [ ] or ] change-at

View File

@ -1 +1,2 @@
Slava Pestov
Doug Coleman

View File

@ -0,0 +1,7 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test db.tester ;
IN: db.tester.tests
[ ] [ sqlite-test-db db-tester ] unit-test
[ ] [ sqlite-test-db db-tester2 ] unit-test

View File

@ -0,0 +1,62 @@
! Copyright (C) 2008 Slava Pestov, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: concurrency.combinators db.pools db.sqlite db.tuples
db.types kernel math random threads tools.test db sequences
io prettyprint ;
IN: db.tester
TUPLE: test-1 id a b c ;
test-1 "TEST1" {
{ "id" "ID" INTEGER +db-assigned-id+ }
{ "a" "A" { VARCHAR 256 } +not-null+ }
{ "b" "B" { VARCHAR 256 } +not-null+ }
{ "c" "C" { VARCHAR 256 } +not-null+ }
} define-persistent
TUPLE: test-2 id x y z ;
test-2 "TEST2" {
{ "id" "ID" INTEGER +db-assigned-id+ }
{ "x" "X" { VARCHAR 256 } +not-null+ }
{ "y" "Y" { VARCHAR 256 } +not-null+ }
{ "z" "Z" { VARCHAR 256 } +not-null+ }
} define-persistent
: sqlite-test-db ( -- db ) "test.db" <sqlite-db> ;
: test-db ( -- db ) "test.db" <sqlite-db> ;
: db-tester ( test-db -- )
[
[
test-1 ensure-table
test-2 ensure-table
] with-db
] [
10 [
drop
10 [
dup [
f 100 random 100 random 100 random test-1 boa
insert-tuple yield
] with-db
] times
] with parallel-each
] bi ;
: db-tester2 ( test-db -- )
[
[
test-1 ensure-table
test-2 ensure-table
] with-db
] [
<db-pool> [
10 [
10 [
f 100 random 100 random 100 random test-1 boa
insert-tuple yield
] times
] parallel-each
] with-pooled-db
] bi ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2007 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: delegate sequences.private sequences assocs
io definitions kernel continuations ;
io io.styles definitions kernel continuations ;
IN: delegate.protocols
PROTOCOL: sequence-protocol

View File

@ -6,6 +6,7 @@ IN: editors.editpadlite
: editpadlite-path ( -- path )
\ editpadlite-path get-global [
"JGsoft" t [ >lower "editpadlite.exe" tail? ] find-in-program-files
[ "editpadlite.exe" ] unless*
] unless* ;
: editpadlite ( file line -- )

View File

@ -6,6 +6,7 @@ IN: editors.editpadpro
: editpadpro-path ( -- path )
\ editpadpro-path get-global [
"JGsoft" t [ >lower "editpadpro.exe" tail? ] find-in-program-files
[ "editpadpro.exe" ] unless*
] unless* ;
: editpadpro ( file line -- )

View File

@ -6,6 +6,7 @@ IN: editors.editplus
: editplus-path ( -- path )
\ editplus-path get-global [
"EditPlus 2" t [ "editplus.exe" tail? ] find-in-program-files
[ "editplus.exe" ] unless*
] unless* ;
: editplus ( file line -- )

View File

@ -6,6 +6,7 @@ IN: editors.emeditor
: emeditor-path ( -- path )
\ emeditor-path get-global [
"EmEditor" t [ "EmEditor.exe" tail? ] find-in-program-files
[ "EmEditor.exe" ] unless*
] unless* ;
: emeditor ( file line -- )

View File

@ -7,6 +7,7 @@ IN: editors.etexteditor
: etexteditor-path ( -- str )
\ etexteditor-path get-global [
"e" t [ "e.exe" tail? ] find-in-program-files
[ "e" ] unless*
] unless* ;
: etexteditor ( file line -- )

View File

@ -3,12 +3,15 @@ namespaces sequences system combinators
editors.vim vocabs.loader make ;
IN: editors.gvim
! This code builds on the code in editors.vim; see there for
! more information.
SINGLETON: gvim
HOOK: gvim-path io-backend ( -- path )
M: gvim vim-command ( file line -- string )
[ gvim-path , swap , "+" swap number>string append , ] { } make ;
[ gvim-path , "+" swap number>string append , , ] { } make ;
gvim vim-editor set-global

View File

@ -6,4 +6,5 @@ IN: editors.gvim.windows
M: windows gvim-path
\ gvim-path get-global [
"vim" t [ "gvim.exe" tail? ] find-in-program-files
[ "gvim.exe" ] unless*
] unless* ;

View File

@ -0,0 +1,18 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: editors io.launcher kernel io.directories.search.windows
math.parser namespaces sequences io.files arrays windows.shell32
io.directories.search ;
IN: editors.notepad
: notepad-path ( -- path )
\ notepad-path get [
windows-directory t
[ "notepad.exe" tail? ] find-file
] unless* ;
: notepad ( file line -- )
drop notepad-path swap 2array run-detached drop ;
[ notepad ] edit-hook set-global

View File

@ -5,6 +5,7 @@ IN: editors.notepad2
: notepad2-path ( -- path )
\ notepad2-path get-global [
windows-directory "system32\\notepad.exe" append-path
[ "notepad.exe" ] unless*
] unless* ;
: notepad2 ( file line -- )

View File

@ -5,6 +5,7 @@ IN: editors.notepadpp
: notepadpp-path ( -- path )
\ notepadpp-path get-global [
"notepad++" t [ "notepad++.exe" tail? ] find-in-program-files
[ "notepad++.exe" ] unless*
] unless* ;
: notepadpp ( file line -- )

View File

@ -9,6 +9,12 @@ IN: editors.scite
\ scite-path get-global [
"Scintilla Text Editor" t
[ >lower "scite.exe" tail? ] find-in-program-files
[
"SciTE Source Code Editor" t
[ >lower "scite.exe" tail? ] find-in-program-files
] unless*
[ "scite.exe" ] unless*
] unless* ;
: scite-command ( file line -- cmd )

View File

@ -5,6 +5,7 @@ IN: editors.ted-notepad
: ted-notepad-path ( -- path )
\ ted-notepad-path get-global [
"TED Notepad" t [ "TedNPad.exe" tail? ] find-in-program-files
[ "TedNPad.exe" ] unless*
] unless* ;
: ted-notepad ( file line -- )

View File

@ -6,6 +6,7 @@ IN: editors.textpad
: textpad-path ( -- path )
\ textpad-path get-global [
"TextPad 5" t [ "TextPad.exe" tail? ] find-in-program-files
[ "TextPad.exe" ] unless*
] unless* ;
: textpad ( file line -- )

View File

@ -5,6 +5,7 @@ IN: editors.ultraedit
: ultraedit-path ( -- path )
\ ultraedit-path get-global [
"IDM Computer Solutions" t [ "uedit32.exe" tail? ] find-in-program-files
[ "uedit32.exe" ] unless*
] unless* ;
: ultraedit ( file line -- )

View File

@ -1,11 +1,10 @@
! Generate a new factor.vim file for syntax highlighting
USING: http.server.templating http.server.templating.fhtml
io.files ;
USING: html.templates html.templates.fhtml io.files io.pathnames ;
IN: editors.vim.generate-syntax
: generate-vim-syntax ( -- )
"misc/factor.vim.fgen" resource-path <fhtml>
"misc/factor.vim" resource-path
"misc/vim/syntax/factor.vim" resource-path
template-convert ;
MAIN: generate-vim-syntax

View File

@ -12,5 +12,6 @@ $nl
"USE: vim"
"\"c:\\\\program files\\\\vim\\\\vim70\\\\gvim\" vim-path set-global"
}
"On Unix, you may omit the last line if " { $snippet "\"vim\"" } " is in your " { $snippet "$PATH" } "." ;
"On Unix, you may omit the last line if " { $snippet "\"vim\"" } " is in your " { $snippet "$PATH" } "."
$nl
"You may also wish to install Vim support files to enable syntax hilighting and other features. These are in the " { $link resource-path } " in " { $snippet "misc/vim" } "." ;

View File

@ -1,6 +1,7 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: farkup kernel peg peg.ebnf tools.test namespaces ;
USING: farkup kernel peg peg.ebnf tools.test namespaces xml
urls.encoding assocs xml.utilities ;
IN: farkup.tests
relative-link-prefix off
@ -157,3 +158,12 @@ link-no-follow? off
[ "<p>hello_world how are you today?\n<ul><li> hello_world how are you today?</li></ul></p>" ]
[ "hello_world how are you today?\n- hello_world how are you today?" convert-farkup ] unit-test
: check-link-escaping ( string -- link )
convert-farkup string>xml-chunk
"a" deep-tag-named "href" swap at url-decode ;
[ "Trader Joe's" ] [ "[[Trader Joe's]]" check-link-escaping ] unit-test
[ "<foo>" ] [ "[[<foo>]]" check-link-escaping ] unit-test
[ "&blah;" ] [ "[[&blah;]]" check-link-escaping ] unit-test
[ "C++" ] [ "[[C++]]" check-link-escaping ] unit-test

View File

@ -167,7 +167,7 @@ stand-alone
} cond ;
: escape-link ( href text -- href-esc text-esc )
[ check-url escape-quoted-string ] dip escape-string ;
[ check-url ] dip escape-string ;
: write-link ( href text -- )
escape-link

View File

@ -3,12 +3,12 @@
USING: combinators.short-circuit accessors combinators io
io.encodings.8-bit io.encodings io.encodings.binary
io.encodings.utf8 io.files io.files.info io.directories
io.pathnames io.sockets kernel math.parser namespaces make
sequences ftp io.launcher.unix.parser unicode.case splitting
io.sockets kernel math.parser namespaces make sequences
ftp io.launcher.unix.parser unicode.case splitting
assocs classes io.servers.connection destructors calendar
io.timeouts io.streams.duplex threads continuations math
concurrency.promises byte-arrays io.backend tools.hexdump
tools.files io.streams.string math.bitwise ;
io.streams.string math.bitwise tools.files io.pathnames ;
IN: ftp.server
TUPLE: ftp-client url mode state command-promise user password ;

View File

@ -229,8 +229,9 @@ HELP: napply
{ $examples
"Some core words expressed in terms of " { $link napply } ":"
{ $table
{ { $link bi@ } { $snippet "1 napply" } }
{ { $link tri@ } { $snippet "2 napply" } }
{ { $link call } { $snippet "1 napply" } }
{ { $link bi@ } { $snippet "2 napply" } }
{ { $link tri@ } { $snippet "3 napply" } }
}
} ;
@ -258,6 +259,55 @@ HELP: mnswap
}
} ;
HELP: n*quot
{ $values
{ "n" integer } { "seq" sequence }
{ "seq'" sequence }
}
{ $examples
{ $example "USING: generalizations prettyprint math ;"
"3 [ + ] n*quot ."
"[ + + + ]"
}
}
{ $description "Construct a quotation containing the contents of " { $snippet "seq" } " repeated " { $snippet "n"} " times." } ;
HELP: nappend
{ $values
{ "n" integer }
{ "seq" sequence }
}
{ $description "Outputs a new sequence consisting of the elements of the top " { $snippet "n" } " sequences from the datastack in turn." }
{ $errors "Throws an error if any of the sequences contain elements that are not permitted in the sequence type of the first sequence." }
{ $examples
{ $example "USING: generalizations prettyprint math ;"
"{ 1 2 } { 3 4 } { 5 6 } { 7 8 } 4 nappend ."
"{ 1 2 3 4 5 6 7 8 }"
}
} ;
HELP: nappend-as
{ $values
{ "n" integer } { "exemplar" sequence }
{ "seq" sequence }
}
{ $description "Outputs a new sequence of type " { $snippet "exemplar" } " consisting of the elements of the top " { $snippet "n" } " sequences from the datastack in turn." }
{ $errors "Throws an error if any of the sequences contain elements that are not permitted in the sequence type of the first sequence." }
{ $examples
{ $example "USING: generalizations prettyprint math ;"
"{ 1 2 } { 3 4 } { 5 6 } { 7 8 } 4 V{ } nappend-as ."
"V{ 1 2 3 4 5 6 7 8 }"
}
} ;
{ nappend nappend-as } related-words
HELP: ntuck
{ $values
{ "n" integer }
}
{ $description "A generalization of " { $link tuck } " that can work for any stack depth. The top item will be copied and placed " { $snippet "n" } " items down on the stack." } ;
ARTICLE: "generalizations" "Generalized shuffle words and combinators"
"The " { $vocab-link "generalizations" } " vocabulary defines a number of stack shuffling words and combinators for use in "
"macros where the arity of the input quotations depends on an "
@ -267,6 +317,8 @@ $nl
{ $subsection narray }
{ $subsection nsequence }
{ $subsection firstn }
{ $subsection nappend }
{ $subsection nappend-as }
"Generated stack shuffle operations:"
{ $subsection ndup }
{ $subsection npick }
@ -274,6 +326,7 @@ $nl
{ $subsection -nrot }
{ $subsection nnip }
{ $subsection ndrop }
{ $subsection ntuck }
{ $subsection nrev }
{ $subsection mnswap }
"Generalized combinators:"

View File

@ -1,10 +1,11 @@
USING: tools.test generalizations kernel math arrays sequences ;
USING: tools.test generalizations kernel math arrays sequences ascii ;
IN: generalizations.tests
{ 1 2 3 4 1 } [ 1 2 3 4 4 npick ] unit-test
{ 1 2 3 4 2 } [ 1 2 3 4 3 npick ] unit-test
{ 1 2 3 4 3 } [ 1 2 3 4 2 npick ] unit-test
{ 1 2 3 4 4 } [ 1 2 3 4 1 npick ] unit-test
[ 1 1 ndup ] must-infer
{ 1 1 } [ 1 1 ndup ] unit-test
{ 1 2 1 2 } [ 1 2 2 ndup ] unit-test
@ -22,12 +23,16 @@ IN: generalizations.tests
{ 4 } [ 1 2 3 4 3 nnip ] unit-test
[ 1 2 3 4 4 ndrop ] must-infer
{ 0 } [ 0 1 2 3 4 4 ndrop ] unit-test
[ [ 1 ] 5 ndip ] must-infer
[ 1 2 3 4 ] [ 2 3 4 [ 1 ] 3 ndip ] unit-test
[ [ 99 ] 1 2 3 4 5 5 nslip ] must-infer
{ 99 1 2 3 4 5 } [ [ 99 ] 1 2 3 4 5 5 nslip ] unit-test
[ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] must-infer
{ 2 1 2 3 4 5 } [ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] unit-test
[ [ 1 2 3 + ] ] [ 1 2 3 [ + ] 3 ncurry ] unit-test
[ "HELLO" ] [ "hello" [ >upper ] 1 napply ] unit-test
[ { 1 2 } { 2 4 } { 3 8 } { 4 16 } { 5 32 } ] [ 1 2 3 4 5 [ dup 2^ 2array ] 5 napply ] unit-test
[ [ dup 2^ 2array ] 5 napply ] must-infer
@ -42,3 +47,9 @@ IN: generalizations.tests
[ 4 5 1 2 3 ] [ 1 2 3 4 5 2 3 mnswap ] unit-test
[ 1 2 3 4 5 6 ] [ 1 2 3 4 5 6 2 4 mnswap 4 2 mnswap ] unit-test
[ { 1 2 3 4 } ] [ { 1 } { 2 } { 3 } { 4 } 4 nappend ] unit-test
[ V{ 1 2 3 4 } ] [ { 1 } { 2 } { 3 } { 4 } 4 V{ } nappend-as ] unit-test
[ 4 nappend ] must-infer
[ 4 { } nappend-as ] must-infer

View File

@ -2,7 +2,7 @@
! Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences sequences.private math math.ranges
combinators macros quotations fry ;
combinators macros quotations fry macros locals ;
IN: generalizations
<<
@ -73,10 +73,13 @@ MACRO: ncleave ( quots n -- )
[ '[ _ '[ _ _ nkeep ] ] map [ ] join ] [ '[ _ ndrop ] ] bi
compose ;
MACRO: napply ( n -- )
2 [a,b]
[ [ 1- ] [ ] bi '[ _ ntuck _ nslip ] ]
map concat >quotation [ call ] append ;
MACRO: napply ( quot n -- )
swap <repetition> spread>quot ;
MACRO: mnswap ( m n -- )
1+ '[ _ -nrot ] <repetition> spread>quot ;
: nappend-as ( n exemplar -- seq )
[ narray concat ] dip like ; inline
: nappend ( n -- seq ) narray concat ; inline

View File

@ -22,15 +22,19 @@ ARTICLE: "grouping" "Groups and clumps"
{ "With clumps, collecting the first element of each subsequence but the last one, together with the last subseqence, yields the original sequence:"
{ $unchecked-example "dup n clumps unclip-last [ [ first ] map ] dip append sequence= ." "t" }
}
} ;
}
"A combinator built using clumps:"
{ $subsection monotonic? }
"Testing how elements are related:"
{ $subsection all-eq? }
{ $subsection all-equal? } ;
ABOUT: "grouping"
HELP: groups
{ $class-description "Instances are virtual sequences whose elements are disjoint fixed-length subsequences of an underlying sequence. Groups are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
$nl
"New groups are created by calling " { $link <groups> } " and " { $link <sliced-groups> } "." }
{ $see-also group } ;
"New groups are created by calling " { $link <groups> } " and " { $link <sliced-groups> } "." } ;
HELP: group
{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
@ -48,11 +52,16 @@ HELP: <groups>
"USING: arrays kernel prettyprint sequences grouping ;"
"9 >array 3 <groups> dup reverse-here concat >array ." "{ 6 7 8 3 4 5 0 1 2 }"
}
{ $example
"USING: kernel prettyprint sequences grouping ;"
"{ 1 2 3 4 5 6 } 3 <groups> first ."
"{ 1 2 3 }"
}
} ;
HELP: <sliced-groups>
{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "groups" groups } }
{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
{ $description "Outputs a virtual sequence whose elements are slices of disjoint subsequences of " { $snippet "n" } " elements from the underlying sequence." }
{ $examples
{ $example
"USING: arrays kernel prettyprint sequences grouping ;"
@ -60,6 +69,11 @@ HELP: <sliced-groups>
"dup [ reverse-here ] each concat >array ."
"{ 2 1 0 5 4 3 8 7 6 }"
}
{ $example
"USING: kernel prettyprint sequences grouping ;"
"{ 1 2 3 4 5 6 } 3 <sliced-groups> second ."
"T{ slice { from 3 } { to 6 } { seq { 1 2 3 4 5 6 } } }"
}
} ;
HELP: clumps
@ -89,11 +103,23 @@ HELP: <clumps>
"share-price 4 <clumps> [ [ sum ] [ length ] bi / ] map ."
"{ 113/400 167/400 201/400 241/400 243/400 91/200 1/4 }"
}
{ $example
"USING: kernel sequences grouping prettyprint ;"
"{ 1 2 3 4 5 6 } 3 <clumps> second ."
"{ 2 3 4 }"
}
} ;
HELP: <sliced-clumps>
{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence." } ;
{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence." }
{ $examples
{ $example
"USING: kernel sequences grouping prettyprint ;"
"{ 1 2 3 4 5 6 } 3 <sliced-clumps> second ."
"T{ slice { from 1 } { to 4 } { seq { 1 2 3 4 5 6 } } }"
}
} ;
{ clumps groups } related-words
@ -102,3 +128,23 @@ HELP: <sliced-clumps>
{ <clumps> <groups> } related-words
{ <sliced-clumps> <sliced-groups> } related-words
HELP: monotonic?
{ $values { "seq" sequence } { "quot" { $quotation "( elt elt -- ? )" } } { "?" "a boolean" } }
{ $description "Applies the relation to successive pairs of elements in the sequence, testing for a truth value. The relation should be a transitive relation, such as a total order or an equality relation." }
{ $examples
"Testing if a sequence is non-decreasing:"
{ $example "USING: grouping math prettyprint ;" "{ 1 1 2 } [ <= ] monotonic? ." "t" }
"Testing if a sequence is decreasing:"
{ $example "USING: grouping math prettyprint ;" "{ 9 8 6 7 } [ < ] monotonic? ." "f" }
} ;
HELP: all-equal?
{ $values { "seq" sequence } { "?" "a boolean" } }
{ $description "Tests if all elements in the sequence are equal. Yields true with an empty sequence." } ;
HELP: all-eq?
{ $values { "seq" sequence } { "?" "a boolean" } }
{ $description "Tests if all elements in the sequence are the same identical object. Yields true with an empty sequence." } ;
{ monotonic? all-eq? all-equal? } related-words

View File

@ -1,4 +1,5 @@
USING: grouping tools.test kernel sequences arrays ;
USING: grouping tools.test kernel sequences arrays
math ;
IN: grouping.tests
[ { 1 2 3 } 0 group ] must-fail
@ -12,3 +13,11 @@ IN: grouping.tests
] unit-test
[ { { 1 2 } { 2 3 } } ] [ { 1 2 3 } 2 <sliced-clumps> [ >array ] map ] unit-test
[ f ] [ [ { } { } "Hello" ] all-equal? ] unit-test
[ f ] [ [ { 2 } { } { } ] all-equal? ] unit-test
[ t ] [ [ ] all-equal? ] unit-test
[ t ] [ [ 1234 ] all-equal? ] unit-test
[ f ] [ [ 1.0 1 1 ] all-equal? ] unit-test
[ t ] [ { 1 2 3 4 } [ < ] monotonic? ] unit-test
[ f ] [ { 1 2 3 4 } [ > ] monotonic? ] unit-test

View File

@ -1,4 +1,4 @@
! Copyright (C) 2005, 2008 Slava Pestov.
! Copyright (C) 2005, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math math.order strings arrays vectors sequences
sequences.private accessors ;
@ -87,3 +87,17 @@ INSTANCE: sliced-clumps slice-chunking
: group ( seq n -- array ) <groups> { } like ;
: clump ( seq n -- array ) <clumps> { } like ;
: monotonic? ( seq quot -- ? )
over length 2 < [ 2drop t ] [
over length 2 = [
[ first2-unsafe ] dip call
] [
[ 2 <sliced-clumps> ] dip
[ first2-unsafe ] prepose all?
] if
] if ; inline
: all-equal? ( seq -- ? ) [ = ] monotonic? ;
: all-eq? ( seq -- ? ) [ eq? ] monotonic? ;

View File

@ -267,8 +267,8 @@ $nl
{ $heading "Example: ls" }
"Here is an example implementing a simplified version of the Unix " { $snippet "ls" } " command in Factor:"
{ $code
<" USING: command-line namespaces io io.files tools.files
sequences kernel ;
<" USING: command-line namespaces io io.files
io.pathnames tools.files sequences kernel ;
command-line get [
current-directory get directory.

View File

@ -181,9 +181,10 @@ ARTICLE: "io" "Input and output"
{ $subsection "io.streams.plain" }
{ $subsection "io.streams.string" }
{ $subsection "io.streams.byte-array" }
{ $subsection "io.streams.limited" }
{ $heading "Utilities" }
{ $subsection "stream-binary" }
{ $subsection "styles" }
{ $subsection "io.styles" }
{ $subsection "checksums" }
{ $heading "Implementation" }
{ $subsection "io.streams.c" }
@ -209,7 +210,8 @@ ARTICLE: "tools" "Developer tools"
{ $subsection "timing" }
{ $subsection "tools.disassembler" }
"Deployment tools:"
{ $subsection "tools.deploy" } ;
{ $subsection "tools.deploy" }
{ $see-also "ui-tools" } ;
ARTICLE: "article-index" "Article index"
{ $index [ articles get keys ] } ;

View File

@ -327,7 +327,7 @@ HELP: $table
HELP: $values
{ $values { "element" "an array of pairs of markup elements" } }
{ $description "Prints the description of arguments and values found on every word help page. The first element of a pair is the argument name and is output with " { $link $snippet } ". The remainder is either a single class word, or an element. If it is a class word " { $snippet "class" } ", it is intereted as if it were shorthand for " { $snippet "{ $instance class }" } "." }
{ $description "Prints the description of arguments and values found on every word help page. The first element of a pair is the argument name and is output with " { $link $snippet } ". The remainder is either a single class word, or an element. If it is a class word " { $snippet "class" } ", it is inserted as if it were shorthand for " { $snippet "{ $instance class }" } "." }
{ $see-also $maybe $instance $quotation } ;
HELP: $instance

View File

@ -6,7 +6,7 @@ io io.streams.string prettyprint definitions arrays vectors
combinators combinators.short-circuit splitting debugger
hashtables sorting effects vocabs vocabs.loader assocs editors
continuations classes.predicate macros math sets eval
vocabs.parser words.symbol ;
vocabs.parser words.symbol values ;
IN: help.lint
: check-example ( element -- )
@ -42,15 +42,25 @@ IN: help.lint
$error-description
} swap '[ _ elements empty? not ] contains? ;
: don't-check-word? ( word -- ? )
{
[ macro? ]
[ symbol? ]
[ value-word? ]
[ parsing-word? ]
[ "declared-effect" word-prop not ]
} 1|| ;
: check-values ( word element -- )
{
[ drop { [ symbol? ] [ macro? ] [ parsing-word? ] } 1|| ]
[ drop "declared-effect" word-prop not ]
[ nip contains-funky-elements? ]
[
[ effect-values >array ]
[ extract-values >array ]
bi* =
[ don't-check-word? ]
[ contains-funky-elements? ]
bi* or
] [
[ effect-values ]
[ extract-values ]
bi* sequence=
]
} 2|| [ "$values don't match stack effect" throw ] unless ;

View File

@ -3,7 +3,7 @@
! Copyright (C) 2004 Chris Double.
! See http://factorcode.org/license.txt for BSD license.
USING: io kernel namespaces prettyprint quotations
USING: io io.styles kernel namespaces prettyprint quotations
sequences strings words xml.entities compiler.units effects
urls math math.parser combinators present fry ;

View File

@ -1,7 +1,8 @@
USING: html.templates html.templates.chloe
tools.test io.streams.string kernel sequences ascii boxes
namespaces xml html.components html.forms
splitting unicode.categories furnace accessors ;
splitting unicode.categories furnace accessors
html.templates.chloe.compiler ;
IN: html.templates.chloe.tests
: run-template
@ -163,3 +164,9 @@ TUPLE: person first-name last-name ;
"test12" test-template call-template
] run-template
] unit-test
[
[
"test13" test-template call-template
] run-template
] [ error>> T{ unknown-chloe-tag f "this-tag-does-not-exist" } = ] must-fail-with

View File

@ -76,10 +76,13 @@ DEFER: compile-element
[ drop tag-stack get pop* ]
} cleave ;
ERROR: unknown-chloe-tag tag ;
: compile-chloe-tag ( tag -- )
! "Unknown chloe tag: " prepend throw
dup main>> dup tags get at
[ curry assert-depth ] [ 2drop ] ?if ;
[ curry assert-depth ]
[ unknown-chloe-tag ]
?if ;
: compile-element ( element -- )
{

View File

@ -0,0 +1,7 @@
<?xml version='1.0' ?>
<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
<t:this-tag-does-not-exist />
</t:chloe>

View File

@ -45,8 +45,8 @@ IN: http
: check-header-string ( str -- str )
#! http://en.wikipedia.org/wiki/HTTP_Header_Injection
dup "\r\n\"" intersect empty?
[ "Header injection attack" throw ] unless ;
dup "\r\n\"" intersects?
[ "Header injection attack" throw ] when ;
: write-header ( assoc -- )
>alist sort-keys [
@ -97,8 +97,8 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s
] { } make ;
: check-cookie-string ( string -- string' )
dup "=;'\"\r\n" intersect empty?
[ "Bad cookie name or value" throw ] unless ;
dup "=;'\"\r\n" intersects?
[ "Bad cookie name or value" throw ] when ;
: unparse-cookie-value ( key value -- )
{

View File

@ -1,7 +1,7 @@
! Copyright (C) 2007, 2008 Slava Pestov.
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces kernel assocs io.files io.streams.duplex
combinators arrays io.launcher io.encodings.binary io
combinators arrays io.launcher io.encodings io.encodings.binary io
http.server.static http.server http accessors sequences strings
math.parser fry urls urls.encoding calendar ;
IN: http.server.cgi
@ -52,6 +52,7 @@ IN: http.server.cgi
200 >>code
"CGI output follows" >>message
swap '[
binary encode-output
_ output-stream get swap <cgi-process> binary <process-stream> [
post-request? [ request get post-data>> raw>> write flush ] when
input-stream get swap (stream-copy)

View File

@ -6,7 +6,7 @@ HELP: cwd
{ $values { "path" "a pathname string" } }
{ $description "Outputs the current working directory of the Factor process." }
{ $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." }
{ $notes "User code should use " { $link with-directory } " or " { $link set-current-directory } " instead." } ;
{ $notes "User code should use the value of the " { $link current-directory } " variable instead." } ;
HELP: cd
{ $values { "path" "a pathname string" } }
@ -50,6 +50,10 @@ HELP: with-directory-files
{ $values { "path" "a pathname string" } { "quot" quotation } }
{ $description "Calls the quotation with the directory file names on the stack and with the directory set as the " { $link current-directory } ". Restores the current directory after the quotation is called." } ;
HELP: with-directory-entries
{ $values { "path" "a pathname string" } { "quot" quotation } }
{ $description "Calls the quotation with the directory entries on the stack and with the directory set as the " { $link current-directory } ". Restores the current directory after the quotation is called." } ;
HELP: delete-file
{ $values { "path" "a pathname string" } }
{ $description "Deletes a file." }
@ -122,6 +126,7 @@ ARTICLE: "io.directories.listing" "Directory listing"
"Directory listing:"
{ $subsection directory-entries }
{ $subsection directory-files }
{ $subsection with-directory-entries }
{ $subsection with-directory-files } ;
ARTICLE: "io.directories.create" "Creating directories"

View File

@ -41,6 +41,9 @@ HOOK: (directory-entries) os ( path -- seq )
: directory-files ( path -- seq )
directory-entries [ name>> ] map ;
: with-directory-entries ( path quot -- )
'[ "" directory-entries @ ] with-directory ; inline
: with-directory-files ( path quot -- )
'[ "" directory-files @ ] with-directory ; inline

View File

@ -0,0 +1,66 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel quotations ;
IN: io.directories.search
HELP: each-file
{ $values
{ "path" "a pathname string" } { "bfs?" "a boolean, breadth-first or depth-first" } { "quot" quotation }
}
{ $description "Performs a directory traversal, breadth-first or depth-first, and calls the quotation on the full pathname of each file." }
{ $examples
{ $unchecked-example "USING: sequences io.directories.search ;"
"\"resource:misc\" t [ . ] each-file"
"! Recursive directory listing prints here"
}
} ;
HELP: recursive-directory
{ $values
{ "path" "a pathname string" } { "bfs?" "a boolean, breadth-first or depth-first" }
{ "paths" "a sequence of pathname strings" }
}
{ $description "Traverses a directory path recursively and returns a sequence of files in a breadth-first or depth-first manner." } ;
HELP: find-file
{ $values
{ "path" "a pathname string" } { "bfs?" "a boolean, breadth-first or depth-first" } { "quot" quotation }
{ "path/f" "a pathname string or f" }
}
{ $description "Finds the first file in the input directory matching the predicate quotation in a breadth-first or depth-first traversal." } ;
HELP: find-in-directories
{ $values
{ "directories" "a sequence of pathnames" } { "bfs?" "a boolean, breadth-first or depth-first" } { "quot" quotation }
{ "path'/f" "a pathname string or f" }
}
{ $description "Finds the first file in the input directories matching the predicate quotation in a breadth-first or depth-first traversal." } ;
HELP: find-all-files
{ $values
{ "path" "a pathname string" } { "bfs?" "a boolean, breadth-first or depth-first" } { "quot" quotation }
{ "paths/f" "a sequence of pathname strings or f" }
}
{ $description "Finds all files in the input directory matching the predicate quotation in a breadth-first or depth-first traversal." } ;
HELP: find-all-in-directories
{ $values
{ "directories" "a sequence of directory paths" } { "bfs?" "a boolean, breadth-first or depth-first" } { "quot" quotation }
{ "paths/f" "a sequence of pathname strings or f" }
}
{ $description "Finds all files in the input directories matching the predicate quotation in a breadth-first or depth-first traversal." } ;
{ find-file find-all-files find-in-directories find-all-in-directories } related-words
ARTICLE: "io.directories.search" "io.directories.search"
"The " { $vocab-link "io.directories.search" } " vocabulary contains words used for recursively iterating over a directory and for finding files in a directory tree." $nl
"Traversing directories:"
{ $subsection recursive-directory }
{ $subsection each-file }
"Finding files:"
{ $subsection find-file }
{ $subsection find-all-files }
{ $subsection find-in-directories }
{ $subsection find-all-in-directories } ;
ABOUT: "io.directories.search"

View File

@ -5,16 +5,16 @@ io.directories io.files io.files.info io.pathnames kernel
sequences system vocabs.loader ;
IN: io.directories.search
TUPLE: directory-iterator path bfs queue ;
<PRIVATE
TUPLE: directory-iterator path bfs queue ;
: qualified-directory ( path -- seq )
dup directory-files [ append-path ] with map ;
: push-directory ( path iter -- )
[ qualified-directory ] dip [
dup queue>> swap bfs>>
[ queue>> ] [ bfs>> ] bi
[ push-front ] [ push-back ] if
] curry each ;
@ -38,22 +38,29 @@ TUPLE: directory-iterator path bfs queue ;
PRIVATE>
: find-file ( path bfs? quot: ( obj -- ? ) -- path/f )
[ <directory-iterator> ] dip
[ keep and ] curry iterate-directory ; inline
: each-file ( path bfs? quot: ( obj -- ? ) -- )
: each-file ( path bfs? quot: ( obj -- ) -- )
[ <directory-iterator> ] dip
[ f ] compose iterate-directory drop ; inline
: find-all-files ( path bfs? quot: ( obj -- ? ) -- paths )
[ <directory-iterator> ] dip
pusher [ [ f ] compose iterate-directory drop ] dip ; inline
: recursive-directory ( path bfs? -- paths )
[ ] accumulator [ each-file ] dip ;
: find-in-directories ( directories bfs? quot -- path' )
'[ _ _ find-file ] attempt-all ; inline
: find-file ( path bfs? quot: ( obj -- ? ) -- path/f )
'[
_ _ _ [ <directory-iterator> ] dip
[ keep and ] curry iterate-directory
] [ drop f ] recover ; inline
: find-all-files ( path bfs? quot: ( obj -- ? ) -- paths/f )
'[
_ _ _ [ <directory-iterator> ] dip
pusher [ [ f ] compose iterate-directory drop ] dip
] [ drop f ] recover ; inline
: find-in-directories ( directories bfs? quot: ( obj -- ? ) -- path'/f )
'[ _ _ find-file ] attempt-all ;
: find-all-in-directories ( directories bfs? quot: ( obj -- ? ) -- paths/f )
'[ _ _ find-all-files ] map concat ;
os windows? [ "io.directories.search.windows" require ] when

View File

@ -5,7 +5,7 @@ io.directories.search ;
IN: io.directories.search.windows
: program-files-directories ( -- array )
program-files program-files-x86 2array ; inline
program-files program-files-x86 2array harvest ; inline
: find-in-program-files ( base-directory bfs? quot -- path )
[

View File

@ -3,7 +3,7 @@
USING: accessors alien.c-types alien.syntax combinators
io.backend io.files io.files.info io.files.unix kernel math system unix
unix.statfs.freebsd unix.statvfs.freebsd unix.getfsstat.freebsd
sequences grouping alien.strings io.encodings.utf8
sequences grouping alien.strings io.encodings.utf8 unix.types
specialized-arrays.direct.uint arrays io.files.info.unix ;
IN: io.files.info.unix.freebsd

View File

@ -5,7 +5,7 @@ io.backend io.encodings.utf8 io.files io.files.info io.streams.string
io.files.unix kernel math.order namespaces sequences sorting
system unix unix.statfs.linux unix.statvfs.linux io.files.links
specialized-arrays.direct.uint arrays io.files.info.unix assocs
io.pathnames ;
io.pathnames unix.types ;
IN: io.files.info.unix.linux
TUPLE: linux-file-system-info < unix-file-system-info

View File

@ -22,11 +22,11 @@ HELP: file-permissions
{ "n" integer } }
{ $description "Returns the Unix file permissions for a given file." } ;
HELP: file-username
HELP: file-user-name
{ $values
{ "path" "a pathname string" }
{ "string" string } }
{ $description "Returns the username for a given file." } ;
{ $description "Returns the user-name for a given file." } ;
HELP: file-user-id
{ $values
@ -110,7 +110,7 @@ HELP: set-file-times
HELP: set-file-user
{ $values
{ "path" "a pathname string" } { "string/id" "a string or a user id" } }
{ $description "Sets a file's user id from the given user id or username." } ;
{ $description "Sets a file's user id from the given user id or user-name." } ;
HELP: set-file-modified-time
{ $values
@ -258,7 +258,7 @@ ARTICLE: "unix-file-timestamps" "Unix file timestamps"
ARTICLE: "unix-file-ids" "Unix file user and group ids"
"Reading file user data:"
{ $subsection file-user-id }
{ $subsection file-username }
{ $subsection file-user-name }
"Setting file user data:"
{ $subsection set-file-user }
"Reading file group data:"

View File

@ -114,30 +114,6 @@ M: file-info file-mode? [ permissions>> ] dip mask? ;
PRIVATE>
: ch>file-type ( ch -- type )
{
{ CHAR: b [ +block-device+ ] }
{ CHAR: c [ +character-device+ ] }
{ CHAR: d [ +directory+ ] }
{ CHAR: l [ +symbolic-link+ ] }
{ CHAR: s [ +socket+ ] }
{ CHAR: p [ +fifo+ ] }
{ CHAR: - [ +regular-file+ ] }
[ drop +unknown+ ]
} case ;
: file-type>ch ( type -- string )
{
{ +block-device+ [ CHAR: b ] }
{ +character-device+ [ CHAR: c ] }
{ +directory+ [ CHAR: d ] }
{ +symbolic-link+ [ CHAR: l ] }
{ +socket+ [ CHAR: s ] }
{ +fifo+ [ CHAR: p ] }
{ +regular-file+ [ CHAR: - ] }
[ drop CHAR: - ]
} case ;
: UID OCT: 0004000 ; inline
: GID OCT: 0002000 ; inline
: STICKY OCT: 0001000 ; inline
@ -243,11 +219,55 @@ M: string set-file-group ( path string -- )
: file-user-id ( path -- uid )
normalize-path file-info uid>> ;
: file-username ( path -- string )
file-user-id username ;
: file-user-name ( path -- string )
file-user-id user-name ;
: file-group-id ( path -- gid )
normalize-path file-info gid>> ;
: file-group-name ( path -- string )
file-group-id group-name ;
: ch>file-type ( ch -- type )
{
{ CHAR: b [ +block-device+ ] }
{ CHAR: c [ +character-device+ ] }
{ CHAR: d [ +directory+ ] }
{ CHAR: l [ +symbolic-link+ ] }
{ CHAR: s [ +socket+ ] }
{ CHAR: p [ +fifo+ ] }
{ CHAR: - [ +regular-file+ ] }
[ drop +unknown+ ]
} case ;
: file-type>ch ( type -- ch )
{
{ +block-device+ [ CHAR: b ] }
{ +character-device+ [ CHAR: c ] }
{ +directory+ [ CHAR: d ] }
{ +symbolic-link+ [ CHAR: l ] }
{ +socket+ [ CHAR: s ] }
{ +fifo+ [ CHAR: p ] }
{ +regular-file+ [ CHAR: - ] }
[ drop CHAR: - ]
} case ;
<PRIVATE
: file-type>executable ( directory-entry -- string )
name>> any-execute? "*" "" ? ;
PRIVATE>
: file-type>trailing ( directory-entry -- string )
dup type>>
{
{ +directory+ [ drop "/" ] }
{ +symbolic-link+ [ drop "@" ] }
{ +fifo+ [ drop "|" ] }
{ +socket+ [ drop "=" ] }
{ +whiteout+ [ drop "%" ] }
{ +unknown+ [ file-type>executable ] }
{ +regular-file+ [ file-type>executable ] }
[ drop file-type>executable ]
} case ;

View File

@ -1,5 +1,5 @@
USING: help.markup help.syntax io io.ports kernel math
io.pathnames io.directories math.parser io.files ;
io.pathnames io.directories math.parser io.files strings ;
IN: io.files.unique
HELP: temporary-path
@ -30,7 +30,7 @@ HELP: make-unique-file ( prefix suffix -- path )
HELP: make-unique-file*
{ $values
{ "prefix" null } { "suffix" null }
{ "prefix" string } { "suffix" string }
{ "path" "a pathname string" }
}
{ $description "Creates a file that is guaranteed not to exist in the directory in the " { $link current-directory } " variable. The file name is composed of a prefix, a number of random digits and letters, and the suffix. Returns the full pathname." } ;
@ -55,11 +55,11 @@ HELP: with-unique-directory ( quot -- )
ARTICLE: "io.files.unique" "Temporary files"
"The " { $vocab-link "io.files.unique" } " vocabulary implements cross-platform temporary file creation in a high-level and secure way." $nl
"Files:"
"Creating temporary files:"
{ $subsection make-unique-file }
{ $subsection make-unique-file* }
{ $subsection with-unique-file }
"Directories:"
"Creating temporary directories:"
{ $subsection make-unique-directory }
{ $subsection with-unique-directory } ;

View File

@ -1,7 +1,8 @@
USING: tools.test io.files io.files.temp io.pathnames
io.directories io.files.info io.files.info.unix continuations
kernel io.files.unix math.bitwise calendar accessors
math.functions math unix.users unix.groups arrays sequences ;
math.functions math unix.users unix.groups arrays sequences
grouping ;
IN: io.files.unix.tests
[ "/usr/libexec/" ] [ "/usr/libexec/awk/" parent-directory ] unit-test
@ -117,12 +118,12 @@ prepare-test-file
[ ] [ test-file f f 2array set-file-times ] unit-test
[ ] [ test-file real-username set-file-user ] unit-test
[ ] [ test-file real-user-name set-file-user ] unit-test
[ ] [ test-file real-user-id set-file-user ] unit-test
[ ] [ test-file real-group-name set-file-group ] unit-test
[ ] [ test-file real-group-id set-file-group ] unit-test
[ t ] [ test-file file-username real-username = ] unit-test
[ t ] [ test-file file-user-name real-user-name = ] unit-test
[ t ] [ test-file file-group-name real-group-name = ] unit-test
[ ]

View File

@ -15,7 +15,7 @@ IN: io.files.windows
CreateFile-flags f CreateFile opened-file
] with-destructors ;
: open-pipe-r/w ( path -- win32-file )
: open-r/w ( path -- win32-file )
{ GENERIC_READ GENERIC_WRITE } flags
OPEN_EXISTING 0 open-file ;

View File

@ -3,11 +3,20 @@ strings byte-arrays continuations destructors quotations ;
IN: io.sockets
ARTICLE: "network-addressing" "Address specifiers"
"The networking words are quite general and work with " { $emphasis "address specifiers" } " rather than concrete concepts such as host names. There are four types of address specifiers:"
"The networking words are quite general and work with " { $emphasis "address specifiers" } " rather than concrete concepts such as host names. There are four types of address specifiers."
$nl
"Unix domain sockets:"
{ $subsection local }
{ $subsection <local> }
"Internet host name/port number pairs; the host name is resolved to an IPv4 or IPv6 address using the operating system's resolver:"
{ $subsection inet }
{ $subsection <inet> }
"IPv4 addresses, with no host name resolution:"
{ $subsection inet4 }
{ $subsection <inet4> }
"IPv6 addresses, with no host name resolution:"
{ $subsection inet6 }
{ $subsection <inet6> }
"While the " { $link inet } " addressing specifier is capable of performing name lookups when passed to " { $link <client> } ", sometimes it is necessary to look up a host name without making a connection:"
{ $subsection resolve-host } ;
@ -73,34 +82,42 @@ HELP: inet
"This address specifier is only supported by " { $link <client> } ", which calls " { $link resolve-host } " to obtain a list of IP addresses associated with the host name, and attempts a connection to each one in turn until one succeeds. Other network words do not accept this address specifier, and " { $link resolve-host } " must be called directly; it is then up to the application to pick the correct address from the (possibly several) addresses associated to the host name."
}
{ $examples
{ $code "\"www.apple.com\" \"http\" <inet>" }
{ $code "\"localhost\" 8080 <inet>" }
{ $code "\"www.apple.com\" 80 <inet>" }
} ;
HELP: <inet>
{ $values { "host" "a host name" } { "port" "a port number" } { "inet" inet } }
{ $description "Creates a new " { $link inet } " address specifier." } ;
HELP: inet4
{ $class-description "IPv4 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv4 address and port number, respectively. New instances are created by calling " { $link <inet4> } "." }
{ $notes
"Most applications do not operate on IPv4 addresses directly, and instead should use " { $link resolve-host } " to look up the address associated to a host name. Also, try to support IPv6 where possible."
}
{ $notes "Most applications do not operate on IPv4 addresses directly, and instead should use the " { $link inet } " address specifier, or call " { $link resolve-host } "." }
{ $examples
{ $code "\"127.0.0.1\" 8080 <inet4>" }
} ;
HELP: <inet4>
{ $values { "host" "an IPv4 address" } { "port" "a port number" } { "inet4" inet4 } }
{ $description "Creates a new " { $link inet4 } " address specifier." } ;
HELP: inet6
{ $class-description "IPv6 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv6 address and port number, respectively. New instances are created by calling " { $link <inet6> } "." }
{ $notes
"Most applications do not operate on IPv6 addresses directly, and instead should use " { $link resolve-host } " to look up the address associated to a host name." }
{ $notes "Most applications do not operate on IPv6 addresses directly, and instead should use the " { $link inet } " address specifier, or call " { $link resolve-host } "." }
{ $examples
{ $code "\"::1\" 8080 <inet6>" }
} ;
HELP: <inet6>
{ $values { "host" "an IPv6 address" } { "port" "a port number" } { "inet6" inet6 } }
{ $description "Creates a new " { $link inet6 } " address specifier." } ;
HELP: <client>
{ $values { "remote" "an address specifier" } { "encoding" "an encding descriptor" } { "stream" "a bidirectional stream" } { "local" "an address specifier" } }
{ $description "Opens a network connection and outputs a bidirectional stream using the given encoding, together with the local address the socket was bound to." }
{ $errors "Throws an error if the connection cannot be established." }
{ $notes "The " { $link with-client } " word is easier to use in most situations." }
{ $examples
{ $code "\"www.apple.com\" \"http\" <inet> utf8 <client>" }
{ $code "\"www.apple.com\" 80 <inet> utf8 <client>" }
} ;
HELP: with-client

View File

@ -33,6 +33,9 @@ concurrency.promises threads io.streams.string ;
[ B{ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 } ]
[ "::1" T{ inet6 } inet-pton ] unit-test
[ B{ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 } ]
[ "::100" T{ inet6 } inet-pton ] unit-test
[ B{ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 } ]
[ "1::2" T{ inet6 } inet-pton ] unit-test
@ -45,6 +48,9 @@ concurrency.promises threads io.streams.string ;
[ "1:2:0:0:0:0:3:4" ]
[ B{ 0 1 0 2 0 0 0 0 0 0 0 0 0 3 0 4 } T{ inet6 } inet-ntop ] unit-test
[ "2001:6f8:37a:5:0:0:0:1" ]
[ "2001:6f8:37a:5::1" T{ inet6 } [ inet-pton ] [ inet-ntop ] bi ] unit-test
[ t ] [ "localhost" 80 <inet> resolve-host length 1 >= ] unit-test
! Smoke-test UDP

View File

@ -109,7 +109,7 @@ M: invalid-inet6 summary drop "Invalid IPv6 address" ;
[ f ] [
":" split [
hex> [ "Component not a number" throw ] unless*
] B{ } map-as
] { } map-as
] if-empty ;
: pad-inet6 ( string1 string2 -- seq )

View File

@ -20,11 +20,11 @@ HELP: <duplex-stream>
HELP: with-stream
{ $values { "stream" duplex-stream } { "quot" quotation } }
{ $description "Calls the quotation in a new dynamic scope, with both " { $link input-stream } " and " { $link output-stream } " rebound to " { $snippet "stream" } ". The stream is closed if the quotation returns or throws an error." } ;
{ $description "Calls the quotation in a new dynamic scope, with both " { $link input-stream } " and " { $link output-stream } " rebound to " { $snippet "stream" } ", which must be a duplex stream. The stream is closed if the quotation returns or throws an error." } ;
HELP: with-stream*
{ $values { "stream" duplex-stream } { "quot" quotation } }
{ $description "Calls the quotation in a new dynamic scope, with both " { $link input-stream } " and " { $link output-stream } " rebound to " { $snippet "stream" } "." }
{ $description "Calls the quotation in a new dynamic scope, with both " { $link input-stream } " and " { $link output-stream } " rebound to " { $snippet "stream" } ", which must be a duplex stream." }
{ $notes "This word does not close the stream. Compare with " { $link with-stream } "." } ;
HELP: <encoder-duplex>

View File

@ -0,0 +1,79 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel math io ;
IN: io.streams.limited
HELP: <limited-stream>
{ $values
{ "stream" "an input stream" } { "limit" integer }
{ "stream'" "an input stream" }
}
{ $description "Constructs a new " { $link limited-stream } " from an existing stream. Upon exhaustion, the stream will throw an error by default." }
{ $examples "Throwing an exception:"
{ $example
"USING: continuations io io.streams.limited io.streams.string"
"kernel prettyprint ;"
"["
" \"123456\" <string-reader> 3 <limited-stream>"
" 100 swap stream-read ."
"] [ ] recover ."
"T{ limit-exceeded }"
}
"Returning " { $link f } " on exhaustion:"
{ $example
"USING: accessors continuations io io.streams.limited"
"io.streams.string kernel prettyprint ;"
"\"123456\" <string-reader> 3 <limited-stream>"
"stream-eofs >>mode"
"100 swap stream-read ."
"\"123\""
}
} ;
HELP: limit
{ $values
{ "stream" "a stream" } { "limit" integer }
{ "stream'" "a stream" }
}
{ $description "Changes a decoder's stream to be a limited stream, or wraps " { $snippet "stream" } " in a " { $link limited-stream } "." } ;
HELP: limited-stream
{ $values
{ "value" "a limited-stream class" }
}
{ $description "Limited streams wrap other streams, changing their behavior to throw an exception or return " { $link f } " upon exhaustion. The default behavior is to throw an exception." } ;
HELP: limit-input
{ $values
{ "limit" integer }
}
{ $description "Wraps the current " { $link input-stream } " in a " { $link limited-stream } "." } ;
HELP: stream-eofs
{ $values
{ "value" "a " { $link limited-stream } " mode singleton" }
}
{ $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will return " { $link f } " upon exhaustion." } ;
HELP: stream-throws
{ $values
{ "value" "a " { $link limited-stream } " mode singleton" }
}
{ $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will throw " { $link limit-exceeded } " upon exhaustion." } ;
{ stream-eofs stream-throws } related-words
ARTICLE: "io.streams.limited" "Limited input streams"
"The " { $vocab-link "io.streams.limited" } " vocabulary wraps a stream to behave as if it had only a limited number of bytes, either throwing an error or returning " { $link f } " upon reaching the end. The default behavior is to throw an error." $nl
"Wrap an existing stream in a limited stream:"
{ $subsection <limited-stream> }
"Wrap a stream in a limited stream:"
{ $subsection limit }
"Wrap the current " { $link input-stream } " in a limited stream:"
{ $subsection limit-input }
"Make a limited stream throw an exception on exhaustion:"
{ $subsection stream-throws }
"Make a limited stream return " { $link f } " on exhaustion:"
{ $subsection stream-eofs } ;
ABOUT: "io.streams.limited"

View File

@ -1,7 +1,7 @@
IN: io.streams.limited.tests
USING: io io.streams.limited io.encodings io.encodings.string
io.encodings.ascii io.encodings.binary io.streams.byte-array
namespaces tools.test strings kernel ;
namespaces tools.test strings kernel io.streams.string accessors ;
IN: io.streams.limited.tests
[ ] [
"hello world\nhow are you today\nthis is a very long line indeed"
@ -38,3 +38,18 @@ namespaces tools.test strings kernel ;
"l" read-until
] with-input-stream
] unit-test
[ CHAR: a ]
[ "a" <string-reader> 1 <limited-stream> stream-read1 ] unit-test
[ "abc" ]
[
"abc" <string-reader> 3 <limited-stream> stream-eofs >>mode
4 swap stream-read
] unit-test
[ f ]
[
"abc" <string-reader> 3 <limited-stream> stream-eofs >>mode
4 over stream-read drop 10 swap stream-read
] unit-test

50
basis/io/streams/limited/limited.factor Normal file → Executable file
View File

@ -1,16 +1,20 @@
! Copyright (C) 2008 Slava Pestov
! Copyright (C) 2008 Slava Pestov.
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math io io.encodings destructors accessors
sequences namespaces byte-vectors ;
sequences namespaces byte-vectors fry combinators ;
IN: io.streams.limited
TUPLE: limited-stream stream count limit ;
TUPLE: limited-stream stream count limit mode ;
SINGLETONS: stream-throws stream-eofs ;
: <limited-stream> ( stream limit -- stream' )
limited-stream new
swap >>limit
swap >>stream
0 >>count ;
0 >>count
stream-throws >>mode ;
GENERIC# limit 1 ( stream limit -- stream' )
@ -22,24 +26,48 @@ M: object limit <limited-stream> ;
ERROR: limit-exceeded ;
: check-limit ( n stream -- )
[ + ] change-count
[ count>> ] [ limit>> ] bi >=
[ limit-exceeded ] when ; inline
ERROR: bad-stream-mode mode ;
<PRIVATE
: adjust-limit ( n stream -- n' stream )
2dup [ + ] change-count
[ count>> ] [ limit>> ] bi >
[
dup mode>> {
{ stream-throws [ limit-exceeded ] }
{ stream-eofs [
dup [ count>> ] [ limit>> ] bi -
'[ _ - ] dip
] }
[ bad-stream-mode ]
} case
] when ; inline
: maybe-read ( n limited-stream quot: ( n stream -- seq/f ) -- seq/f )
[ adjust-limit ] dip
pick 0 <= [ 3drop f ] [ [ stream>> ] dip call ] if ; inline
PRIVATE>
M: limited-stream stream-read1
1 over check-limit stream>> stream-read1 ;
1 swap
[ nip stream-read1 ] maybe-read ;
M: limited-stream stream-read
2dup check-limit stream>> stream-read ;
[ stream-read ] maybe-read ;
M: limited-stream stream-read-partial
2dup check-limit stream>> stream-read-partial ;
[ stream-read-partial ] maybe-read ;
<PRIVATE
: (read-until) ( stream seps buf -- stream seps buf sep/f )
3dup [ [ stream-read1 dup ] dip memq? ] dip
swap [ drop ] [ push (read-until) ] if ;
PRIVATE>
M: limited-stream stream-read-until
swap BV{ } clone (read-until) [ 2nip B{ } like ] dip ;

View File

@ -0,0 +1,28 @@
USING: io help.markup help.syntax quotations ;
IN: io.streams.null
HELP: null-reader
{ $class-description "Singleton class of null reader streams." } ;
HELP: null-writer
{ $class-description "Singleton class of null writer streams." } ;
HELP: with-null-reader
{ $values { "quot" quotation } }
{ $description "Calls the quotation with " { $link input-stream } " rebound to a " { $link null-reader } " which always produces EOF." } ;
HELP: with-null-writer
{ $values { "quot" quotation } }
{ $description "Calls the quotation with " { $link output-stream } " rebound to a " { $link null-writer } " which ignores all output." } ;
ARTICLE: "io.streams.null" "Null streams"
"The " { $vocab-link "io.streams.null" } " vocabulary implements a pair of streams which are useful for testing. The null reader always yields EOF and the null writer ignores all output. Conceptually, they are similar to " { $snippet "/dev/null" } " on a Unix system."
$nl
"Null readers:"
{ $subsection null-reader }
{ $subsection with-null-writer }
"Null writers:"
{ $subsection null-writer }
{ $subsection with-null-reader } ;
ABOUT: "io.streams.null"

View File

View File

@ -1,22 +1,19 @@
! Copyright (C) 2007 Slava Pestov.
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel io io.timeouts io.styles destructors ;
IN: io.streams.null
USING: kernel io io.timeouts io.streams.duplex destructors ;
TUPLE: null-stream ;
SINGLETONS: null-reader null-writer ;
UNION: null-stream null-reader null-writer ;
M: null-stream dispose drop ;
M: null-stream set-timeout 2drop ;
TUPLE: null-reader < null-stream ;
M: null-reader stream-readln drop f ;
M: null-reader stream-read1 drop f ;
M: null-reader stream-read-until 2drop f f ;
M: null-reader stream-read 2drop f ;
TUPLE: null-writer < null-stream ;
M: null-writer stream-write1 2drop ;
M: null-writer stream-write 2drop ;
M: null-writer stream-nl drop ;
@ -28,11 +25,7 @@ M: null-writer make-cell-stream nip ;
M: null-writer stream-write-table 3drop ;
: with-null-reader ( quot -- )
T{ null-reader } swap with-input-stream* ; inline
null-reader swap with-input-stream* ; inline
: with-null-writer ( quot -- )
T{ null-writer } swap with-output-stream* ; inline
: with-null-stream ( quot -- )
T{ duplex-stream f T{ null-reader } T{ null-writer } }
swap with-stream* ; inline
null-writer swap with-output-stream* ; inline

View File

@ -1,7 +1,116 @@
USING: help.markup help.syntax io.streams.plain io strings
hashtables ;
hashtables kernel quotations ;
IN: io.styles
HELP: stream-format
{ $values { "str" string } { "style" "a hashtable" } { "stream" "an output stream" } }
{ $contract "Writes formatted text to the stream. If the stream does buffering, output may not be performed immediately; use " { $link stream-flush } " to force output."
$nl
"The " { $snippet "style" } " hashtable holds character style information. See " { $link "character-styles" } "." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link format } "; see " { $link "stdio" } "." }
$io-error ;
HELP: make-block-stream
{ $values { "style" "a hashtable" } { "stream" "an output stream" } { "stream'" "an output stream" } }
{ $contract "Creates an output stream which wraps " { $snippet "stream" } " and adds " { $snippet "style" } " on calls to " { $link stream-write } " and " { $link stream-format } "."
$nl
"Unlike " { $link make-span-stream } ", this creates a new paragraph block in the output."
$nl
"The " { $snippet "style" } " hashtable holds paragraph style information. See " { $link "paragraph-styles" } "." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link with-nesting } "; see " { $link "stdio" } "." }
$io-error ;
HELP: stream-write-table
{ $values { "table-cells" "a sequence of sequences of table cells" } { "style" "a hashtable" } { "stream" "an output stream" } }
{ $contract "Prints a table of cells produced by " { $link with-cell } "."
$nl
"The " { $snippet "style" } " hashtable holds table style information. See " { $link "table-styles" } "." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link tabular-output } "; see " { $link "stdio" } "." }
$io-error ;
HELP: make-cell-stream
{ $values { "style" hashtable } { "stream" "an output stream" } { "stream'" object } }
{ $contract "Creates an output stream which writes to a table cell object." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link with-cell } "; see " { $link "stdio" } "." }
$io-error ;
HELP: make-span-stream
{ $values { "style" "a hashtable" } { "stream" "an output stream" } { "stream'" "an output stream" } }
{ $contract "Creates an output stream which wraps " { $snippet "stream" } " and adds " { $snippet "style" } " on calls to " { $link stream-write } " and " { $link stream-format } "."
$nl
"Unlike " { $link make-block-stream } ", the stream output is inline, and not nested in a paragraph block." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link with-style } "; see " { $link "stdio" } "." }
$io-error ;
HELP: format
{ $values { "str" string } { "style" "a hashtable" } }
{ $description "Writes formatted text to " { $link output-stream } ". If the stream does buffering, output may not be performed immediately; use " { $link flush } " to force output." }
{ $notes "Details are in the documentation for " { $link stream-format } "." }
$io-error ;
HELP: with-nesting
{ $values { "style" "a hashtable" } { "quot" quotation } }
{ $description "Calls the quotation in a new dynamic scope with " { $link output-stream } " rebound to a nested paragraph stream, with formatting information applied." }
{ $notes "Details are in the documentation for " { $link make-block-stream } "." }
$io-error ;
HELP: tabular-output
{ $values { "style" "a hashtable" } { "quot" quotation } }
{ $description "Calls a quotation which emits a series of equal-length table rows using " { $link with-row } ". The results are laid out in a tabular fashion on " { $link output-stream } "."
$nl
"The " { $snippet "style" } " hashtable holds table style information. See " { $link "table-styles" } "." }
{ $examples
{ $code
"{ { 1 2 } { 3 4 } }"
"H{ { table-gap { 10 10 } } } ["
" [ [ [ [ . ] with-cell ] each ] with-row ] each"
"] tabular-output"
}
}
$io-error ;
HELP: with-row
{ $values { "quot" quotation } }
{ $description "Calls a quotation which emits a series of table cells using " { $link with-cell } ". This word can only be called inside the quotation given to " { $link tabular-output } "." }
$io-error ;
HELP: with-cell
{ $values { "quot" quotation } }
{ $description "Calls a quotation in a new scope with " { $link output-stream } " rebound. Output performed by the quotation is displayed in a table cell. This word can only be called inside the quotation given to " { $link with-row } "." }
$io-error ;
HELP: write-cell
{ $values { "str" string } }
{ $description "Outputs a table cell containing a single string. This word can only be called inside the quotation given to " { $link with-row } "." }
$io-error ;
HELP: with-style
{ $values { "style" "a hashtable" } { "quot" quotation } }
{ $description "Calls the quotation in a new dynamic scope where calls to " { $link write } ", " { $link format } " and other stream output words automatically inherit style settings from " { $snippet "style" } "." }
{ $notes "Details are in the documentation for " { $link make-span-stream } "." }
$io-error ;
ARTICLE: "formatted-stream-protocol" "Formatted stream protocol"
"The " { $vocab-link "io.styles" } " vocabulary defines a protocol for output streams that support rich text."
{ $subsection stream-format }
{ $subsection make-span-stream }
{ $subsection make-block-stream }
{ $subsection make-cell-stream }
{ $subsection stream-write-table } ;
ARTICLE: "formatted-stdout" "Formatted output on the default stream"
"The below words perform formatted output on " { $link output-stream } "."
$nl
"Formatted output:"
{ $subsection format }
{ $subsection with-style }
{ $subsection with-nesting }
"Tabular output:"
{ $subsection tabular-output }
{ $subsection with-row }
{ $subsection with-cell }
{ $subsection write-cell } ;
ARTICLE: "character-styles" "Character styles"
"Character styles for " { $link stream-format } " and " { $link with-style } ":"
{ $subsection foreground }
@ -33,7 +142,7 @@ ARTICLE: "presentations" "Presentations"
"The " { $link presented } " style can be used to emit clickable objects. A utility word for outputting this style:"
{ $subsection write-object } ;
ARTICLE: "styles" "Formatted output"
ARTICLE: "styles" "Styled text"
"The " { $link stream-format } ", " { $link with-style } ", " { $link with-nesting } " and " { $link tabular-output } " words take a hashtable of style attributes. Output stream implementations are free to ignore style information."
$nl
"Style hashtables are keyed by symbols from the " { $vocab-link "io.styles" } " vocabulary."
@ -42,7 +151,13 @@ $nl
{ $subsection "table-styles" }
{ $subsection "presentations" } ;
ABOUT: "styles"
ARTICLE: "io.styles" "Formatted output"
"The " { $vocab-link "io.styles" } " vocabulary defines a protocol for formatted output. This is used by the prettyprinter, help system, and various developer tools. Implementations include " { $vocab-link "ui.gadgets.panes" } ", " { $vocab-link "html.streams" } ", and " { $vocab-link "io.streams.plain" } "."
{ $subsection "formatted-stream-protocol" }
{ $subsection "formatted-stdout" }
{ $subsection "styles" } ;
ABOUT: "io.styles"
HELP: plain
{ $description "A value for the " { $link font-style } " character style denoting plain text." } ;
@ -157,3 +272,12 @@ HELP: <input>
HELP: standard-table-style
{ $values { "style" hashtable } }
{ $description "Outputs a table style where cells are separated by 5-pixel gaps and framed by a light gray border. This style can be passed to " { $link tabular-output } "." } ;
ARTICLE: "io.streams.plain" "Plain writer streams"
"Plain writer streams wrap an underlying stream and provide a default implementation of "
{ $link stream-nl } ", "
{ $link stream-format } ", "
{ $link make-span-stream } ", "
{ $link make-block-stream } " and "
{ $link make-cell-stream } "."
{ $subsection plain-writer } ;

View File

@ -0,0 +1,8 @@
IN: io.styles.tests
USING: io.styles tools.test ;
\ stream-format must-infer
\ stream-write-table must-infer
\ make-span-stream must-infer
\ make-block-stream must-infer
\ make-cell-stream must-infer

View File

@ -1,9 +1,139 @@
! Copyright (C) 2005, 2008 Slava Pestov.
! Copyright (C) 2005, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: hashtables io colors summary make accessors splitting
kernel ;
USING: hashtables io io.streams.plain io.streams.string
colors summary make accessors splitting math.order
kernel namespaces assocs destructors strings sequences ;
IN: io.styles
GENERIC: stream-format ( str style stream -- )
GENERIC: make-span-stream ( style stream -- stream' )
GENERIC: make-block-stream ( style stream -- stream' )
GENERIC: make-cell-stream ( style stream -- stream' )
GENERIC: stream-write-table ( table-cells style stream -- )
: format ( str style -- ) output-stream get stream-format ;
: tabular-output ( style quot -- )
swap [ { } make ] dip output-stream get stream-write-table ; inline
: with-row ( quot -- )
{ } make , ; inline
: with-cell ( quot -- )
H{ } output-stream get make-cell-stream
[ swap with-output-stream ] keep , ; inline
: write-cell ( str -- )
[ write ] with-cell ; inline
: with-style ( style quot -- )
swap dup assoc-empty? [
drop call
] [
output-stream get make-span-stream swap with-output-stream
] if ; inline
: with-nesting ( style quot -- )
[ output-stream get make-block-stream ] dip
with-output-stream ; inline
TUPLE: filter-writer stream ;
M: filter-writer stream-format
stream>> stream-format ;
M: filter-writer stream-write
stream>> stream-write ;
M: filter-writer stream-write1
stream>> stream-write1 ;
M: filter-writer make-span-stream
stream>> make-span-stream ;
M: filter-writer make-block-stream
stream>> make-block-stream ;
M: filter-writer make-cell-stream
stream>> make-cell-stream ;
M: filter-writer stream-flush
stream>> stream-flush ;
M: filter-writer stream-nl
stream>> stream-nl ;
M: filter-writer stream-write-table
stream>> stream-write-table ;
M: filter-writer dispose
stream>> dispose ;
TUPLE: ignore-close-stream < filter-writer ;
M: ignore-close-stream dispose drop ;
C: <ignore-close-stream> ignore-close-stream
TUPLE: style-stream < filter-writer style ;
: do-nested-style ( style style-stream -- style stream )
[ style>> swap assoc-union ] [ stream>> ] bi ; inline
C: <style-stream> style-stream
M: style-stream stream-format
do-nested-style stream-format ;
M: style-stream stream-write
[ style>> ] [ stream>> ] bi stream-format ;
M: style-stream stream-write1
[ 1string ] dip stream-write ;
M: style-stream make-span-stream
do-nested-style make-span-stream ;
M: style-stream make-block-stream
[ do-nested-style make-block-stream ] [ style>> ] bi
<style-stream> ;
M: style-stream make-cell-stream
[ do-nested-style make-cell-stream ] [ style>> ] bi
<style-stream> ;
M: style-stream stream-write-table
[ [ [ stream>> ] map ] map ] [ ] [ stream>> ] tri*
stream-write-table ;
M: plain-writer stream-format
nip stream-write ;
M: plain-writer make-span-stream
swap <style-stream> <ignore-close-stream> ;
M: plain-writer make-block-stream
nip <ignore-close-stream> ;
: format-column ( seq ? -- seq )
[
[ 0 [ length max ] reduce ] keep
swap [ CHAR: \s pad-right ] curry map
] unless ;
: map-last ( seq quot -- seq )
[ dup length <reversed> ] dip [ 0 = ] prepose 2map ; inline
: format-table ( table -- seq )
flip [ format-column ] map-last
flip [ " " join ] map ;
M: plain-writer stream-write-table
[ drop format-table [ print ] each ] with-output-stream* ;
M: plain-writer make-cell-stream 2drop <string-writer> ;
! Font styles
SYMBOL: plain
SYMBOL: bold
SYMBOL: italic

View File

@ -32,3 +32,7 @@ IN: math.bitwise.tests
[ 8 ] [ 0 3 toggle-bit ] unit-test
[ 0 ] [ 8 3 toggle-bit ] unit-test
[ 4 ] [ BIN: 1010101 bit-count ] unit-test
[ 0 ] [ BIN: 0 bit-count ] unit-test
[ 1 ] [ BIN: 1 bit-count ] unit-test

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel math math.functions sequences
sequences.private words namespaces macros hints
combinators fry io.binary ;
combinators fry io.binary combinators.smart ;
IN: math.bitwise
! utilities
@ -76,12 +76,14 @@ DEFER: byte-bit-count
GENERIC: (bit-count) ( x -- n )
M: fixnum (bit-count)
{
[ byte-bit-count ]
[ -8 shift byte-bit-count ]
[ -16 shift byte-bit-count ]
[ -24 shift byte-bit-count ]
} cleave + + + ;
[
{
[ byte-bit-count ]
[ -8 shift byte-bit-count ]
[ -16 shift byte-bit-count ]
[ -24 shift byte-bit-count ]
} cleave
] sum-outputs ;
M: bignum (bit-count)
dup 0 = [ drop 0 ] [

View File

@ -1,4 +1,4 @@
! Copyright (C) 2006, 2008 Slava Pestov.
! Copyright (C) 2006, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel kernel.private math math.private
math.libm math.functions arrays math.functions.private sequences
@ -47,3 +47,9 @@ M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ;
IN: syntax
: C{ \ } [ first2 rect> ] parse-literal ; parsing
USE: prettyprint.custom
M: complex pprint* pprint-object ;
M: complex pprint-delims drop \ C{ \ } ;
M: complex >pprint-sequence >rect 2array ;

View File

@ -1,8 +0,0 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math math.functions arrays prettyprint.custom kernel ;
IN: math.complex.prettyprint
M: complex pprint* pprint-object ;
M: complex pprint-delims drop \ C{ \ } ;
M: complex >pprint-sequence >rect 2array ;

View File

@ -1,12 +1,12 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: combinators io locals kernel math math.functions
math.ranges namespaces random sequences hashtables sets ;
USING: combinators kernel locals math math.functions math.ranges
random sequences sets ;
IN: math.miller-rabin
: >even ( n -- int ) dup even? [ 1- ] unless ; foldable
<PRIVATE
: >odd ( n -- int ) dup even? [ 1+ ] when ; foldable
: next-odd ( m -- n ) dup even? [ 1+ ] [ 2 + ] if ;
TUPLE: positive-even-expected n ;
@ -28,12 +28,16 @@ TUPLE: positive-even-expected n ;
] unless drop
] each prime? ] ;
PRIVATE>
: next-odd ( m -- n ) dup even? [ 1+ ] [ 2 + ] if ;
: miller-rabin* ( n numtrials -- ? )
over {
{ [ dup 1 <= ] [ 3drop f ] }
{ [ dup 2 = ] [ 3drop t ] }
{ [ dup even? ] [ 3drop f ] }
[ [ drop (miller-rabin) ] with-scope ]
[ drop (miller-rabin) ]
} cond ;
: miller-rabin ( n -- ? ) 10 miller-rabin* ;
@ -46,11 +50,15 @@ TUPLE: positive-even-expected n ;
ERROR: no-relative-prime n ;
<PRIVATE
: (find-relative-prime) ( n guess -- p )
over 1 <= [ over no-relative-prime ] when
dup 1 <= [ drop 3 ] when
2dup gcd nip 1 > [ 2 + (find-relative-prime) ] [ nip ] if ;
PRIVATE>
: find-relative-prime* ( n guess -- p )
#! find a prime relative to n with initial guess
>odd (find-relative-prime) ;

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