Merge branch 'master' into new_ui

db4
Slava Pestov 2009-01-07 21:41:27 -06:00
commit b8351d9da0
50 changed files with 603 additions and 136 deletions

View File

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

View File

@ -83,7 +83,7 @@ M: bit-array byte-length length 7 + -3 shift ;
] if ; ] if ;
: bit-array>integer ( bit-array -- n ) : bit-array>integer ( bit-array -- n )
0 swap underlying>> dup length [ 0 swap underlying>> dup length <reversed> [
alien-unsigned-1 swap 8 shift bitor alien-unsigned-1 swap 8 shift bitor
] with each ; ] with each ;

View File

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

View File

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

View File

@ -0,0 +1,29 @@
! Copyright (C) 2007-2009 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays combinators kernel make math math.primes sequences ;
IN: math.primes.factors
<PRIVATE
: count-factor ( n d -- n' c )
[ 1 ] 2dip [ /i ] keep
[ dupd /mod zero? ] curry [ nip [ 1+ ] dip ] [ drop ] while
swap ;
: write-factor ( n d -- n' d )
2dup mod zero? [ [ [ count-factor ] keep swap 2array , ] keep ] when ;
PRIVATE>
: group-factors ( n -- seq )
[ 2 [ over 1 > ] [ write-factor next-prime ] [ ] while 2drop ] { } make ;
: unique-factors ( n -- seq ) group-factors [ first ] map ;
: factors ( n -- seq ) group-factors [ first2 swap <array> ] map concat ;
: totient ( n -- t )
{
{ [ dup 2 < ] [ drop 0 ] }
[ dup unique-factors [ 1 [ 1- * ] reduce ] [ product ] bi / * ]
} cond ; foldable

View File

@ -11,15 +11,7 @@ HELP: prime?
{ $values { "n" "an integer" } { "?" "a boolean" } } { $values { "n" "an integer" } { "?" "a boolean" } }
{ $description "Test if an integer is a prime number." } ; { $description "Test if an integer is a prime number." } ;
{ lprimes lprimes-from primes-upto primes-between } related-words { primes-upto primes-between } related-words
HELP: lprimes
{ $values { "list" "a lazy list" } }
{ $description "Return a sorted list containing all the prime numbers." } ;
HELP: lprimes-from
{ $values { "n" "an integer" } { "list" "a lazy list" } }
{ $description "Return a sorted list containing all the prime numbers greater or equal to " { $snippet "n" } "." } ;
HELP: primes-upto HELP: primes-upto
{ $values { "n" "an integer" } { "seq" "a sequence" } } { $values { "n" "an integer" } { "seq" "a sequence" } }

View File

@ -0,0 +1,9 @@
USING: arrays math.primes tools.test ;
{ 1237 } [ 1234 next-prime ] unit-test
{ f t } [ 1234 prime? 1237 prime? ] unit-test
{ { 2 3 5 7 } } [ 10 primes-upto >array ] unit-test
{ { 999983 1000003 } } [ 999982 1000010 primes-between >array ] unit-test
{ { 4999963 4999999 5000011 5000077 5000081 } }
[ 4999962 5000082 primes-between >array ] unit-test

View File

@ -1,7 +1,7 @@
! Copyright (C) 2007 Samuel Tardieu. ! Copyright (C) 2007-2009 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: combinators kernel lists.lazy math math.functions USING: combinators kernel math math.functions math.miller-rabin
math.miller-rabin math.order math.primes.erato math.ranges sequences ; math.order math.primes.erato math.ranges sequences ;
IN: math.primes IN: math.primes
<PRIVATE <PRIVATE
@ -23,11 +23,6 @@ PRIVATE>
: next-prime ( n -- p ) : next-prime ( n -- p )
next-odd [ dup really-prime? ] [ 2 + ] [ ] until ; foldable next-odd [ dup really-prime? ] [ 2 + ] [ ] until ; foldable
: lprimes ( -- list ) 2 [ next-prime ] lfrom-by ;
: lprimes-from ( n -- list )
dup 3 < [ drop lprimes ] [ 1- next-prime [ next-prime ] lfrom-by ] if ;
: primes-between ( low high -- seq ) : primes-between ( low high -- seq )
[ dup 3 max dup even? [ 1 + ] when ] dip [ dup 3 max dup even? [ 1 + ] when ] dip
2 <range> [ prime? ] filter 2 <range> [ prime? ] filter

View File

@ -0,0 +1,39 @@
USING: help.syntax help.markup strings ;
IN: unicode.breaks
ABOUT: "unicode.breaks"
ARTICLE: "unicode.breaks" "Word and grapheme breaks"
"The " { $vocab-link "unicode.breaks" "unicode.breaks" } " vocabulary partially implements Unicode Standard Annex #29. This provides for segmentation of a string along grapheme and word boundaries. In Unicode, a grapheme, or a basic unit of display in text, may be more than one code point. For example, in the string \"e\\u000301\" (where U+0301 is a combining acute accent), there is only one grapheme, as the acute accent goes above the e, forming a single grapheme. Word breaks, in general, are more complicated than simply splitting by whitespace, and the Unicode algorithm provides for that."
$nl "Operations for graphemes:"
{ $subsection first-grapheme }
{ $subsection last-grapheme }
{ $subsection >graphemes }
{ $subsection string-reverse }
"Operations on words:"
{ $subsection first-word }
{ $subsection >words } ;
HELP: first-grapheme
{ $values { "str" string } { "i" "an index" } }
{ $description "Finds the length of the first grapheme of the string. This can be used repeatedly to efficiently traverse the graphemes of the string, using slices." } ;
HELP: last-grapheme
{ $values { "str" string } { "i" "an index" } }
{ $description "Finds the index of the start of the last grapheme of the string. This can be used to traverse the graphemes of a string backwards." } ;
HELP: >graphemes
{ $values { "str" string } { "graphemes" "an array of strings" } }
{ $description "Divides a string into a sequence of individual graphemes." } ;
HELP: string-reverse
{ $values { "str" string } { "rts" string } }
{ $description "Reverses a string, leaving graphemes in-tact." } ;
HELP: first-word
{ $values { "str" string } { "i" "index" } }
{ $description "Finds the length of the first word in the string." } ;
HELP: >words
{ $values { "str" string } { "words" "an array of strings" } }
{ $description "Divides the string up into words." } ;

View File

@ -36,4 +36,4 @@ IN: unicode.breaks.tests
] each ; ] each ;
grapheme-break-test parse-test-file [ >graphemes ] test grapheme-break-test parse-test-file [ >graphemes ] test
! word-break-test parse-test-file [ >words ] test word-break-test parse-test-file [ >words ] test

