Merge commit 'origin/master' into emacs
commit
982e14a7fd
basis
bootstrap/unicode
combinators/smart
compiler/tree/propagation/inlining
io/files
info/unix
math/bitwise
regexp
nfa
parser
soundex
splitting/monotonic
tools
cocoa
files
ui/gadgets/buttons
unicode
breaks
data
unix
statfs
values
xmode/marker
core
extra
benchmark/reverse-complement
geo-ip
parser-combinators/regexp
usa-cities
|
@ -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 ;
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
USING: strings.parser kernel namespaces unicode unicode.data ;
|
||||
IN: bootstrap.unicode
|
||||
|
||||
[ name>char [ "Invalid character" throw ] unless* ]
|
||||
name>char-hook set-global
|
|
@ -0,0 +1 @@
|
|||
Doug Coleman
|
|
@ -0,0 +1,91 @@
|
|||
! 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"
|
||||
}
|
||||
} ;
|
||||
|
||||
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 } ;
|
||||
|
||||
ABOUT: "combinators.smart"
|
|
@ -0,0 +1,21 @@
|
|||
! 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
|
|
@ -0,0 +1,22 @@
|
|||
! 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
|
|
@ -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 ;
|
||||
|
|
|
@ -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:"
|
||||
|
|
|
@ -243,8 +243,8 @@ 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>> ;
|
||||
|
|
|
@ -117,12 +117,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
|
||||
|
||||
[ ]
|
||||
|
|
|
@ -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 ] [
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
USING: accessors arrays assocs grouping kernel regexp.backend
|
||||
locals math namespaces regexp.parser sequences fry quotations
|
||||
math.order math.ranges vectors unicode.categories regexp.utils
|
||||
regexp.transition-tables words sets regexp.classes unicode.case ;
|
||||
regexp.transition-tables words sets regexp.classes unicode.case.private ;
|
||||
! This uses unicode.case.private for ch>upper and ch>lower
|
||||
! but case-insensitive matching should be done by case-folding everything
|
||||
! before processing starts
|
||||
IN: regexp.nfa
|
||||
|
||||
SYMBOL: negation-mode
|
||||
|
@ -160,6 +163,8 @@ M: LETTER-class nfa-node ( node -- )
|
|||
|
||||
M: character-class-range nfa-node ( node -- )
|
||||
case-insensitive option? [
|
||||
! This should be implemented for Unicode by case-folding
|
||||
! the input and all strings in the regexp.
|
||||
dup [ from>> ] [ to>> ] bi
|
||||
2dup [ Letter? ] bi@ and [
|
||||
rot drop
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
USING: accessors arrays assocs combinators io io.streams.string
|
||||
kernel math math.parser namespaces sets
|
||||
quotations sequences splitting vectors math.order
|
||||
unicode.categories strings regexp.backend regexp.utils
|
||||
unicode.case words locals regexp.classes ;
|
||||
strings regexp.backend regexp.utils
|
||||
unicode.case unicode.categories words locals regexp.classes ;
|
||||
IN: regexp.parser
|
||||
|
||||
FROM: math.ranges => [a,b] ;
|
||||
|
@ -261,7 +261,7 @@ ERROR: bad-escaped-literals seq ;
|
|||
parse-til-E
|
||||
drop1
|
||||
[ epsilon ] [
|
||||
[ quot call <constant> ] V{ } map-as
|
||||
quot call [ <constant> ] V{ } map-as
|
||||
first|concatenation
|
||||
] if-empty ; inline
|
||||
|
||||
|
@ -269,10 +269,10 @@ ERROR: bad-escaped-literals seq ;
|
|||
[ ] (parse-escaped-literals) ;
|
||||
|
||||
: lower-case-literals ( -- obj )
|
||||
[ ch>lower ] (parse-escaped-literals) ;
|
||||
[ >lower ] (parse-escaped-literals) ;
|
||||
|
||||
: upper-case-literals ( -- obj )
|
||||
[ ch>upper ] (parse-escaped-literals) ;
|
||||
[ >upper ] (parse-escaped-literals) ;
|
||||
|
||||
: parse-escaped ( -- obj )
|
||||
read1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: sequences grouping assocs kernel ascii unicode.case tr ;
|
||||
USING: sequences grouping assocs kernel ascii ascii tr ;
|
||||
IN: soundex
|
||||
|
||||
TR: soundex-tr
|
||||
|
|
|
@ -15,6 +15,8 @@ USING: tools.test math arrays kernel sequences ;
|
|||
[ { { 1 } } ]
|
||||
[ { 1 } [ = ] slice monotonic-slice [ >array ] map ] unit-test
|
||||
|
||||
[ { 1 } [ = ] slice monotonic-slice ] must-infer
|
||||
|
||||
[ t ]
|
||||
[ { 1 1 1 2 2 3 3 4 } [ = ] slice monotonic-slice [ slice? ] all? ] unit-test
|
||||
|
||||
|
|
|
@ -24,13 +24,15 @@ PRIVATE>
|
|||
<PRIVATE
|
||||
|
||||
: (monotonic-slice) ( seq quot class -- slices )
|
||||
-rot
|
||||
dupd '[
|
||||
[ length ] [ ] [ <circular> 1 over change-circular-start ] tri
|
||||
[ @ not [ , ] [ drop ] if ] 3each
|
||||
] { } make
|
||||
dup empty? [ over length 1- prefix ] when -1 prefix 2 clump
|
||||
[ first2 [ 1+ ] bi@ rot roll boa ] with with map ; inline
|
||||
[
|
||||
dupd '[
|
||||
[ length ] [ ] [ <circular> 1 over change-circular-start ] tri
|
||||
[ @ not [ , ] [ drop ] if ] 3each
|
||||
] { } make
|
||||
dup empty? [ over length 1- prefix ] when -1 prefix 2 clump
|
||||
swap
|
||||
] dip
|
||||
'[ first2 [ 1+ ] bi@ _ _ boa ] map ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
|
@ -39,7 +41,7 @@ PRIVATE>
|
|||
{ 0 [ 2drop ] }
|
||||
{ 1 [ nip [ 0 1 rot ] dip boa 1array ] }
|
||||
[ drop (monotonic-slice) ]
|
||||
} case ;
|
||||
} case ; inline
|
||||
|
||||
TUPLE: downward-slice < slice ;
|
||||
TUPLE: stable-slice < slice ;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: arrays cocoa.messages cocoa.runtime combinators
|
||||
prettyprint ;
|
||||
prettyprint combinators.smart ;
|
||||
IN: tools.cocoa
|
||||
|
||||
: method. ( method -- )
|
||||
{
|
||||
[ method_getName sel_getName ]
|
||||
[ method-return-type ]
|
||||
[ method-arg-types ]
|
||||
[ method_getImplementation ]
|
||||
} cleave 4array . ;
|
||||
[
|
||||
{
|
||||
[ method_getName sel_getName ]
|
||||
[ method-return-type ]
|
||||
[ method-arg-types ]
|
||||
[ method_getImplementation ]
|
||||
} cleave
|
||||
] output>array . ;
|
||||
|
||||
: methods. ( class -- )
|
||||
[ method. ] each-method-in-class ;
|
||||
|
|
|
@ -65,7 +65,7 @@ percent-used percent-free ;
|
|||
[ [ unparse ] map ] bi prefix simple-table. ;
|
||||
|
||||
: file-systems. ( -- )
|
||||
{ device-name free-space used-space total-space percent-used mount-point }
|
||||
{ device-name available-space free-space used-space total-space percent-used mount-point }
|
||||
print-file-systems ;
|
||||
|
||||
{
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
USING: accessors combinators kernel system unicode.case io.files
|
||||
io.files.info io.files.info.unix tools.files generalizations
|
||||
strings arrays sequences math.parser unix.groups unix.users
|
||||
tools.files.private unix.stat math fry macros ;
|
||||
tools.files.private unix.stat math fry macros combinators.smart ;
|
||||
IN: tools.files.unix
|
||||
|
||||
MACRO: cleave>array ( array -- quot )
|
||||
dup length '[ _ cleave _ narray ] ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: unix-execute>string ( str bools -- str' )
|
||||
|
@ -20,18 +17,20 @@ MACRO: cleave>array ( array -- quot )
|
|||
} case ;
|
||||
|
||||
: permissions-string ( permissions -- str )
|
||||
{
|
||||
[ type>> file-type>ch 1string ]
|
||||
[ user-read? read>string ]
|
||||
[ user-write? write>string ]
|
||||
[ [ uid? ] [ user-execute? ] bi 2array "s" unix-execute>string ]
|
||||
[ group-read? read>string ]
|
||||
[ group-write? write>string ]
|
||||
[ [ gid? ] [ group-execute? ] bi 2array "s" unix-execute>string ]
|
||||
[ other-read? read>string ]
|
||||
[ other-write? write>string ]
|
||||
[ [ sticky? ] [ other-execute? ] bi 2array "t" unix-execute>string ]
|
||||
} cleave>array concat ;
|
||||
[
|
||||
{
|
||||
[ type>> file-type>ch 1string ]
|
||||
[ user-read? read>string ]
|
||||
[ user-write? write>string ]
|
||||
[ [ uid? ] [ user-execute? ] bi 2array "s" unix-execute>string ]
|
||||
[ group-read? read>string ]
|
||||
[ group-write? write>string ]
|
||||
[ [ gid? ] [ group-execute? ] bi 2array "s" unix-execute>string ]
|
||||
[ other-read? read>string ]
|
||||
[ other-write? write>string ]
|
||||
[ [ sticky? ] [ other-execute? ] bi 2array "t" unix-execute>string ]
|
||||
} cleave
|
||||
] output>array concat ;
|
||||
|
||||
: mode>symbol ( mode -- ch )
|
||||
S_IFMT bitand
|
||||
|
@ -48,15 +47,16 @@ MACRO: cleave>array ( array -- quot )
|
|||
M: unix (directory.) ( path -- lines )
|
||||
[ [
|
||||
[
|
||||
dup file-info
|
||||
{
|
||||
[ permissions-string ]
|
||||
[ nlink>> number>string 3 CHAR: \s pad-left ]
|
||||
[ uid>> user-name ]
|
||||
[ gid>> group-name ]
|
||||
[ size>> number>string 15 CHAR: \s pad-left ]
|
||||
[ modified>> ls-timestamp ]
|
||||
} cleave>array swap suffix " " join
|
||||
dup file-info [
|
||||
{
|
||||
[ permissions-string ]
|
||||
[ nlink>> number>string 3 CHAR: \s pad-left ]
|
||||
[ uid>> user-name ]
|
||||
[ gid>> group-name ]
|
||||
[ size>> number>string 15 CHAR: \s pad-left ]
|
||||
[ modified>> ls-timestamp ]
|
||||
} cleave
|
||||
] output>array swap suffix " " join
|
||||
] map
|
||||
] with-group-cache ] with-user-cache ;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
IN: tr.tests
|
||||
USING: tr tools.test unicode.case ;
|
||||
USING: tr tools.test ascii ;
|
||||
|
||||
TR: tr-test ch>upper "ABC" "XYZ" ;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: byte-arrays strings sequences sequences.private
|
||||
USING: byte-arrays strings sequences sequences.private ascii
|
||||
fry kernel words parser lexer assocs math math.order summary ;
|
||||
IN: tr
|
||||
|
||||
|
@ -11,8 +11,6 @@ M: bad-tr summary
|
|||
|
||||
<PRIVATE
|
||||
|
||||
: ascii? ( ch -- ? ) 0 127 between? ; inline
|
||||
|
||||
: tr-nth ( n mapping -- ch ) nth-unsafe 127 bitand ; inline
|
||||
|
||||
: check-tr ( from to -- )
|
||||
|
|
|
@ -6,7 +6,7 @@ classes.tuple opengl opengl.gl math.vectors ui.commands ui.gadgets
|
|||
ui.gadgets.borders ui.gadgets.labels ui.gadgets.theme
|
||||
ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures
|
||||
ui.render math.geometry.rect locals alien.c-types
|
||||
specialized-arrays.float fry ;
|
||||
specialized-arrays.float fry combinators.smart ;
|
||||
IN: ui.gadgets.buttons
|
||||
|
||||
TUPLE: button < border pressed? selected? quot ;
|
||||
|
@ -111,12 +111,14 @@ TUPLE: checkmark-paint < caching-pen color last-vertices ;
|
|||
<PRIVATE
|
||||
|
||||
: checkmark-points ( dim -- points )
|
||||
{
|
||||
[ { 0 0 } v* { 0.5 0.5 } v+ ]
|
||||
[ { 1 1 } v* { 0.5 0.5 } v+ ]
|
||||
[ { 1 0 } v* { -0.3 0.5 } v+ ]
|
||||
[ { 0 1 } v* { -0.3 0.5 } v+ ]
|
||||
} cleave 4array ;
|
||||
[
|
||||
{
|
||||
[ { 0 0 } v* { 0.5 0.5 } v+ ]
|
||||
[ { 1 1 } v* { 0.5 0.5 } v+ ]
|
||||
[ { 1 0 } v* { -0.3 0.5 } v+ ]
|
||||
[ { 0 1 } v* { -0.3 0.5 } v+ ]
|
||||
} cleave
|
||||
] output>array ;
|
||||
|
||||
: checkmark-vertices ( dim -- vertices )
|
||||
checkmark-points concat >float-array ;
|
||||
|
|
|
@ -4,7 +4,8 @@ USING: combinators.short-circuit unicode.categories kernel math
|
|||
combinators splitting sequences math.parser io.files io assocs
|
||||
arrays namespaces make math.ranges unicode.normalize.private values
|
||||
io.encodings.ascii unicode.syntax unicode.data compiler.units fry
|
||||
alien.syntax sets accessors interval-maps memoize locals words ;
|
||||
alien.syntax sets accessors interval-maps memoize locals words
|
||||
strings hints ;
|
||||
IN: unicode.breaks
|
||||
|
||||
<PRIVATE
|
||||
|
@ -58,38 +59,31 @@ SYMBOL: table
|
|||
: finish-table ( -- table )
|
||||
table get [ [ 1 = ] map ] map ;
|
||||
|
||||
: set-table ( class1 class2 val -- )
|
||||
: eval-seq ( seq -- seq ) [ dup word? [ execute ] when ] map ;
|
||||
|
||||
: (set-table) ( class1 class2 val -- )
|
||||
-rot table get nth [ swap or ] change-nth ;
|
||||
|
||||
: set-table ( classes1 classes2 val -- )
|
||||
[ [ eval-seq ] bi@ ] dip
|
||||
[ [ (set-table) ] curry with each ] 2curry each ;
|
||||
|
||||
: connect ( class1 class2 -- ) 1 set-table ;
|
||||
: disconnect ( class1 class2 -- ) 0 set-table ;
|
||||
|
||||
: check-before ( class classes value -- )
|
||||
[ set-table ] curry with each ;
|
||||
|
||||
: check-after ( classes class value -- )
|
||||
[ set-table ] 2curry each ;
|
||||
|
||||
: connect-before ( class classes -- )
|
||||
1 check-before ;
|
||||
|
||||
: connect-after ( classes class -- )
|
||||
1 check-after ;
|
||||
|
||||
: break-around ( classes1 classes2 -- )
|
||||
[ [ 2dup disconnect swap disconnect ] with each ] curry each ;
|
||||
[ disconnect ] [ swap disconnect ] 2bi ;
|
||||
|
||||
: make-grapheme-table ( -- )
|
||||
CR LF connect
|
||||
Control CR LF 3array graphemes break-around
|
||||
L L V LV LVT 4array connect-before
|
||||
V V T 2array connect-before
|
||||
LV V T 2array connect-before
|
||||
T T connect
|
||||
LVT T connect
|
||||
graphemes Extend connect-after
|
||||
graphemes SpacingMark connect-after
|
||||
Prepend graphemes connect-before ;
|
||||
{ CR } { LF } connect
|
||||
{ Control CR LF } graphemes disconnect
|
||||
graphemes { Control CR LF } disconnect
|
||||
{ L } { L V LV LVT } connect
|
||||
{ LV V } { V T } connect
|
||||
{ LVT T } { T } connect
|
||||
graphemes { Extend } connect
|
||||
graphemes { SpacingMark } connect
|
||||
{ Prepend } graphemes connect ;
|
||||
|
||||
VALUE: grapheme-table
|
||||
|
||||
|
@ -99,14 +93,11 @@ VALUE: grapheme-table
|
|||
: chars ( i str n -- str[i] str[i+n] )
|
||||
swap [ dupd + ] dip [ ?nth ] curry bi@ ;
|
||||
|
||||
: find-index ( seq quot -- i ) find drop ; inline
|
||||
: find-last-index ( seq quot -- i ) find-last drop ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: first-grapheme ( str -- i )
|
||||
unclip-slice grapheme-class over
|
||||
[ grapheme-class tuck grapheme-break? ] find-index
|
||||
[ grapheme-class tuck grapheme-break? ] find drop
|
||||
nip swap length or 1+ ;
|
||||
|
||||
<PRIVATE
|
||||
|
@ -125,7 +116,7 @@ PRIVATE>
|
|||
|
||||
: last-grapheme ( str -- i )
|
||||
unclip-last-slice grapheme-class swap
|
||||
[ grapheme-class dup rot grapheme-break? ] find-last-index ?1+ nip ;
|
||||
[ grapheme-class dup rot grapheme-break? ] find-last drop ?1+ nip ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
|
@ -156,27 +147,23 @@ wMidNum wMidNumLet wNumeric wExtendNumLet words ;
|
|||
word-break-table interval-at
|
||||
word-break-classes at [ wOther ] unless* ;
|
||||
|
||||
: e ( seq -- seq ) [ execute ] map ;
|
||||
|
||||
SYMBOL: check-letter-before
|
||||
SYMBOL: check-letter-after
|
||||
SYMBOL: check-number-before
|
||||
SYMBOL: check-number-after
|
||||
|
||||
: make-word-table ( -- )
|
||||
wCR wLF connect
|
||||
{ wNewline wCR wLF } e words break-around
|
||||
wALetter dup connect
|
||||
wALetter { wMidLetter wMidNumLet } e check-letter-after check-before
|
||||
{ wMidLetter wMidNumLet } e wALetter check-letter-before check-after
|
||||
wNumeric dup connect
|
||||
wALetter wNumeric connect
|
||||
wNumeric wALetter connect
|
||||
wNumeric { wMidNum wMidNumLet } e check-number-after check-before
|
||||
{ wMidNum wMidNumLet } e wNumeric check-number-before check-after
|
||||
wKatakana dup connect
|
||||
{ wALetter wNumeric wKatakana wExtendNumLet } e wExtendNumLet
|
||||
[ connect-after ] [ swap connect-before ] 2bi ;
|
||||
{ wCR } { wLF } connect
|
||||
{ wNewline wCR wLF } words disconnect
|
||||
words { wNewline wCR wLF } disconnect
|
||||
{ wALetter } { wMidLetter wMidNumLet } check-letter-after set-table
|
||||
{ wMidLetter wMidNumLet } { wALetter } check-letter-before set-table
|
||||
{ wNumeric wALetter } { wNumeric wALetter } connect
|
||||
{ wNumeric } { wMidNum wMidNumLet } check-number-after set-table
|
||||
{ wMidNum wMidNumLet } { wNumeric } check-number-before set-table
|
||||
{ wKatakana } { wKatakana } connect
|
||||
{ wALetter wNumeric wKatakana wExtendNumLet } { wExtendNumLet }
|
||||
[ connect ] [ swap connect ] 2bi ;
|
||||
|
||||
VALUE: word-table
|
||||
|
||||
|
@ -192,48 +179,58 @@ to: word-table
|
|||
: word-table-nth ( class1 class2 -- ? )
|
||||
word-table nth nth ;
|
||||
|
||||
: property-not= ( i str property -- ? )
|
||||
pick [
|
||||
[ ?nth ] dip swap
|
||||
[ word-break-prop = not ] [ drop f ] if*
|
||||
] [ 3drop t ] if ;
|
||||
:: property-not= ( str i property -- ? )
|
||||
i [
|
||||
i str ?nth [ word-break-prop property = not ]
|
||||
[ f ] if*
|
||||
] [ t ] if ;
|
||||
|
||||
: format/extended? ( ch -- ? )
|
||||
word-break-prop { 4 5 } member? ;
|
||||
|
||||
:: walk-up ( str i -- j )
|
||||
i 1 + str [ format/extended? not ] find-from drop
|
||||
1+ str [ format/extended? not ] find-from drop ; ! possible bounds error?
|
||||
: (walk-up) ( str i -- j )
|
||||
swap [ format/extended? not ] find-from drop ;
|
||||
|
||||
:: walk-down ( str i -- j )
|
||||
i str [ format/extended? not ] find-last-from drop
|
||||
1- str [ format/extended? not ] find-last-from drop ; ! possible bounds error?
|
||||
: walk-up ( str i -- j )
|
||||
dupd 1+ (walk-up) [ 1+ (walk-up) ] [ drop f ] if* ;
|
||||
|
||||
:: word-break? ( table-entry i str -- ? )
|
||||
table-entry {
|
||||
{ t [ f ] }
|
||||
{ f [ t ] }
|
||||
: (walk-down) ( str i -- j )
|
||||
swap [ format/extended? not ] find-last-from drop ;
|
||||
|
||||
: walk-down ( str i -- j )
|
||||
dupd (walk-down) [ 1- (walk-down) ] [ drop f ] if* ;
|
||||
|
||||
: word-break? ( table-entry i str -- ? )
|
||||
spin {
|
||||
{ t [ 2drop f ] }
|
||||
{ f [ 2drop t ] }
|
||||
{ check-letter-after
|
||||
[ str i walk-up str wALetter property-not= ] }
|
||||
[ dupd walk-up wALetter property-not= ] }
|
||||
{ check-letter-before
|
||||
[ str i walk-down str wALetter property-not= ] }
|
||||
[ dupd walk-down wALetter property-not= ] }
|
||||
{ check-number-after
|
||||
[ str i walk-up str wNumeric property-not= ] }
|
||||
[ dupd walk-up wNumeric property-not= ] }
|
||||
{ check-number-before
|
||||
[ str i walk-down str wNumeric property-not= ] }
|
||||
} case ;
|
||||
[ dupd walk-down wNumeric property-not= ] }
|
||||
} case ; inline
|
||||
|
||||
:: word-break-next ( old-class new-char i str -- next-class ? )
|
||||
new-char word-break-prop dup { 4 5 } member?
|
||||
[ drop old-class dup { 1 2 3 } member? ]
|
||||
[ old-class over word-table-nth i str word-break? ] if ;
|
||||
new-char dup format/extended?
|
||||
[ drop old-class dup { 1 2 3 } member? ] [
|
||||
word-break-prop old-class over word-table-nth
|
||||
i str word-break?
|
||||
] if ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
:: first-word ( str -- i )
|
||||
str unclip-slice word-break-prop over <enum>
|
||||
[ swap str word-break-next ] assoc-find 2drop
|
||||
nip swap length or 1+ ;
|
||||
: first-word ( str -- i )
|
||||
[ unclip-slice word-break-prop over <enum> ] keep
|
||||
'[ swap _ word-break-next ] assoc-find 2drop
|
||||
nip swap length or 1+ ; inline
|
||||
|
||||
HINTS: first-word string ;
|
||||
|
||||
: >words ( str -- words )
|
||||
[ first-word ] >pieces ;
|
||||
|
||||
HINTS: >words string ;
|
||||
|
|
|
@ -9,10 +9,6 @@ ARTICLE: "unicode.case" "Case mapping"
|
|||
{ $subsection >lower }
|
||||
{ $subsection >title }
|
||||
{ $subsection >case-fold }
|
||||
"There are analogous routines which operate on individual code points, but these should " { $emphasis "not be used" } " in general as they have slightly different behavior. In some cases, for example, they do not perform the case operation, as a single code point must expand to more than one."
|
||||
{ $subsection ch>upper }
|
||||
{ $subsection ch>lower }
|
||||
{ $subsection ch>title }
|
||||
"To test if a string is in a given case:"
|
||||
{ $subsection upper? }
|
||||
{ $subsection lower? }
|
||||
|
@ -53,18 +49,3 @@ HELP: title?
|
|||
HELP: case-fold?
|
||||
{ $values { "string" string } { "?" "a boolean" } }
|
||||
{ $description "Tests if a string is in case-folded form." } ;
|
||||
|
||||
HELP: ch>lower
|
||||
{ $values { "ch" "a code point" } { "lower" "a code point" } }
|
||||
{ $description "Converts a code point to lower case." }
|
||||
{ $warning "Don't use this unless you know what you're doing! " { $code ">lower" } " is not the same as " { $code "[ ch>lower ] map" } "." } ;
|
||||
|
||||
HELP: ch>upper
|
||||
{ $values { "ch" "a code point" } { "upper" "a code point" } }
|
||||
{ $description "Converts a code point to upper case." }
|
||||
{ $warning "Don't use this unless you know what you're doing! " { $code ">upper" } " is not the same as " { $code "[ ch>upper ] map" } "." } ;
|
||||
|
||||
HELP: ch>title
|
||||
{ $values { "ch" "a code point" } { "title" "a code point" } }
|
||||
{ $description "Converts a code point to title case." }
|
||||
{ $warning "Don't use this unless you know what you're doing! " { $code ">title" } " is not the same as " { $code "[ ch>title ] map" } "." } ;
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
! Copyright (C) 2008 Daniel Ehrenberg.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: unicode.data sequences sequences.next namespaces make
|
||||
unicode.normalize math unicode.categories combinators unicode.syntax
|
||||
assocs strings splitting kernel accessors unicode.breaks fry ;
|
||||
USING: unicode.data sequences sequences.next namespaces
|
||||
sbufs make unicode.syntax unicode.normalize math hints
|
||||
unicode.categories combinators unicode.syntax assocs
|
||||
strings splitting kernel accessors unicode.breaks fry locals ;
|
||||
QUALIFIED: ascii
|
||||
IN: unicode.case
|
||||
|
||||
<PRIVATE
|
||||
: at-default ( key assoc -- value/key ) [ at ] [ drop ] 2bi or ;
|
||||
PRIVATE>
|
||||
: at-default ( key assoc -- value/key ) [ at ] [ drop ] 2bi or ; inline
|
||||
|
||||
: ch>lower ( ch -- lower ) simple-lower at-default ;
|
||||
: ch>upper ( ch -- upper ) simple-upper at-default ;
|
||||
: ch>title ( ch -- title ) simple-title at-default ;
|
||||
: ch>lower ( ch -- lower ) simple-lower at-default ; inline
|
||||
: ch>upper ( ch -- upper ) simple-upper at-default ; inline
|
||||
: ch>title ( ch -- title ) simple-title at-default ; inline
|
||||
PRIVATE>
|
||||
|
||||
SYMBOL: locale ! Just casing locale, or overall?
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: split-subseq ( string sep -- strings )
|
||||
[ dup ] swap '[ _ split1 swap ] [ ] produce nip ;
|
||||
[ dup ] swap '[ _ split1-slice swap ] [ ] produce nip ;
|
||||
|
||||
: replace ( old new str -- newstr )
|
||||
[ split-subseq ] dip join ;
|
||||
[ split-subseq ] dip join ; inline
|
||||
|
||||
: i-dot? ( -- ? )
|
||||
locale get { "tr" "az" } member? ;
|
||||
|
@ -44,24 +46,24 @@ SYMBOL: locale ! Just casing locale, or overall?
|
|||
[ [ "" ] [
|
||||
dup first mark-above?
|
||||
[ CHAR: combining-dot-above prefix ] when
|
||||
] if-empty ] with-rest ;
|
||||
] if-empty ] with-rest ; inline
|
||||
|
||||
: lithuanian>lower ( string -- lower )
|
||||
"i" split add-dots "i" join
|
||||
"j" split add-dots "i" join ;
|
||||
"j" split add-dots "i" join ; inline
|
||||
|
||||
: turk>upper ( string -- upper-i )
|
||||
"i" "I\u000307" replace ;
|
||||
"i" "I\u000307" replace ; inline
|
||||
|
||||
: turk>lower ( string -- lower-i )
|
||||
"I\u000307" "i" replace
|
||||
"I" "\u000131" replace ;
|
||||
"I" "\u000131" replace ; inline
|
||||
|
||||
: fix-sigma-end ( string -- string )
|
||||
[ "" ] [
|
||||
dup peek CHAR: greek-small-letter-sigma =
|
||||
[ 1 head* CHAR: greek-small-letter-final-sigma suffix ] when
|
||||
] if-empty ;
|
||||
] if-empty ; inline
|
||||
|
||||
: sigma-map ( string -- string )
|
||||
{ CHAR: greek-capital-letter-sigma } split [ [
|
||||
|
@ -70,19 +72,20 @@ SYMBOL: locale ! Just casing locale, or overall?
|
|||
CHAR: greek-small-letter-final-sigma
|
||||
CHAR: greek-small-letter-sigma ? prefix
|
||||
] if-empty
|
||||
] map ] with-rest concat fix-sigma-end ;
|
||||
] map ] with-rest concat fix-sigma-end ; inline
|
||||
|
||||
: final-sigma ( string -- string )
|
||||
CHAR: greek-capital-letter-sigma
|
||||
over member? [ sigma-map ] when ;
|
||||
over member? [ sigma-map ] when
|
||||
"" like ; inline
|
||||
|
||||
: map-case ( string string-quot char-quot -- case )
|
||||
[
|
||||
[
|
||||
[ dup special-casing at ] 2dip
|
||||
[ [ % ] compose ] [ [ , ] compose ] bi* ?if
|
||||
] 2curry each
|
||||
] "" make ; inline
|
||||
:: map-case ( string string-quot char-quot -- case )
|
||||
string length <sbuf> :> out
|
||||
string [
|
||||
dup special-casing at
|
||||
[ string-quot call out push-all ]
|
||||
[ char-quot call out push ] ?if
|
||||
] each out "" like ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
|
@ -90,24 +93,30 @@ PRIVATE>
|
|||
i-dot? [ turk>lower ] when final-sigma
|
||||
[ lower>> ] [ ch>lower ] map-case ;
|
||||
|
||||
HINTS: >lower string ;
|
||||
|
||||
: >upper ( string -- upper )
|
||||
i-dot? [ turk>upper ] when
|
||||
[ upper>> ] [ ch>upper ] map-case ;
|
||||
|
||||
HINTS: >upper string ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: (>title) ( string -- title )
|
||||
i-dot? [ turk>upper ] when
|
||||
[ title>> ] [ ch>title ] map-case ;
|
||||
[ title>> ] [ ch>title ] map-case ; inline
|
||||
|
||||
: title-word ( string -- title )
|
||||
unclip 1string [ >lower ] [ (>title) ] bi* prepend ;
|
||||
unclip 1string [ >lower ] [ (>title) ] bi* prepend ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: >title ( string -- title )
|
||||
final-sigma >words [ title-word ] map concat ;
|
||||
|
||||
HINTS: >title string ;
|
||||
|
||||
: >case-fold ( string -- fold )
|
||||
>upper >lower ;
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ USING: combinators.short-circuit assocs math kernel sequences
|
|||
io.files hashtables quotations splitting grouping arrays io
|
||||
math.parser hash2 math.order byte-arrays words namespaces words
|
||||
compiler.units parser io.encodings.ascii values interval-maps
|
||||
ascii sets combinators locals math.ranges sorting make io.encodings.utf8 ;
|
||||
ascii sets combinators locals math.ranges sorting make
|
||||
strings.parser io.encodings.utf8 ;
|
||||
IN: unicode.data
|
||||
|
||||
VALUE: simple-lower
|
||||
|
@ -23,7 +24,7 @@ VALUE: properties
|
|||
: combine-chars ( a b -- char/f ) combine-map hash2 ;
|
||||
: compatibility-entry ( char -- seq ) compatibility-map at ;
|
||||
: combining-class ( char -- n ) class-map at ;
|
||||
: non-starter? ( char -- ? ) class-map key? ;
|
||||
: non-starter? ( char -- ? ) combining-class { 0 f } member? not ;
|
||||
: name>char ( name -- char ) name-map at ;
|
||||
: char>name ( char -- name ) name-map value-at ;
|
||||
: property? ( char property -- ? ) properties at interval-key? ;
|
||||
|
@ -128,12 +129,9 @@ VALUE: properties
|
|||
cat categories index char table ?set-nth
|
||||
] assoc-each table fill-ranges ] ;
|
||||
|
||||
: ascii-lower ( string -- lower )
|
||||
[ dup CHAR: A CHAR: Z between? [ HEX: 20 + ] when ] map ;
|
||||
|
||||
: process-names ( data -- names-hash )
|
||||
1 swap (process-data) [
|
||||
ascii-lower { { CHAR: \s CHAR: - } } substitute swap
|
||||
>lower { { CHAR: \s CHAR: - } } substitute swap
|
||||
] H{ } assoc-map-as ;
|
||||
|
||||
: multihex ( hexstring -- string )
|
||||
|
@ -183,6 +181,13 @@ load-data {
|
|||
[ process-category to: category-map ]
|
||||
} cleave
|
||||
|
||||
: postprocess-class ( -- )
|
||||
combine-map [ [ second ] map ] map concat
|
||||
[ combining-class not ] filter
|
||||
[ 0 swap class-map set-at ] each ;
|
||||
|
||||
postprocess-class
|
||||
|
||||
load-special-casing to: special-casing
|
||||
|
||||
load-properties to: properties
|
||||
|
@ -214,3 +219,6 @@ SYMBOL: interned
|
|||
|
||||
: load-script ( filename -- table )
|
||||
ascii <file-reader> parse-script process-script ;
|
||||
|
||||
[ name>char [ "Invalid character" throw ] unless* ]
|
||||
name>char-hook set-global
|
||||
|
|
|
@ -3,6 +3,8 @@ unicode.data io.encodings.utf8 io.files splitting math.parser
|
|||
locals math quotations assocs combinators unicode.normalize.private ;
|
||||
IN: unicode.normalize.tests
|
||||
|
||||
{ nfc nfkc nfd nfkd } [ must-infer ] each
|
||||
|
||||
[ "ab\u000323\u000302cd" ] [ "ab\u000302" "\u000323cd" string-append ] unit-test
|
||||
|
||||
[ "ab\u00064b\u000347\u00034e\u00034d\u000346" ] [ "ab\u000346\u000347\u00064b\u00034e\u00034d" dup reorder ] unit-test
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
! Copyright (C) 2008 Daniel Ehrenberg.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: sequences namespaces make unicode.data kernel math arrays
|
||||
locals sorting.insertion accessors assocs math.order ;
|
||||
USING: ascii sequences namespaces make unicode.data kernel math arrays
|
||||
locals sorting.insertion accessors assocs math.order combinators
|
||||
unicode.syntax strings sbufs hints combinators.short-circuit vectors ;
|
||||
IN: unicode.normalize
|
||||
|
||||
<PRIVATE
|
||||
|
@ -18,16 +19,16 @@ CONSTANT: medial-count 21
|
|||
CONSTANT: final-count 28
|
||||
|
||||
: ?between? ( n/f from to -- ? )
|
||||
pick [ between? ] [ 3drop f ] if ;
|
||||
pick [ between? ] [ 3drop f ] if ; inline
|
||||
|
||||
: hangul? ( ch -- ? ) hangul-base hangul-end ?between? ;
|
||||
: jamo? ( ch -- ? ) HEX: 1100 HEX: 11FF ?between? ;
|
||||
: hangul? ( ch -- ? ) hangul-base hangul-end ?between? ; inline
|
||||
: jamo? ( ch -- ? ) HEX: 1100 HEX: 11FF ?between? ; inline
|
||||
|
||||
! These numbers come from UAX 29
|
||||
: initial? ( ch -- ? )
|
||||
dup HEX: 1100 HEX: 1159 ?between? [ ] [ HEX: 115F = ] ?if ;
|
||||
: medial? ( ch -- ? ) HEX: 1160 HEX: 11A2 ?between? ;
|
||||
: final? ( ch -- ? ) HEX: 11A8 HEX: 11F9 ?between? ;
|
||||
dup HEX: 1100 HEX: 1159 ?between? [ ] [ HEX: 115F = ] ?if ; inline
|
||||
: medial? ( ch -- ? ) HEX: 1160 HEX: 11A2 ?between? ; inline
|
||||
: final? ( ch -- ? ) HEX: 11A8 HEX: 11F9 ?between? ; inline
|
||||
|
||||
: hangul>jamo ( hangul -- jamo-string )
|
||||
hangul-base - final-count /mod final-base +
|
||||
|
@ -47,16 +48,16 @@ CONSTANT: final-count 28
|
|||
|
||||
: reorder-slice ( string start -- slice done? )
|
||||
2dup swap [ non-starter? not ] find-from drop
|
||||
[ [ over length ] unless* rot <slice> ] keep not ;
|
||||
[ [ over length ] unless* rot <slice> ] keep not ; inline
|
||||
|
||||
: reorder-next ( string i -- new-i done? )
|
||||
over [ non-starter? ] find-from drop [
|
||||
reorder-slice
|
||||
[ dup [ combining-class ] insertion-sort to>> ] dip
|
||||
] [ length t ] if* ;
|
||||
] [ length t ] if* ; inline
|
||||
|
||||
: reorder-loop ( string start -- )
|
||||
dupd reorder-next [ 2drop ] [ reorder-loop ] if ;
|
||||
dupd reorder-next [ 2drop ] [ reorder-loop ] if ; inline recursive
|
||||
|
||||
: reorder ( string -- )
|
||||
0 reorder-loop ;
|
||||
|
@ -65,108 +66,131 @@ CONSTANT: final-count 28
|
|||
over [ non-starter? not ] find-last-from drop ?1+ reorder-next 2drop ;
|
||||
|
||||
:: decompose ( string quot -- decomposed )
|
||||
! When there are 8 and 32-bit strings, this'll be
|
||||
! equivalent to clone on 8 and the contents of the last
|
||||
! main quotation on 32.
|
||||
string [ 127 < ] all? [ string ] [
|
||||
[
|
||||
string [
|
||||
dup hangul? [ hangul>jamo % ]
|
||||
[ dup quot call [ % ] [ , ] ?if ] if
|
||||
] each
|
||||
] "" make
|
||||
dup reorder
|
||||
] if ; inline
|
||||
string length <sbuf> :> out
|
||||
string [
|
||||
>fixnum dup ascii? [ out push ] [
|
||||
dup hangul? [ hangul>jamo out push-all ]
|
||||
[ dup quot call [ out push-all ] [ out push ] ?if ] if
|
||||
] if
|
||||
] each
|
||||
out "" like dup reorder ; inline
|
||||
|
||||
: with-string ( str quot -- str )
|
||||
over aux>> [ call ] [ drop ] if ; inline
|
||||
|
||||
: (nfd) ( string -- nfd )
|
||||
[ canonical-entry ] decompose ;
|
||||
|
||||
HINTS: (nfd) string ;
|
||||
|
||||
: (nfkd) ( string -- nfkd )
|
||||
[ compatibility-entry ] decompose ;
|
||||
|
||||
HINTS: (nfkd) string ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: nfd ( string -- nfd )
|
||||
[ canonical-entry ] decompose ;
|
||||
[ (nfd) ] with-string ;
|
||||
|
||||
: nfkd ( string -- nfkd )
|
||||
[ compatibility-entry ] decompose ;
|
||||
[ (nfkd) ] with-string ;
|
||||
|
||||
: string-append ( s1 s2 -- string )
|
||||
[ append ] keep
|
||||
0 over ?nth non-starter?
|
||||
[ length dupd reorder-back ] [ drop ] if ;
|
||||
|
||||
HINTS: string-append string string ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
! Normalization -- Composition
|
||||
SYMBOL: main-str
|
||||
SYMBOL: ind
|
||||
SYMBOL: after
|
||||
SYMBOL: char
|
||||
|
||||
: get-str ( i -- ch ) ind get + main-str get ?nth ;
|
||||
: current ( -- ch ) 0 get-str ;
|
||||
: to ( -- ) ind inc ;
|
||||
: initial-medial? ( str i -- ? )
|
||||
{ [ swap nth initial? ] [ 1+ swap ?nth medial? ] } 2&& ;
|
||||
|
||||
: initial-medial? ( -- ? )
|
||||
current initial? [ 1 get-str medial? ] [ f ] if ;
|
||||
: --final? ( str i -- ? )
|
||||
2 + swap ?nth final? ;
|
||||
|
||||
: --final? ( -- ? )
|
||||
2 get-str final? ;
|
||||
: imf, ( str i -- str i )
|
||||
[ tail-slice first3 jamo>hangul , ]
|
||||
[ 3 + ] 2bi ;
|
||||
|
||||
: imf, ( -- )
|
||||
current to current to current jamo>hangul , ;
|
||||
: im, ( str i -- str i )
|
||||
[ tail-slice first2 final-base jamo>hangul , ]
|
||||
[ 2 + ] 2bi ;
|
||||
|
||||
: im, ( -- )
|
||||
current to current final-base jamo>hangul , ;
|
||||
: compose-jamo ( str i -- str i )
|
||||
2dup initial-medial? [
|
||||
2dup --final? [ imf, ] [ im, ] if
|
||||
] [ 2dup swap nth , 1+ ] if ;
|
||||
|
||||
: compose-jamo ( -- )
|
||||
initial-medial? [
|
||||
--final? [ imf, ] [ im, ] if
|
||||
] [ current , ] if to ;
|
||||
: pass-combining ( str -- str i )
|
||||
dup [ non-starter? not ] find drop
|
||||
[ dup length ] unless*
|
||||
2dup head-slice % ;
|
||||
|
||||
: pass-combining ( -- )
|
||||
current non-starter? [ current , to pass-combining ] when ;
|
||||
TUPLE: compose-state i str char after last-class ;
|
||||
|
||||
:: try-compose ( last-class new-char current-class -- new-class )
|
||||
last-class current-class = [ new-char after get push last-class ] [
|
||||
char get new-char combine-chars
|
||||
[ char set last-class ]
|
||||
[ new-char after get push current-class ] if*
|
||||
] if ;
|
||||
: get-str ( state i -- ch )
|
||||
swap [ i>> + ] [ str>> ] bi ?nth ; inline
|
||||
: current ( state -- ch ) 0 get-str ; inline
|
||||
: to ( state -- state ) [ 1+ ] change-i ; inline
|
||||
: push-after ( ch state -- state ) [ ?push ] change-after ; inline
|
||||
|
||||
:: try-compose ( state new-char current-class -- state )
|
||||
state last-class>> current-class =
|
||||
[ new-char state push-after ] [
|
||||
state char>> new-char combine-chars
|
||||
[ state swap >>char ] [
|
||||
new-char state push-after
|
||||
current-class >>last-class
|
||||
] if*
|
||||
] if ; inline
|
||||
|
||||
DEFER: compose-iter
|
||||
|
||||
: try-noncombining ( char -- )
|
||||
char get swap combine-chars
|
||||
[ char set to f compose-iter ] when* ;
|
||||
: try-noncombining ( char state -- state )
|
||||
tuck char>> swap combine-chars
|
||||
[ >>char to f >>last-class compose-iter ] when* ; inline
|
||||
|
||||
: compose-iter ( last-class -- )
|
||||
current [
|
||||
dup combining-class
|
||||
[ try-compose to compose-iter ]
|
||||
[ swap [ drop ] [ try-noncombining ] if ] if*
|
||||
] [ drop ] if* ;
|
||||
: compose-iter ( state -- state )
|
||||
dup current [
|
||||
dup combining-class {
|
||||
{ f [ drop ] }
|
||||
{ 0 [
|
||||
over last-class>>
|
||||
[ drop ] [ swap try-noncombining ] if ] }
|
||||
[ try-compose to compose-iter ]
|
||||
} case
|
||||
] when* ; inline recursive
|
||||
|
||||
: ?new-after ( -- )
|
||||
after [ dup empty? [ drop SBUF" " clone ] unless ] change ;
|
||||
: compose-combining ( ch str i -- str i )
|
||||
compose-state new
|
||||
swap >>i
|
||||
swap >>str
|
||||
swap >>char
|
||||
compose-iter
|
||||
{ [ char>> , ] [ after>> % ] [ str>> ] [ i>> ] } cleave ; inline
|
||||
|
||||
: (compose) ( -- )
|
||||
current [
|
||||
dup jamo? [ drop compose-jamo ] [
|
||||
char set to ?new-after
|
||||
f compose-iter
|
||||
char get , after get %
|
||||
:: (compose) ( str i -- )
|
||||
i str ?nth [
|
||||
dup jamo? [ drop str i compose-jamo ] [
|
||||
i 1+ str ?nth combining-class
|
||||
[ str i 1+ compose-combining ] [ , str i 1+ ] if
|
||||
] if (compose)
|
||||
] when* ;
|
||||
] when* ; inline recursive
|
||||
|
||||
: combine ( str -- comp )
|
||||
[
|
||||
main-str set
|
||||
0 ind set
|
||||
SBUF" " clone after set
|
||||
pass-combining (compose)
|
||||
] "" make ;
|
||||
[ pass-combining (compose) ] "" make ;
|
||||
|
||||
HINTS: combine string ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: nfc ( string -- nfc )
|
||||
nfd combine ;
|
||||
[ (nfd) combine ] with-string ;
|
||||
|
||||
: nfkc ( string -- nfkc )
|
||||
nfkd combine ;
|
||||
[ (nfkd) combine ] with-string ;
|
||||
|
|
|
@ -24,8 +24,8 @@ HELP: group-cache
|
|||
HELP: group-id
|
||||
{ $values
|
||||
{ "string" string }
|
||||
{ "id" integer } }
|
||||
{ $description "Returns the group id given a group name." } ;
|
||||
{ "id/f" "an integer or f" } }
|
||||
{ $description "Returns the group id given a group name. Returns " { $link f } " if the group does not exist." } ;
|
||||
|
||||
HELP: group-name
|
||||
{ $values
|
||||
|
@ -36,7 +36,7 @@ HELP: group-name
|
|||
HELP: group-struct
|
||||
{ $values
|
||||
{ "obj" object }
|
||||
{ "group" "a group struct" } }
|
||||
{ "group/f" "a group struct or f" } }
|
||||
{ $description "Returns an alien group struct to be turned into a group tuple by calling subsequent words." } ;
|
||||
|
||||
HELP: real-group-id
|
||||
|
|
|
@ -27,3 +27,5 @@ IN: unix.groups.tests
|
|||
[ ] [ real-group-id group-name drop ] unit-test
|
||||
|
||||
[ "888888888888888" ] [ 888888888888888 group-name ] unit-test
|
||||
[ f ]
|
||||
[ "please-oh-please-don't-have-a-group-named-this123lalala" group-struct ] unit-test
|
||||
|
|
|
@ -13,7 +13,7 @@ TUPLE: group id name passwd members ;
|
|||
|
||||
SYMBOL: group-cache
|
||||
|
||||
GENERIC: group-struct ( obj -- group )
|
||||
GENERIC: group-struct ( obj -- group/f )
|
||||
|
||||
<PRIVATE
|
||||
|
||||
|
@ -24,11 +24,14 @@ GENERIC: group-struct ( obj -- group )
|
|||
"group" <c-object> tuck 4096
|
||||
[ <byte-array> ] keep f <void*> ;
|
||||
|
||||
M: integer group-struct ( id -- group )
|
||||
(group-struct) getgrgid_r io-error ;
|
||||
: check-group-struct ( group-struct ptr -- group-struct/f )
|
||||
*void* [ drop f ] unless ;
|
||||
|
||||
M: string group-struct ( string -- group )
|
||||
(group-struct) getgrnam_r 0 = [ (io-error) ] unless ;
|
||||
M: integer group-struct ( id -- group/f )
|
||||
(group-struct) [ getgrgid_r io-error ] keep check-group-struct ;
|
||||
|
||||
M: string group-struct ( string -- group/f )
|
||||
(group-struct) [ getgrnam_r io-error ] keep check-group-struct ;
|
||||
|
||||
: group-struct>group ( group-struct -- group )
|
||||
[ \ group new ] dip
|
||||
|
@ -45,12 +48,12 @@ PRIVATE>
|
|||
dup group-cache get [
|
||||
dupd at* [ name>> nip ] [ drop number>string ] if
|
||||
] [
|
||||
group-struct group-gr_name
|
||||
group-struct [ group-gr_name ] [ f ] if*
|
||||
] if*
|
||||
[ nip ] [ number>string ] if* ;
|
||||
|
||||
: group-id ( string -- id )
|
||||
group-struct group-gr_gid ;
|
||||
: group-id ( string -- id/f )
|
||||
group-struct [ group-gr_gid ] [ f ] if* ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.syntax ;
|
||||
USING: alien.syntax unix.types unix.stat ;
|
||||
IN: unix.statfs.freebsd
|
||||
|
||||
CONSTANT: MFSNAMELEN 16 ! length of type name including null */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.syntax ;
|
||||
USING: alien.syntax unix.types unix.stat ;
|
||||
IN: unix.statfs.linux
|
||||
|
||||
C-STRUCT: statfs64
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.c-types io.encodings.utf8 io.encodings.string
|
||||
kernel sequences unix.stat accessors unix combinators math
|
||||
grouping system alien.strings math.bitwise alien.syntax ;
|
||||
grouping system alien.strings math.bitwise alien.syntax
|
||||
unix.types ;
|
||||
IN: unix.statfs.macosx
|
||||
|
||||
CONSTANT: MNT_RDONLY HEX: 00000001
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.syntax ;
|
||||
USING: alien.syntax unix.types unix.stat ;
|
||||
IN: unix.statfs.openbsd
|
||||
|
||||
CONSTANT: MFSNAMELEN 16
|
||||
|
|
|
@ -19,6 +19,7 @@ HELP: VALUE:
|
|||
{ $examples
|
||||
{ $example
|
||||
"USING: values math prettyprint ;"
|
||||
"IN: scratchpad"
|
||||
"VALUE: x"
|
||||
"2 2 + to: x"
|
||||
"x ."
|
||||
|
|
|
@ -5,7 +5,7 @@ USING: kernel namespaces make xmode.rules xmode.tokens
|
|||
xmode.marker.state xmode.marker.context xmode.utilities
|
||||
xmode.catalog sequences math assocs combinators strings
|
||||
parser-combinators.regexp splitting parser-combinators ascii
|
||||
unicode.case combinators.short-circuit accessors ;
|
||||
ascii combinators.short-circuit accessors ;
|
||||
|
||||
! Based on org.gjt.sp.jedit.syntax.TokenMarker
|
||||
|
||||
|
|
|
@ -338,6 +338,10 @@ HELP: 2each
|
|||
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- )" } } }
|
||||
{ $description "Applies the quotation to pairs of elements from " { $snippet "seq1" } " and " { $snippet "seq2" } "." } ;
|
||||
|
||||
HELP: 3each
|
||||
{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "quot" { $quotation "( elt1 elt2 elt3 -- )" } } }
|
||||
{ $description "Applies the quotation to triples of elements from " { $snippet "seq1" } ", " { $snippet "seq2" } " and " { $snippet "seq3" } "." } ;
|
||||
|
||||
HELP: 2reduce
|
||||
{ $values { "seq1" sequence }
|
||||
{ "seq2" sequence }
|
||||
|
@ -350,10 +354,18 @@ HELP: 2map
|
|||
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- new )" } } { "newseq" "a new sequence" } }
|
||||
{ $description "Applies the quotation to each pair of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "seq1" } "." } ;
|
||||
|
||||
HELP: 3map
|
||||
{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "quot" { $quotation "( elt1 elt2 elt3 -- new )" } } { "newseq" "a new sequence" } }
|
||||
{ $description "Applies the quotation to each triple of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "seq1" } "." } ;
|
||||
|
||||
HELP: 2map-as
|
||||
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- new )" } } { "exemplar" sequence } { "newseq" "a new sequence" } }
|
||||
{ $description "Applies the quotation to each pair of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "exemplar" } "." } ;
|
||||
|
||||
HELP: 3map-as
|
||||
{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "quot" { $quotation "( elt1 elt2 elt3 -- new )" } } { "exemplar" sequence } { "newseq" "a new sequence" } }
|
||||
{ $description "Applies the quotation to each triple of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "exemplar" } "." } ;
|
||||
|
||||
HELP: 2all?
|
||||
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- ? )" } } { "?" "a boolean" } }
|
||||
{ $description "Tests the predicate pairwise against elements of " { $snippet "seq1" } " and " { $snippet "seq2" } "." } ;
|
||||
|
@ -1262,6 +1274,17 @@ HELP: shorten
|
|||
"V{ 1 2 3 }"
|
||||
} } ;
|
||||
|
||||
HELP: iota
|
||||
{ $values { "n" integer } { "iota" iota } }
|
||||
{ $description "Creates an immutable virtual sequence containing the integers from 0 to " { $snippet "n-1" } "." }
|
||||
{ $examples
|
||||
{ $example
|
||||
"USING: math sequences prettyprint ;"
|
||||
"3 iota [ sq ] map ."
|
||||
"{ 0 1 4 }"
|
||||
}
|
||||
} ;
|
||||
|
||||
ARTICLE: "sequences-unsafe" "Unsafe sequence operations"
|
||||
"The " { $link nth-unsafe } " and " { $link set-nth-unsafe } " sequence protocol bypasses bounds checks for increased performance."
|
||||
$nl
|
||||
|
@ -1422,16 +1445,23 @@ ARTICLE: "sequences-combinators" "Sequence combinators"
|
|||
{ $subsection all? }
|
||||
"Testing how elements are related:"
|
||||
{ $subsection monotonic? }
|
||||
{ $subsection "sequence-2combinators" } ;
|
||||
{ $subsection "sequence-2combinators" }
|
||||
{ $subsection "sequence-3combinators" } ;
|
||||
|
||||
ARTICLE: "sequence-2combinators" "Pair-wise sequence combinators"
|
||||
"There is a set of combinators which traverse two sequences pairwise. If one sequence is shorter than the other, than only the prefix having the length of the minimum of the two is examined."
|
||||
"There is a set of combinators which traverse two sequences pairwise. If one sequence is shorter than the other, then only the prefix having the length of the minimum of the two is examined."
|
||||
{ $subsection 2each }
|
||||
{ $subsection 2reduce }
|
||||
{ $subsection 2map }
|
||||
{ $subsection 2map-as }
|
||||
{ $subsection 2all? } ;
|
||||
|
||||
ARTICLE: "sequence-3combinators" "Triple-wise sequence combinators"
|
||||
"There is a set of combinators which traverse three sequences triple-wise. If one sequence is shorter than the others, then only the prefix having the length of the minimum of the three is examined."
|
||||
{ $subsection 3each }
|
||||
{ $subsection 3map }
|
||||
{ $subsection 3map-as } ;
|
||||
|
||||
ARTICLE: "sequences-tests" "Testing sequences"
|
||||
"Testing for an empty sequence:"
|
||||
{ $subsection empty? }
|
||||
|
|
|
@ -276,4 +276,8 @@ M: bogus-hashcode hashcode* 2drop 0 >bignum ;
|
|||
|
||||
{ 3 0 } [ [ 3drop ] 3each ] must-infer-as
|
||||
|
||||
[ V{ 0 3 } ] [ "A" { "A" "B" "C" "A" "D" } indices ] unit-test
|
||||
[ V{ 0 3 } ] [ "A" { "A" "B" "C" "A" "D" } indices ] unit-test
|
||||
|
||||
[ "asdf" iota ] must-fail
|
||||
[ T{ iota { n 10 } } ] [ 10 iota ] unit-test
|
||||
[ 0 ] [ 10 iota first ] unit-test
|
||||
|
|
|
@ -101,6 +101,20 @@ M: integer nth-unsafe drop ;
|
|||
|
||||
INSTANCE: integer immutable-sequence
|
||||
|
||||
PRIVATE>
|
||||
|
||||
! In the future, this will replace integer sequences
|
||||
TUPLE: iota { n integer read-only } ;
|
||||
|
||||
: iota ( n -- iota ) \ iota boa ; inline
|
||||
|
||||
<PRIVATE
|
||||
|
||||
M: iota length n>> ;
|
||||
M: iota nth-unsafe drop ;
|
||||
|
||||
INSTANCE: iota immutable-sequence
|
||||
|
||||
: first-unsafe ( seq -- first )
|
||||
0 swap nth-unsafe ; inline
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ ABOUT: "sequences-sorting"
|
|||
|
||||
HELP: sort
|
||||
{ $values { "seq" "a sequence" } { "quot" { $quotation "( obj1 obj2 -- <=> )" } } { "sortedseq" "a new sorted sequence" } }
|
||||
{ $description "Sorts the elements into a new array." } ;
|
||||
{ $description "Sorts the elements into a new array using a stable sort." }
|
||||
{ $notes "The algorithm used is the merge sort." } ;
|
||||
|
||||
HELP: sort-keys
|
||||
{ $values { "seq" "an alist" } { "sortedseq" "a new sorted sequence" } }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
USING: io io.files io.files.temp io.streams.duplex kernel
|
||||
sequences sequences.private strings vectors words memoize
|
||||
splitting grouping hints tr continuations io.encodings.ascii
|
||||
unicode.case ;
|
||||
ascii ;
|
||||
IN: benchmark.reverse-complement
|
||||
|
||||
TR: trans-map ch>upper "ACGTUMRYKVHDB" "TGCAAKYRMBDHV" ;
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: kernel sequences io.files io.files.temp io.launcher
|
|||
io.pathnames io.encodings.ascii io.streams.string http.client
|
||||
generalizations combinators math.parser math.vectors
|
||||
math.intervals interval-maps memoize csv accessors assocs
|
||||
strings math splitting grouping arrays ;
|
||||
strings math splitting grouping arrays combinators.smart ;
|
||||
IN: geo-ip
|
||||
|
||||
: db-path ( -- path ) "IpToCountry.csv" temp-file ;
|
||||
|
@ -20,15 +20,17 @@ IN: geo-ip
|
|||
TUPLE: ip-entry from to registry assigned city cntry country ;
|
||||
|
||||
: parse-ip-entry ( row -- ip-entry )
|
||||
7 firstn {
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
} spread ip-entry boa ;
|
||||
[
|
||||
{
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
[ ]
|
||||
} spread
|
||||
] input<sequence ip-entry boa ;
|
||||
|
||||
MEMO: ip-db ( -- seq )
|
||||
download-db ascii file-lines
|
||||
|
|
|
@ -2,7 +2,7 @@ USING: arrays combinators kernel lists math math.parser
|
|||
namespaces parser lexer parser-combinators
|
||||
parser-combinators.simple promises quotations sequences strings
|
||||
math.order assocs prettyprint.backend prettyprint.custom memoize
|
||||
unicode.case unicode.categories combinators.short-circuit
|
||||
ascii unicode.categories combinators.short-circuit
|
||||
accessors make io ;
|
||||
IN: parser-combinators.regexp
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
! Copyright (C) 2009 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors kernel tools.test usa-cities ;
|
||||
IN: usa-cities.tests
|
||||
|
||||
[ t ] [ 55406 find-zip-code name>> "Minneapolis" = ] unit-test
|
|
@ -2,7 +2,7 @@
|
|||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: io.files io.encodings.ascii sequences generalizations
|
||||
math.parser combinators kernel memoize csv summary
|
||||
words accessors math.order binary-search ;
|
||||
words accessors math.order binary-search combinators.smart ;
|
||||
IN: usa-cities
|
||||
|
||||
SINGLETONS: AK AL AR AS AZ CA CO CT DC DE FL GA HI IA ID IL IN
|
||||
|
@ -30,15 +30,17 @@ first-zip name state latitude longitude gmt-offset dst-offset ;
|
|||
MEMO: cities ( -- seq )
|
||||
"resource:extra/usa-cities/zipcode.csv" ascii <file-reader>
|
||||
csv rest-slice [
|
||||
7 firstn {
|
||||
[ string>number ]
|
||||
[ ]
|
||||
[ string>state ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
} spread city boa
|
||||
[
|
||||
{
|
||||
[ string>number ]
|
||||
[ ]
|
||||
[ string>state ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
[ string>number ]
|
||||
} spread
|
||||
] input<sequence city boa
|
||||
] map ;
|
||||
|
||||
MEMO: cities-named ( name -- cities )
|
||||
|
|
Loading…
Reference in New Issue