Merge branch 'master' of git://factorcode.org/git/factor
commit
67081ddff5
|
@ -21,3 +21,4 @@ logs
|
|||
work
|
||||
build-support/wordsize
|
||||
*.bak
|
||||
.#*
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Doug Coleman
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
Slava Pestov
|
||||
Doug Coleman
|
|
@ -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
|
|
@ -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 ;
|
|
@ -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
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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* ;
|
||||
|
|
0
extra/math/primes/list/authors.txt → basis/editors/notepad/authors.txt
Normal file → Executable file
0
extra/math/primes/list/authors.txt → basis/editors/notepad/authors.txt
Normal file → Executable 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
|
||||
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" } "." ;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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:"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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? ;
|
|
@ -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.
|
||||
|
|
|
@ -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 ] } ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 -- )
|
||||
{
|
||||
|
|
|
@ -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>
|
|
@ -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 -- )
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
[
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:"
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 } ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
[ ]
|
||||
|
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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"
|
|
@ -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
|
|
@ -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 } ;
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ] [
|
||||
|
|
|
@ -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 ;
|
|
@ -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 ;
|
|
@ -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
Loading…
Reference in New Issue