View File

@ -2,11 +2,12 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: combinators.short-circuit unicode.categories kernel math USING: combinators.short-circuit unicode.categories kernel math
combinators splitting sequences math.parser io.files io assocs combinators splitting sequences math.parser io.files io assocs
arrays namespaces make math.ranges unicode.normalize values arrays namespaces make math.ranges unicode.normalize.private values
io.encodings.ascii unicode.syntax unicode.data compiler.units io.encodings.ascii unicode.syntax unicode.data compiler.units
alien.syntax sets accessors interval-maps memoize locals words ; alien.syntax sets accessors interval-maps memoize locals words ;
IN: unicode.breaks IN: unicode.breaks
<PRIVATE
! Grapheme breaks ! Grapheme breaks
C-ENUM: Any L V T LV LVT Extend Control CR LF C-ENUM: Any L V T LV LVT Extend Control CR LF
@ -101,19 +102,25 @@ VALUE: grapheme-table
: find-index ( seq quot -- i ) find drop ; inline : find-index ( seq quot -- i ) find drop ; inline
: find-last-index ( seq quot -- i ) find-last drop ; inline : find-last-index ( seq quot -- i ) find-last drop ; inline
PRIVATE>
: first-grapheme ( str -- i ) : first-grapheme ( str -- i )
unclip-slice grapheme-class over unclip-slice grapheme-class over
[ grapheme-class tuck grapheme-break? ] find-index [ grapheme-class tuck grapheme-break? ] find-index
nip swap length or 1+ ; nip swap length or 1+ ;
<PRIVATE
:: (>pieces) ( str quot -- ) :: (>pieces) ( str quot -- )
str [ str [
dup quot call cut-slice dup quot call cut-slice
swap , quot (>pieces) swap , quot (>pieces)
] unless-empty ; ] unless-empty ; inline recursive
: >pieces ( str quot -- graphemes ) : >pieces ( str quot -- graphemes )
[ (>pieces) ] { } make ; [ (>pieces) ] { } make ; inline
PRIVATE>
: >graphemes ( str -- graphemes ) : >graphemes ( str -- graphemes )
[ first-grapheme ] >pieces ; [ first-grapheme ] >pieces ;
@ -125,6 +132,8 @@ VALUE: grapheme-table
unclip-last-slice grapheme-class swap 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-index ?1+ nip ;
<PRIVATE
graphemes init-table table graphemes init-table table
[ make-grapheme-table finish-table ] with-variable [ make-grapheme-table finish-table ] with-variable
to: grapheme-table to: grapheme-table
@ -139,14 +148,14 @@ to: word-break-table
C-ENUM: wOther wCR wLF wNewline wExtend wFormat wKatakana wALetter wMidLetter C-ENUM: wOther wCR wLF wNewline wExtend wFormat wKatakana wALetter wMidLetter
wMidNum wMidNumLet wNumeric wExtendNumLet words ; wMidNum wMidNumLet wNumeric wExtendNumLet words ;
MEMO: word-break-classes ( -- table ) : word-break-classes ( -- table ) ! Is there a way to avoid this?
H{ H{
{ "Other" wOther } { "CR" wCR } { "LF" wLF } { "Newline" wNewline } { "Other" 0 } { "CR" 1 } { "LF" 2 } { "Newline" 3 }
{ "Extend" wExtend } { "Format" wFormat } { "Katakana" wKatakana } { "Extend" 4 } { "Format" 5 } { "Katakana" 6 }
{ "ALetter" wALetter } { "MidLetter" wMidLetter } { "ALetter" 7 } { "MidLetter" 8 }
{ "MidNum" wMidNum } { "MidNumLet" wMidNumLet } { "Numeric" wNumeric } { "MidNum" 9 } { "MidNumLet" 10 } { "Numeric" 11 }
{ "ExtendNumLet" wExtendNumLet } { "ExtendNumLet" 12 }
} [ execute ] assoc-map ; } ;
: word-break-prop ( char -- word-break-prop ) : word-break-prop ( char -- word-break-prop )
word-break-table interval-at word-break-table interval-at
@ -185,22 +194,51 @@ words init-table table
[ make-word-table finish-word-table ] with-variable [ make-word-table finish-word-table ] with-variable
to: word-table to: word-table
: word-break? ( class1 class2 -- ? ) : word-table-nth ( class1 class2 -- ? )
word-table nth nth not ; word-table nth nth ;
: skip? ( char -- ? ) : property-not= ( i str property -- ? )
word-break-prop { 4 5 } member? ; ! wExtend or wFormat pick [
[ ?nth ] dip swap
[ word-break-prop = not ] [ drop f ] if*
] [ 3drop t ] if ;
: word-break-next ( old-class new-char -- next-class ? ) : format/extended? ( ch -- ? )
word-break-prop dup { 4 5 } member? word-break-prop { 4 5 } member? ;
[ drop f ] [ tuck word-break? ] if ;
: first-word ( str -- i ) :: walk-up ( str i -- j )
unclip-slice word-break-prop over i 1 + str [ format/extended? not ] find-from drop
[ word-break-next ] find-index 1+ str [ format/extended? not ] find-from drop ; ! possible bounds error?
:: 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?
:: word-break? ( table-entry i str -- ? )
table-entry {
{ t [ f ] }
{ f [ t ] }
{ check-letter-after
[ str i walk-up str wALetter property-not= ] }
{ check-letter-before
[ str i walk-down str wALetter property-not= ] }
{ check-number-after
[ str i walk-up str wNumeric property-not= ] }
{ check-number-before
[ str i walk-down str wNumeric property-not= ] }
} case ;
:: 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 ;
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+ ; nip swap length or 1+ ;
! This must be changed to ignore format/extended chars and
! handle symbols in the table specially
: >words ( str -- words ) : >words ( str -- words )
[ first-word ] >pieces ; [ first-word ] >pieces ;

View File

@ -0,0 +1,19 @@
USING: help.syntax help.markup ;
IN: unicode.case
ABOUT: "unicode.case"
ARTICLE: "unicode.case" "Case mapping"
"When considering Unicode in general and not just ASCII or a smaller character set, putting a string in upper case, title case or lower case is slightly more complicated. In most contexts it's best to use the general Unicode routines for case conversion. There is an additional type of casing, case-fold, which is defined as bringing a string into upper case and then lower. This exists because in some cases it is different from simple lower case."
{ $subsection >upper }
{ $subsection >lower }
{ $subsection >title }
{ $subsection >case-fold }
"To test if a string is in a given case:"
{ $subsection upper? }
{ $subsection lower? }
{ $subsection title? }
{ $subsection case-fold? }
"For certain languages (Turkish, Azeri, Lithuanian), case mapping is dependent on locale; To change this, set the following variable to the ISO-639-1 code for your language:"
{ $subsection locale }
"This is unnecessary for most languages." ;

View File

@ -5,14 +5,15 @@ unicode.normalize math unicode.categories combinators
assocs strings splitting kernel accessors ; assocs strings splitting kernel accessors ;
IN: unicode.case IN: unicode.case
<PRIVATE
: at-default ( key assoc -- value/key ) [ at ] [ drop ] 2bi or ; : at-default ( key assoc -- value/key ) [ at ] [ drop ] 2bi or ;
: ch>lower ( ch -- lower ) simple-lower at-default ; : ch>lower ( ch -- lower ) simple-lower at-default ;
: ch>upper ( ch -- upper ) simple-upper at-default ; : ch>upper ( ch -- upper ) simple-upper at-default ;
: ch>title ( ch -- title ) simple-title at-default ; : ch>title ( ch -- title ) simple-title at-default ;
PRIVATE>
SYMBOL: locale ! Just casing locale, or overall? SYMBOL: locale ! Just casing locale, or overall?
<PRIVATE
: i-dot? ( -- ? ) : i-dot? ( -- ? )
locale get { "tr" "az" } member? ; locale get { "tr" "az" } member? ;
@ -79,7 +80,7 @@ SYMBOL: locale ! Just casing locale, or overall?
[ [ % ] compose ] [ [ , ] compose ] bi* ?if [ [ % ] compose ] [ [ , ] compose ] bi* ?if
] 2curry each ] 2curry each
] "" make ; inline ] "" make ; inline
PRIVATE>
: >lower ( string -- lower ) : >lower ( string -- lower )
i-dot? [ turk>lower ] when i-dot? [ turk>lower ] when
final-sigma [ lower>> ] [ ch>lower ] map-case ; final-sigma [ lower>> ] [ ch>lower ] map-case ;

View File

@ -0,0 +1,59 @@
! Copyright (C) 2009 Your name.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel ;
IN: unicode.categories
HELP: LETTER?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether the code point is an upper-cased letter" } ;
HELP: Letter?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether the code point is a letter of any case" } ;
HELP: alpha?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether the code point is alphanumeric" } ;
HELP: blank?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether the code point is whitespace" } ;
HELP: character?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a number is a code point which has been assigned" } ;
HELP: control?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a code point is a control character" } ;
HELP: digit?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a code point is a digit" } ;
HELP: letter?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a code point is a lower-cased letter" } ;
HELP: printable?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a code point is printable, as opposed to being a control character or formatting character" } ;
HELP: uncased?
{ $values { "ch" "a character" } { "?" "a boolean" } }
{ $description "Determines whether a character has a case" } ;
ARTICLE: "unicode.categories" "Character classes"
{ $vocab-link "unicode.categories" } " is a vocabulary which provides predicates for determining if a code point has a particular property, for example being a lower cased letter. These should be used in preference to the " { $vocab-link "ASCII" "ascii" } " equivalents in most cases. Below are links to the useful predicates, but note that each of these is defined to be a predicate class."
{ $subsection blank? }
{ $subsection letter? }
{ $subsection LETTER? }
{ $subsection Letter? }
{ $subsection digit? }
{ $subsection printable? }
{ $subsection alpha? }
{ $subsection control? }
{ $subsection uncased? }
{ $subsection character? } ;
ABOUT: "unicode.categories"

View File

@ -1,10 +1,8 @@
USING: help.syntax help.markup strings byte-arrays ; USING: help.syntax help.markup strings byte-arrays ;
IN: unicode.collation IN: unicode.collation
ABOUT: "unicode.collation" ARTICLE: "unicode.collation" "Collation and weak comparison"
"The " { $vocab-link "unicode.collation" "unicode.collation" } " vocabulary implements the Unicode Collation Algorithm. The Unicode Collation Algorithm (UTS #10) forms a reasonable way to sort strings when accouting for all of the characters in Unicode. It is far preferred over code point order when sorting for human consumption, in user interfaces. At the moment, only the default Unicode collation element table (DUCET) is used, but a more accurate collation would take locale into account. The following words are defined:"
ARTICLE: "unicode.collation" "Unicode collation algorithm (UCA)"
"The Unicode Collation Algorithm (UTS #10) forms a reasonable way to sort strings when accouting for all of the characters in Unicode. At the moment, only the default Unicode collation element table (DUCET) is used, but a more accurate collation would take locale into account. The following words are defined:"
{ $subsection sort-strings } { $subsection sort-strings }
{ $subsection collation-key } { $subsection collation-key }
{ $subsection string<=> } { $subsection string<=> }
@ -13,6 +11,8 @@ ARTICLE: "unicode.collation" "Unicode collation algorithm (UCA)"
{ $subsection tertiary= } { $subsection tertiary= }
{ $subsection quaternary= } ; { $subsection quaternary= } ;
ABOUT: "unicode.collation"
HELP: sort-strings HELP: sort-strings
{ $values { "strings" "a sequence of strings" } { "sorted" "the strings in DUCET order" } } { $values { "strings" "a sequence of strings" } { "sorted" "the strings in DUCET order" } }
{ $description "This word takes a sequence of strings and sorts them according to the UCA, using code point order as a tie-breaker." } ; { $description "This word takes a sequence of strings and sorts them according to the UCA, using code point order as a tie-breaker." } ;

View File

@ -0,0 +1,33 @@
USING: help.syntax help.markup strings ;
IN: unicode.normalize
ABOUT: "unicode.normalize"
ARTICLE: "unicode.normalize" "Unicode normalization"
"The " { $vocab-link "unicode.normalize" "unicode.normalize" } " vocabulary defines words for normalizing Unicode strings. In Unicode, it is often possible to have multiple sequences of characters which really represent exactly the same thing. For example, to represent e with an acute accent above, there are two possible strings: \"e\\u000301\" (the e character, followed by the combining acute accent character) and \"\\u0000e9\" (a single character, e with an acute accent). There are four normalization forms: NFD, NFC, NFKD, and NFKC. Basically, in NFD and NFKD, everything is expanded, whereas in NFC and NFKC, everything is contracted. In NFKD and NFKC, more things are expanded and contracted. This is a process which loses some information, so it should be done only with care. Most of the world uses NFC to communicate, but for many purposes, NFD/NFKD is easier to process. For more information, see Unicode Standard Annex #15 and section 3 of the Unicode standard."
{ $subsection nfc }
{ $subsection nfd }
{ $subsection nfkc }
{ $subsection nfkd }
"If two strings in a normalization form are appended, the result may not be in that normalization form still. To append two strings in NFD and make sure the result is in NFD, the following procedure is supplied:"
{ $subsection string-append } ;
HELP: nfc
{ $values { "string" string } { "nfc" "a string in NFC" } }
{ $description "Converts a string to Normalization Form C" } ;
HELP: nfd
{ $values { "string" string } { "nfd" "a string in NFD" } }
{ $description "Converts a string to Normalization Form D" } ;
HELP: nfkc
{ $values { "string" string } { "nfkc" "a string in NFKC" } }
{ $description "Converts a string to Normalization Form KC" } ;
HELP: nfkd
{ $values { "string" string } { "nfc" "a string in NFKD" } }
{ $description "Converts a string to Normalization Form KD" } ;
HELP: string-append
{ $values { "s1" "a string in NFD" } { "s2" "a string in NFD" } { "string" "a string in NFD" } }
{ $description "Appends two strings, putting the result in NFD." } ;

View File

@ -4,6 +4,7 @@ USING: sequences namespaces make unicode.data kernel math arrays
locals sorting.insertion accessors assocs ; locals sorting.insertion accessors assocs ;
IN: unicode.normalize IN: unicode.normalize
<PRIVATE
! Conjoining Jamo behavior ! Conjoining Jamo behavior
: hangul-base HEX: ac00 ; inline : hangul-base HEX: ac00 ; inline
@ -74,10 +75,12 @@ IN: unicode.normalize
dup reorder dup reorder
] if ; inline ] if ; inline
: nfd ( string -- string ) PRIVATE>
: nfd ( string -- nfd )
[ canonical-entry ] decompose ; [ canonical-entry ] decompose ;
: nfkd ( string -- string ) : nfkd ( string -- nfkd )
[ compatibility-entry ] decompose ; [ compatibility-entry ] decompose ;
: string-append ( s1 s2 -- string ) : string-append ( s1 s2 -- string )
@ -87,6 +90,8 @@ IN: unicode.normalize
0 over ?nth non-starter? 0 over ?nth non-starter?
[ length dupd reorder-back ] [ drop ] if ; [ length dupd reorder-back ] [ drop ] if ;
<PRIVATE
! Normalization -- Composition ! Normalization -- Composition
SYMBOL: main-str SYMBOL: main-str
SYMBOL: ind SYMBOL: ind
@ -157,6 +162,8 @@ DEFER: compose-iter
pass-combining (compose) pass-combining (compose)
] "" make ; ] "" make ;
PRIVATE>
: nfc ( string -- nfc ) : nfc ( string -- nfc )
nfd compose ; nfd compose ;

View File

@ -0,0 +1,16 @@
USING: help.markup help.syntax ;
IN: unicode
ARTICLE: "unicode" "Unicode"
"Unicode is a set of characters, or " { $emphasis "code points" } " covering what's used in most world writing systems. Any Factor string can hold any of these code points transparently; a factor string is a sequence of Unicode code points. Unicode is accompanied by several standard algorithms for common operations like encoding in files, capitalizing a string, finding the boundaries between words, etc. When a programmer is faced with a string manipulation problem, where the string represents human language, a Unicode algorithm is often much better than the naive one. This is not in terms of efficiency, but rather internationalization. Even English text that remains in ASCII is better served by the Unicode collation algorithm than a naive algorithm. The Unicode algorithms implemented here are:"
{ $vocab-subsection "Case mapping" "unicode.case" }
{ $vocab-subsection "Collation and weak comparison" "unicode.collation" }
{ $vocab-subsection "Character classes" "unicode.categories" }
{ $vocab-subsection "Word and grapheme breaks" "unicode.breaks" }
{ $vocab-subsection "Unicode normalization" "unicode.normalize" }
"The following are mostly for internal use:"
{ $vocab-subsection "Unicode syntax" "unicode.syntax" }
{ $vocab-subsection "Unicode data tables" "unicode.data" }
{ $see-also "io.encodings" } ;
ABOUT: "unicode"

View File

@ -0,0 +1 @@
IN: unicode

View File

@ -691,11 +691,10 @@ HELP: assert=
{ $values { "a" object } { "b" object } } { $values { "a" object } { "b" object } }
{ $description "Throws an " { $link assert } " error if " { $snippet "a" } " does not equal " { $snippet "b" } "." } ; { $description "Throws an " { $link assert } " error if " { $snippet "a" } " does not equal " { $snippet "b" } "." } ;
ARTICLE: "shuffle-words" "Shuffle words" ARTICLE: "shuffle-words" "Shuffle words"
"Shuffle words rearrange items at the top of the data stack. They control the flow of data between words that perform actions." "Shuffle words rearrange items at the top of the data stack. They control the flow of data between words that perform actions."
$nl $nl
"The " { $link "cleave-combinators" } " and " { $link "spread-combinators" } " are closely related to shuffle words and should be used instead where possible because they can result in clearer code; also, see the advice in " { $link "cookbook-philosophy" } "." "The " { $link "cleave-combinators" } ", " { $link "spread-combinators" } " and " { $link "apply-combinators" } " are closely related to shuffle words and should be used instead where possible because they can result in clearer code; also, see the advice in " { $link "cookbook-philosophy" } "."
$nl $nl
"Removing stack elements:" "Removing stack elements:"
{ $subsection drop } { $subsection drop }

View File

@ -1,9 +1,10 @@
USING: accessors arrays assocs colors combinators.short-circuit USING: accessors arrays assocs calendar colors
kernel locals math math.functions math.matrices math.order combinators.short-circuit help.markup help.syntax kernel locals
math.parser math.trig math.vectors opengl opengl.demo-support math math.functions math.matrices math.order math.parser
opengl.gl sbufs sequences strings ui.gadgets ui.gadgets.worlds math.trig math.vectors opengl opengl.demo-support opengl.gl
ui.gestures ui.render ; sbufs sequences strings threads ui.gadgets ui.gadgets.worlds
ui.gestures ui.render ui.tools.workspace ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -255,8 +256,26 @@ DEFER: default-L-parser-values
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
TUPLE: <L-system> < gadget TUPLE: <L-system> < gadget
camera display-list camera display-list pedestal paused commands axiom rules string ;
commands axiom rules string ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:: iterate-system ( GADGET -- ) GADGET pedestal>> 0.5 + GADGET (>>pedestal) ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:: start-rotation-thread ( GADGET -- )
GADGET f >>paused drop
[
[
GADGET paused>>
[ f ]
[ GADGET iterate-system GADGET relayout-1 25 milliseconds sleep t ]
if
]
loop
]
in-thread ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -332,7 +351,7 @@ TUPLE: <L-system> < gadget
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:: iterate-L-system-string ( L-SYSTEM -- ) :: iterate-L-system-string ( L-SYSTEM -- )
L-SYSTEM string>> L-SYSTEM string>> L-SYSTEM axiom>> or
L-SYSTEM rules>> L-SYSTEM rules>>
iterate-string iterate-string
L-SYSTEM (>>string) ; L-SYSTEM (>>string) ;
@ -357,7 +376,7 @@ TUPLE: <L-system> < gadget
L-SYSTEM display-list>> GL_COMPILE glNewList L-SYSTEM display-list>> GL_COMPILE glNewList
turtle turtle
L-SYSTEM string>> L-SYSTEM string>> L-SYSTEM axiom>> or
L-SYSTEM commands>> L-SYSTEM commands>>
interpret-string interpret-string
drop drop
@ -387,6 +406,10 @@ M:: <L-system> draw-gadget* ( L-SYSTEM -- )
! draw axis ! draw axis
white gl-color GL_LINES glBegin { 0 0 0 } gl-vertex { 0 0 1 } gl-vertex glEnd white gl-color GL_LINES glBegin { 0 0 0 } gl-vertex { 0 0 1 } gl-vertex glEnd
! rotate pedestal
L-SYSTEM pedestal>> 0 0 1 glRotated
L-SYSTEM display-list>> glCallList ; L-SYSTEM display-list>> glCallList ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -403,16 +426,12 @@ M:: <L-system> pref-dim* ( L-SYSTEM -- dim ) { 400 400 } ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:: camera-left ( L-SYSTEM -- )
L-SYSTEM camera>> 5 turn-left drop
L-SYSTEM relayout-1 ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:: with-camera ( L-SYSTEM QUOT -- ) :: with-camera ( L-SYSTEM QUOT -- )
L-SYSTEM camera>> QUOT call drop L-SYSTEM camera>> QUOT call drop
L-SYSTEM relayout-1 ; L-SYSTEM relayout-1 ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<L-system> <L-system>
H{ H{
{ T{ key-down f f "LEFT" } [ [ 5 turn-left ] with-camera ] } { T{ key-down f f "LEFT" } [ [ 5 turn-left ] with-camera ] }
@ -423,6 +442,11 @@ H{
{ T{ key-down f f "a" } [ [ 1 step-turtle ] with-camera ] } { T{ key-down f f "a" } [ [ 1 step-turtle ] with-camera ] }
{ T{ key-down f f "z" } [ [ -1 step-turtle ] with-camera ] } { T{ key-down f f "z" } [ [ -1 step-turtle ] with-camera ] }
{ T{ key-down f f "q" } [ [ 5 roll-left ] with-camera ] }
{ T{ key-down f f "w" } [ [ 5 roll-right ] with-camera ] }
{ T{ key-down f f "r" } [ start-rotation-thread ] }
{ {
T{ key-down f f "x" } T{ key-down f f "x" }
[ [
@ -433,6 +457,8 @@ H{
] ]
} }
{ T{ key-down f f "F1" } [ drop "L-system" help-window ] }
} }
set-gestures set-gestures
@ -442,7 +468,35 @@ set-gestures
<L-system> new-gadget <L-system> new-gadget
turtle 45 turn-left 45 pitch-up 5 step-turtle 180 turn-left >>camera ; 0 >>pedestal
! turtle 45 turn-left 45 pitch-up 5 step-turtle 180 turn-left >>camera ;
turtle 90 pitch-down -5 step-turtle 2 strafe-up >>camera
dup start-rotation-thread
;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ARTICLE: "L-system" "L-system"
"Press 'x' to iterate the L-system." $nl
"Camera control:"
{ $table
{ "a" "Forward" }
{ "z" "Backward" }
{ "LEFT" "Turn left" }
{ "RIGHT" "Turn right" }
{ "UP" "Pitch down" }
{ "DOWN" "Pitch up" }
{ "q" "Roll left" }
{ "w" "Roll right" } } ;
ABOUT: "L-system"

View File

@ -1,5 +1,5 @@
USING: accessors kernel ui L-system ; USING: accessors ui L-system ;
IN: L-system.models.abop-1 IN: L-system.models.abop-1
@ -12,15 +12,13 @@ IN: L-system.models.abop-1
"c(12)FFAL" >>axiom "c(12)FFAL" >>axiom
{ {
{ "A" "F[&'(.8)!BL]>(137)'!(.9)A" } { "A" "F [ & '(.8) ! B L ] >(137) ' !(.9) A" }
{ "B" "F[-'(.8)!(.9)$CL]'!(.9)C" } { "B" "F [ - '(.8) !(.9) $ C L ] ' !(.9) C" }
{ "C" "F[+'(.8)!(.9)$BL]'!(.9)B" } { "C" "F [ + '(.8) !(.9) $ B L ] ' !(.9) B" }
{ "L" "~c(8){+(30)f-(120)f-(120)f}" } { "L" " ~ c(8) { +(30) f -(120) f -(120) f }" }
} }
>>rules >>rules ;
dup axiom>> >>string ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

View File

@ -0,0 +1,28 @@
USING: accessors ui L-system ;
IN: L-system.models.abop-2
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: abop-2 ( <L-system> -- <L-system> )
L-parser-dialect >>commands
"c(12)FAL" >>axiom
{
{ "A" "F[&'(.7)!BL]>(137)[&'(.6)!BL]>(137)'(.9)!(.9)A" }
{ "B" "F[-'(.7)!(.9)$CL]'(.9)!(.9)C" }
{ "C" "F[+'(.7)!(.9)$BL]'(.9)!(.9)B" }
{ "L" "~c(8){+f(.1)-f(.1)-f(.1)+|+f(.1)-f(.1)-f(.1)}" }
} >>rules ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: main ( -- ) [ L-system abop-2 "L-system" open-window ] with-ui ;
MAIN: main

View File

@ -0,0 +1,25 @@
USING: accessors ui L-system ;
IN: L-system.models.abop-3
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: abop-3 ( <L-system> -- <L-system> )
L-parser-dialect >>commands
"c(12)FA" >>axiom
{
{ "A" "!(.9)t(.4)FB>(94)B>(132)B" }
{ "B" "[&t(.4)F$A]" }
{ "F" "'(1.25)F'(.8)" }
}
>>rules ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: main ( -- ) [ L-system abop-3 "L-system" open-window ] with-ui ;
MAIN: main

View File

@ -0,0 +1,54 @@
USING: accessors ui L-system ;
IN: L-system.models.abop-4
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: abop-4 ( <L-system> -- <L-system> )
L-parser-dialect >>commands
"c(12)&(20)N" >>axiom
{
{
"N"
"FII[&(60)rY]>(90)[&(45)'(0.8)rA]>(90)[&(60)rY]>(90)[&(45)'(0.8)rD]!FIK"
}
{ "Y" "[c(4){++l.--l.--l.++|++l.--l.--l.}]" }
{ "l" "g(.2)l" }
{ "K" "[!c(2)FF>w>(72)w>(72)w>(72)w>(72)w]" }
{ "w" "[c(2)^!F][c(5)&(72){-(54)f(3)+(54)f(3)|-(54)f(3)+(54)f(3)}]" }
{ "f" "_" }
{ "A" "B" }
{ "B" "C" }
{ "C" "D" }
{ "D" "E" }
{ "E" "G" }
{ "G" "H" }
{ "H" "N" }
{ "I" "FoO" }
{ "O" "FoP" }
{ "P" "FoQ" }
{ "Q" "FoR" }
{ "R" "FoS" }
{ "S" "FoT" }
{ "T" "FoU" }
{ "U" "FoV" }
{ "V" "FoW" }
{ "W" "FoX" }
{ "X" "_" }
{ "o" "$t(-0.03)" }
{ "r" "~(30)" }
}
>>rules ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: main ( -- ) [ L-system abop-4 "L-system" open-window ] with-ui ;
MAIN: main

View File

@ -0,0 +1,33 @@
USING: accessors ui L-system ;
IN: L-system.models.abop-5
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: abop-5 ( <L-system> -- <L-system> )
L-parser-dialect >>commands
"&(90)+(90)a" >>axiom
{
{ "a" "F[+(45)l][-(45)l]^;ca" }
{ "l" "j" }
{ "j" "h" }
{ "h" "s" }
{ "s" "d" }
{ "d" "x" }
{ "x" "a" }
{ "F" "'(1.17)F'(.855)" }
}
>>rules ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: main ( -- ) [ L-system abop-5 "L-system" open-window ] with-ui ;
MAIN: main

View File

@ -269,7 +269,7 @@ MEMO: fuel-article-title ( name -- title/f )
help-path [ dup article-title swap 2array ] map ; inline help-path [ dup article-title swap 2array ] map ; inline
: (fuel-word-help) ( word -- element ) : (fuel-word-help) ( word -- element )
dup \ article swap article-title rot \ article swap dup article-title swap
[ [
{ {
[ fuel-parent-topics [ \ $doc-path prefix , ] unless-empty ] [ fuel-parent-topics [ \ $doc-path prefix , ] unless-empty ]

View File

@ -1,40 +0,0 @@
! Copyright (C) 2007-2009 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel lists make math math.primes sequences ;
IN: math.primes.factors
<PRIVATE
: count-factor ( n d -- n' c )
0 [ [ 2dup mod zero? ] dip swap ] [ [ [ / ] keep ] dip 1+ ] [ ] while nip ;
: (factor) ( n d -- n' ) dup [ , ] curry [ count-factor ] dip times ;
: (count) ( n d -- n' )
dup [ swap 2array , ] curry
[ count-factor dup zero? [ drop ] ] dip if ;
: (unique) ( n d -- n' )
dup [ , ] curry [ count-factor zero? ] dip unless ;
: (factors) ( quot list n -- )
dup 1 > [
swap uncons swap [ pick call ] dip swap (factors)
] [ 3drop ] if ; inline recursive
: decompose ( n quot -- seq ) [ lprimes rot (factors) ] { } make ; inline
PRIVATE>
: factors ( n -- seq ) [ (factor) ] decompose ; flushable
: group-factors ( n -- seq ) [ (count) ] decompose ; flushable
: unique-factors ( n -- seq ) [ (unique) ] decompose ; flushable
: totient ( n -- t )
dup 2 < [
drop 0
] [
dup unique-factors [ 1 [ 1- * ] reduce ] [ product ] bi / *
] if ; foldable

View File

@ -0,0 +1 @@
Samuel Tardieu

View File

@ -0,0 +1,10 @@
USING: help.markup help.syntax ;
IN: math.primes.lists
HELP: lprimes
{ $values { "list" "a lazy list" } }
{ $description "Return a sorted list containing all the prime numbers." } ;
HELP: lprimes-from
{ $values { "n" "an integer" } { "list" "a lazy list" } }
{ $description "Return a sorted list containing all the prime numbers greater or equal to " { $snippet "n" } "." } ;

View File

@ -0,0 +1,6 @@
USING: lists.lazy math.primes.lists tools.test ;
{ { 2 3 5 7 11 13 17 19 23 29 } } [ 10 lprimes ltake list>array ] unit-test
{ { 101 103 107 109 113 } } [ 5 100 lprimes-from ltake list>array ] unit-test
{ { 1000117 1000121 } } [ 2 1000100 lprimes-from ltake list>array ] unit-test
{ { 999983 1000003 } } [ 2 999982 lprimes-from ltake list>array ] unit-test

View File

@ -0,0 +1,9 @@
! Copyright (C) 2007-2009 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel lists.lazy math math.primes ;
IN: math.primes.lists
: lprimes ( -- list ) 2 [ next-prime ] lfrom-by ;
: lprimes-from ( n -- list )
dup 3 < [ drop lprimes ] [ 1- next-prime [ next-prime ] lfrom-by ] if ;

View File

@ -0,0 +1 @@
Infinite stream of prime numbers through lazy lists

View File

@ -1,14 +0,0 @@
USING: arrays math.primes tools.test lists.lazy ;
{ 1237 } [ 1234 next-prime ] unit-test
{ f t } [ 1234 prime? 1237 prime? ] unit-test
{ { 2 3 5 7 11 13 17 19 23 29 } } [ 10 lprimes ltake list>array ] unit-test
{ { 101 103 107 109 113 } } [ 5 100 lprimes-from ltake list>array ] unit-test
{ { 1000117 1000121 } } [ 2 1000100 lprimes-from ltake list>array ] unit-test
{ { 999983 1000003 } } [ 2 999982 lprimes-from ltake list>array ] unit-test
{ { 2 3 5 7 } } [ 10 primes-upto >array ] unit-test
{ { 999983 1000003 } } [ 999982 1000010 primes-between >array ] unit-test
{ { 4999963 4999999 5000011 5000077 5000081 } }
[ 4999962 5000082 primes-between >array ]
unit-test

View File

@ -1,6 +1,6 @@
! Copyright (c) 2007 Aaron Schaefer. ! Copyright (c) 2007 Aaron Schaefer.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: lists math math.primes ; USING: lists math math.primes.lists ;
IN: project-euler.007 IN: project-euler.007
! http://projecteuler.net/index.php?section=problems&id=7 ! http://projecteuler.net/index.php?section=problems&id=7

View File

@ -1,7 +1,7 @@
! Copyright (c) 2007 Samuel Tardieu. ! Copyright (c) 2007 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel lists lists.lazy math.algebra math math.functions USING: arrays kernel lists lists.lazy math.algebra math math.functions
math.order math.primes math.ranges project-euler.common sequences ; math.order math.primes.lists math.ranges project-euler.common sequences ;
IN: project-euler.134 IN: project-euler.134
! http://projecteuler.net/index.php?section=problems&id=134 ! http://projecteuler.net/index.php?section=problems&id=134

View File

@ -74,6 +74,8 @@ beast.
- C-cM-<, C-cC-d< : show callers of word at point - C-cM-<, C-cC-d< : show callers of word at point
- C-cM->, C-cC-d> : show callees of word at point - C-cM->, C-cC-d> : show callees of word at point
- C-cC-xw : extract region as a separate word
*** In the listener: *** In the listener:
- TAB : complete word at point - TAB : complete word at point

View File

@ -21,6 +21,7 @@
(require 'fuel-eval) (require 'fuel-eval)
(require 'fuel-help) (require 'fuel-help)
(require 'fuel-xref) (require 'fuel-xref)
(require 'fuel-refactor)
(require 'fuel-stack) (require 'fuel-stack)
(require 'fuel-autodoc) (require 'fuel-autodoc)
(require 'fuel-font-lock) (require 'fuel-font-lock)
@ -224,6 +225,8 @@ interacting with a factor listener is at your disposal.
(fuel-mode--key ?e ?w 'fuel-edit-word) (fuel-mode--key ?e ?w 'fuel-edit-word)
(fuel-mode--key ?e ?x 'fuel-eval-definition) (fuel-mode--key ?e ?x 'fuel-eval-definition)
(fuel-mode--key ?x ?w 'fuel-refactor-extract-word)
(fuel-mode--key ?d ?> 'fuel-show-callees) (fuel-mode--key ?d ?> 'fuel-show-callees)
(fuel-mode--key ?d ?< 'fuel-show-callers) (fuel-mode--key ?d ?< 'fuel-show-callers)
(fuel-mode--key ?d ?a 'fuel-autodoc-mode) (fuel-mode--key ?d ?a 'fuel-autodoc-mode)

View File

@ -0,0 +1,57 @@
;;; fuel-refactor.el -- code refactoring support
;; Copyright (C) 2009 Jose Antonio Ortega Ruiz
;; See http://factorcode.org/license.txt for BSD license.
;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
;; Keywords: languages, fuel, factor
;; Start date: Thu Jan 08, 2009 00:57
;;; Comentary:
;; Utilities performing refactoring on factor code.
;;; Code:
(require 'fuel-stack)
(require 'fuel-syntax)
(require 'fuel-base)
;;; Extract word:
(defun fuel-refactor-extract-word (begin end)
"Extracts current region as a separate word."
(interactive "r")
(let* ((word (read-string "New word name: "))
(begin (save-excursion
(goto-char begin)
(when (zerop (skip-syntax-backward "w"))
(skip-syntax-forward "-"))
(point)))
(end (save-excursion
(goto-char end)
(skip-syntax-forward "w")
(point)))
(code (buffer-substring begin end))
(code-str (fuel--region-to-string begin end))
(stack-effect (or (fuel-stack--infer-effect code-str)
(read-string "Stack effect: "))))
(goto-char begin)
(delete-region begin end)
(insert word)
(indent-region begin (point))
(set-mark (point))
(fuel-syntax--beginning-of-defun)
(open-line 1)
(let ((start (point)))
(insert ": " word " " stack-effect "\n" code " ;\n")
(indent-region start (point))
(move-overlay fuel-stack--overlay start (point))
(goto-char (mark))
(sit-for fuel-stack-highlight-period)
(delete-overlay fuel-stack--overlay))))
(provide 'fuel-refactor)
;;; fuel-refactor.el ends here