diff --git a/.gitignore b/.gitignore index 290f075aae..f4334f3727 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ temp logs work build-support/wordsize +*.bak diff --git a/Makefile b/Makefile index 973ba1f3d4..ffcbf6364c 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ factor: $(DLL_OBJS) $(EXE_OBJS) clean: rm -f vm/*.o - rm -f factor*.dll libfactor*.* + rm -f factor*.dll libfactor.{a,so,dylib} vm/resources.o: $(WINDRES) vm/factor.rs vm/resources.o diff --git a/basis/alarms/alarms.factor b/basis/alarms/alarms.factor index 7fdeca9ae6..ad1838b3df 100644 --- a/basis/alarms/alarms.factor +++ b/basis/alarms/alarms.factor @@ -35,7 +35,7 @@ ERROR: bad-alarm-frequency frequency ; [ time>> ] dip before=? ; : reschedule-alarm ( alarm -- ) - dup [ swap interval>> time+ ] change-time register-alarm ; + dup [ swap interval>> time+ now max ] change-time register-alarm ; : call-alarm ( alarm -- ) [ entry>> box> drop ] diff --git a/basis/bootstrap/help/help.factor b/basis/bootstrap/help/help.factor index e2a2288988..5b49ce2802 100644 --- a/basis/bootstrap/help/help.factor +++ b/basis/bootstrap/help/help.factor @@ -1,6 +1,6 @@ USING: help help.topics help.syntax help.crossref help.definitions io io.files kernel namespaces vocabs sequences -parser vocabs.loader ; +parser vocabs.loader vocabs.loader.private accessors assocs ; IN: bootstrap.help : load-help ( -- ) @@ -10,8 +10,8 @@ IN: bootstrap.help t load-help? set-global [ drop ] load-vocab-hook [ - vocabs - [ vocab-docs-loaded? not ] filter + dictionary get values + [ docs-loaded?>> not ] filter [ load-docs ] each ] with-variable ; diff --git a/basis/bootstrap/image/image.factor b/basis/bootstrap/image/image.factor index c0fafdc0f5..d5f36db776 100644 --- a/basis/bootstrap/image/image.factor +++ b/basis/bootstrap/image/image.factor @@ -130,6 +130,12 @@ SYMBOL: jit-if-word SYMBOL: jit-if-jump SYMBOL: jit-dispatch-word SYMBOL: jit-dispatch +SYMBOL: jit-dip-word +SYMBOL: jit-dip +SYMBOL: jit-2dip-word +SYMBOL: jit-2dip +SYMBOL: jit-3dip-word +SYMBOL: jit-3dip SYMBOL: jit-epilog SYMBOL: jit-return SYMBOL: jit-profiling @@ -139,8 +145,8 @@ SYMBOL: jit-save-stack ! Default definition for undefined words SYMBOL: undefined-quot -: userenv-offset ( symbol -- n ) - { +: userenvs ( -- assoc ) + H{ { bootstrap-boot-quot 20 } { bootstrap-global 21 } { jit-code-format 22 } @@ -160,8 +166,17 @@ SYMBOL: undefined-quot { jit-push-immediate 36 } { jit-declare-word 42 } { jit-save-stack 43 } + { jit-dip-word 44 } + { jit-dip 45 } + { jit-2dip-word 46 } + { jit-2dip 47 } + { jit-3dip-word 48 } + { jit-3dip 49 } { undefined-quot 60 } - } at header-size + ; + } ; inline + +: userenv-offset ( symbol -- n ) + userenvs at header-size + ; : emit ( cell -- ) image get push ; @@ -443,6 +458,9 @@ M: quotation ' \ dispatch jit-dispatch-word set \ do-primitive jit-primitive-word set \ declare jit-declare-word set + \ dip jit-dip-word set + \ 2dip jit-2dip-word set + \ 3dip jit-3dip-word set [ undefined ] undefined-quot set { jit-code-format @@ -457,6 +475,12 @@ M: quotation ' jit-if-jump jit-dispatch-word jit-dispatch + jit-dip-word + jit-dip + jit-2dip-word + jit-2dip + jit-3dip-word + jit-3dip jit-epilog jit-return jit-profiling diff --git a/basis/bootstrap/stage2.factor b/basis/bootstrap/stage2.factor index 78d555fe92..ac8e5343e1 100644 --- a/basis/bootstrap/stage2.factor +++ b/basis/bootstrap/stage2.factor @@ -67,7 +67,7 @@ SYMBOL: bootstrap-time os wince? [ "windows.ce" require ] when os winnt? [ "windows.nt" require ] when - "deploy-vocab" get [ + "staging" get "deploy-vocab" get or [ "stage2: deployment mode" print ] [ "listener" require diff --git a/basis/cocoa/dialogs/dialogs.factor b/basis/cocoa/dialogs/dialogs.factor index 606526a240..662b4a7bae 100644 --- a/basis/cocoa/dialogs/dialogs.factor +++ b/basis/cocoa/dialogs/dialogs.factor @@ -26,7 +26,7 @@ IN: cocoa.dialogs [ -> filenames CF>string-array ] [ drop f ] if ; : split-path ( path -- dir file ) - "/" last-split1 [ ] bi@ ; + "/" split1-last [ ] bi@ ; : save-panel ( path -- paths ) dup diff --git a/basis/combinators/short-circuit/short-circuit-docs.factor b/basis/combinators/short-circuit/short-circuit-docs.factor index 54fc3aac43..6cd18201fe 100644 --- a/basis/combinators/short-circuit/short-circuit-docs.factor +++ b/basis/combinators/short-circuit/short-circuit-docs.factor @@ -52,17 +52,17 @@ HELP: 3|| { "quot" quotation } } { $description "Returns true if any quotation in the sequence returns true. Each quotation takes the same three elements from the datastack and must return a boolean." } ; -HELP: n&&-rewrite +HELP: n&& { $values { "quots" "a sequence of quotations" } { "N" integer } { "quot" quotation } } -{ $description "A macro that reqrites the code to pass " { $snippet "N" } " parameters from the stack to each AND quotation." } ; +{ $description "A macro that rewrites the code to pass " { $snippet "n" } " parameters from the stack to each AND quotation." } ; -HELP: n||-rewrite +HELP: n|| { $values - { "quots" "a sequence of quotations" } { "N" integer } + { "quots" "a sequence of quotations" } { "n" integer } { "quot" quotation } } -{ $description "A macro that reqrites the code to pass " { $snippet "N" } " parameters from the stack to each OR quotation." } ; +{ $description "A macro that rewrites the code to pass " { $snippet "n" } " parameters from the stack to each OR quotation." } ; ARTICLE: "combinators.short-circuit" "Short-circuit combinators" "The " { $vocab-link "combinators.short-circuit" } " vocabulary stops a computation early once a condition is met." $nl @@ -77,8 +77,8 @@ ARTICLE: "combinators.short-circuit" "Short-circuit combinators" { $subsection 2|| } { $subsection 3|| } "Generalized combinators:" -{ $subsection n&&-rewrite } -{ $subsection n||-rewrite } +{ $subsection n&& } +{ $subsection n|| } ; ABOUT: "combinators.short-circuit" diff --git a/basis/combinators/short-circuit/short-circuit.factor b/basis/combinators/short-circuit/short-circuit.factor index 7b6c1d126d..2b4e522789 100644 --- a/basis/combinators/short-circuit/short-circuit.factor +++ b/basis/combinators/short-circuit/short-circuit.factor @@ -1,35 +1,26 @@ - USING: kernel combinators quotations arrays sequences assocs - locals generalizations macros fry ; - +locals generalizations macros fry ; IN: combinators.short-circuit -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +MACRO:: n&& ( quots n -- quot ) + [ f ] + quots [| q | { [ drop n ndup q call dup not ] [ drop n ndrop f ] } ] map + [ n nnip ] suffix 1array + [ cond ] 3append ; -:: n&&-rewrite ( quots N -- quot ) - quots - [ '[ drop N ndup @ dup not ] [ drop N ndrop f ] 2array ] - map - [ t ] [ N nnip ] 2array suffix - '[ f _ cond ] ; +MACRO: 0&& ( quots -- quot ) '[ _ 0 n&& ] ; +MACRO: 1&& ( quots -- quot ) '[ _ 1 n&& ] ; +MACRO: 2&& ( quots -- quot ) '[ _ 2 n&& ] ; +MACRO: 3&& ( quots -- quot ) '[ _ 3 n&& ] ; -MACRO: 0&& ( quots -- quot ) 0 n&&-rewrite ; -MACRO: 1&& ( quots -- quot ) 1 n&&-rewrite ; -MACRO: 2&& ( quots -- quot ) 2 n&&-rewrite ; -MACRO: 3&& ( quots -- quot ) 3 n&&-rewrite ; +MACRO:: n|| ( quots n -- quot ) + [ f ] + quots + [| q | { [ drop n ndup q call dup ] [ n nnip ] } ] map + { [ drop n ndrop t ] [ f ] } suffix 1array + [ cond ] 3append ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -:: n||-rewrite ( quots N -- quot ) - quots - [ '[ drop N ndup @ dup ] [ N nnip ] 2array ] - map - [ drop N ndrop t ] [ f ] 2array suffix - '[ f _ cond ] ; - -MACRO: 0|| ( quots -- quot ) 0 n||-rewrite ; -MACRO: 1|| ( quots -- quot ) 1 n||-rewrite ; -MACRO: 2|| ( quots -- quot ) 2 n||-rewrite ; -MACRO: 3|| ( quots -- quot ) 3 n||-rewrite ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +MACRO: 0|| ( quots -- quot ) '[ _ 0 n|| ] ; +MACRO: 1|| ( quots -- quot ) '[ _ 1 n|| ] ; +MACRO: 2|| ( quots -- quot ) '[ _ 2 n|| ] ; +MACRO: 3|| ( quots -- quot ) '[ _ 3 n|| ] ; diff --git a/basis/combinators/short-circuit/smart/smart.factor b/basis/combinators/short-circuit/smart/smart.factor index ca659cacbe..b80e7294d1 100644 --- a/basis/combinators/short-circuit/smart/smart.factor +++ b/basis/combinators/short-circuit/smart/smart.factor @@ -1,7 +1,5 @@ - USING: kernel sequences math stack-checker effects accessors macros - combinators.short-circuit ; - +fry combinators.short-circuit ; IN: combinators.short-circuit.smart -MACRO: && ( quots -- quot ) dup arity n&&-rewrite ; +MACRO: && ( quots -- quot ) dup arity '[ _ _ n&& ] ; -MACRO: || ( quots -- quot ) dup arity n||-rewrite ; +MACRO: || ( quots -- quot ) dup arity '[ _ _ n|| ] ; diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor index a6afc4b243..e5cbd888d9 100644 --- a/basis/compiler/compiler.factor +++ b/basis/compiler/compiler.factor @@ -91,8 +91,8 @@ t compile-dependencies? set-global [ dup crossref? [ - dependencies get >alist - generic-dependencies get >alist + dependencies get + generic-dependencies get compiled-xref ] [ drop ] if ] tri ; diff --git a/basis/compiler/tests/redefine13.factor b/basis/compiler/tests/redefine13.factor new file mode 100644 index 0000000000..d092cd4ee1 --- /dev/null +++ b/basis/compiler/tests/redefine13.factor @@ -0,0 +1,14 @@ +USING: math fry macros eval tools.test ; +IN: compiler.tests.redefine13 + +: breakage-word ( a b -- c ) + ; + +MACRO: breakage-macro ( a -- ) '[ _ breakage-word ] ; + +GENERIC: breakage-caller ( a -- c ) + +M: fixnum breakage-caller 2 breakage-macro ; + +: breakage ( -- obj ) 2 breakage-caller ; + +! [ ] [ "IN: compiler.tests.redefine13 : breakage-word ( a b -- c ) ;" eval ] unit-test diff --git a/basis/compiler/tests/redefine14.factor b/basis/compiler/tests/redefine14.factor new file mode 100644 index 0000000000..807f3ed2c7 --- /dev/null +++ b/basis/compiler/tests/redefine14.factor @@ -0,0 +1,8 @@ +USING: compiler.units definitions tools.test sequences ; +IN: compiler.tests.redefine14 + +! TUPLE: bad ; +! +! M: bad length 1 2 3 ; +! +! [ ] [ [ { bad length } forget ] with-compilation-unit ] unit-test diff --git a/basis/compiler/tree/propagation/info/info.factor b/basis/compiler/tree/propagation/info/info.factor index e89a9c6211..771d3800df 100644 --- a/basis/compiler/tree/propagation/info/info.factor +++ b/basis/compiler/tree/propagation/info/info.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: assocs classes classes.algebra classes.tuple classes.tuple.private kernel accessors math math.intervals -namespaces sequences words combinators combinators.short-circuit +namespaces sequences words combinators arrays compiler.tree.propagation.copy ; IN: compiler.tree.propagation.info @@ -253,12 +253,13 @@ DEFER: (value-info-union) { [ over not ] [ 2drop f ] } [ { - [ [ class>> ] bi@ class<= ] - [ [ interval>> ] bi@ interval-subset? ] - [ literals<= ] - [ [ length>> ] bi@ value-info<= ] - [ [ slots>> ] bi@ [ value-info<= ] 2all? ] - } 2&& + { [ 2dup [ class>> ] bi@ class<= not ] [ f ] } + { [ 2dup [ interval>> ] bi@ interval-subset? not ] [ f ] } + { [ 2dup literals<= not ] [ f ] } + { [ 2dup [ length>> ] bi@ value-info<= not ] [ f ] } + { [ 2dup [ slots>> ] bi@ [ value-info<= ] 2all? not ] [ f ] } + [ t ] + } cond 2nip ] } cond ; diff --git a/basis/compiler/tree/propagation/known-words/known-words.factor b/basis/compiler/tree/propagation/known-words/known-words.factor index 3b698e0001..f6e2bc0940 100644 --- a/basis/compiler/tree/propagation/known-words/known-words.factor +++ b/basis/compiler/tree/propagation/known-words/known-words.factor @@ -138,6 +138,12 @@ most-negative-fixnum most-positive-fixnum [a,b] \ mod [ [ interval-mod ] [ real-valued ] binary-op ] each-derived-op \ rem [ [ interval-rem ] [ may-overflow real-valued ] binary-op ] each-derived-op +{ /mod fixnum/mod } [ + \ /i \ mod + [ "outputs" word-prop ] bi@ + '[ _ _ 2bi ] "outputs" set-word-prop +] each + \ shift [ [ interval-shift-safe ] [ may-overflow integer-valued ] binary-op ] each-derived-op \ shift [ [ interval-shift-safe ] [ integer-valued ] binary-op ] each-fast-derived-op diff --git a/basis/concurrency/combinators/combinators-docs.factor b/basis/concurrency/combinators/combinators-docs.factor index cb07e5a8d6..c61967fc8a 100644 --- a/basis/concurrency/combinators/combinators-docs.factor +++ b/basis/concurrency/combinators/combinators-docs.factor @@ -27,11 +27,17 @@ HELP: parallel-filter { $errors "Throws an error if one of the iterations throws an error." } ; ARTICLE: "concurrency.combinators" "Concurrent combinators" -"The " { $vocab-link "concurrency.combinators" } " vocabulary provides concurrent variants of " { $link each } ", " { $link map } " and " { $link filter } ":" +"The " { $vocab-link "concurrency.combinators" } " vocabulary provides concurrent variants of various combinators." +$nl +"Concurrent sequence combinators:" { $subsection parallel-each } { $subsection 2parallel-each } { $subsection parallel-map } { $subsection 2parallel-map } -{ $subsection parallel-filter } ; +{ $subsection parallel-filter } +"Concurrent cleave combinators:" +{ $subsection parallel-cleave } +{ $subsection parallel-spread } +{ $subsection parallel-napply } ; ABOUT: "concurrency.combinators" diff --git a/basis/concurrency/combinators/combinators-tests.factor b/basis/concurrency/combinators/combinators-tests.factor index 440a6766c5..1c2dea2d79 100644 --- a/basis/concurrency/combinators/combinators-tests.factor +++ b/basis/concurrency/combinators/combinators-tests.factor @@ -1,6 +1,7 @@ IN: concurrency.combinators.tests USING: concurrency.combinators tools.test random kernel math -concurrency.mailboxes threads sequences accessors arrays ; +concurrency.mailboxes threads sequences accessors arrays +math.parser ; [ [ drop ] parallel-each ] must-infer { 2 0 } [ [ 2drop ] 2parallel-each ] must-infer-as @@ -45,3 +46,10 @@ concurrency.mailboxes threads sequences accessors arrays ; ] unit-test [ { f } [ "OOPS" throw ] parallel-each ] must-fail + +[ "1a" "4b" "3c" ] [ + 2 + { [ 1- ] [ sq ] [ 1+ ] } parallel-cleave + [ number>string ] 3 parallel-napply + { [ "a" append ] [ "b" append ] [ "c" append ] } parallel-spread +] unit-test diff --git a/basis/concurrency/combinators/combinators.factor b/basis/concurrency/combinators/combinators.factor index ab3ca7ed4a..4608faf79b 100644 --- a/basis/concurrency/combinators/combinators.factor +++ b/basis/concurrency/combinators/combinators.factor @@ -1,34 +1,58 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: concurrency.futures concurrency.count-downs sequences -kernel ; +kernel macros fry combinators generalizations ; IN: concurrency.combinators r r> keep await ; inline + [ ] dip keep await ; inline + PRIVATE> : parallel-each ( seq quot -- ) over length [ - [ >r curry r> spawn-stage ] 2curry each + '[ _ curry _ spawn-stage ] each ] (parallel-each) ; inline : 2parallel-each ( seq1 seq2 quot -- ) 2over min-length [ - [ >r 2curry r> spawn-stage ] 2curry 2each + '[ _ 2curry _ spawn-stage ] 2each ] (parallel-each) ; inline : parallel-filter ( seq quot -- newseq ) - over >r pusher >r each r> r> like ; inline + over [ pusher [ each ] dip ] dip like ; inline : parallel-map ( seq quot -- newseq ) - [ curry future ] curry map future-values ; - inline + [future] map future-values ; inline : 2parallel-map ( seq1 seq2 quot -- newseq ) - [ 2curry future ] curry 2map future-values ; + '[ _ 2curry future ] 2map future-values ; + + ; inline + +: (parallel-cleave) ( quots -- quot-array spread-array ) + [ [future] ] map dup length (parallel-spread) ; inline + +PRIVATE> + +MACRO: parallel-cleave ( quots -- ) + (parallel-cleave) '[ _ cleave _ spread ] ; + +MACRO: parallel-spread ( quots -- ) + (parallel-cleave) '[ _ spread _ spread ] ; + +MACRO: parallel-napply ( quot n -- ) + [ [future] ] dip dup (parallel-spread) '[ _ _ napply _ spread ] ; diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor index aee0f3f4f3..56ef89884c 100644 --- a/basis/cpu/ppc/bootstrap.factor +++ b/basis/cpu/ppc/bootstrap.factor @@ -71,11 +71,16 @@ big-endian on [ 0 B ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define -: jit-call-quot ( -- ) +: jit-jump-quot ( -- ) 4 3 quot-xt-offset LWZ 4 MTCTR BCTR ; +: jit-call-quot ( -- ) + 4 3 quot-xt-offset LWZ + 4 MTLR + BLR ; + [ 0 3 LOAD32 6 ds-reg 0 LWZ @@ -84,7 +89,7 @@ big-endian on 3 3 4 ADDI 3 3 0 LWZ ds-reg dup 4 SUBI - jit-call-quot + jit-jump-quot ] rc-absolute-ppc-2/2 rt-literal 1 jit-if-jump jit-define [ @@ -95,9 +100,83 @@ big-endian on 3 3 6 ADD 3 3 array-start-offset LWZ ds-reg dup 4 SUBI - jit-call-quot + jit-jump-quot ] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define +! These should not clobber r3 since we store a quotation in there +! in jit-dip + +: jit->r ( -- ) + 4 ds-reg 0 LWZ + ds-reg dup 4 SUBI + 4 rs-reg 4 STWU ; + +: jit-2>r ( -- ) + 4 ds-reg 0 LWZ + 5 ds-reg -4 LWZ + ds-reg dup 8 SUBI + rs-reg dup 8 ADDI + 4 rs-reg 0 STW + 5 rs-reg -4 STW ; + +: jit-3>r ( -- ) + 4 ds-reg 0 LWZ + 5 ds-reg -4 LWZ + 6 ds-reg -8 LWZ + ds-reg dup 12 SUBI + rs-reg dup 12 ADDI + 4 rs-reg 0 STW + 5 rs-reg -4 STW + 6 rs-reg -8 STW ; + +: jit-r> ( -- ) + 4 ds-reg 0 LWZ + ds-reg dup 4 SUBI + 4 rs-reg 4 STWU ; + +: jit-2r> ( -- ) + 4 rs-reg 0 LWZ + 5 rs-reg -4 LWZ + rs-reg dup 8 SUBI + ds-reg dup 8 ADDI + 4 ds-reg 0 STW + 5 ds-reg -4 STW ; + +: jit-3r> ( -- ) + 4 rs-reg 0 LWZ + 5 rs-reg -4 LWZ + 6 rs-reg -8 LWZ + rs-reg dup 12 SUBI + ds-reg dup 12 ADDI + 4 ds-reg 0 STW + 5 ds-reg -4 STW + 6 ds-reg -8 STW ; + +: prepare-dip ( -- ) + 0 3 LOAD32 + 3 3 0 LWZ ; + +[ + prepare-dip + jit->r + jit-call-quot + jit-r> +] rc-absolute-ppc-2/2 rt-literal 1 jit-dip jit-define + +[ + prepare-dip + jit-2>r + jit-call-quot + jit-2r> +] rc-absolute-ppc-2/2 rt-literal 1 jit-2dip jit-define + +[ + prepare-dip + jit-3>r + jit-call-quot + jit-3r> +] rc-absolute-ppc-2/2 rt-literal 1 jit-3dip jit-define + [ 0 1 lr-save stack-frame + LWZ 1 1 stack-frame ADDI @@ -112,7 +191,7 @@ big-endian on [ 3 ds-reg 0 LWZ ds-reg dup 4 SUBI - jit-call-quot + jit-jump-quot ] f f f \ (call) define-sub-primitive [ @@ -245,17 +324,9 @@ big-endian on 4 ds-reg 0 STW ] f f f \ -rot define-sub-primitive -[ - 3 ds-reg 0 LWZ - ds-reg dup 4 SUBI - 3 rs-reg 4 STWU -] f f f \ >r define-sub-primitive +[ jit->r ] f f f \ >r define-sub-primitive -[ - 3 rs-reg 0 LWZ - rs-reg dup 4 SUBI - 3 ds-reg 4 STWU -] f f f \ r> define-sub-primitive +[ jit-r> ] f f f \ r> define-sub-primitive ! Comparisons : jit-compare ( insn -- ) @@ -335,6 +406,24 @@ big-endian on 7 ds-reg 0 STW ] f f f \ fixnum-mod define-sub-primitive +[ + 3 ds-reg 0 LWZ + ds-reg ds-reg 4 SUBI + 4 ds-reg 0 LWZ + 5 4 3 DIVW + 5 ds-reg 0 STW +] f f f \ fixnum/i-fast define-sub-primitive + +[ + 3 ds-reg 0 LWZ + 4 ds-reg -4 LWZ + 5 4 3 DIVW + 6 5 3 MULLW + 7 6 4 SUBF + 5 ds-reg -4 STW + 7 ds-reg 0 STW +] f f f \ fixnum/mod-fast define-sub-primitive + [ 3 ds-reg 0 LWZ 3 3 1 SRAWI diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index ba963ab477..04bdcca68b 100644 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -12,6 +12,7 @@ IN: bootstrap.x86 : mod-arg ( -- reg ) EDX ; : arg0 ( -- reg ) EAX ; : arg1 ( -- reg ) EDX ; +: arg2 ( -- reg ) ECX ; : temp-reg ( -- reg ) EBX ; : stack-reg ( -- reg ) ESP ; : ds-reg ( -- reg ) ESI ; diff --git a/basis/cpu/x86/64/unix/bootstrap.factor b/basis/cpu/x86/64/unix/bootstrap.factor index 29d48bd794..f0ca56da14 100644 --- a/basis/cpu/x86/64/unix/bootstrap.factor +++ b/basis/cpu/x86/64/unix/bootstrap.factor @@ -7,6 +7,7 @@ IN: bootstrap.x86 : stack-frame-size ( -- n ) 4 bootstrap-cells ; : arg0 ( -- reg ) RDI ; : arg1 ( -- reg ) RSI ; +: arg2 ( -- reg ) RDX ; << "resource:basis/cpu/x86/64/bootstrap.factor" parse-file parsed >> call diff --git a/basis/cpu/x86/64/winnt/bootstrap.factor b/basis/cpu/x86/64/winnt/bootstrap.factor index a62b946e83..459945d82e 100644 --- a/basis/cpu/x86/64/winnt/bootstrap.factor +++ b/basis/cpu/x86/64/winnt/bootstrap.factor @@ -7,6 +7,7 @@ IN: bootstrap.x86 : stack-frame-size ( -- n ) 8 bootstrap-cells ; : arg0 ( -- reg ) RCX ; : arg1 ( -- reg ) RDX ; +: arg2 ( -- reg ) R8 ; << "resource:basis/cpu/x86/64/bootstrap.factor" parse-file parsed >> call diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index 1ee74a434b..af7c9e2f0f 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -73,6 +73,80 @@ big-endian off arg0 quot-xt-offset [+] JMP ! execute branch ] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define +! The jit->r words cannot clobber arg0 + +: jit->r ( -- ) + rs-reg bootstrap-cell ADD + temp-reg ds-reg [] MOV + ds-reg bootstrap-cell SUB + rs-reg [] temp-reg MOV ; + +: jit-2>r ( -- ) + rs-reg 2 bootstrap-cells ADD + temp-reg ds-reg [] MOV + arg1 ds-reg -1 bootstrap-cells [+] MOV + ds-reg 2 bootstrap-cells SUB + rs-reg [] temp-reg MOV + rs-reg -1 bootstrap-cells [+] arg1 MOV ; + +: jit-3>r ( -- ) + rs-reg 3 bootstrap-cells ADD + temp-reg ds-reg [] MOV + arg1 ds-reg -1 bootstrap-cells [+] MOV + arg2 ds-reg -2 bootstrap-cells [+] MOV + ds-reg 3 bootstrap-cells SUB + rs-reg [] temp-reg MOV + rs-reg -1 bootstrap-cells [+] arg1 MOV + rs-reg -2 bootstrap-cells [+] arg2 MOV ; + +: jit-r> ( -- ) + ds-reg bootstrap-cell ADD + temp-reg rs-reg [] MOV + rs-reg bootstrap-cell SUB + ds-reg [] temp-reg MOV ; + +: jit-2r> ( -- ) + ds-reg 2 bootstrap-cells ADD + temp-reg rs-reg [] MOV + arg1 rs-reg -1 bootstrap-cells [+] MOV + rs-reg 2 bootstrap-cells SUB + ds-reg [] temp-reg MOV + ds-reg -1 bootstrap-cells [+] arg1 MOV ; + +: jit-3r> ( -- ) + ds-reg 3 bootstrap-cells ADD + temp-reg rs-reg [] MOV + arg1 rs-reg -1 bootstrap-cells [+] MOV + arg2 rs-reg -2 bootstrap-cells [+] MOV + rs-reg 3 bootstrap-cells SUB + ds-reg [] temp-reg MOV + ds-reg -1 bootstrap-cells [+] arg1 MOV + ds-reg -2 bootstrap-cells [+] arg2 MOV ; + +[ + arg0 0 MOV ! load quotation addr + arg0 arg0 [] MOV ! load quotation + jit->r + arg0 quot-xt-offset [+] CALL ! call quotation + jit-r> +] rc-absolute-cell rt-literal 1 rex-length + jit-dip jit-define + +[ + arg0 0 MOV ! load quotation addr + arg0 arg0 [] MOV ! load quotation + jit-2>r + arg0 quot-xt-offset [+] CALL ! call quotation + jit-2r> +] rc-absolute-cell rt-literal 1 rex-length + jit-2dip jit-define + +[ + arg0 0 MOV ! load quotation addr + arg0 arg0 [] MOV ! load quotation + jit-3>r + arg0 quot-xt-offset [+] CALL ! call quotation + jit-3r> +] rc-absolute-cell rt-literal 1 rex-length + jit-3dip jit-define + [ stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame ] f f f jit-epilog jit-define @@ -223,19 +297,9 @@ big-endian off ds-reg [] arg1 MOV ] f f f \ -rot define-sub-primitive -[ - rs-reg bootstrap-cell ADD - arg0 ds-reg [] MOV - ds-reg bootstrap-cell SUB - rs-reg [] arg0 MOV -] f f f \ >r define-sub-primitive +[ jit->r ] f f f \ >r define-sub-primitive -[ - ds-reg bootstrap-cell ADD - arg0 rs-reg [] MOV - rs-reg bootstrap-cell SUB - ds-reg [] arg0 MOV -] f f f \ r> define-sub-primitive +[ jit-r> ] f f f \ r> define-sub-primitive ! Comparisons : jit-compare ( insn -- ) @@ -305,16 +369,33 @@ big-endian off ds-reg [] arg1 MOV ! push to stack ] f f f \ fixnum-shift-fast define-sub-primitive -[ +: jit-fixnum-/mod ( -- ) temp-reg ds-reg [] MOV ! load second parameter - ds-reg bootstrap-cell SUB ! adjust stack pointer - div-arg ds-reg [] MOV ! load first parameter + div-arg ds-reg bootstrap-cell neg [+] MOV ! load first parameter mod-arg div-arg MOV ! make a copy mod-arg bootstrap-cell-bits 1- SAR ! sign-extend - temp-reg IDIV ! divide + temp-reg IDIV ; ! divide + +[ + jit-fixnum-/mod + ds-reg bootstrap-cell SUB ! adjust stack pointer ds-reg [] mod-arg MOV ! push to stack ] f f f \ fixnum-mod define-sub-primitive +[ + jit-fixnum-/mod + ds-reg bootstrap-cell SUB ! adjust stack pointer + div-arg tag-bits get SHL ! tag it + ds-reg [] div-arg MOV ! push to stack +] f f f \ fixnum/i-fast define-sub-primitive + +[ + jit-fixnum-/mod + div-arg tag-bits get SHL ! tag it + ds-reg [] mod-arg MOV ! push to stack + ds-reg bootstrap-cell neg [+] div-arg MOV +] f f f \ fixnum/mod-fast define-sub-primitive + [ arg0 ds-reg [] MOV ! load local number fixnum>slot@ ! turn local number into offset diff --git a/basis/debugger/debugger.factor b/basis/debugger/debugger.factor index ec93a01c19..0e7a56ee5f 100644 --- a/basis/debugger/debugger.factor +++ b/basis/debugger/debugger.factor @@ -206,9 +206,8 @@ M: no-cond summary M: no-case summary drop "Fall-through in case" ; -M: slice-error error. - "Cannot create slice because " write - reason>> print ; +M: slice-error summary + drop "Cannot create slice" ; M: bounds-error summary drop "Sequence index out of bounds" ; diff --git a/basis/documents/documents.factor b/basis/documents/documents.factor index 54bc85284a..a82437ba40 100644 --- a/basis/documents/documents.factor +++ b/basis/documents/documents.factor @@ -5,9 +5,9 @@ sequences strings splitting combinators unicode.categories math.order ; IN: documents -: +col ( loc n -- newloc ) >r first2 r> + 2array ; +: +col ( loc n -- newloc ) [ first2 ] dip + 2array ; -: +line ( loc n -- newloc ) >r first2 swap r> + swap 2array ; +: +line ( loc n -- newloc ) [ first2 swap ] dip + swap 2array ; : =col ( n loc -- newloc ) first swap 2array ; @@ -31,10 +31,10 @@ TUPLE: document < model locs ; : doc-line ( n document -- string ) value>> nth ; : doc-lines ( from to document -- slice ) - >r 1+ r> value>> ; + [ 1+ ] dip value>> ; : start-on-line ( document from line# -- n1 ) - >r dup first r> = [ nip second ] [ 2drop 0 ] if ; + [ dup first ] dip = [ nip second ] [ 2drop 0 ] if ; : end-on-line ( document to line# -- n2 ) over first over = [ @@ -47,12 +47,14 @@ TUPLE: document < model locs ; 2over = [ 3drop ] [ - >r [ first ] bi@ 1+ dup r> each + [ [ first ] bi@ 1+ dup ] dip each ] if ; inline : start/end-on-line ( from to line# -- n1 n2 ) - tuck >r >r document get -rot start-on-line r> r> - document get -rot end-on-line ; + tuck + [ [ document get ] 2dip start-on-line ] + [ [ document get ] 2dip end-on-line ] + 2bi* ; : (doc-range) ( from to line# -- ) [ start/end-on-line ] keep document get doc-line , ; @@ -60,16 +62,18 @@ TUPLE: document < model locs ; : doc-range ( from to document -- string ) [ document set 2dup [ - >r 2dup r> (doc-range) + [ 2dup ] dip (doc-range) ] each-line 2drop ] { } make "\n" join ; : text+loc ( lines loc -- loc ) - over >r over length 1 = [ - nip first2 - ] [ - first swap length 1- + 0 - ] if r> peek length + 2array ; + over [ + over length 1 = [ + nip first2 + ] [ + first swap length 1- + 0 + ] if + ] dip peek length + 2array ; : prepend-first ( str seq -- ) 0 swap [ append ] change-nth ; @@ -78,25 +82,25 @@ TUPLE: document < model locs ; [ length 1- ] keep [ prepend ] change-nth ; : loc-col/str ( loc document -- str col ) - >r first2 swap r> nth swap ; + [ first2 swap ] dip nth swap ; : prepare-insert ( newinput from to lines -- newinput ) - tuck loc-col/str tail-slice >r loc-col/str head-slice r> + tuck [ loc-col/str head-slice ] [ loc-col/str tail-slice ] 2bi* pick append-last over prepend-first ; : (set-doc-range) ( newlines from to lines -- ) [ prepare-insert ] 3keep - >r [ first ] bi@ 1+ r> + [ [ first ] bi@ 1+ ] dip replace-slice ; : set-doc-range ( string from to document -- ) [ - >r >r >r string-lines r> [ text+loc ] 2keep r> r> + [ [ string-lines ] dip [ text+loc ] 2keep ] 2dip [ [ (set-doc-range) ] keep ] change-model ] keep update-locs ; : remove-doc-range ( from to document -- ) - >r >r >r "" r> r> r> set-doc-range ; + [ "" ] 3dip set-doc-range ; : last-line# ( document -- line ) value>> length 1- ; @@ -111,7 +115,7 @@ TUPLE: document < model locs ; dupd doc-line length 2array ; : line-end? ( loc document -- ? ) - >r first2 swap r> doc-line length = ; + [ first2 swap ] dip doc-line length = ; : doc-end ( document -- loc ) [ last-line# ] keep line-end ; @@ -123,7 +127,7 @@ TUPLE: document < model locs ; over first 0 < [ 2drop { 0 0 } ] [ - >r first2 swap tuck r> validate-col 2array + [ first2 swap tuck ] dip validate-col 2array ] if ] if ; @@ -131,7 +135,7 @@ TUPLE: document < model locs ; value>> "\n" join ; : set-doc-string ( string document -- ) - >r string-lines V{ } like r> [ set-model ] keep + [ string-lines V{ } like ] dip [ set-model ] keep [ doc-end ] [ update-locs ] bi ; : clear-doc ( document -- ) @@ -141,17 +145,17 @@ GENERIC: prev-elt ( loc document elt -- newloc ) GENERIC: next-elt ( loc document elt -- newloc ) : prev/next-elt ( loc document elt -- start end ) - 3dup next-elt >r prev-elt r> ; + [ prev-elt ] [ next-elt ] 3bi ; : elt-string ( loc document elt -- string ) - over >r prev/next-elt r> doc-range ; + [ prev/next-elt ] [ drop ] 2bi doc-range ; TUPLE: char-elt ; : (prev-char) ( loc document quot -- loc ) -rot { { [ over { 0 0 } = ] [ drop ] } - { [ over second zero? ] [ >r first 1- r> line-end ] } + { [ over second zero? ] [ [ first 1- ] dip line-end ] } [ pick call ] } cond nip ; inline @@ -175,14 +179,14 @@ M: one-char-elt prev-elt 2drop ; M: one-char-elt next-elt 2drop ; : (word-elt) ( loc document quot -- loc ) - pick >r - >r >r first2 swap r> doc-line r> call - r> =col ; inline + pick [ + [ [ first2 swap ] dip doc-line ] dip call + ] dip =col ; inline : ((word-elt)) ( n seq -- ? n seq ) [ ?nth blank? ] 2keep ; : break-detector ( ? -- quot ) - [ >r blank? r> xor ] curry ; inline + [ [ blank? ] dip xor ] curry ; inline : (prev-word) ( ? col str -- col ) rot break-detector find-last-from drop ?1+ ; @@ -195,17 +199,17 @@ TUPLE: one-word-elt ; M: one-word-elt prev-elt drop - [ f -rot >r 1- r> (prev-word) ] (word-elt) ; + [ [ [ f ] dip 1- ] dip (prev-word) ] (word-elt) ; M: one-word-elt next-elt drop - [ f -rot (next-word) ] (word-elt) ; + [ [ f ] 2dip (next-word) ] (word-elt) ; TUPLE: word-elt ; M: word-elt prev-elt drop - [ [ >r 1- r> ((word-elt)) (prev-word) ] (word-elt) ] + [ [ [ 1- ] dip ((word-elt)) (prev-word) ] (word-elt) ] (prev-char) ; M: word-elt next-elt @@ -219,7 +223,7 @@ M: one-line-elt prev-elt 2drop first 0 2array ; M: one-line-elt next-elt - drop >r first dup r> doc-line length 2array ; + drop [ first dup ] dip doc-line length 2array ; TUPLE: line-elt ; diff --git a/basis/editors/notepad2/authors.txt b/basis/editors/notepad2/authors.txt new file mode 100644 index 0000000000..7852139357 --- /dev/null +++ b/basis/editors/notepad2/authors.txt @@ -0,0 +1 @@ +Marc Fauconneau diff --git a/basis/editors/notepad2/notepad2.factor b/basis/editors/notepad2/notepad2.factor new file mode 100644 index 0000000000..4d333e45dd --- /dev/null +++ b/basis/editors/notepad2/notepad2.factor @@ -0,0 +1,16 @@ +USING: editors io.files io.launcher kernel math.parser +namespaces sequences windows.shell32 make ; +IN: editors.notepad2 + +: notepad2-path ( -- str ) + \ notepad2-path get-global [ + program-files "C:\\Windows\\system32\\notepad.exe" append-path + ] unless* ; + +: notepad2 ( file line -- ) + [ + notepad2-path , + "/g" , number>string , , + ] { } make run-detached drop ; + +[ notepad2 ] edit-hook set-global \ No newline at end of file diff --git a/basis/editors/notepad2/summary.txt b/basis/editors/notepad2/summary.txt new file mode 100644 index 0000000000..ab4a8ce377 --- /dev/null +++ b/basis/editors/notepad2/summary.txt @@ -0,0 +1 @@ +Notepad2 editor integration diff --git a/basis/editors/notepad2/tags.txt b/basis/editors/notepad2/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/editors/notepad2/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/farkup/farkup.factor b/basis/farkup/farkup.factor index 21e3c05d04..77a9038cd9 100644 --- a/basis/farkup/farkup.factor +++ b/basis/farkup/farkup.factor @@ -36,7 +36,7 @@ TUPLE: line-break ; { "http://" "https://" "ftp://" } [ head? ] with contains? ; : simple-link-title ( string -- string' ) - dup absolute-url? [ "/" last-split1 swap or ] unless ; + dup absolute-url? [ "/" split1-last swap or ] unless ; EBNF: parse-farkup nl = ("\r\n" | "\r" | "\n") => [[ drop "\n" ]] diff --git a/basis/fry/fry-docs.factor b/basis/fry/fry-docs.factor index 286dbb469e..b5d1b8d8d2 100644 --- a/basis/fry/fry-docs.factor +++ b/basis/fry/fry-docs.factor @@ -15,10 +15,13 @@ HELP: fry } ; HELP: '[ -{ $syntax "code... ]" } +{ $syntax "'[ code... ]" } { $description "Literal fried quotation. Expands into code which takes values from the stack and substitutes them in place of the fry specifiers " { $link _ } " and " { $link @ } "." } { $examples "See " { $link "fry.examples" } "." } ; +HELP: >r/r>-in-fry-error +{ $error-description "Thrown by " { $link POSTPONE: '[ } " if the fried quotation contains calls to " { $link >r } " or " { $link r> } ". Explicit retain stack manipulation of this form does not work with fry; use " { $link dip } " instead." } ; + ARTICLE: "fry.examples" "Examples of fried quotations" "The easiest way to understand fried quotations is to look at some examples." $nl @@ -49,6 +52,8 @@ $nl "{ 8 13 14 27 } [ even? ] 5 [ dup ] swap [ ? ] curry 3compose map" "{ 8 13 14 27 } [ even? dup 5 ? ] map" } +"The following is a no-op:" +{ $code "'[ @ ]" } "Here are some built-in combinators rewritten in terms of fried quotations:" { $table { { $link literalize } { $snippet ": literalize '[ _ ] ;" } } @@ -71,21 +76,27 @@ ARTICLE: "fry.philosophy" "Fried quotation philosophy" } ; ARTICLE: "fry.limitations" "Fried quotation limitations" -"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead." ; +"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead." +$nl +"An error thrown if a fried quotation contains calls to " { $link >r } " and " { $link r> } ":" +{ $subsection >r/r>-in-fry-error } ; ARTICLE: "fry" "Fried quotations" -"A " { $emphasis "fried quotation" } " differs from a literal quotation in that when it is evaluated, instead of just pushing itself on the stack, it consumes zero or more stack values and inserts them into the quotation." +"The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with ``holes'' (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack." $nl -"Fried quotations are denoted with a special parsing word:" +"Fried quotations are started by a special parsing word:" { $subsection POSTPONE: '[ } -"Fried quotations contain zero or more " { $emphasis "fry specifiers" } ":" +"There are two types of fry specifiers; the first can hold a value, and the second ``splices'' a quotation, as if it were inserted without surrounding brackets:" { $subsection _ } { $subsection @ } -"When a fried quotation is being evaluated, values are consumed from the stack and spliced into the quotation from right to left." +"The holes are filled in with the top of stack going in the rightmost hole, the second item on the stack going in the second hole from the right, and so on." { $subsection "fry.examples" } { $subsection "fry.philosophy" } { $subsection "fry.limitations" } -"Quotations can also be fried without using a parsing word:" -{ $subsection fry } ; +"Fry is implemented as a parsing word which reads a quotation and scans for occurrences of " { $link _ } " and " { $link @ } "; these words are not actually executed, and doing so raises an error (this can happen if they're accidentally used outside of a fry)." +$nl +"Fried quotations can also be constructed without using a parsing word; this is useful when meta-programming:" +{ $subsection fry } +"Fried quotations are an abstraction on top of the " { $link "compositional-combinators" } "; their use is encouraged over the combinators, because often the fry form is shorter and clearer than the combinator form." ; ABOUT: "fry" diff --git a/basis/fry/fry-tests.factor b/basis/fry/fry-tests.factor index d4a3b8b734..0137e8be22 100644 --- a/basis/fry/fry-tests.factor +++ b/basis/fry/fry-tests.factor @@ -1,23 +1,20 @@ IN: fry.tests USING: fry tools.test math prettyprint kernel io arrays -sequences ; +sequences eval accessors ; [ [ 3 + ] ] [ 3 '[ _ + ] ] unit-test [ [ 1 3 + ] ] [ 1 3 '[ _ _ + ] ] unit-test -[ [ 1 + ] ] [ 1 [ + ] '[ _ @ ] ] unit-test +[ [ 1 [ + ] call ] ] [ 1 [ + ] '[ _ @ ] ] unit-test -[ [ 1 + . ] ] [ 1 [ + ] '[ _ @ . ] ] unit-test +[ [ 1 [ + ] call . ] ] [ 1 [ + ] '[ _ @ . ] ] unit-test -[ [ + - ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test +[ [ [ + ] [ - ] [ call ] dip call ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test -[ [ "a" write "b" print ] ] +[ [ "a" "b" [ write ] dip print ] ] [ "a" "b" '[ _ write _ print ] ] unit-test -[ [ 1 2 + 3 4 - ] ] -[ [ + ] [ - ] '[ 1 2 @ 3 4 @ ] ] unit-test - [ 1/2 ] [ 1 '[ [ _ ] dip / ] 2 swap call ] unit-test @@ -58,3 +55,10 @@ sequences ; [ { { { 3 } } } ] [ 3 '[ [ [ _ 1array ] call 1array ] call 1array ] call ] unit-test + +[ "USING: fry kernel ; f '[ >r _ r> ]" eval ] +[ error>> >r/r>-in-fry-error? ] must-fail-with + +[ { { "a" 1 } { "b" 2 } { "c" 3 } { "d" 4 } } ] [ + 1 2 3 4 '[ "a" _ 2array "b" _ 2array "c" _ 2array "d" _ 2array 4array ] call +] unit-test diff --git a/basis/fry/fry.factor b/basis/fry/fry.factor index 87c59e18a0..ac036f58ad 100644 --- a/basis/fry/fry.factor +++ b/basis/fry/fry.factor @@ -1,33 +1,37 @@ ! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences combinators parser splitting math -quotations arrays make words ; +quotations arrays make words locals.backend summary sets ; IN: fry : _ ( -- * ) "Only valid inside a fry" throw ; : @ ( -- * ) "Only valid inside a fry" throw ; +ERROR: >r/r>-in-fry-error ; + ] + } case ; -: ((shallow-fry)) ( accum quot adder -- result ) - >r shallow-fry r> - append swap [ - [ prepose ] curry append - ] unless-empty ; inline +M: >r/r>-in-fry-error summary + drop + "Explicit retain stack manipulation is not permitted in fried quotations" ; -: (shallow-fry) ( accum quot -- result ) - [ 1quotation ] [ - unclip { - { \ _ [ [ curry ] ((shallow-fry)) ] } - { \ @ [ [ compose ] ((shallow-fry)) ] } - [ swap >r suffix r> (shallow-fry) ] - } case - ] if-empty ; +: check-fry ( quot -- quot ) + dup { >r r> load-locals get-local drop-locals } intersect + empty? [ >r/r>-in-fry-error ] unless ; -: shallow-fry ( quot -- quot' ) [ ] swap (shallow-fry) ; +: shallow-fry ( quot -- quot' ) + check-fry + [ dup \ @ = [ drop [ _ call ] ] [ 1array ] if ] map concat + { _ } split [ length 1- [ncurry] ] [ spread>quot ] bi prefix ; PREDICATE: fry-specifier < word { _ @ } memq? ; diff --git a/basis/generalizations/generalizations-tests.factor b/basis/generalizations/generalizations-tests.factor index 75985c9368..1ebe528f35 100644 --- a/basis/generalizations/generalizations-tests.factor +++ b/basis/generalizations/generalizations-tests.factor @@ -36,3 +36,5 @@ IN: generalizations.tests [ 1 2 3 4 ] [ { 1 2 3 4 } 4 firstn ] unit-test [ ] [ { } 0 firstn ] unit-test [ "a" ] [ { "a" } 1 firstn ] unit-test + +[ [ 1 2 ] ] [ 1 2 2 [ ] nsequence ] unit-test diff --git a/basis/generalizations/generalizations.factor b/basis/generalizations/generalizations.factor index 069d59cee1..c63c2b66ca 100644 --- a/basis/generalizations/generalizations.factor +++ b/basis/generalizations/generalizations.factor @@ -6,8 +6,11 @@ math.ranges combinators macros quotations fry arrays ; IN: generalizations MACRO: nsequence ( n seq -- quot ) - [ drop ] [ '[ _ _ new-sequence ] ] 2bi - [ '[ @ [ _ swap set-nth-unsafe ] keep ] ] reduce ; + [ + [ drop ] [ '[ _ _ new-sequence ] ] 2bi + [ '[ @ [ _ swap set-nth-unsafe ] keep ] ] reduce + ] keep + '[ @ _ like ] ; MACRO: narray ( n -- quot ) '[ _ { } nsequence ] ; diff --git a/basis/help/cookbook/cookbook.factor b/basis/help/cookbook/cookbook.factor index 9fb837a873..6e27bd9256 100644 --- a/basis/help/cookbook/cookbook.factor +++ b/basis/help/cookbook/cookbook.factor @@ -1,5 +1,6 @@ USING: help.markup help.syntax io kernel math namespaces parser -prettyprint sequences vocabs.loader namespaces stack-checker ; +prettyprint sequences vocabs.loader namespaces stack-checker +help ; IN: help.cookbook ARTICLE: "cookbook-syntax" "Basic syntax cookbook" @@ -324,6 +325,19 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid" { "If " { $link run-file } " throws a stack depth assertion, it means that the top-level form in the file left behind values on the stack. The stack depth is compared before and after loading a source file, since this type of situation is almost always an error. If you have a legitimate need to load a source file which returns data in some manner, define a word in the source file which produces this data on the stack and call the word after loading the file." } } ; +ARTICLE: "cookbook-next" "Next steps" +"Once you have read through " { $link "first-program" } " and " { $link "cookbook" } ", the best way to keep learning Factor is to start looking at some simple example programs. Here are a few particularly nice vocabularies which should keep you busy for a little while:" +{ $list + { $vocab-link "base64" } + { $vocab-link "roman" } + { $vocab-link "rot13" } + { $vocab-link "smtp" } + { $vocab-link "time-server" } + { $vocab-link "tools.hexdump" } + { $vocab-link "webapps.counter" } +} +"If you see code in there that you do not understand, use " { $link see } " and " { $link help } " to explore." ; + ARTICLE: "cookbook" "Factor cookbook" "The Factor cookbook is a high-level overview of the most important concepts required to program in Factor." { $subsection "cookbook-syntax" } @@ -336,6 +350,7 @@ ARTICLE: "cookbook" "Factor cookbook" { $subsection "cookbook-scripts" } { $subsection "cookbook-compiler" } { $subsection "cookbook-philosophy" } -{ $subsection "cookbook-pitfalls" } ; +{ $subsection "cookbook-pitfalls" } +{ $subsection "cookbook-next" } ; ABOUT: "cookbook" diff --git a/basis/help/definitions/definitions-tests.factor b/basis/help/definitions/definitions-tests.factor index 1b8bcccce7..d95f6988a2 100644 --- a/basis/help/definitions/definitions-tests.factor +++ b/basis/help/definitions/definitions-tests.factor @@ -34,7 +34,7 @@ IN: help.definitions.tests [ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ; HELP: xxx ;" eval ] unit-test - [ ] [ "xxx" "help.definitions.tests" lookup help ] unit-test + [ ] [ "xxx" "help.definitions.tests" lookup print-topic ] unit-test [ ] [ "xxx" "help.definitions.tests" lookup >link synopsis print ] unit-test ] with-file-vocabs diff --git a/basis/help/handbook/handbook-tests.factor b/basis/help/handbook/handbook-tests.factor index ae6c7d55f4..240ce67240 100644 --- a/basis/help/handbook/handbook-tests.factor +++ b/basis/help/handbook/handbook-tests.factor @@ -1,8 +1,8 @@ IN: help.handbook.tests USING: help tools.test ; -[ ] [ "article-index" help ] unit-test -[ ] [ "primitive-index" help ] unit-test -[ ] [ "error-index" help ] unit-test -[ ] [ "type-index" help ] unit-test -[ ] [ "class-index" help ] unit-test +[ ] [ "article-index" print-topic ] unit-test +[ ] [ "primitive-index" print-topic ] unit-test +[ ] [ "error-index" print-topic ] unit-test +[ ] [ "type-index" print-topic ] unit-test +[ ] [ "class-index" print-topic ] unit-test diff --git a/basis/help/handbook/handbook.factor b/basis/help/handbook/handbook.factor index d1d9ca049a..2ed86a0a19 100644 --- a/basis/help/handbook/handbook.factor +++ b/basis/help/handbook/handbook.factor @@ -65,6 +65,11 @@ $nl { "word" { "the basic unit of code, analogous to a function or procedure in other programming languages. See " { $link "words" } } } } ; +ARTICLE: "tail-call-opt" "Tail-call optimization" +"If the last action performed is the execution of a word, the current quotation is not saved on the call stack; this is known as " { $emphasis "tail-call optimization" } " and the Factor implementation guarantees that it will be performed." +$nl +"Tail-call optimization allows iterative algorithms to be implemented in an efficient manner using recursion, without the need for any kind of primitive looping construct in the language. However, in practice, most iteration is performed via combinators such as " { $link while } ", " { $link each } ", " { $link map } ", " { $link assoc-each } ", and so on. The definitions of these combinators do bottom-out in recursive words, however." ; + ARTICLE: "evaluator" "Evaluation semantics" { $link "quotations" } " are evaluated sequentially from beginning to end. When the end is reached, the quotation returns to its caller. As each object in the quotation is evaluated in turn, an action is taken based on its type:" { $list @@ -72,7 +77,7 @@ ARTICLE: "evaluator" "Evaluation semantics" { "a " { $link wrapper } " - the wrapped object is pushed on the data stack. Wrappers are used to push word objects directly on the stack when they would otherwise execute. See the " { $link POSTPONE: \ } " parsing word." } { "All other types of objects are pushed on the data stack." } } -"If the last action performed is the execution of a word, the current quotation is not saved on the call stack; this is known as " { $snippet "tail-recursion" } " and allows iterative algorithms to execute without incurring unbounded call stack usage." +{ $subsection "tail-call-opt" } { $see-also "compiler" } ; ARTICLE: "objects" "Objects" diff --git a/basis/help/help-docs.factor b/basis/help/help-docs.factor index 277d965e39..4a06235c69 100644 --- a/basis/help/help-docs.factor +++ b/basis/help/help-docs.factor @@ -129,12 +129,17 @@ HELP: $title { $values { "topic" "a help article name or a word" } } { $description "Prints a help article's title, or a word's " { $link summary } ", depending on the type of " { $snippet "topic" } "." } ; +HELP: print-topic +{ $values { "topic" "an article name or a word" } } +{ $description + "Displays a help topic on " { $link output-stream } "." +} ; + HELP: help { $values { "topic" "an article name or a word" } } { $description - "Displays a help article or documentation associated to a word on " { $link output-stream } "." + "Displays a help topic." } ; - HELP: about { $values { "vocab" "a vocabulary specifier" } } { $description diff --git a/basis/help/help.factor b/basis/help/help.factor index 686578f1b6..a3e3890687 100644 --- a/basis/help/help.factor +++ b/basis/help/help.factor @@ -19,7 +19,7 @@ GENERIC: word-help* ( word -- content ) { { "object" object } { "?" "a boolean" } } $values [ "Tests if the object is an instance of the " , - first "predicating" word-prop \ $link swap 2array , + first "predicating" word-prop <$link> , " class." , ] { } make $description ; @@ -58,15 +58,36 @@ M: word article-title append ] if ; -M: word article-content + + +M: generic article-content word-with-methods ; + +M: class article-content word-with-methods ; + M: word article-parent "help-parent" word-prop ; M: word set-article-parent swap "help-parent" set-word-prop ; @@ -89,10 +110,17 @@ M: word set-article-parent swap "help-parent" set-word-prop ; ] with-nesting ] with-style nl ; -: help ( topic -- ) +: print-topic ( topic -- ) last-element off dup $title article-content print-content nl ; +SYMBOL: help-hook + +help-hook global [ [ print-topic ] or ] change-at + +: help ( topic -- ) + help-hook get call ; + : about ( vocab -- ) dup require dup vocab [ ] [ diff --git a/basis/help/lint/lint.factor b/basis/help/lint/lint.factor index be6206f59c..c7d505d86a 100644 --- a/basis/help/lint/lint.factor +++ b/basis/help/lint/lint.factor @@ -68,7 +68,7 @@ IN: help.lint ] each ; : check-rendering ( word element -- ) - [ help ] with-string-writer drop ; + [ print-topic ] with-string-writer drop ; : all-word-help ( words -- seq ) [ word-help ] filter ; diff --git a/basis/help/markup/markup-tests.factor b/basis/help/markup/markup-tests.factor index 222c4e7d3f..b9ec34a831 100644 --- a/basis/help/markup/markup-tests.factor +++ b/basis/help/markup/markup-tests.factor @@ -6,12 +6,12 @@ TUPLE: blahblah quux ; [ "an int" ] [ [ { "int" } $instance ] with-string-writer ] unit-test -[ ] [ \ quux>> help ] unit-test -[ ] [ \ >>quux help ] unit-test -[ ] [ \ blahblah? help ] unit-test +[ ] [ \ quux>> print-topic ] unit-test +[ ] [ \ >>quux print-topic ] unit-test +[ ] [ \ blahblah? print-topic ] unit-test : fooey "fooey" throw ; -[ ] [ \ fooey help ] unit-test +[ ] [ \ fooey print-topic ] unit-test -[ ] [ gensym help ] unit-test +[ ] [ gensym print-topic ] unit-test diff --git a/basis/help/markup/markup.factor b/basis/help/markup/markup.factor index a307833338..899cad2404 100644 --- a/basis/help/markup/markup.factor +++ b/basis/help/markup/markup.factor @@ -285,11 +285,16 @@ M: f ($instance) : $see ( element -- ) first [ see ] ($see) ; +: $see-methods ( element -- ) first [ see-methods ] ($see) ; + : $synopsis ( element -- ) first [ synopsis write ] ($see) ; : $definition ( element -- ) "Definition" $heading $see ; +: $methods ( element -- ) + "Methods" $heading $see-methods ; + : $value ( object -- ) "Variable value" $heading "Current value in global namespace:" print-element @@ -348,3 +353,6 @@ M: array elements* ] each ] curry each ] H{ } make-assoc keys ; + +: <$link> ( topic -- element ) + \ $link swap 2array ; diff --git a/basis/html/templates/fhtml/fhtml-tests.factor b/basis/html/templates/fhtml/fhtml-tests.factor index d314a60124..6cebb55688 100644 --- a/basis/html/templates/fhtml/fhtml-tests.factor +++ b/basis/html/templates/fhtml/fhtml-tests.factor @@ -6,11 +6,8 @@ IN: html.templates.fhtml.tests : test-template ( path -- ? ) "resource:basis/html/templates/fhtml/test/" prepend - [ - ".fhtml" append [ call-template ] with-string-writer - lines - ] keep - ".html" append utf8 file-lines + [ ".fhtml" append [ call-template ] with-string-writer ] + [ ".html" append utf8 file-contents ] bi [ . . ] [ = ] 2bi ; [ t ] [ "example" test-template ] unit-test diff --git a/basis/http/server/static/static.factor b/basis/http/server/static/static.factor index 208273364c..0bc644d019 100644 --- a/basis/http/server/static/static.factor +++ b/basis/http/server/static/static.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: calendar io io.files kernel math math.order math.parser namespaces parser sequences strings -assocs hashtables debugger mime-types sorting logging +assocs hashtables debugger mime.types sorting logging calendar.format accessors splitting io.encodings.binary fry xml.entities destructors urls html.elements html.templates.fhtml diff --git a/basis/io/encodings/utf16/.utf16.factor.swo b/basis/io/encodings/utf16/.utf16.factor.swo deleted file mode 100644 index 01be8fdab2..0000000000 Binary files a/basis/io/encodings/utf16/.utf16.factor.swo and /dev/null differ diff --git a/basis/io/files/listing/unix/unix.factor b/basis/io/files/listing/unix/unix.factor index 313ce1f79a..bef8d3dc56 100755 --- a/basis/io/files/listing/unix/unix.factor +++ b/basis/io/files/listing/unix/unix.factor @@ -3,7 +3,7 @@ USING: accessors combinators kernel system unicode.case io.unix.files io.files.listing generalizations strings arrays sequences io.files math.parser unix.groups unix.users -io.files.listing.private ; +io.files.listing.private unix.stat math ; IN: io.files.listing.unix string ] } cleave 10 narray concat ; +: mode>symbol ( mode -- ch ) + S_IFMT bitand + { + { [ dup S_IFDIR = ] [ drop "/" ] } + { [ dup S_IFIFO = ] [ drop "|" ] } + { [ dup any-execute? ] [ drop "*" ] } + { [ dup S_IFLNK = ] [ drop "@" ] } + { [ dup S_IFWHT = ] [ drop "%" ] } + { [ dup S_IFSOCK = ] [ drop "=" ] } + { [ t ] [ drop "" ] } + } cond ; + M: unix (directory.) ( path -- lines ) [ [ [ diff --git a/basis/io/sockets/secure/openssl/openssl.factor b/basis/io/sockets/secure/openssl/openssl.factor new file mode 100644 index 0000000000..83d7763bb4 --- /dev/null +++ b/basis/io/sockets/secure/openssl/openssl.factor @@ -0,0 +1,197 @@ +! Copyright (C) 2007, 2008, Slava Pestov, Elie CHAFTARI. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors byte-arrays kernel debugger sequences namespaces math +math.order combinators init alien alien.c-types alien.strings libc +continuations destructors debugger summary splitting assocs +random math.parser locals unicode.case +openssl.libcrypto openssl.libssl +io.backend io.ports io.files io.encodings.8-bit +io.timeouts ; +IN: io.sockets.secure.openssl + +GENERIC: ssl-method ( symbol -- method ) + +M: SSLv2 ssl-method drop SSLv2_client_method ; +M: SSLv23 ssl-method drop SSLv23_method ; +M: SSLv3 ssl-method drop SSLv3_method ; +M: TLSv1 ssl-method drop TLSv1_method ; + +TUPLE: openssl-context < secure-context aliens sessions ; + +: set-session-cache ( ctx -- ) + handle>> + [ SSL_SESS_CACHE_BOTH SSL_CTX_set_session_cache_mode ssl-error ] + [ 32 random-bits >hex dup length SSL_CTX_set_session_id_context ssl-error ] + bi ; + +: load-certificate-chain ( ctx -- ) + dup config>> key-file>> [ + [ handle>> ] [ config>> key-file>> (normalize-path) ] bi + SSL_CTX_use_certificate_chain_file + ssl-error + ] [ drop ] if ; + +: password-callback ( -- alien ) + "int" { "void*" "int" "bool" "void*" } "cdecl" + [| buf size rwflag password! | + password [ B{ 0 } password! ] unless + + [let | len [ password strlen ] | + buf password len 1+ size min memcpy + len + ] + ] alien-callback ; + +: default-pasword ( ctx -- alien ) + [ config>> password>> latin1 malloc-string ] [ aliens>> ] bi + [ push ] [ drop ] 2bi ; + +: set-default-password ( ctx -- ) + [ handle>> password-callback SSL_CTX_set_default_passwd_cb ] + [ + [ handle>> ] [ default-pasword ] bi + SSL_CTX_set_default_passwd_cb_userdata + ] bi ; + +: use-private-key-file ( ctx -- ) + dup config>> key-file>> [ + [ handle>> ] [ config>> key-file>> (normalize-path) ] bi + SSL_FILETYPE_PEM SSL_CTX_use_PrivateKey_file + ssl-error + ] [ drop ] if ; + +: load-verify-locations ( ctx -- ) + dup config>> [ ca-file>> ] [ ca-path>> ] bi or [ + [ handle>> ] + [ + config>> + [ ca-file>> dup [ (normalize-path) ] when ] + [ ca-path>> dup [ (normalize-path) ] when ] bi + ] bi + SSL_CTX_load_verify_locations + ] [ handle>> SSL_CTX_set_default_verify_paths ] if ssl-error ; + +: set-verify-depth ( ctx -- ) + dup config>> verify-depth>> [ + [ handle>> ] [ config>> verify-depth>> ] bi + SSL_CTX_set_verify_depth + ] [ drop ] if ; + +TUPLE: bio handle disposed ; + +: ( handle -- bio ) f bio boa ; + +M: bio dispose* handle>> BIO_free ssl-error ; + +: ( path -- bio ) + normalize-path "r" BIO_new_file dup ssl-error ; + +: load-dh-params ( ctx -- ) + dup config>> dh-file>> [ + [ handle>> ] [ config>> dh-file>> ] bi &dispose + handle>> f f f PEM_read_bio_DHparams dup ssl-error + SSL_CTX_set_tmp_dh ssl-error + ] [ drop ] if ; + +TUPLE: rsa handle disposed ; + +: ( handle -- rsa ) f rsa boa ; + +M: rsa dispose* handle>> RSA_free ; + +: generate-eph-rsa-key ( ctx -- ) + [ handle>> ] + [ + config>> ephemeral-key-bits>> RSA_F4 f f RSA_generate_key + dup ssl-error &dispose handle>> + ] bi + SSL_CTX_set_tmp_rsa ssl-error ; + +: ( config ctx -- context ) + openssl-context new + swap >>handle + swap >>config + V{ } clone >>aliens + H{ } clone >>sessions ; + +M: openssl ( config -- context ) + maybe-init-ssl + [ + dup method>> ssl-method SSL_CTX_new + dup ssl-error |dispose + { + [ set-session-cache ] + [ load-certificate-chain ] + [ set-default-password ] + [ use-private-key-file ] + [ load-verify-locations ] + [ set-verify-depth ] + [ load-dh-params ] + [ generate-eph-rsa-key ] + [ ] + } cleave + ] with-destructors ; + +M: openssl-context dispose* + [ aliens>> [ free ] each ] + [ sessions>> values [ SSL_SESSION_free ] each ] + [ handle>> SSL_CTX_free ] + tri ; + +TUPLE: ssl-handle file handle connected disposed ; + +SYMBOL: default-secure-context + +: context-expired? ( context -- ? ) + dup [ handle>> expired? ] [ drop t ] if ; + +: current-secure-context ( -- ctx ) + secure-context get [ + default-secure-context get dup context-expired? [ + drop + default-secure-context set-global + current-secure-context + ] when + ] unless* ; + +: ( fd -- ssl ) + current-secure-context handle>> SSL_new dup ssl-error + f f ssl-handle boa ; + +M: ssl-handle dispose* + [ handle>> SSL_free ] [ file>> dispose ] bi ; + +: check-verify-result ( ssl-handle -- ) + SSL_get_verify_result dup X509_V_OK = + [ drop ] [ verify-message certificate-verify-error ] if ; + +: common-name ( certificate -- host ) + X509_get_subject_name + NID_commonName 256 + [ 256 X509_NAME_get_text_by_NID ] keep + swap -1 = [ drop f ] [ latin1 alien>string ] if ; + +: common-names-match? ( expected actual -- ? ) + [ >lower ] bi@ "*." ?head [ tail? ] [ = ] if ; + +: check-common-name ( host ssl-handle -- ) + SSL_get_peer_certificate common-name + 2dup common-names-match? + [ 2drop ] [ common-name-verify-error ] if ; + +M: openssl check-certificate ( host ssl -- ) + current-secure-context config>> verify>> [ + handle>> + [ nip check-verify-result ] + [ check-common-name ] + 2bi + ] [ 2drop ] if ; + +: get-session ( addrspec -- session/f ) + current-secure-context sessions>> at + dup expired? [ drop f ] when ; + +: save-session ( session addrspec -- ) + current-secure-context sessions>> set-at ; + +openssl secure-socket-backend set-global diff --git a/basis/io/unix/files/files.factor b/basis/io/unix/files/files.factor index fb8615c47b..9fa1727e16 100644 --- a/basis/io/unix/files/files.factor +++ b/basis/io/unix/files/files.factor @@ -6,7 +6,8 @@ math.bitwise byte-arrays alien combinators calendar io.encodings.binary accessors sequences strings system io.files.private destructors vocabs.loader calendar.unix unix.stat alien.c-types arrays unix.users unix.groups -environment fry io.encodings.utf8 alien.strings unix.statfs ; +environment fry io.encodings.utf8 alien.strings unix.statfs +combinators.short-circuit ; IN: io.unix.files M: unix cwd ( -- path ) @@ -117,8 +118,8 @@ M: unix stat>file-info ( stat -- file-info ) [ stat-st_blksize >>blocksize ] } cleave ; -M: unix stat>type ( stat -- type ) - stat-st_mode S_IFMT bitand { +: n>file-type ( n -- type ) + S_IFMT bitand { { S_IFREG [ +regular-file+ ] } { S_IFDIR [ +directory+ ] } { S_IFCHR [ +character-device+ ] } @@ -129,6 +130,9 @@ M: unix stat>type ( stat -- type ) [ drop +unknown+ ] } case ; +M: unix stat>type ( stat -- type ) + stat-st_mode n>file-type ; + ! Linux has no extra fields in its stat struct os { { macosx [ "io.unix.files.bsd" require ] } @@ -150,7 +154,7 @@ os { M: unix >directory-entry ( byte-array -- directory-entry ) [ dirent-d_name utf8 alien>string ] - [ dirent-d_type ] bi directory-entry boa ; + [ dirent-d_type dirent-type>file-type ] bi directory-entry boa ; M: unix (directory-entries) ( path -- seq ) [ @@ -225,6 +229,15 @@ GENERIC: other-read? ( obj -- ? ) GENERIC: other-write? ( obj -- ? ) GENERIC: other-execute? ( obj -- ? ) +: any-read? ( obj -- ? ) + { [ user-read? ] [ group-read? ] [ other-read? ] } 1|| ; + +: any-write? ( obj -- ? ) + { [ user-write? ] [ group-write? ] [ other-write? ] } 1|| ; + +: any-execute? ( obj -- ? ) + { [ user-execute? ] [ group-execute? ] [ other-execute? ] } 1|| ; + M: integer uid? ( integer -- ? ) UID mask? ; M: integer gid? ( integer -- ? ) GID mask? ; M: integer sticky? ( integer -- ? ) STICKY mask? ; diff --git a/basis/io/unix/sockets/secure/secure.factor b/basis/io/unix/sockets/secure/secure.factor index 649c68673f..fb5ed93978 100644 --- a/basis/io/unix/sockets/secure/secure.factor +++ b/basis/io/unix/sockets/secure/secure.factor @@ -1,11 +1,11 @@ ! Copyright (C) 2007, 2008, Slava Pestov, Elie CHAFTARI. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors unix byte-arrays kernel debugger sequences namespaces math -math.order combinators init alien alien.c-types alien.strings libc -continuations destructors -openssl openssl.libcrypto openssl.libssl -io.files io.ports io.unix.backend io.unix.sockets -io.encodings.ascii io.buffers io.sockets io.sockets.secure +USING: accessors unix byte-arrays kernel debugger sequences +namespaces math math.order combinators init alien alien.c-types +alien.strings libc continuations destructors openssl +openssl.libcrypto openssl.libssl io.files io.ports +io.unix.backend io.unix.sockets io.encodings.ascii io.buffers +io.sockets io.sockets.secure io.sockets.secure.openssl io.timeouts system summary ; IN: io.unix.sockets.secure diff --git a/basis/io/windows/files/files.factor b/basis/io/windows/files/files.factor index d0409ce59a..7f84b9d9e5 100755 --- a/basis/io/windows/files/files.factor +++ b/basis/io/windows/files/files.factor @@ -114,11 +114,6 @@ M: windows delete-directory ( path -- ) normalize-path RemoveDirectory win32-error=0/f ; -M: windows >directory-entry ( byte-array -- directory-entry ) - [ WIN32_FIND_DATA-cFileName utf16n alien>string ] - [ WIN32_FIND_DATA-dwFileAttributes ] - bi directory-entry boa ; - : find-first-file ( path -- WIN32_FIND_DATA handle ) "WIN32_FIND_DATA" tuck FindFirstFile @@ -177,6 +172,15 @@ TUPLE: windows-file-info < file-info attributes ; : win32-file-type ( n -- symbol ) FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ; +TUPLE: windows-directory-entry < directory-entry attributes ; + +M: windows >directory-entry ( byte-array -- directory-entry ) + [ WIN32_FIND_DATA-cFileName utf16n alien>string ] + [ WIN32_FIND_DATA-dwFileAttributes win32-file-type ] + [ WIN32_FIND_DATA-dwFileAttributes win32-file-attributes ] + tri + dupd remove windows-directory-entry boa ; + : WIN32_FIND_DATA>file-info ( WIN32_FIND_DATA -- file-info ) [ \ windows-file-info new ] dip { diff --git a/basis/listener/listener-docs.factor b/basis/listener/listener-docs.factor index beea9005b4..014e096b1d 100644 --- a/basis/listener/listener-docs.factor +++ b/basis/listener/listener-docs.factor @@ -1,34 +1,60 @@ USING: help.markup help.syntax kernel io system prettyprint ; IN: listener +ARTICLE: "listener-watch" "Watching variables in the listener" +"The listener prints the concepts of the data and retain stacks after every expression. It can also print values of dynamic variables which are added to a watch list:" +{ $subsection visible-vars } +"To add or remove a single variable:" +{ $subsection show-var } +{ $subsection hide-var } +"To add and remove multiple variables:" +{ $subsection show-vars } +{ $subsection hide-vars } +"Hiding all visible variables:" +{ $subsection hide-all-vars } ; + +HELP: show-var +{ $values { "var" "a variable name" } } +{ $description "Adds a variable to the watch list; its value will be printed by the listener after every expression." } ; + +HELP: show-vars +{ $values { "seq" "a sequence of variable names" } } +{ $description "Adds a sequence of variables to the watch list; their values will be printed by the listener after every expression." } ; + +HELP: hide-var +{ $values { "var" "a variable name" } } +{ $description "Removes a variable from the watch list." } ; + +HELP: hide-vars +{ $values { "seq" "a sequence of variable names" } } +{ $description "Removes a sequence of variables from the watch list." } ; + +HELP: hide-all-vars +{ $description "Removes all variables from the watch list." } ; + ARTICLE: "listener" "The listener" "The listener evaluates Factor expressions read from a stream. The listener is the primary interface to the Factor runtime. Typically, you write Factor code in a text editor, then load it using the listener and test it." $nl "The classical first program can be run in the listener:" { $example "\"Hello, world\" print" "Hello, world" } -"Multi-line phrases are supported:" +"Multi-line expressions are supported:" { $example "{ 1 2 3 } [\n .\n] each" "1\n2\n3" } "The listener knows when to expect more input by looking at the height of the stack. Parsing words such as " { $link POSTPONE: { } " leave elements on the parser stack, and corresponding words such as " { $link POSTPONE: } } " pop them." -$nl -"A very common operation is to inspect the contents of the data stack in the listener:" -{ $subsection .s } -"Note that calls to " { $link .s } " can also be included inside words as a debugging aid, however a more convenient way to achieve this is to use the annotation facility. See " { $link "tools.annotations" } "." -$nl +{ $subsection "listener-watch" } "You can start a nested listener or exit a listener using the following words:" { $subsection listener } { $subsection bye } -"The following variables can be rebound inside a nested scope to customize the behavior of a listener; this can be done to create a development tool with a custom interaction loop:" -{ $subsection listener-hook } "Finally, the multi-line expression reading word can be used independently of the rest of the listener:" { $subsection read-quot } ; ABOUT: "listener" + HELP: read-quot { $values { "quot/f" "a parsed quotation, or " { $link f } " indicating end of file" } } diff --git a/basis/listener/listener.factor b/basis/listener/listener.factor index feddbdc042..95ad264000 100644 --- a/basis/listener/listener.factor +++ b/basis/listener/listener.factor @@ -3,16 +3,10 @@ USING: arrays hashtables io kernel math math.parser memory namespaces parser lexer sequences strings io.styles vectors words generic system combinators continuations debugger -definitions compiler.units accessors colors ; - +definitions compiler.units accessors colors prettyprint fry +sets ; IN: listener -SYMBOL: quit-flag - -SYMBOL: listener-hook - -[ ] listener-hook set-global - GENERIC: stream-read-quot ( stream -- quot/f ) : parse-lines-interactive ( lines -- quot/f ) @@ -38,18 +32,65 @@ M: object stream-read-quot : read-quot ( -- quot/f ) input-stream get stream-read-quot ; + + : bye ( -- ) quit-flag on ; -: prompt. ( -- ) - "( " in get " )" 3append - H{ { background T{ rgba f 1 0.7 0.7 1 } } } format bl flush ; +SYMBOL: visible-vars + +: show-var ( var -- ) visible-vars [ swap suffix ] change ; + +: show-vars ( seq -- ) visible-vars [ swap union ] change ; + +: hide-var ( var -- ) visible-vars [ remove ] change ; + +: hide-vars ( seq -- ) visible-vars [ swap diff ] change ; + +: hide-all-vars ( -- ) visible-vars off ; SYMBOL: error-hook [ print-error-and-restarts ] error-hook set-global + + : listener ( -- ) [ until-quit ] with-interactive-vocabs ; diff --git a/basis/locals/locals-docs.factor b/basis/locals/locals-docs.factor index 35e0536530..18488ed1dd 100644 --- a/basis/locals/locals-docs.factor +++ b/basis/locals/locals-docs.factor @@ -132,8 +132,8 @@ $nl "Unlike some languages such as Python and Java, writing to mutable locals in outer scopes is fully supported and has the expected semantics." ; ARTICLE: "locals-limitations" "Limitations of locals" -"The first limitation is that the " { $link >r } " and " { $link r> } " words may not be used together with locals. Instead, use the " { $link dip } " combinator." -$nl +"The first limitation is also shared by " { $vocab-link "fry" } ": the " { $link >r } " and " { $link r> } " words may not be used together with locals. Instead, use the " { $link dip } " combinator. An error is thrown at parse time if an attempt is made to use " { $link >r } " and " { $link r> } " inside a lambda body:" +{ $subsection >r/r>-in-lambda-error } "Another limitation concerns combinators implemented as macros. Locals can only be used with such combinators if the input array immediately precedes the combinator call. For example, the following will work:" { $code ":: good-cond-usage ( a -- ... )" diff --git a/basis/locals/locals-tests.factor b/basis/locals/locals-tests.factor index ca6697be1c..44c04da1a1 100644 --- a/basis/locals/locals-tests.factor +++ b/basis/locals/locals-tests.factor @@ -2,7 +2,7 @@ USING: locals math sequences tools.test hashtables words kernel namespaces arrays strings prettyprint io.streams.string parser accessors generic eval combinators combinators.short-circuit combinators.short-circuit.smart math.order math.functions -definitions compiler.units ; +definitions compiler.units fry lexer ; IN: locals.tests :: foo ( a b -- a a ) a a ; @@ -286,6 +286,8 @@ M:: sequence method-with-locals ( a -- y ) a reverse ; { [ a b > ] [ 5 ] } } cond ; +\ cond-test must-infer + [ 3 ] [ 1 2 cond-test ] unit-test [ 4 ] [ 2 2 cond-test ] unit-test [ 5 ] [ 3 2 cond-test ] unit-test @@ -293,6 +295,8 @@ M:: sequence method-with-locals ( a -- y ) a reverse ; :: 0&&-test ( a -- ? ) { [ a integer? ] [ a even? ] [ a 10 > ] } 0&& ; +\ 0&&-test must-infer + [ f ] [ 1.5 0&&-test ] unit-test [ f ] [ 3 0&&-test ] unit-test [ f ] [ 8 0&&-test ] unit-test @@ -301,6 +305,8 @@ M:: sequence method-with-locals ( a -- y ) a reverse ; :: &&-test ( a -- ? ) { [ a integer? ] [ a even? ] [ a 10 > ] } && ; +\ &&-test must-infer + [ f ] [ 1.5 &&-test ] unit-test [ f ] [ 3 &&-test ] unit-test [ f ] [ 8 &&-test ] unit-test @@ -346,6 +352,10 @@ M:: sequence method-with-locals ( a -- y ) a reverse ; { 3 1 } [| from to seq | T{ slice f from to seq } ] must-infer-as +ERROR: punned-class x ; + +[ T{ punned-class f 3 } ] [ 3 [| a | T{ punned-class f a } ] call ] unit-test + :: literal-identity-test ( -- a b ) { } V{ } ; @@ -388,6 +398,26 @@ M:: integer lambda-method-forget-test ( a -- b ) ; [ ] [ [ { integer lambda-method-forget-test } forget ] with-compilation-unit ] unit-test +[ { [ 10 ] } ] [ 10 [| A | { [ A ] } ] call ] unit-test + +[ + "USING: locals fry math ; [ 0 '[ [let | A [ 10 ] | A _ + ] ] ]" eval +] [ error>> >r/r>-in-fry-error? ] must-fail-with + +:: (funny-macro-test) ( obj quot -- ? ) obj { quot } 1&& ; inline +: funny-macro-test ( n -- ? ) [ odd? ] (funny-macro-test) ; + +\ funny-macro-test must-infer + +[ t ] [ 3 funny-macro-test ] unit-test +[ f ] [ 2 funny-macro-test ] unit-test + +! Some odd parser corner cases +[ "USE: locals [let" eval ] [ error>> unexpected-eof? ] must-fail-with +[ "USE: locals [let |" eval ] [ error>> unexpected-eof? ] must-fail-with +[ "USE: locals [let | a" eval ] [ error>> unexpected-eof? ] must-fail-with +[ "USE: locals [|" eval ] [ error>> unexpected-eof? ] must-fail-with + ! :: wlet-&&-test ( a -- ? ) ! [wlet | is-integer? [ a integer? ] ! is-even? [ a even? ] diff --git a/basis/locals/locals.factor b/basis/locals/locals.factor index 7de9d10436..e66b1531d2 100644 --- a/basis/locals/locals.factor +++ b/basis/locals/locals.factor @@ -6,12 +6,18 @@ quotations debugger macros arrays macros splitting combinators prettyprint.backend definitions prettyprint hashtables prettyprint.sections sets sequences.private effects effects.parser generic generic.parser compiler.units accessors -locals.backend memoize macros.expander lexer classes ; +locals.backend memoize macros.expander lexer classes summary ; IN: locals ! Inspired by ! http://cat-language.googlecode.com/svn/trunk/CatPointFreeForm.cs +ERROR: >r/r>-in-lambda-error ; + +M: >r/r>-in-lambda-error summary + drop + "Explicit retain stack manipulation is not permitted in lambda bodies" ; + > , ] } - { [ t ] [ free-vars* ] } - } cond ; +M: local-writer free-vars* "local-reader" word-prop , ; + +M: lexical free-vars* , ; + +M: quote free-vars* , ; M: object free-vars* drop ; -M: quotation free-vars* [ add-if-free ] each ; +M: quotation free-vars* [ free-vars* ] each ; -M: lambda free-vars* - [ vars>> ] [ body>> ] bi free-vars swap diff % ; +M: lambda free-vars* [ vars>> ] [ body>> ] bi free-vars swap diff % ; GENERIC: lambda-rewrite* ( obj -- ) @@ -201,6 +204,8 @@ M: special rewrite-literal? drop t ; M: array rewrite-literal? [ rewrite-literal? ] contains? ; +M: quotation rewrite-literal? [ rewrite-literal? ] contains? ; + M: hashtable rewrite-literal? drop t ; M: vector rewrite-literal? drop t ; @@ -215,17 +220,20 @@ GENERIC: rewrite-element ( obj -- ) [ rewrite-element ] each ; : rewrite-sequence ( seq -- ) - [ rewrite-elements ] [ length , ] [ , ] tri \ nsequence , ; + [ rewrite-elements ] [ length , ] [ 0 head , ] tri \ nsequence , ; M: array rewrite-element dup rewrite-literal? [ rewrite-sequence ] [ , ] if ; +M: quotation rewrite-element + dup rewrite-literal? [ rewrite-sequence ] [ , ] if ; + M: vector rewrite-element rewrite-sequence ; M: hashtable rewrite-element >alist rewrite-sequence \ >hashtable , ; M: tuple rewrite-element - [ tuple-slots rewrite-elements ] [ class , ] bi \ boa , ; + [ tuple-slots rewrite-elements ] [ class literalize , ] bi \ boa , ; M: local rewrite-element , ; @@ -243,6 +251,10 @@ M: tuple local-rewrite* rewrite-element ; M: hashtable local-rewrite* rewrite-element ; +M: word local-rewrite* + dup { >r r> } memq? + [ >r/r>-in-lambda-error ] [ call-next-method ] if ; + M: object lambda-rewrite* , ; M: object local-rewrite* , ; @@ -277,18 +289,16 @@ SYMBOL: in-lambda? \ ] (parse-lambda) ; : parse-binding ( -- pair/f ) - scan dup "|" = [ - drop f - ] [ - scan { - { "[" [ \ ] parse-until >quotation ] } - { "[|" [ parse-lambda ] } - } case 2array - ] if ; + scan { + { [ dup not ] [ unexpected-eof ] } + { [ dup "|" = ] [ drop f ] } + { [ dup "!" = ] [ drop POSTPONE: ! parse-binding ] } + [ scan-object 2array ] + } cond ; : (parse-bindings) ( -- ) parse-binding [ - first2 >r make-local r> 2array , + first2 [ make-local ] dip 2array , (parse-bindings) ] when* ; @@ -341,7 +351,7 @@ M: wlet local-rewrite* in>> [ dup pair? [ first ] when ] map make-locals dup push-locals ; : parse-locals-definition ( word -- word quot ) - scan "(" assert= parse-locals \ ; (parse-lambda) + "(" expect parse-locals \ ; (parse-lambda) 2dup "lambda" set-word-prop lambda-rewrite first ; @@ -359,15 +369,15 @@ PRIVATE> : [| parse-lambda parsed-lambda ; parsing : [let - scan "|" assert= parse-bindings + "|" expect parse-bindings \ ] (parse-lambda) parsed-lambda ; parsing : [let* - scan "|" assert= parse-bindings* + "|" expect parse-bindings* \ ] (parse-lambda) parsed-lambda ; parsing : [wlet - scan "|" assert= parse-wbindings + "|" expect parse-wbindings \ ] (parse-lambda) parsed-lambda ; parsing : :: (::) define ; parsing diff --git a/basis/macros/expander/expander.factor b/basis/macros/expander/expander.factor index 3666fa2423..cdd2b49d9c 100644 --- a/basis/macros/expander/expander.factor +++ b/basis/macros/expander/expander.factor @@ -37,9 +37,17 @@ M: wrapper expand-macros* wrapped>> literal ; [ '[ _ ndrop _ nnip call ] [ ] like ] 2map , \ dispatch , ] bi ; -: expand-macro ( quot -- ) - stack [ swap with-datastack >vector ] change - stack get pop >quotation end (expand-macros) ; +: word, ( word -- ) end , ; + +: expand-macro ( word quot -- ) + '[ + drop + stack [ _ with-datastack >vector ] change + stack get pop >quotation end (expand-macros) + ] [ + drop + word, + ] recover ; : expand-macro? ( word -- quot ? ) dup [ "transform-quot" word-prop ] [ "macro" word-prop ] bi or dup [ @@ -47,11 +55,9 @@ M: wrapper expand-macros* wrapped>> literal ; stack get length <= ] [ 2drop f f ] if ; -: word, ( word -- ) end , ; - M: word expand-macros* dup expand-dispatch? [ drop expand-dispatch ] [ - dup expand-macro? [ nip expand-macro ] [ + dup expand-macro? [ expand-macro ] [ drop word, ] if ] if ; diff --git a/basis/math/bitwise/bitwise-docs.factor b/basis/math/bitwise/bitwise-docs.factor index 4f2606bda0..9ed164330b 100644 --- a/basis/math/bitwise/bitwise-docs.factor +++ b/basis/math/bitwise/bitwise-docs.factor @@ -310,8 +310,9 @@ ARTICLE: "math-bitfields" "Constructing bit fields" "Some applications, such as binary communication protocols and assemblers, need to construct integers from elaborate bit field specifications. Hand-coding this using " { $link shift } " and " { $link bitor } " results in repetitive code. A higher-level facility exists to factor out this repetition:" { $subsection bitfield } ; -ARTICLE: "math.bitwise" "Bitwise arithmetic" -"The " { $vocab-link "math.bitwise" } " vocabulary can implements bitwise arithmetic words that are useful for efficiency, low-level programming, and interfacing with C libraries." $nl +ARTICLE: "math.bitwise" "Additional bitwise arithmetic" +"The " { $vocab-link "math.bitwise" } " vocabulary provides bitwise arithmetic words extending " { $link "bitwise-arithmetic" } ". They are useful for efficiency, low-level programming, and interfacing with C libraries." +$nl "Setting and clearing bits:" { $subsection set-bit } { $subsection clear-bit } diff --git a/basis/math/geometry/rect/rect-docs.factor b/basis/math/geometry/rect/rect-docs.factor index a892940363..31c9e44b1d 100644 --- a/basis/math/geometry/rect/rect-docs.factor +++ b/basis/math/geometry/rect/rect-docs.factor @@ -47,3 +47,21 @@ HELP: { $values { "rect" "a new " { $link rect } } } { $description "Creates a rectangle located at the origin with zero dimensions." } ; +ARTICLE: "math.geometry.rect" "Rectangles" +"The " { $vocab-link "math.geometry.rect" } " vocabulary defines a rectangle data type and operations on them." +{ $subsection rect } +"Rectangles can be taken apart:" +{ $subsection rect-loc } +{ $subsection rect-dim } +{ $subsection rect-bounds } +{ $subsection rect-extent } +"New rectangles can be created:" +{ $subsection } +{ $subsection } +{ $subsection } +"More utility words for working with rectangles:" +{ $subsection offset-rect } +{ $subsection rect-intersect } +{ $subsection intersects? } ; + +ABOUT: "math.geometry.rect" diff --git a/basis/math/partial-dispatch/partial-dispatch.factor b/basis/math/partial-dispatch/partial-dispatch.factor index 6874b79d2e..ddde4e1244 100644 --- a/basis/math/partial-dispatch/partial-dispatch.factor +++ b/basis/math/partial-dispatch/partial-dispatch.factor @@ -29,6 +29,8 @@ M: word integer-op-input-classes { fixnum- fixnum-fast } { fixnum* fixnum*fast } { fixnum-shift fixnum-shift-fast } + { fixnum/i fixnum/i-fast } + { fixnum/mod fixnum/mod-fast } } at ; : modular-variant ( op -- fast-op ) diff --git a/basis/mime/multipart/authors.txt b/basis/mime/multipart/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/basis/mime/multipart/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/basis/mime/multipart/multipart-tests.factor b/basis/mime/multipart/multipart-tests.factor new file mode 100644 index 0000000000..68b4bff266 --- /dev/null +++ b/basis/mime/multipart/multipart-tests.factor @@ -0,0 +1,1485 @@ +USING: accessors io io.streams.string kernel mime.multipart +tools.test make multiline strings ; +IN: mime.multipart.tests + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + +[ { "a" "a" f } ] [ + [ + "aazzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "zz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [ + [ + "azzbzzczzdzz" "zzz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "az" "zb" "zz" "cz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "zzb" "zzc" "zzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "az" "zbzz" "czzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "azz" "bzzcz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + + +[ { "a" "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + + + +[ { "a" f "b" f "c" f "d" f } ] [ + [ + "azzbzzczzdzz" "zz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [ + [ + "azzbzzczzdzz" "zzz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "az" "zb" "zz" "cz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "zzb" "zzc" "zzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "az" "zbzz" "czzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "azz" "bzzcz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + + +: dog-upload ( -- string ) + B{ + 45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66 + 111 117 110 100 97 114 121 115 105 103 113 43 53 113 87 116 + 54 79 114 122 56 76 79 13 10 67 111 110 116 101 110 116 45 + 68 105 115 112 111 115 105 116 105 111 110 58 32 102 111 + 114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105 + 108 101 34 59 32 102 105 108 101 110 97 109 101 61 34 100 + 111 103 46 106 112 103 34 13 10 67 111 110 116 101 110 116 + 45 84 121 112 101 58 32 105 109 97 103 101 47 106 112 101 + 103 13 10 13 10 253 253 253 253 0 16 74 70 73 70 0 1 1 0 0 + 1 0 1 0 0 253 253 0 67 0 5 3 4 4 4 3 5 4 4 4 5 5 5 6 7 12 8 + 7 7 7 7 15 11 11 9 12 17 15 18 18 17 15 17 17 19 22 28 23 + 19 20 26 21 17 17 24 33 24 26 29 29 31 31 31 19 23 34 36 34 + 30 36 28 30 31 30 253 253 0 67 1 5 5 5 7 6 7 14 8 8 14 30 + 20 17 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 + 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 + 30 30 30 30 30 30 30 30 30 30 30 30 30 253 253 0 17 8 1 49 + 1 64 3 1 34 0 2 17 1 3 17 1 253 253 0 29 0 0 2 2 3 1 1 1 0 + 0 0 0 0 0 0 0 0 4 5 6 7 2 3 8 0 1 9 253 253 0 74 16 0 2 1 3 + 3 2 4 4 3 4 5 10 5 3 5 1 1 2 3 0 4 17 5 18 33 6 49 19 34 65 + 81 7 50 97 113 20 35 253 21 51 66 82 36 52 253 253 253 8 53 + 83 98 114 115 253 253 253 253 22 37 67 116 253 99 253 253 + 23 68 84 100 253 253 253 253 0 25 1 0 3 1 1 1 0 0 0 0 0 0 0 + 0 0 0 0 1 2 3 0 4 5 253 253 0 39 17 0 2 2 2 2 3 0 2 1 5 1 0 + 0 0 0 0 0 1 2 17 3 33 18 49 34 50 65 19 81 4 5 20 35 66 97 + 82 253 253 0 12 3 1 0 2 17 3 17 0 63 0 253 253 253 253 253 + 253 253 253 253 68 253 253 112 60 21 45 253 91 253 57 253 + 253 253 75 56 95 111 253 253 51 253 253 11 253 253 14 118 + 253 22 253 253 104 253 118 82 46 253 45 253 98 79 253 102 + 253 38 253 98 253 64 253 253 72 253 49 46 104 11 8 253 111 + 253 253 253 253 70 253 12 253 112 61 253 57 36 253 31 82 7 + 253 253 78 253 253 253 253 0 253 41 100 253 76 15 253 253 + 118 60 31 253 85 253 126 253 253 253 253 253 253 113 253 66 + 253 253 253 82 74 49 45 253 253 42 49 253 253 253 108 253 + 99 21 68 253 88 116 253 83 17 253 253 253 253 109 253 253 + 253 6 253 83 253 109 1 253 115 253 10 253 90 106 23 106 253 + 95 59 73 253 253 77 44 111 89 79 253 24 253 253 253 253 86 + 253 253 71 253 20 52 253 253 253 24 253 253 253 253 61 253 + 66 253 65 253 253 253 64 253 5 253 127 253 45 3 99 42 253 + 42 253 253 79 253 83 253 38 86 92 21 57 20 76 253 253 78 + 253 98 88 31 253 253 125 253 253 45 108 253 253 97 253 0 + 253 44 253 0 253 45 22 253 253 253 253 99 88 74 98 77 99 78 + 253 69 111 14 253 253 23 28 253 48 15 253 253 30 253 21 253 + 105 8 253 253 103 253 253 253 253 121 253 127 253 87 253 + 253 253 253 31 253 253 253 253 253 28 88 253 253 120 99 253 + 52 100 253 0 253 253 253 253 108 109 11 103 253 253 127 253 + 253 118 82 71 253 47 253 253 253 11 253 30 74 81 253 102 + 253 253 35 253 97 104 62 253 46 104 41 45 109 119 127 86 + 253 253 21 48 253 253 9 253 104 105 253 24 118 53 76 77 81 + 253 73 105 109 253 253 253 127 253 21 253 89 253 110 63 253 + 97 253 0 253 69 65 253 110 15 39 253 253 253 253 253 41 6 + 253 102 5 22 54 253 114 109 45 253 123 24 253 53 253 45 44 + 253 253 79 253 253 253 253 253 118 101 112 253 253 253 102 + 253 253 253 35 253 99 95 253 253 119 253 253 253 253 253 21 + 18 253 125 253 92 253 2 253 253 16 253 15 253 253 253 71 46 + 253 253 106 253 78 253 40 253 253 109 83 33 45 253 253 253 + 253 253 253 253 253 30 253 253 69 45 37 253 253 253 253 12 + 253 253 253 253 253 253 253 8 75 123 253 15 69 96 7 253 253 + 253 253 253 31 253 253 253 253 253 102 120 253 0 68 253 253 + 253 253 12 15 253 253 253 253 253 253 253 253 253 253 253 + 253 7 253 123 80 253 253 253 118 253 66 253 253 118 62 253 + 253 253 38 91 55 253 253 253 253 60 253 22 96 14 253 253 + 107 84 253 69 253 253 253 253 100 253 0 65 18 253 43 253 82 + 105 253 253 108 64 253 31 102 253 253 253 253 253 253 253 + 39 253 73 38 50 84 253 253 112 253 19 253 4 118 54 253 253 + 22 33 68 54 253 253 52 96 253 253 253 15 115 16 253 66 253 + 253 77 253 253 40 115 253 90 253 91 73 253 116 253 29 253 + 77 253 253 253 253 46 64 109 253 88 45 253 31 253 253 92 + 127 253 253 19 97 99 253 16 253 125 253 253 63 253 20 100 + 253 56 253 253 253 66 84 253 253 253 253 253 253 253 125 18 + 253 125 253 253 108 72 7 253 125 253 63 253 45 109 253 77 + 253 253 253 111 253 253 0 253 253 68 76 253 253 253 51 253 + 103 43 0 253 253 253 253 72 253 253 54 113 253 5 91 120 50 + 59 253 77 7 120 109 253 48 22 8 1 253 253 98 253 106 253 + 253 253 45 253 253 253 93 41 97 253 253 73 97 253 96 19 253 + 103 253 253 23 253 253 253 71 253 93 253 253 110 117 101 67 + 90 253 253 253 55 253 97 253 253 37 122 124 253 253 48 118 + 253 253 81 66 116 253 82 123 2 253 103 108 55 30 99 31 253 + 253 253 253 63 56 253 253 253 253 26 90 253 253 56 20 109 + 253 253 89 16 253 253 80 253 253 80 49 253 110 253 63 253 + 253 253 107 74 62 44 253 36 253 253 17 253 253 253 253 26 + 253 253 253 253 21 40 253 113 253 253 253 253 253 53 253 + 253 63 253 57 253 253 85 55 253 34 5 87 126 124 253 123 26 + 253 15 253 253 42 253 59 108 123 112 51 27 14 253 90 253 61 + 68 253 253 253 253 58 35 7 253 253 57 253 253 253 91 25 82 + 71 24 253 0 253 44 253 253 21 253 99 16 253 120 253 253 253 + 97 253 253 99 81 253 5 253 74 253 253 29 253 253 253 99 121 + 253 253 80 127 253 253 253 22 253 96 121 19 84 253 253 253 + 253 77 106 61 62 253 25 35 114 253 253 1 253 43 253 253 253 + 72 71 24 56 253 125 107 253 253 253 253 253 253 93 61 253 + 35 76 253 42 43 253 253 253 253 253 58 123 85 253 9 37 67 + 103 63 74 117 39 123 37 253 26 110 253 20 14 64 53 253 253 + 253 253 22 253 21 253 253 111 83 69 22 80 72 253 89 253 103 + 61 253 253 117 60 253 121 15 253 253 253 253 8 23 253 253 + 253 253 253 253 36 253 11 253 253 28 85 123 253 253 93 64 + 253 57 52 99 32 253 45 89 253 15 253 253 253 46 253 253 60 + 253 253 48 43 69 253 253 24 253 109 253 61 253 21 57 118 96 + 253 57 92 253 52 43 253 253 253 126 253 68 18 3 88 253 253 + 253 253 108 253 253 8 107 64 62 65 253 253 253 253 91 25 + 253 253 39 38 253 253 99 253 122 253 112 253 118 59 253 83 + 253 114 54 59 46 253 253 89 39 253 90 93 89 88 115 253 110 + 64 74 113 83 253 253 5 59 62 253 35 253 253 16 253 253 124 + 109 253 123 253 253 19 13 253 35 38 253 253 69 62 253 105 + 253 253 0 253 253 85 253 253 82 253 253 253 60 103 253 77 + 253 253 253 66 253 98 253 253 82 253 73 24 253 45 34 81 253 + 253 75 44 253 253 7 114 72 110 253 253 36 73 12 42 253 253 + 253 253 73 52 253 253 253 253 253 253 253 253 113 253 253 + 49 253 90 253 124 40 253 122 110 253 253 253 65 66 12 48 + 253 253 253 94 54 253 61 253 253 94 28 123 10 253 10 78 59 + 253 253 109 253 58 253 8 253 253 253 253 19 73 53 253 86 80 + 253 253 253 1 253 107 253 253 77 101 105 103 51 253 253 36 + 253 24 25 39 253 0 253 93 18 253 253 18 253 253 253 30 253 + 253 85 253 253 109 39 253 253 253 253 110 8 253 253 253 253 + 253 253 253 14 253 253 27 66 253 60 46 54 110 5 72 31 253 + 82 253 57 253 72 253 253 253 64 253 70 127 253 13 253 253 + 107 253 253 253 5 253 91 253 253 253 58 75 253 253 48 72 36 + 47 117 253 71 39 113 4 23 253 253 253 253 96 100 114 107 24 + 253 253 126 62 253 253 101 57 253 253 89 70 6 7 2 253 253 + 35 253 71 102 253 84 40 253 253 110 57 38 253 253 3 253 86 + 19 1 253 253 253 253 253 34 253 253 253 253 100 253 253 253 + 52 121 77 253 253 253 67 117 253 253 253 253 253 17 253 81 + 253 253 116 52 72 253 253 253 253 21 253 253 126 30 79 76 + 46 253 62 253 16 27 253 7 34 55 253 55 63 253 116 253 253 + 118 253 117 253 253 127 253 253 253 253 15 13 127 253 253 + 16 10 253 253 253 69 43 253 253 253 88 23 253 71 70 32 110 + 253 253 253 253 25 99 99 253 78 127 253 253 253 253 253 253 + 253 253 86 35 253 253 42 253 253 253 253 50 65 253 253 53 9 + 89 253 253 253 253 253 253 253 253 54 61 100 68 118 253 86 + 253 89 253 253 121 253 72 1 2 253 253 253 253 253 253 70 + 253 253 28 253 253 253 253 253 253 92 253 253 253 87 23 253 + 92 253 253 253 253 253 121 253 253 107 253 253 103 253 253 + 35 253 253 253 253 84 6 99 253 85 36 253 34 253 98 253 34 + 100 89 89 253 43 6 97 253 35 253 253 95 94 86 17 2 253 56 + 253 105 119 253 253 253 253 253 39 253 253 27 253 16 95 113 + 79 95 253 16 253 30 253 253 253 11 253 60 253 59 253 75 253 + 103 77 91 253 58 101 253 253 253 253 253 253 253 253 78 97 + 253 253 253 253 253 10 31 65 253 253 253 100 253 21 253 253 + 253 29 253 5 87 253 253 110 253 109 31 80 253 36 111 32 39 + 57 253 57 253 77 253 253 92 69 253 253 49 253 126 253 105 + 124 86 253 27 125 70 22 253 253 253 9 2 253 253 253 53 76 + 66 38 253 253 65 109 48 111 8 253 18 123 81 253 20 253 253 + 101 253 253 253 253 94 253 14 253 105 27 253 106 253 253 20 + 11 253 125 51 253 253 253 70 253 253 104 253 87 28 85 117 + 117 253 117 253 253 253 84 87 253 253 26 253 108 253 5 3 + 253 77 253 78 253 74 253 253 253 7 253 115 18 253 253 253 + 253 33 27 48 253 64 24 26 253 126 13 108 253 253 253 253 9 + 253 79 106 26 92 253 253 253 253 253 93 253 124 253 48 107 + 34 253 39 253 253 253 0 253 122 253 253 253 253 253 65 253 + 253 27 253 24 253 101 253 40 253 253 253 49 253 90 109 85 + 29 124 253 253 253 253 19 28 98 253 123 253 253 64 46 253 + 13 122 22 253 39 28 253 253 86 253 253 4 19 90 1 253 253 50 + 28 253 253 52 91 253 253 55 253 62 253 56 91 68 253 88 110 + 253 30 253 37 253 49 253 253 106 58 253 51 73 253 253 119 + 19 253 253 253 253 61 253 253 253 12 253 253 79 253 57 32 + 253 253 51 253 253 90 253 65 253 253 253 8 253 0 51 104 46 + 125 106 115 253 78 253 124 17 113 253 253 37 26 85 253 122 + 109 253 113 68 253 96 49 253 253 125 253 253 85 59 90 64 + 119 124 253 253 253 43 5 43 253 31 79 253 10 253 36 44 26 + 70 253 253 253 30 253 253 253 253 253 253 253 10 253 98 253 + 253 253 253 253 253 253 28 253 253 88 122 253 253 253 253 + 253 52 253 253 88 98 253 253 253 253 36 46 112 15 53 253 56 + 253 253 65 253 0 253 77 253 253 69 253 118 253 253 253 54 + 118 253 253 253 116 73 72 253 253 253 253 253 253 253 31 + 253 22 18 253 26 36 253 2 72 21 60 253 64 253 253 253 106 + 253 253 67 38 253 37 36 253 253 51 90 91 253 253 104 253 13 + 18 253 253 253 253 127 46 43 5 253 253 253 253 55 127 253 + 253 253 43 85 253 100 253 253 253 94 71 20 253 253 103 23 + 43 253 125 253 84 253 253 253 253 253 253 43 100 253 40 253 + 9 22 253 253 45 253 253 253 253 253 253 40 93 79 253 67 62 + 253 253 22 253 253 1 253 96 53 98 253 253 12 253 253 253 + 253 3 253 102 81 253 71 82 41 99 12 59 253 74 117 91 114 45 + 253 117 31 253 103 253 253 253 253 253 45 55 44 17 99 253 + 29 23 12 253 28 6 3 20 20 19 127 71 253 253 253 42 253 28 + 253 253 7 253 253 103 253 253 0 253 253 253 253 120 253 3 + 12 12 253 69 111 253 253 253 253 66 253 36 253 90 253 253 + 253 253 253 253 74 253 89 253 67 123 11 6 57 253 21 63 253 + 253 253 68 253 253 110 253 102 253 253 253 253 253 253 60 + 253 253 253 253 253 253 253 253 253 253 253 15 25 253 253 + 253 39 253 43 63 15 79 19 76 7 253 253 253 253 253 30 253 + 50 253 43 42 253 48 253 253 253 253 253 55 253 71 253 253 + 97 253 253 28 99 253 253 69 117 30 253 31 105 30 253 253 46 + 253 253 75 253 253 253 253 253 253 60 253 70 253 253 80 253 + 253 75 253 34 253 101 253 54 253 25 102 253 55 70 35 3 253 + 118 253 108 39 87 253 66 253 108 61 253 253 253 253 253 119 + 82 49 253 253 253 123 10 253 253 82 89 36 88 253 253 38 253 + 121 37 76 253 253 253 123 36 253 253 253 253 253 20 253 60 + 61 253 253 72 253 253 127 253 23 70 253 253 253 253 253 253 + 107 103 253 253 253 253 70 86 253 66 28 253 3 253 26 58 253 + 253 43 253 66 92 66 253 79 253 115 253 108 56 253 253 105 + 253 115 105 60 253 253 253 23 80 253 253 71 5 253 122 253 + 253 253 253 29 253 42 253 22 253 253 253 253 253 253 253 + 253 70 253 45 21 81 253 253 253 10 253 253 253 71 253 253 + 77 253 49 8 253 84 253 253 35 253 93 112 253 253 253 253 60 + 93 253 116 37 253 39 10 0 126 41 253 119 81 1 253 253 22 + 120 253 35 92 253 253 253 253 253 253 33 253 253 65 87 253 + 253 13 50 87 253 253 253 253 126 253 253 253 253 253 253 10 + 253 46 253 253 115 253 72 253 253 253 41 253 253 253 67 253 + 9 51 12 253 253 114 253 82 120 106 56 113 80 253 253 72 88 + 5 76 31 253 20 253 253 253 253 253 253 253 50 102 37 118 + 253 253 253 253 253 253 253 18 71 253 253 253 253 84 119 + 253 1 73 253 49 253 253 253 253 110 253 253 106 253 253 104 + 253 74 29 253 253 253 253 29 253 89 253 58 77 253 253 253 + 253 20 112 253 253 125 253 6 253 253 253 75 253 253 65 36 + 113 253 253 9 0 253 253 15 253 253 19 79 253 253 79 42 25 + 253 253 253 31 74 76 253 253 71 84 49 253 253 253 253 68 + 253 253 253 253 253 6 253 56 86 28 253 253 45 253 253 253 + 253 66 253 30 61 253 253 253 253 253 253 26 15 40 39 253 + 253 107 253 22 253 253 46 37 36 124 253 127 253 253 83 91 + 118 86 253 253 253 14 253 253 253 103 253 253 253 253 253 + 253 253 48 86 39 253 253 253 253 253 253 253 56 17 91 253 + 253 81 253 17 88 53 253 253 253 28 114 56 92 122 253 253 27 + 253 253 253 253 24 253 253 253 43 85 253 50 253 14 15 36 + 253 87 109 34 253 27 253 121 253 54 108 253 253 12 118 253 + 82 253 253 253 112 253 253 253 253 253 253 77 30 118 120 + 253 253 253 253 122 253 48 107 54 253 103 253 253 253 253 + 253 253 253 253 253 253 253 253 101 109 50 82 253 253 253 + 253 253 115 71 253 11 55 253 253 253 88 253 17 253 253 1 + 253 253 253 253 57 102 253 68 107 48 54 253 27 24 253 68 15 + 114 49 253 253 253 253 19 37 253 253 38 253 253 120 10 253 + 253 86 253 253 108 253 123 9 253 253 253 253 253 253 253 + 253 59 253 253 70 49 253 73 253 253 91 80 99 253 253 62 253 + 253 253 253 111 253 75 253 24 253 253 253 253 90 109 103 31 + 253 97 253 115 84 253 28 253 40 253 253 117 253 100 12 118 + 253 253 253 253 253 92 48 253 34 39 253 253 253 253 14 24 + 253 49 64 253 253 253 78 253 87 253 253 61 43 84 253 253 94 + 55 253 253 253 253 253 61 253 253 89 101 253 16 108 61 253 + 253 253 253 253 253 11 253 253 253 253 91 253 253 253 100 + 86 32 119 253 109 80 30 253 95 79 253 253 30 253 253 253 + 253 127 18 253 0 101 110 253 23 253 43 253 253 107 253 5 + 253 253 30 119 29 253 54 44 125 253 127 253 28 119 253 73 + 72 253 253 40 253 60 31 122 253 253 253 253 38 253 253 3 32 + 253 119 253 21 253 253 253 12 253 67 115 253 84 253 91 253 + 253 97 89 64 253 32 253 84 253 253 119 67 253 253 53 253 38 + 253 30 25 253 112 253 29 69 63 48 253 73 253 65 253 83 13 + 65 48 37 1 124 253 253 253 55 61 253 40 20 109 253 253 90 + 253 253 4 253 78 253 70 24 83 253 253 80 253 253 69 16 253 + 14 14 87 253 104 11 253 104 253 90 118 5 84 253 253 125 253 + 253 126 253 253 21 253 253 69 253 4 103 13 253 253 253 253 + 253 70 55 253 38 88 253 39 253 13 253 253 34 253 33 253 253 + 253 253 253 253 253 253 121 253 85 1 97 253 112 253 90 253 + 90 253 253 253 64 27 45 253 253 127 253 253 253 253 253 98 + 253 253 253 253 77 253 253 99 70 253 253 253 99 253 253 253 + 43 123 77 62 84 37 70 88 253 53 253 253 20 122 253 253 253 + 127 253 100 102 12 71 7 253 253 253 253 80 253 253 123 253 + 93 92 253 90 92 48 253 126 11 3 85 253 253 52 253 72 253 36 + 253 253 253 125 105 253 26 253 253 253 253 253 48 75 253 26 + 50 253 31 253 253 86 253 253 253 120 114 70 67 253 253 253 + 253 123 78 253 253 253 25 60 57 29 36 94 123 112 125 253 77 + 253 116 253 253 253 253 92 70 3 69 253 253 14 72 30 253 94 + 253 253 70 42 93 253 70 127 3 111 32 5 253 28 253 30 253 + 253 13 46 253 253 24 7 253 106 253 253 253 39 253 253 25 + 253 2 253 110 1 253 253 253 45 253 253 253 22 112 6 10 253 + 253 253 253 25 79 253 83 113 90 253 43 253 253 253 253 253 + 253 253 253 253 38 69 97 253 253 90 253 253 253 91 253 253 + 85 253 18 253 103 7 253 253 253 253 253 68 74 253 253 104 + 253 253 253 253 253 51 108 73 97 253 253 2 110 35 93 253 + 253 253 253 253 253 22 253 253 75 253 79 49 253 253 253 76 + 253 253 253 253 30 253 253 253 116 253 113 19 253 19 253 + 253 87 118 253 253 66 253 253 113 253 253 0 84 123 26 253 + 253 17 253 79 253 58 87 253 47 85 90 20 253 99 120 253 253 + 48 253 7 253 253 44 253 72 110 33 115 28 253 253 253 107 + 253 253 73 253 253 13 34 253 43 253 91 253 86 86 253 103 + 253 43 253 253 21 117 253 253 253 253 253 52 253 253 253 42 + 79 57 253 101 253 253 253 89 37 47 253 253 123 62 27 253 + 253 66 253 253 253 253 87 72 253 253 253 253 31 253 253 83 + 11 125 67 253 86 98 67 253 253 92 253 119 20 253 85 253 97 + 108 253 253 253 124 118 253 253 253 7 253 53 253 253 77 253 + 253 8 253 253 106 253 5 122 9 94 253 253 34 253 253 253 119 + 94 29 253 113 253 108 89 253 253 11 127 16 253 111 253 21 + 253 69 35 253 253 253 253 3 253 253 253 253 253 253 253 41 + 253 253 109 86 72 253 253 99 253 32 253 21 50 253 67 51 13 + 253 70 253 253 253 253 91 1 54 253 253 79 106 253 105 49 31 + 46 253 1 253 253 91 125 253 253 253 253 114 253 253 87 253 + 253 253 96 31 253 115 103 253 23 118 253 253 36 82 253 55 + 253 253 90 253 47 253 253 253 39 25 59 121 253 253 109 253 + 0 40 116 120 110 253 253 99 119 97 84 253 253 253 101 253 + 253 88 15 19 77 12 127 74 253 28 124 80 253 50 40 253 253 + 70 70 70 253 125 40 253 124 40 253 106 253 253 253 253 89 + 109 253 34 93 253 253 112 118 10 12 51 23 28 26 253 253 16 + 253 253 253 253 40 253 253 18 63 253 115 121 30 61 253 253 + 253 253 69 44 253 124 253 41 253 253 253 54 253 55 253 49 + 253 27 253 25 253 253 253 105 102 253 24 91 9 253 253 253 + 63 20 253 94 35 253 253 5 253 47 253 9 253 0 253 61 43 70 + 54 253 253 253 253 253 101 33 79 253 35 103 253 253 52 113 + 253 253 253 253 253 37 253 253 253 253 22 253 26 253 108 64 + 22 253 14 253 76 115 74 253 253 76 253 253 253 120 253 253 + 25 116 253 30 253 114 253 253 115 253 253 103 253 2 69 22 + 253 42 253 41 38 15 253 97 253 253 104 253 109 253 253 253 + 70 52 253 253 83 253 253 253 73 253 253 103 65 124 33 253 + 253 253 106 18 99 120 253 121 253 106 253 253 50 253 253 + 103 80 95 24 21 0 253 17 121 29 253 79 253 27 253 253 7 253 + 253 253 45 63 253 253 72 253 83 28 87 61 118 253 253 63 34 + 5 253 47 253 253 113 35 253 123 82 11 253 21 253 11 24 253 + 71 114 106 73 253 90 72 253 253 27 21 253 124 122 253 102 + 253 53 253 253 253 253 0 61 253 37 89 253 29 253 53 75 253 + 111 21 13 253 253 108 112 91 253 253 253 97 109 58 34 253 + 18 253 253 97 253 25 253 253 253 253 126 253 253 82 253 33 + 117 253 253 5 91 253 253 74 81 38 253 119 253 23 253 253 13 + 36 64 111 253 253 120 107 68 253 77 253 59 253 253 99 253 + 253 109 253 253 81 253 121 253 253 253 84 253 253 253 253 + 55 119 18 90 253 253 253 253 253 253 107 253 79 253 32 253 + 253 24 33 253 253 3 253 253 85 253 253 17 253 253 44 253 + 116 39 42 87 253 253 106 253 77 253 83 253 61 31 45 253 253 + 253 1 102 27 100 118 253 29 253 253 21 253 253 253 253 253 + 117 88 99 32 253 102 0 253 79 253 253 253 114 253 253 91 + 253 253 253 31 106 253 62 29 116 253 253 253 14 253 253 253 + 115 253 253 253 79 253 253 85 23 253 253 40 253 116 253 93 + 13 253 253 94 74 18 253 253 114 14 72 92 253 106 253 253 14 + 253 253 253 253 253 49 253 253 72 253 253 253 48 253 30 253 + 253 253 253 47 24 253 253 57 97 253 253 253 253 253 85 253 + 253 100 34 253 253 57 28 122 253 102 253 253 58 97 20 253 + 253 253 253 253 253 253 72 103 253 253 253 253 253 28 17 78 + 83 253 253 253 4 253 96 7 111 126 253 58 253 108 253 90 253 + 40 253 253 253 253 253 253 253 77 253 54 253 110 34 253 253 + 113 123 101 115 115 253 253 253 101 253 253 113 81 253 106 + 35 253 61 46 253 253 44 118 104 3 38 253 253 253 253 253 + 253 253 45 253 101 119 0 9 35 253 41 14 253 104 253 73 101 + 10 253 253 253 119 253 50 253 89 253 253 87 253 48 77 60 + 253 253 110 253 253 253 253 1 253 253 253 253 253 253 253 + 22 253 86 75 117 253 95 31 253 253 114 106 253 69 253 253 + 52 71 111 57 46 113 253 253 253 253 253 253 253 253 110 90 + 253 253 94 253 22 253 253 126 253 253 253 45 253 81 253 253 + 253 253 105 35 253 253 253 41 67 253 122 15 253 253 253 253 + 66 77 47 82 51 89 54 17 78 55 19 253 125 253 253 94 105 253 + 253 253 22 253 16 253 44 124 64 125 90 253 253 253 253 253 + 102 253 70 62 253 31 253 94 124 90 57 84 253 54 116 39 253 + 253 253 253 253 78 253 124 92 52 99 12 24 253 84 253 125 74 + 253 253 22 13 253 35 12 7 253 125 15 253 253 253 65 253 253 + 253 253 253 12 253 253 253 253 253 253 30 253 253 66 253 + 253 114 253 253 253 253 253 253 253 253 104 57 61 253 45 + 253 253 48 52 253 253 253 34 253 37 253 67 26 253 81 253 61 + 253 253 253 49 100 85 253 112 63 90 253 45 253 253 253 253 + 79 82 37 80 253 253 102 253 26 9 253 67 120 253 72 85 91 + 253 72 253 114 59 253 253 18 88 253 116 253 253 253 253 98 + 253 253 66 253 253 253 253 31 74 253 253 253 253 253 35 253 + 253 253 253 253 253 118 253 110 253 97 23 253 49 73 253 253 + 54 253 29 92 253 253 253 109 253 115 253 253 253 87 51 253 + 0 253 20 253 13 253 120 78 253 124 253 253 253 253 253 253 + 27 123 23 50 76 82 69 253 253 253 92 253 253 253 253 253 93 + 84 253 43 29 253 253 55 253 253 253 83 103 14 94 253 60 113 + 50 75 18 253 79 253 253 52 94 253 2 253 253 253 253 84 253 + 50 253 253 253 7 253 253 118 12 253 253 253 18 75 71 56 79 + 253 25 101 81 253 99 253 253 253 253 253 27 253 253 253 74 + 24 253 253 24 112 43 253 32 253 41 253 253 8 253 86 62 48 + 253 253 253 253 93 253 45 3 253 253 253 253 253 90 105 253 + 46 97 24 253 253 72 253 115 253 16 41 253 253 58 253 99 253 + 93 28 124 253 57 31 253 76 253 70 35 253 64 253 8 253 253 + 47 121 253 0 253 253 253 0 45 82 49 253 253 58 116 91 253 + 253 253 253 253 253 253 53 35 105 60 253 253 71 253 59 111 + 253 99 253 253 253 39 120 253 253 115 61 253 58 49 253 62 + 253 27 106 40 253 11 253 253 253 253 90 52 110 112 15 124 + 253 80 253 59 253 60 253 253 93 253 52 5 27 253 123 98 253 + 253 253 253 121 123 23 111 253 253 25 19 253 253 253 25 253 + 25 253 253 253 123 253 253 253 253 6 72 253 55 16 253 253 + 253 253 61 253 253 253 253 253 76 253 12 22 253 253 49 99 + 253 253 253 253 253 253 253 253 82 253 81 253 125 123 87 36 + 253 253 117 253 253 96 58 253 253 253 59 253 253 20 253 253 + 253 253 53 1 253 253 21 253 253 253 253 253 60 253 253 43 + 87 94 253 125 253 253 20 253 73 17 253 118 25 253 253 253 + 253 253 253 253 81 90 253 253 114 253 253 72 253 253 86 253 + 91 253 253 34 253 253 51 253 253 253 253 86 120 81 64 43 + 253 57 253 253 68 253 85 123 61 253 253 95 57 67 253 63 78 + 253 253 26 107 253 12 253 253 253 253 253 61 253 1 113 118 + 253 253 253 253 15 253 118 67 29 253 100 253 253 253 25 125 + 127 253 37 253 253 253 253 253 15 253 39 253 59 88 253 96 + 253 253 90 253 253 36 253 253 253 253 80 71 44 253 42 253 + 253 102 56 81 253 253 253 253 253 87 119 100 253 253 253 + 253 38 253 253 70 24 253 11 24 253 253 253 253 39 253 253 + 253 253 13 253 114 107 91 40 63 18 33 253 114 253 253 72 + 253 253 125 126 253 76 253 0 253 253 253 253 90 253 29 253 + 253 253 92 253 253 253 253 253 118 253 29 253 253 57 31 95 + 253 253 253 67 253 253 19 79 111 28 23 17 253 94 51 253 21 + 253 0 10 253 253 253 253 14 42 253 253 253 51 253 56 253 + 253 253 76 253 253 60 52 109 25 57 253 62 253 253 23 253 18 + 93 21 253 101 66 253 253 253 253 253 253 60 62 42 253 253 + 253 253 253 111 253 253 78 253 253 101 253 253 77 253 91 97 + 53 253 253 56 86 253 19 253 253 253 253 0 253 253 99 253 + 253 88 253 34 253 11 253 253 253 95 72 74 253 253 99 70 54 + 96 118 28 10 87 127 110 100 253 112 118 47 115 77 253 253 + 253 80 119 253 253 253 42 253 15 253 253 253 119 253 104 57 + 39 253 37 117 96 85 253 253 253 51 253 125 105 102 253 253 + 69 54 253 34 253 46 253 253 30 253 0 74 253 93 253 101 253 + 35 47 253 253 33 253 65 253 111 61 253 253 253 253 253 70 + 253 70 253 253 96 43 36 253 253 105 100 109 81 253 253 0 26 + 122 94 253 253 119 19 36 253 69 30 60 253 32 36 253 253 0 + 253 115 30 253 38 253 83 13 253 52 108 59 6 24 56 253 253 + 63 253 253 253 92 105 253 21 253 253 253 19 103 253 21 87 + 43 253 98 73 253 92 75 253 71 69 253 253 122 253 253 253 + 109 253 104 253 35 253 24 32 125 72 253 253 253 253 100 114 + 69 253 22 253 253 253 121 78 1 253 253 253 70 253 115 107 + 34 253 253 98 253 253 122 253 253 6 100 253 253 79 106 253 + 5 253 253 253 47 98 49 85 253 22 46 253 97 69 253 51 92 95 + 253 253 253 253 5 253 99 61 253 253 105 116 253 253 111 113 + 98 30 50 253 84 253 7 61 253 253 115 253 253 253 253 253 88 + 47 253 253 52 108 26 253 253 253 253 253 253 253 11 253 253 + 253 0 253 77 35 253 253 253 253 57 18 253 103 91 253 253 + 253 110 23 116 253 253 102 50 125 13 77 116 75 253 109 109 + 253 33 103 25 253 253 253 253 253 253 253 34 36 253 8 253 + 36 104 253 7 253 253 7 253 253 253 253 77 90 253 253 253 26 + 9 55 2 61 253 253 253 101 253 253 74 107 253 77 121 113 115 + 253 253 253 70 36 253 253 30 99 47 253 253 253 253 62 46 90 + 90 253 253 34 77 104 253 54 253 0 253 253 253 91 253 253 + 253 113 19 96 253 36 253 253 253 253 253 253 51 106 253 86 + 112 70 253 253 253 84 253 53 100 253 105 82 35 18 57 99 90 + 7 253 43 4 253 33 91 253 123 86 107 253 110 253 253 36 101 + 253 19 253 0 253 253 21 253 253 121 39 253 253 253 253 253 + 32 253 71 253 253 253 105 253 253 8 253 253 253 253 253 109 + 253 253 253 253 253 51 253 85 253 253 74 87 253 61 69 29 + 253 253 253 253 253 40 253 57 253 51 103 6 253 253 8 93 58 + 253 60 127 71 127 253 104 253 62 253 22 253 253 253 101 253 + 127 253 253 253 0 45 20 253 24 85 253 73 26 253 65 253 253 + 18 86 70 100 50 253 253 90 89 104 253 253 86 253 253 63 253 + 63 253 253 253 100 253 253 112 253 253 253 69 37 101 99 253 + 116 253 253 253 253 42 253 50 31 8 253 253 253 253 253 127 + 87 0 253 94 9 253 253 253 78 14 51 253 253 253 253 253 253 + 39 127 8 122 253 253 253 253 253 253 253 54 253 253 113 253 + 52 71 92 124 78 253 253 23 253 253 253 28 253 253 253 113 + 253 253 88 253 253 253 253 44 80 253 253 253 253 253 253 38 + 253 253 253 253 121 49 73 253 101 63 253 79 45 253 253 253 + 253 73 78 253 107 253 29 90 253 92 253 101 113 39 253 253 + 253 34 104 102 253 253 253 56 253 104 253 6 61 253 253 253 + 107 11 253 118 253 253 115 52 123 72 253 117 42 253 253 253 + 253 57 35 253 15 24 253 253 253 115 114 14 253 253 253 253 + 18 48 253 23 253 122 253 18 51 72 253 253 253 253 124 253 + 89 253 253 253 82 45 15 253 253 253 253 64 35 253 253 50 60 + 253 253 60 253 253 122 253 34 253 253 253 105 22 52 83 253 + 56 21 119 124 40 253 61 22 11 120 117 14 253 91 71 253 253 + 253 253 253 253 253 253 253 76 253 253 253 63 253 253 18 + 253 18 57 54 253 100 253 253 253 63 253 91 58 253 90 125 + 107 82 253 0 253 61 62 253 253 253 253 253 253 120 253 253 + 82 82 253 69 253 253 253 253 253 253 253 36 253 253 27 253 + 53 90 60 43 62 253 253 253 253 253 253 124 122 30 253 253 + 31 29 52 104 253 253 95 253 32 5 27 100 36 253 45 253 253 + 10 253 253 62 14 116 119 78 253 49 106 29 125 253 253 6 78 + 253 253 253 253 253 253 253 126 25 253 253 0 253 31 253 253 + 111 253 253 253 253 75 11 33 253 58 253 253 253 253 253 111 + 253 253 253 18 253 105 41 253 127 11 55 77 253 253 13 253 + 253 52 253 253 62 32 50 253 253 57 253 253 253 71 253 253 + 253 253 122 253 5 253 105 253 253 57 253 14 11 253 120 253 + 63 253 253 92 19 253 253 53 253 80 253 253 253 253 37 96 36 + 8 112 28 122 30 61 49 87 123 253 75 105 253 99 253 52 253 + 69 118 253 26 0 16 253 253 74 253 104 10 253 71 82 105 125 + 92 253 27 253 253 253 253 253 12 41 37 253 45 253 68 75 253 + 79 115 253 253 5 253 253 253 253 84 103 253 253 253 253 253 + 253 23 49 253 121 21 93 253 36 253 253 253 63 253 90 253 + 115 72 253 28 109 253 86 95 48 30 253 253 46 253 68 253 62 + 253 253 22 88 78 21 253 253 46 120 253 44 126 253 253 253 + 253 72 124 104 253 253 79 13 253 39 0 253 253 253 55 253 64 + 44 102 54 86 40 36 33 28 253 7 21 76 253 62 253 115 253 253 + 253 253 30 37 253 253 49 253 253 253 62 253 88 253 253 253 + 62 34 253 253 58 102 253 2 121 12 14 253 120 80 253 253 253 + 253 253 54 253 253 253 78 253 253 253 253 253 253 110 253 + 253 253 16 253 40 253 253 78 113 253 253 253 17 53 127 253 + 104 253 75 123 253 253 74 17 20 253 253 63 253 253 0 62 253 + 82 116 253 253 253 117 70 253 107 253 253 253 120 253 253 + 79 253 253 253 253 253 253 111 253 28 253 97 20 253 253 253 + 253 253 58 99 87 253 253 253 73 107 36 48 253 16 253 253 70 + 253 253 77 253 62 253 253 253 253 253 63 253 253 13 253 253 + 253 108 253 26 9 253 13 46 253 115 253 3 253 81 85 253 123 + 253 253 79 253 58 54 253 253 253 253 253 96 36 253 110 10 + 253 253 64 253 103 253 70 126 35 124 48 253 253 99 6 253 + 253 253 253 253 253 253 70 253 7 2 253 253 55 41 69 121 116 + 68 62 34 253 106 253 253 253 73 100 253 61 253 253 17 253 + 66 253 253 80 253 253 39 253 253 28 253 253 105 253 105 253 + 87 253 253 26 59 253 253 253 127 13 253 23 253 253 44 14 + 253 253 253 253 68 106 253 61 253 107 110 253 253 30 119 14 + 253 253 253 253 253 120 253 66 253 253 253 33 253 64 42 79 + 57 253 253 253 81 253 67 28 108 18 34 253 27 253 115 75 253 + 13 58 253 253 253 57 253 105 30 253 26 50 253 253 12 253 + 106 111 253 100 253 253 14 110 45 100 30 29 253 108 93 253 + 253 253 253 253 253 253 253 253 46 253 253 65 116 253 253 + 253 253 14 56 39 253 253 253 253 253 253 102 114 65 253 253 + 29 45 253 253 253 253 253 123 82 253 13 253 253 253 111 94 + 253 127 103 35 13 253 89 59 103 253 253 30 253 253 55 253 + 253 253 253 28 253 253 81 14 253 253 46 253 42 253 52 253 + 253 253 3 253 253 253 55 121 253 253 253 253 62 253 62 253 + 119 253 106 33 86 39 253 15 253 81 80 253 28 253 253 102 84 + 57 35 253 81 91 33 60 96 253 253 42 253 253 253 77 253 45 + 72 53 253 65 253 28 253 253 12 110 20 253 253 107 50 253 + 253 253 253 97 14 253 253 100 253 253 253 26 88 99 0 35 253 + 253 253 35 41 253 62 253 126 253 34 253 101 76 115 75 35 4 + 253 124 253 43 70 253 253 253 122 63 253 253 253 0 253 71 + 73 253 87 253 122 7 80 253 0 54 94 253 0 253 253 253 90 41 + 42 48 253 253 253 61 253 13 253 34 76 10 253 4 91 101 25 + 253 253 253 253 95 253 253 253 74 253 13 123 253 40 253 253 + 55 56 253 115 92 253 71 24 253 253 77 103 253 253 29 253 + 253 23 253 3 253 104 29 53 253 69 253 253 28 253 253 32 48 + 31 122 253 253 253 253 253 253 107 253 77 85 253 253 253 + 253 253 253 253 75 20 253 253 253 38 253 253 253 253 95 83 + 57 253 253 0 123 28 253 97 253 253 23 119 6 86 113 253 3 28 + 3 64 73 118 105 253 253 75 253 253 71 96 253 253 62 253 253 + 43 30 253 253 253 90 68 253 253 69 24 253 76 56 253 101 82 + 71 253 84 253 253 253 253 253 117 125 13 253 54 253 253 30 + 253 253 253 253 253 50 61 253 253 17 93 253 253 19 50 253 + 102 24 78 253 253 253 253 29 55 105 99 253 253 253 104 253 + 253 253 253 1 35 253 5 253 253 253 116 95 253 91 125 52 67 + 53 253 253 253 12 22 9 253 126 253 105 253 253 54 58 126 + 253 27 253 253 253 60 253 253 115 253 84 253 100 101 253 + 253 253 253 127 16 35 253 253 54 253 107 253 253 82 253 253 + 102 43 28 64 121 253 253 126 253 253 253 253 253 253 110 + 253 253 59 253 253 55 120 114 253 0 23 124 253 253 253 36 + 90 253 253 253 253 46 104 35 253 4 39 108 253 60 253 253 + 253 253 115 84 102 253 253 253 3 253 253 253 253 253 98 49 + 253 253 65 253 66 253 253 253 86 253 41 73 81 57 253 22 75 + 126 54 92 253 106 253 105 253 45 253 80 253 62 253 253 127 + 20 127 74 19 253 253 253 253 253 253 38 253 113 253 69 121 + 103 125 101 56 253 44 99 102 253 6 60 253 253 103 253 253 + 253 20 253 253 253 253 0 253 55 87 253 253 253 106 38 253 + 29 67 24 253 33 253 7 31 253 253 80 253 42 253 77 253 9 253 + 253 253 34 120 116 93 253 60 253 253 253 253 253 253 253 + 253 36 63 253 253 253 253 122 59 253 253 28 95 253 44 42 62 + 68 123 253 116 253 33 117 253 20 71 109 12 253 51 36 95 253 + 253 253 0 253 51 253 253 73 253 27 253 253 253 253 253 71 + 253 61 253 2 56 253 253 253 253 35 253 77 93 99 94 75 88 99 + 72 253 253 253 253 10 253 9 253 253 122 35 69 253 253 253 + 113 253 112 23 253 91 253 105 61 253 122 116 253 109 253 + 253 253 253 72 253 99 253 44 253 253 253 253 253 253 253 + 253 10 253 84 253 37 105 49 49 72 253 127 253 253 20 253 + 253 253 253 86 107 115 34 253 253 69 108 253 253 21 253 253 + 126 90 40 253 92 115 82 253 253 76 73 253 23 253 253 253 + 253 253 17 77 43 73 110 253 253 66 57 253 36 253 93 26 253 + 253 253 253 3 92 253 253 253 253 253 49 86 11 61 253 253 + 105 20 253 253 253 80 48 43 69 253 253 253 253 253 28 107 + 27 24 253 253 127 95 253 253 253 61 28 253 253 253 253 88 + 253 13 44 253 43 73 31 253 89 253 0 253 253 65 124 52 253 + 253 253 253 253 253 34 253 253 37 253 253 253 253 253 20 + 253 253 10 253 7 106 253 114 1 253 31 253 39 74 253 253 253 + 68 82 126 72 47 253 253 253 253 66 44 253 253 125 107 79 75 + 123 253 253 253 253 36 253 112 14 10 48 253 253 86 253 253 + 9 78 253 253 253 28 253 253 109 253 111 109 253 253 253 6 + 253 45 253 98 253 89 34 13 253 253 253 40 253 253 253 122 + 253 253 253 253 253 253 253 123 92 253 253 15 253 253 253 + 253 253 253 62 94 59 253 85 78 253 253 253 85 253 253 253 + 253 44 253 29 51 80 253 76 59 253 253 253 253 253 110 121 + 253 253 253 111 88 253 86 253 253 253 53 7 76 253 23 253 35 + 72 253 37 121 34 253 50 125 253 8 97 253 95 43 61 95 253 + 253 0 59 22 124 80 253 35 253 82 80 253 51 75 253 253 253 + 253 253 25 31 253 17 253 17 253 111 253 253 253 253 253 253 + 253 109 103 71 253 59 16 253 73 253 91 253 28 99 253 253 + 253 15 58 89 110 253 4 253 253 39 113 32 253 253 93 114 253 + 253 0 82 43 253 253 253 22 253 107 2 253 253 253 253 253 + 253 64 7 253 253 253 35 253 253 103 18 253 111 253 253 126 + 54 253 253 47 253 253 253 253 12 253 253 34 253 75 253 253 + 86 62 11 7 25 253 43 253 58 253 253 44 253 120 36 73 6 253 + 253 99 253 4 19 253 42 253 253 253 253 98 253 253 126 51 78 + 18 73 30 114 253 87 3 253 40 253 253 83 253 78 253 44 103 + 52 253 78 253 253 54 253 253 122 127 47 253 253 119 125 31 + 117 14 253 39 253 60 72 6 74 253 253 253 106 253 9 109 91 + 44 253 253 28 110 20 253 253 253 253 59 253 30 253 253 6 21 + 253 9 253 123 253 117 19 21 253 101 35 253 68 58 114 253 52 + 41 253 253 253 64 253 253 58 253 120 108 253 253 77 35 253 + 22 8 253 253 98 253 16 253 21 112 8 253 15 63 253 253 6 112 + 125 43 253 35 110 253 0 253 0 253 87 23 65 24 66 253 121 + 253 253 109 253 253 21 253 15 42 121 253 28 253 253 59 253 + 253 24 79 253 253 84 253 253 253 253 253 79 253 253 253 253 + 253 253 253 17 253 115 69 105 35 49 45 99 12 253 253 253 + 253 15 253 101 253 253 253 253 0 253 253 101 24 10 253 74 + 11 81 253 77 253 253 0 253 253 253 253 253 66 253 253 253 + 253 253 103 105 253 253 42 253 57 253 117 57 39 253 107 103 + 110 253 253 253 10 63 253 253 126 253 253 98 253 253 20 10 + 253 67 56 253 65 253 16 253 15 122 57 253 253 253 253 115 + 64 88 253 124 49 253 27 28 101 92 253 114 41 253 253 27 43 + 253 253 38 61 66 76 115 253 127 74 253 91 253 102 253 87 + 253 88 253 253 253 253 111 253 6 253 126 253 253 253 253 + 253 253 24 253 2 50 57 62 253 253 253 253 120 253 106 253 + 253 253 59 253 94 38 253 22 253 116 100 87 253 253 80 70 49 + 253 253 58 43 73 68 253 253 253 52 253 253 253 23 35 56 253 + 58 34 72 253 253 58 47 54 253 253 253 24 253 253 253 79 253 + 31 77 16 253 253 253 67 25 6 253 42 13 253 253 253 253 123 + 253 253 253 13 253 26 253 253 253 57 253 0 26 95 253 86 253 + 14 38 0 253 17 253 125 42 75 20 6 20 41 26 253 253 40 253 + 253 253 253 253 24 60 253 78 89 87 253 253 253 253 253 253 + 253 253 253 22 253 60 253 253 253 74 1 34 253 253 253 253 + 253 253 253 253 79 253 47 72 111 89 117 61 99 84 253 253 + 253 103 33 253 253 253 10 253 0 42 253 253 253 253 253 253 + 253 253 50 253 253 77 44 253 253 54 8 65 253 36 253 40 253 + 253 253 253 95 253 253 253 73 17 253 91 253 253 253 253 253 + 253 253 253 253 253 6 253 55 37 118 253 124 253 253 253 253 + 253 253 253 118 253 253 80 74 54 253 1 90 97 253 253 253 + 253 3 81 253 253 253 91 125 63 77 88 108 253 70 21 97 253 + 253 43 253 53 45 120 119 253 253 253 253 253 253 124 24 253 + 10 1 96 59 253 253 116 253 76 253 104 253 253 253 253 4 101 + 253 253 253 94 91 253 253 253 253 11 26 91 253 47 253 253 + 26 52 117 23 55 18 44 253 253 32 253 253 126 253 97 105 253 + 20 118 253 253 120 107 253 2 121 52 253 18 107 253 253 117 + 35 253 17 70 253 66 107 125 253 253 253 253 59 119 1 253 + 253 253 253 106 118 51 105 253 99 27 253 253 20 253 253 85 + 51 253 90 253 253 253 27 36 55 253 253 253 253 253 3 253 57 + 253 253 253 253 253 253 32 253 101 44 253 99 53 59 41 253 + 253 20 253 253 41 119 253 56 253 253 31 105 121 29 253 42 + 253 253 3 253 253 42 253 107 120 2 16 253 100 253 253 253 + 253 253 253 13 20 253 253 253 253 50 86 9 53 123 50 253 11 + 11 107 253 41 253 60 99 35 4 253 0 125 85 253 71 253 82 253 + 87 15 123 4 253 253 49 253 32 28 15 92 253 86 253 120 253 + 40 4 33 253 12 253 54 253 253 253 253 37 253 253 75 253 253 + 70 253 253 38 80 59 12 253 253 19 253 75 253 77 117 119 76 + 253 117 23 78 253 47 253 99 253 253 121 253 253 54 253 3 + 253 253 253 253 253 29 51 253 253 253 122 253 95 27 104 110 + 253 253 76 253 253 83 253 117 43 87 61 253 76 54 253 118 + 253 89 253 81 68 91 43 253 95 113 253 124 253 116 253 59 + 253 54 23 81 253 110 253 253 253 64 54 122 253 39 253 104 + 114 98 73 253 91 253 125 35 253 105 98 107 75 29 66 7 253 + 253 60 253 57 0 59 121 253 39 253 253 253 253 56 45 253 253 + 253 253 36 253 253 44 253 253 253 253 253 253 253 253 106 + 253 111 43 77 19 68 121 253 253 253 253 253 253 79 253 253 + 93 253 253 253 253 253 253 106 253 64 48 87 253 30 253 253 + 40 253 253 253 5 253 77 253 36 102 48 253 7 36 253 253 253 + 253 253 27 70 253 253 41 253 253 253 253 105 253 253 10 22 + 12 253 109 253 253 253 126 253 90 253 119 110 253 6 253 253 + 253 253 253 72 45 253 253 69 253 75 253 125 121 61 253 100 + 5 30 253 253 115 253 253 253 253 253 68 253 253 32 25 253 + 83 253 98 7 34 253 253 88 253 253 79 253 23 253 253 253 253 + 10 253 253 0 253 41 80 99 115 120 253 253 3 253 67 6 253 28 + 253 253 117 84 253 79 253 121 253 253 253 123 26 253 3 253 + 253 81 14 253 253 253 253 253 253 253 253 253 82 253 50 23 + 253 76 253 253 79 253 31 83 253 62 113 253 253 69 69 10 17 + 253 56 253 66 70 253 20 253 115 68 71 56 0 125 120 253 253 + 253 253 253 49 253 253 86 74 25 125 43 253 28 14 56 253 101 + 253 253 84 48 253 89 82 253 46 54 253 253 109 253 253 49 + 125 253 29 96 253 253 121 253 253 253 253 253 71 21 253 53 + 253 253 253 253 29 253 109 70 54 253 253 120 253 253 54 253 + 253 0 45 18 119 46 57 253 253 117 94 116 59 253 253 253 253 + 0 253 107 24 253 89 51 27 24 6 15 253 253 253 253 13 253 + 100 103 53 253 253 15 253 253 253 253 253 253 253 253 253 + 253 110 253 253 99 253 109 59 253 127 253 22 85 73 60 253 + 90 110 68 32 253 122 34 114 253 253 253 253 253 253 117 29 + 89 39 253 16 253 253 54 253 253 6 253 54 101 29 253 54 9 + 253 107 111 65 52 119 55 253 253 14 253 253 253 123 253 120 + 253 111 253 253 253 1 253 76 253 33 253 253 113 71 253 41 + 88 253 0 104 253 36 253 253 253 100 253 253 253 79 84 58 + 126 71 78 253 253 67 253 91 71 31 38 76 42 17 253 86 253 71 + 253 253 40 253 253 253 104 3 30 253 85 116 253 107 47 253 + 253 253 26 121 253 106 253 253 253 68 253 253 253 253 103 + 118 253 253 253 253 253 253 253 52 74 253 101 92 7 94 113 + 81 253 253 253 253 65 45 253 115 0 66 253 253 253 13 253 85 + 253 253 48 60 253 253 253 92 118 253 253 253 253 253 118 96 + 253 253 63 253 253 125 0 253 253 253 107 253 26 41 253 253 + 105 32 81 253 100 67 37 253 104 253 62 253 253 44 37 253 + 253 253 127 253 93 253 253 253 253 34 85 253 107 253 253 + 253 9 27 121 253 56 253 107 55 45 34 253 114 253 253 47 4 + 253 9 253 10 253 253 79 89 253 97 27 94 77 34 253 47 253 51 + 30 13 9 253 253 253 253 253 24 80 18 253 253 253 61 69 71 + 253 253 253 88 253 88 85 21 45 253 60 5 39 253 51 80 253 + 253 65 253 73 37 253 54 253 70 253 4 14 70 59 81 76 106 253 + 253 23 55 253 91 253 127 253 105 253 48 253 48 253 253 3 + 253 0 253 253 58 253 253 6 253 253 253 253 69 253 123 253 + 84 253 253 253 253 11 85 101 253 47 253 53 30 253 253 253 + 40 100 123 125 56 54 253 253 253 111 46 51 253 253 106 53 + 253 253 253 253 253 253 15 253 70 43 253 7 253 100 15 253 + 93 115 122 253 253 111 115 4 1 253 253 98 253 3 253 91 253 + 253 253 253 253 44 117 253 23 112 253 17 66 253 253 253 9 + 253 58 253 253 253 53 93 29 113 253 5 35 43 253 0 253 81 + 127 253 253 68 15 253 0 253 47 253 86 253 118 253 253 76 23 + 253 28 113 253 253 253 124 105 253 91 59 253 253 87 253 253 + 253 253 99 253 35 253 62 253 116 253 76 126 31 253 253 44 + 57 253 253 119 85 253 118 253 253 74 40 12 79 4 253 20 90 + 111 253 27 253 46 253 253 253 253 19 253 253 109 253 253 + 253 253 253 61 253 253 253 79 253 126 253 34 253 21 253 41 + 26 253 253 253 253 8 253 253 253 29 253 253 253 100 253 41 + 36 253 88 253 253 120 253 253 253 253 123 253 253 253 253 + 253 253 253 253 19 76 253 36 253 253 253 253 253 9 253 253 + 253 253 118 253 73 253 93 58 63 80 253 253 35 105 23 253 + 108 253 46 6 253 253 253 253 253 253 253 89 253 65 27 74 + 253 38 253 15 253 253 253 253 253 122 253 253 253 253 55 80 + 253 253 20 253 18 47 253 253 253 253 117 111 253 67 253 253 + 18 5 253 78 3 10 91 12 83 110 253 253 85 253 253 110 90 253 + 68 253 6 95 253 42 60 253 253 79 253 72 253 125 111 38 253 + 53 253 253 253 118 124 253 253 253 26 253 115 253 253 253 0 + 88 253 88 253 85 253 253 68 116 253 253 34 119 253 253 69 + 109 253 113 253 253 108 253 75 31 72 253 120 253 48 25 4 + 253 12 253 43 116 253 253 253 15 13 99 98 8 253 253 105 253 + 91 96 253 253 43 97 253 30 253 253 106 253 253 253 98 253 + 253 253 253 253 253 91 36 253 58 43 253 253 253 72 46 32 + 253 67 253 13 253 253 85 31 25 253 253 253 253 85 253 253 + 21 253 253 253 253 30 61 69 91 253 94 127 21 104 95 4 253 + 121 126 253 89 253 117 253 87 90 116 126 59 253 27 105 92 + 253 64 21 37 26 118 91 253 253 253 253 62 253 253 53 16 253 + 103 28 110 78 73 253 253 47 253 0 253 253 55 253 253 37 253 + 70 61 57 253 29 89 253 92 104 253 253 253 253 253 34 124 + 253 122 99 253 253 253 253 253 74 253 114 64 253 86 82 100 + 253 253 67 34 108 46 115 69 71 38 253 253 41 100 47 253 122 + 54 253 253 253 253 253 253 45 58 24 253 253 253 62 253 253 + 253 103 253 253 68 253 253 94 253 96 20 14 106 253 34 97 0 + 253 121 25 29 253 124 253 37 111 8 253 59 26 253 253 6 77 + 253 253 123 253 122 253 70 253 253 121 253 253 253 253 253 + 21 253 84 35 253 77 253 253 17 57 63 109 253 65 27 87 60 80 + 253 253 253 0 253 111 127 253 253 253 24 253 253 38 21 253 + 253 253 253 253 253 253 127 253 110 4 9 121 25 253 108 37 + 85 253 253 95 85 253 110 253 253 253 253 253 36 7 253 26 + 253 41 30 253 253 25 253 78 71 253 109 253 64 16 253 95 65 + 253 88 90 16 109 253 253 28 86 253 253 119 253 60 253 253 + 107 124 73 253 121 16 253 253 95 26 80 23 253 253 253 253 + 253 9 253 121 253 253 253 253 51 57 39 253 253 253 253 253 + 253 105 82 253 253 253 253 253 11 253 110 53 253 253 23 253 + 253 253 122 44 81 253 48 253 253 0 61 49 74 24 253 14 122 + 66 253 253 94 48 253 253 80 63 253 253 88 90 72 96 253 54 + 56 253 105 7 78 88 253 31 52 253 253 94 88 253 253 79 253 + 74 32 253 75 123 116 253 68 253 118 110 253 253 253 46 253 + 253 58 65 18 253 74 253 253 112 59 84 115 253 46 253 253 + 253 95 121 44 62 81 253 253 253 253 253 119 81 253 108 253 + 253 42 25 253 90 253 253 253 102 93 253 253 119 96 41 253 + 42 253 253 29 253 107 71 253 87 35 253 99 253 106 35 253 90 + 253 78 5 253 253 22 99 253 41 253 253 253 44 26 83 52 101 + 76 44 48 54 118 53 26 253 109 253 253 253 33 253 253 12 12 + 253 25 253 253 47 12 111 76 253 124 53 253 253 16 45 253 + 253 110 64 114 115 253 84 253 253 253 101 78 253 123 102 + 253 26 56 253 253 102 253 123 67 253 75 123 51 101 8 13 253 + 12 127 253 253 92 107 253 253 27 253 126 253 253 98 253 253 + 253 124 253 253 105 253 28 253 253 68 253 52 253 12 48 44 + 118 253 253 253 253 253 37 15 253 62 253 253 53 63 1 253 60 + 39 253 253 84 253 253 46 253 253 253 109 62 253 253 51 92 + 54 12 253 7 253 253 253 87 82 89 54 253 36 87 22 253 253 62 + 94 59 85 34 253 253 253 110 253 97 124 56 253 45 253 8 28 + 253 12 253 253 253 86 5 253 253 253 75 113 12 108 253 77 + 253 110 56 253 35 253 13 253 91 253 38 53 253 253 111 253 + 253 123 253 253 84 91 253 104 17 253 65 24 17 253 15 253 + 116 66 105 253 113 67 109 70 91 88 253 253 118 0 253 5 72 + 81 253 253 78 253 253 56 127 27 45 253 253 253 55 253 49 + 253 253 110 253 253 29 58 101 253 42 5 253 253 66 12 122 + 123 253 62 253 253 253 253 253 0 253 116 60 92 49 253 253 + 253 253 253 55 72 253 80 93 253 253 50 8 253 253 253 253 + 253 110 5 49 253 253 0 253 253 97 24 23 253 28 40 253 253 + 127 253 107 253 253 73 119 50 253 253 253 253 253 114 121 + 253 125 93 62 253 113 253 25 253 29 253 253 65 253 253 253 + 253 12 253 114 253 253 73 69 253 253 95 8 26 253 253 253 54 + 104 253 253 35 68 72 81 253 21 27 253 77 54 125 23 88 18 + 253 253 253 253 69 51 253 0 37 253 27 253 253 253 253 74 + 253 253 66 253 95 114 123 253 253 253 94 253 253 253 253 + 253 42 36 98 114 19 253 126 253 25 253 40 253 50 46 64 61 + 45 117 107 253 89 51 69 38 14 57 7 253 109 253 111 253 253 + 10 13 253 46 60 253 253 25 253 15 76 253 92 88 253 70 5 5 + 73 60 113 253 82 253 253 51 126 253 112 34 19 99 253 253 + 119 30 253 253 0 253 104 116 52 253 79 69 253 109 119 253 + 17 22 66 87 119 13 253 253 35 83 11 253 253 253 253 253 106 + 45 253 253 120 253 36 253 25 253 253 81 75 253 40 88 253 + 253 253 74 253 115 53 253 70 253 253 253 253 117 253 64 253 + 253 53 93 253 253 253 52 253 23 253 62 14 0 95 253 253 90 + 253 253 56 253 49 253 253 253 75 118 6 253 253 253 48 253 + 253 253 105 24 253 48 71 253 253 36 55 39 253 253 127 20 33 + 253 253 253 101 79 6 102 89 24 46 253 62 82 113 253 84 6 88 + 22 44 52 44 253 253 94 253 253 253 253 58 47 253 104 38 253 + 101 253 71 253 81 253 6 83 253 253 83 54 30 42 72 253 253 + 253 3 253 48 253 110 126 253 64 253 104 253 253 253 253 253 + 253 253 64 57 110 107 102 253 110 253 9 253 65 30 253 253 + 253 104 253 35 253 253 42 253 253 253 100 253 46 99 63 253 + 95 39 253 99 253 115 72 34 253 253 253 99 253 253 253 253 + 67 253 106 87 20 253 253 253 253 253 253 30 253 253 253 253 + 253 253 253 253 253 125 253 2 84 253 253 253 100 5 253 253 + 0 53 40 7 253 253 44 80 90 253 253 253 122 114 127 253 61 + 109 253 253 46 87 253 253 26 253 101 109 34 253 253 253 112 + 126 253 253 70 253 253 52 253 111 253 91 253 28 253 253 253 + 118 114 121 253 253 116 253 253 24 71 111 253 253 253 253 + 253 253 5 98 253 253 89 253 253 115 253 253 66 253 99 5 253 + 253 63 253 62 106 105 99 25 48 42 253 253 39 253 104 253 + 253 29 253 253 1 21 83 112 253 253 111 253 253 37 48 14 253 + 253 253 109 107 253 253 253 50 46 253 253 99 253 13 116 78 + 253 56 253 253 20 253 81 253 80 13 253 253 253 85 253 253 + 94 253 59 253 253 99 12 253 253 253 21 108 90 253 253 36 79 + 10 30 0 253 88 253 253 253 253 23 253 253 253 96 253 253 + 126 253 253 253 12 253 34 253 253 253 63 253 35 253 253 88 + 80 35 67 253 79 253 15 253 253 41 253 55 50 71 3 253 253 + 253 63 59 253 253 253 86 20 253 253 9 49 253 253 75 253 7 + 14 59 26 253 122 253 101 253 253 253 253 70 253 79 57 253 + 19 90 253 253 253 253 253 253 253 60 253 85 91 253 91 79 + 121 123 35 126 42 20 85 57 253 253 253 253 39 253 52 59 21 + 95 71 52 120 85 253 253 19 24 253 61 253 253 38 253 109 62 + 56 84 95 120 253 52 253 12 70 23 253 253 253 8 45 33 102 62 + 35 69 113 253 253 43 28 253 253 253 28 253 53 1 12 253 109 + 253 56 69 30 253 90 89 71 253 87 58 90 44 253 253 253 108 + 45 112 24 253 64 59 253 35 39 253 253 63 253 253 253 253 + 110 35 77 90 16 253 253 71 31 253 253 118 63 253 253 0 95 + 253 253 59 76 253 101 45 113 253 67 10 253 253 34 253 253 + 57 253 253 95 116 253 253 253 109 253 19 66 253 32 253 253 + 14 8 253 253 93 81 253 66 253 253 109 253 253 253 253 38 + 253 125 253 92 253 253 82 120 115 253 3 253 253 253 253 81 + 253 253 253 253 114 253 76 253 253 52 253 64 253 253 57 63 + 83 79 253 108 253 58 51 253 102 253 72 93 32 119 36 100 119 + 25 253 72 253 109 109 253 43 253 253 253 253 119 83 253 253 + 81 83 253 116 253 253 43 253 253 253 253 253 53 87 253 109 + 253 20 253 8 29 253 253 253 0 253 117 88 99 253 18 253 121 + 75 253 112 15 253 10 115 253 253 104 253 253 109 253 47 253 + 3 24 253 70 253 34 35 253 50 253 74 253 79 253 253 23 76 95 + 253 68 253 87 253 37 253 253 26 53 97 28 253 253 253 253 0 + 102 42 253 253 253 111 253 101 123 253 50 253 19 253 35 253 + 253 84 253 68 104 4 253 253 98 112 6 125 253 84 82 27 253 + 253 253 253 97 253 253 56 253 253 77 253 113 118 65 83 78 + 253 58 253 253 36 253 253 253 253 121 253 253 253 253 253 + 253 253 253 253 80 253 253 253 253 97 8 253 48 253 253 106 + 253 253 117 11 77 19 76 125 54 253 30 57 82 9 28 3 79 253 0 + 253 253 253 253 253 253 51 253 253 70 35 253 27 10 253 14 + 59 253 253 70 9 253 253 101 20 253 116 253 253 61 10 253 71 + 253 107 107 59 21 100 11 15 253 61 253 253 253 253 71 12 97 + 253 253 253 1 253 253 253 83 13 26 253 43 88 253 75 108 35 + 253 110 253 57 253 253 253 38 253 253 253 253 253 101 253 + 48 253 253 253 253 253 253 98 56 253 253 253 253 75 3 103 + 126 253 13 253 69 253 253 73 253 253 253 67 20 99 253 253 + 253 102 253 13 27 253 253 28 253 18 77 53 253 93 253 253 79 + 106 16 88 52 253 253 111 32 12 253 253 253 253 0 106 253 + 253 59 253 253 97 116 84 108 85 3 72 36 56 253 34 253 80 70 + 253 253 253 81 253 253 24 61 253 253 253 253 253 253 253 + 253 101 45 253 253 253 253 88 253 95 93 44 106 253 81 253 + 31 50 253 253 253 253 253 105 253 108 253 253 31 16 253 253 + 51 27 253 253 253 74 253 94 253 25 253 253 253 22 94 114 87 + 52 253 253 105 35 117 104 83 45 253 27 253 253 119 253 253 + 19 253 62 25 85 110 253 253 52 76 85 253 0 17 253 253 253 + 253 37 253 253 46 20 21 7 110 253 125 253 253 253 79 253 60 + 253 39 32 253 79 253 107 253 122 253 68 253 75 86 253 25 92 + 100 253 59 26 253 253 253 253 38 253 88 253 253 253 119 28 + 30 107 24 253 253 14 253 44 253 253 79 253 253 99 75 110 45 + 85 253 253 83 62 253 253 253 253 108 253 18 253 125 253 34 + 253 110 253 92 253 86 17 253 71 37 253 0 253 253 253 253 + 253 82 48 253 253 124 253 253 37 253 253 92 253 253 253 105 + 253 253 253 19 33 253 127 109 63 253 253 253 253 253 253 + 253 253 253 253 253 85 10 78 40 253 15 8 59 113 253 120 253 + 96 253 253 50 29 253 26 253 253 68 19 72 253 62 253 11 253 + 253 253 253 15 253 253 253 21 253 84 253 0 50 253 55 24 107 + 119 24 253 97 14 253 36 102 253 32 253 253 253 116 253 253 + 253 87 83 253 253 253 81 107 253 253 53 253 18 7 35 253 253 + 253 44 253 37 105 17 119 28 253 253 82 28 253 253 82 253 18 + 49 253 69 79 253 253 75 121 32 92 253 73 28 253 253 68 69 + 253 65 253 106 253 253 253 36 49 253 38 61 87 253 253 253 + 253 253 94 68 253 95 253 66 253 253 253 253 253 253 97 253 + 72 253 106 109 6 103 93 253 253 253 253 253 58 110 253 253 + 2 36 4 1 253 253 253 253 15 253 44 108 253 253 124 25 253 + 127 253 253 71 253 82 107 123 49 34 253 113 253 253 71 253 + 253 65 253 88 87 42 6 22 110 1 253 253 253 92 121 84 253 + 253 253 5 253 253 253 88 253 84 19 253 93 253 65 111 103 + 253 84 253 104 253 253 65 253 253 82 253 42 66 253 41 31 + 253 253 17 253 253 44 28 253 92 253 109 253 253 113 110 253 + 74 253 253 30 253 84 253 253 127 253 253 253 253 3 253 4 + 253 253 253 253 108 253 253 14 114 49 253 95 253 253 127 + 253 72 253 253 53 41 87 12 253 253 253 39 253 83 253 253 + 253 253 253 253 26 253 253 253 11 253 253 16 82 114 78 78 + 106 95 253 253 17 253 253 69 253 253 253 31 253 84 253 106 + 253 253 253 27 98 253 253 102 10 87 29 253 106 99 253 253 + 50 71 253 253 253 253 253 73 253 253 31 90 253 253 100 73 + 45 23 31 79 253 253 253 104 84 253 253 253 120 253 253 71 + 253 83 253 66 55 75 114 253 253 253 43 253 0 25 253 21 16 + 253 253 18 107 104 253 110 11 55 0 15 253 123 84 253 253 + 120 253 253 253 253 253 253 253 8 25 253 118 65 253 60 253 + 253 119 253 253 253 49 253 36 253 253 253 92 253 253 253 + 253 44 85 253 253 253 94 42 253 253 253 90 253 105 253 56 + 253 253 253 253 253 253 253 117 253 253 9 253 123 253 253 + 105 34 104 253 253 253 253 253 127 253 84 31 89 91 253 253 + 253 99 253 30 82 55 40 29 253 253 253 253 23 253 41 112 253 + 253 253 253 103 253 102 123 253 95 57 253 33 24 3 253 42 61 + 253 120 51 36 69 109 119 3 47 253 61 78 15 21 33 253 253 + 253 253 253 9 70 84 15 54 125 253 116 253 253 24 93 253 253 + 253 6 6 59 26 253 17 253 72 253 253 253 98 108 27 117 4 253 + 253 92 253 111 253 65 253 64 98 75 43 87 17 253 253 44 56 + 253 253 253 3 107 110 99 99 52 253 50 253 56 99 253 253 123 + 253 253 77 38 253 37 101 253 31 253 253 70 43 253 110 82 10 + 253 253 253 253 53 253 71 253 87 253 28 253 88 121 125 43 + 253 253 26 253 50 253 22 253 111 253 16 253 42 253 253 253 + 9 253 253 253 253 126 10 253 13 109 253 115 253 31 253 253 + 42 253 253 253 253 11 77 253 25 36 73 90 110 253 15 57 253 + 253 253 25 253 84 55 253 253 97 21 253 74 253 253 15 54 253 + 121 53 5 253 9 86 253 105 118 253 253 119 253 33 253 84 253 + 253 21 253 253 253 253 35 253 253 0 49 253 56 253 253 253 + 110 253 253 253 253 253 253 253 253 90 253 99 253 9 14 253 + 90 57 49 253 253 111 253 87 253 253 79 4 253 52 253 43 253 + 253 253 253 124 12 253 122 253 253 6 253 253 110 1 253 103 + 63 253 253 81 253 94 253 253 25 253 40 87 70 253 127 81 253 + 253 103 45 29 253 28 253 48 253 15 253 27 253 253 18 27 119 + 253 2 63 76 85 253 253 89 253 73 26 42 253 253 28 253 85 + 253 253 29 42 75 253 253 253 253 24 253 253 253 0 15 30 253 + 113 253 253 55 16 253 253 253 253 60 253 123 85 99 253 114 + 253 253 253 1 29 253 9 253 253 87 9 253 253 253 253 253 54 + 73 253 76 253 253 253 121 119 112 64 253 42 68 34 23 10 4 + 109 253 253 76 253 253 54 110 253 87 253 43 32 253 253 7 + 253 253 62 104 253 107 26 118 99 253 253 253 253 14 121 253 + 86 125 99 253 253 253 5 105 110 23 96 62 102 65 87 101 253 + 253 101 30 59 253 121 253 253 51 70 50 13 67 253 253 46 253 + 253 253 253 253 53 253 253 74 7 6 253 253 253 68 117 253 48 + 8 253 72 253 50 38 253 33 116 108 253 253 19 253 253 62 59 + 253 113 87 71 94 253 47 38 253 253 253 253 43 97 86 253 253 + 253 253 34 253 253 48 85 253 253 253 43 2 74 253 253 253 + 103 253 253 101 39 253 25 53 253 253 253 253 253 253 115 85 + 64 52 253 22 80 253 24 56 253 253 78 253 8 0 119 253 23 253 + 253 27 113 253 75 253 10 253 253 2 253 105 253 253 24 105 + 58 110 10 253 74 18 253 0 63 253 110 253 253 253 253 253 + 253 253 99 11 253 72 253 117 31 253 85 253 61 253 78 15 253 + 253 253 253 253 90 253 116 253 76 50 253 253 253 253 21 253 + 8 253 109 253 18 57 24 253 253 124 253 253 109 253 253 253 + 22 253 20 253 253 253 118 253 253 29 253 253 35 253 62 253 + 253 63 253 253 85 109 253 253 253 253 125 253 253 253 87 + 253 98 253 117 42 253 113 253 90 253 253 253 253 77 253 110 + 253 109 253 14 253 253 95 13 253 45 253 81 90 100 44 23 253 + 253 253 127 253 253 253 91 253 68 45 106 253 253 253 24 253 + 253 253 253 253 253 253 93 253 253 253 253 253 253 122 65 + 253 25 253 95 253 253 16 51 253 79 27 105 253 253 253 253 + 121 253 39 60 39 253 105 253 253 13 253 8 84 102 112 4 112 + 253 253 253 52 108 80 71 23 253 253 253 253 253 253 253 32 + 81 253 82 62 253 253 253 80 253 114 126 253 253 253 38 253 + 59 17 121 1 113 253 118 253 253 253 253 107 253 253 36 105 + 253 253 253 253 94 57 82 119 47 253 253 253 253 253 253 6 + 72 31 253 35 253 253 106 253 253 253 5 253 124 86 101 12 + 253 253 253 24 57 253 253 20 253 96 253 62 69 19 13 253 253 + 253 71 253 120 253 102 52 253 253 105 253 253 61 253 253 + 253 253 18 253 50 12 125 90 253 253 19 103 253 120 18 253 + 96 253 0 125 104 103 253 253 101 253 106 253 27 79 111 74 + 253 105 253 119 57 114 90 45 126 253 253 86 253 102 55 40 8 + 253 253 78 253 31 60 86 95 253 107 253 253 253 111 47 36 + 253 253 253 27 253 253 253 253 41 253 253 81 253 112 123 + 253 253 253 253 253 253 253 253 253 253 253 253 56 99 253 + 43 253 30 95 253 253 253 253 253 67 62 253 253 0 22 88 89 + 78 253 89 253 24 85 62 253 68 253 253 20 253 253 120 253 15 + 39 253 253 253 253 253 253 21 100 253 93 81 253 253 253 253 + 121 253 253 27 253 9 24 97 75 253 109 253 123 253 253 118 + 253 72 253 21 59 6 6 11 55 106 253 82 253 57 41 69 21 69 + 253 107 60 253 93 253 253 253 253 75 55 4 26 2 253 55 93 + 253 253 253 91 253 253 253 120 75 253 253 29 253 253 75 118 + 30 253 100 81 28 253 253 253 70 72 253 253 253 0 76 253 124 + 23 81 107 2 253 70 253 7 253 253 253 253 253 253 253 73 100 + 253 253 253 253 35 12 21 253 253 9 253 51 253 105 253 253 + 53 253 47 106 253 55 253 81 38 253 29 253 253 92 253 253 + 253 253 93 2 253 253 253 55 27 253 253 97 253 253 15 253 0 + 253 15 107 253 253 127 107 93 71 0 253 253 253 97 253 253 + 253 113 30 18 114 86 36 253 253 253 253 253 253 253 20 15 + 253 253 27 253 253 253 95 61 33 125 253 253 99 253 94 2 253 + 115 73 32 253 253 253 84 253 253 253 253 253 253 253 253 + 253 253 253 4 253 0 253 253 82 24 253 253 56 253 36 253 253 + 113 253 253 37 253 31 253 36 253 253 26 253 253 53 253 253 + 37 253 47 13 253 65 72 33 253 61 253 253 253 89 253 253 76 + 97 253 43 49 253 10 253 127 253 253 61 253 48 253 93 253 + 124 253 17 253 253 253 253 253 253 253 4 253 253 41 253 39 + 253 253 87 62 73 253 253 98 253 253 77 70 253 105 110 253 + 253 253 50 89 41 253 0 253 31 106 9 108 115 118 253 36 98 + 88 253 253 95 253 13 31 102 253 253 253 253 35 60 253 253 + 253 83 253 253 253 253 253 253 253 253 108 253 253 0 253 + 253 53 72 253 121 20 116 253 19 253 253 253 253 12 107 17 + 119 253 253 253 253 253 0 10 253 253 253 253 253 40 253 253 + 253 81 253 253 253 253 253 253 253 18 40 253 82 0 5 253 253 + 253 22 253 118 253 113 253 59 26 253 253 93 108 253 253 92 + 253 253 53 253 127 253 253 78 87 253 30 253 253 253 253 25 + 253 48 24 118 49 253 113 76 253 89 99 56 253 67 253 20 120 + 253 253 125 13 55 16 8 111 253 76 253 253 37 39 25 253 14 + 253 1 253 117 1 253 101 253 74 96 55 253 88 23 253 19 70 + 253 253 253 253 253 62 253 21 253 72 253 54 253 70 253 84 + 253 253 253 63 253 253 18 253 119 253 253 253 107 253 253 + 101 112 48 74 253 253 253 253 55 253 21 253 101 109 253 118 + 253 49 87 253 253 11 59 89 253 253 253 253 253 86 11 253 86 + 253 253 7 253 41 253 253 253 13 253 119 119 20 253 31 26 4 + 253 53 253 253 114 56 253 35 253 253 99 16 93 253 253 253 + 10 253 253 253 51 11 253 253 253 253 253 253 253 253 253 + 253 97 117 253 31 253 45 253 253 253 87 253 253 82 14 253 + 253 253 65 253 103 253 40 13 74 48 116 253 253 28 253 0 70 + 122 48 73 253 67 52 22 253 253 88 93 253 60 253 56 20 89 + 253 253 253 33 253 253 253 253 253 253 25 98 253 253 55 122 + 253 90 253 99 38 253 253 63 253 253 253 253 10 48 53 33 253 + 253 36 17 76 55 59 253 28 253 86 253 253 253 82 71 253 85 + 253 86 253 253 253 253 253 253 253 73 66 253 253 28 253 253 + 253 57 253 253 253 83 71 253 72 253 97 253 39 106 253 58 + 253 67 121 30 253 68 253 253 34 103 253 57 60 49 253 84 253 + 253 253 59 114 253 42 253 28 253 2 7 97 80 110 253 253 5 + 253 253 18 27 253 57 60 113 253 126 253 55 253 253 253 66 + 38 253 253 253 253 120 57 63 253 89 253 253 57 253 253 35 + 72 23 119 0 253 253 253 35 81 253 253 253 13 8 118 33 253 + 253 253 253 101 253 32 253 253 6 62 50 253 119 99 253 253 + 74 122 253 253 110 253 253 253 11 253 29 253 253 72 253 114 + 71 21 253 48 253 10 253 253 83 253 253 65 253 45 20 253 88 + 253 52 253 91 27 253 104 80 253 18 119 122 253 253 253 11 + 253 123 253 110 31 78 253 93 253 67 253 123 87 79 107 253 + 53 253 253 253 43 75 17 253 253 253 125 253 253 253 253 253 + 73 114 100 84 96 253 253 13 253 126 253 25 70 253 253 253 + 253 253 35 253 116 253 253 253 16 52 253 42 253 253 253 253 + 253 253 253 54 253 253 105 90 253 253 61 253 253 11 28 253 + 83 253 253 253 83 253 253 253 253 253 253 253 100 253 253 + 253 67 96 114 61 253 253 253 52 253 117 253 17 90 56 253 + 253 12 253 35 56 21 60 77 73 253 83 253 253 253 72 253 253 + 45 112 253 253 26 86 59 20 253 4 253 22 253 52 253 98 253 + 253 253 253 253 62 57 253 18 54 253 253 3 253 253 83 78 253 + 253 112 99 253 253 253 45 13 253 32 253 116 125 253 253 121 + 253 104 253 253 101 253 253 0 253 253 253 5 116 62 253 120 + 253 82 123 39 58 253 88 253 117 253 253 253 253 75 124 86 + 253 24 253 253 70 253 253 7 253 53 60 253 253 43 117 253 + 253 75 253 253 253 253 18 89 253 253 44 253 253 253 253 21 + 253 10 123 253 51 253 253 115 253 107 253 36 253 253 253 + 253 253 253 253 253 82 109 7 253 31 89 104 253 71 109 109 + 253 94 4 253 253 253 253 50 8 253 54 253 253 17 253 253 253 + 88 87 253 253 31 253 253 253 126 253 253 43 13 48 94 88 61 + 253 70 63 26 253 88 253 33 125 253 253 51 253 253 106 29 + 253 253 103 253 58 253 253 253 253 253 253 83 35 32 88 253 + 253 32 47 114 126 253 19 253 253 253 253 117 253 33 253 81 + 253 253 253 253 253 12 80 120 253 110 253 253 253 71 253 + 253 66 44 55 19 90 71 253 75 253 253 25 253 115 90 253 73 + 46 253 253 253 53 67 253 78 253 95 20 253 77 253 50 121 253 + 104 253 253 75 253 253 34 253 253 253 253 3 16 253 3 253 47 + 67 253 253 253 64 253 253 253 71 35 253 253 14 253 253 106 + 253 62 27 253 16 253 253 61 253 105 48 253 18 253 96 22 95 + 253 253 253 253 4 253 253 253 7 253 29 47 125 30 253 53 253 + 253 253 253 253 253 253 30 64 253 253 253 253 103 28 123 + 100 253 253 253 120 84 110 253 253 83 126 253 253 253 253 + 253 37 253 253 116 44 56 85 36 55 24 253 253 253 253 83 123 + 118 94 66 67 19 253 106 253 116 253 253 73 18 94 253 253 + 253 83 95 253 76 253 76 46 112 253 31 253 87 31 73 116 253 + 253 253 49 253 253 14 1 253 253 111 253 23 11 20 34 8 35 + 253 253 56 253 3 21 104 90 90 27 93 253 36 126 35 253 253 + 253 79 31 74 253 253 7 86 253 60 253 97 118 253 253 77 253 + 118 253 253 253 91 90 53 253 28 125 253 21 253 60 50 253 + 253 253 253 119 253 253 42 53 58 253 253 51 42 253 253 65 + 253 23 94 12 69 100 253 35 253 123 253 60 253 253 253 20 27 + 253 71 253 253 62 253 90 1 35 253 115 43 40 113 32 253 55 + 124 84 47 253 100 253 49 253 253 253 253 65 253 124 91 253 + 253 85 253 98 253 253 253 103 42 253 121 253 253 253 253 + 253 253 253 253 253 253 253 90 125 253 91 107 253 105 7 253 + 253 253 53 253 68 253 253 47 107 253 95 253 253 49 253 253 + 48 28 73 25 253 253 253 253 87 253 0 253 253 253 51 100 253 + 110 253 87 94 106 67 88 253 55 253 253 253 31 92 113 253 14 + 73 253 85 87 253 82 4 253 253 124 253 253 253 253 253 68 52 + 89 253 73 52 2 253 253 121 253 109 253 50 253 253 253 88 17 + 102 253 253 253 35 253 75 253 27 110 253 76 253 20 96 253 + 253 253 253 85 253 253 14 54 253 253 26 253 253 61 41 102 + 253 41 253 21 253 253 253 39 253 50 253 48 253 253 253 253 + 253 63 5 63 253 253 253 253 17 253 102 122 48 63 253 253 + 253 253 253 43 126 71 253 253 90 253 72 79 253 253 253 253 + 253 36 253 18 45 253 75 17 81 101 253 253 253 253 253 61 77 + 15 111 122 253 87 65 253 118 253 253 30 253 253 253 253 253 + 253 57 253 90 253 253 121 34 110 71 40 7 56 28 253 253 253 + 40 253 47 99 253 126 4 117 253 253 253 253 253 63 253 44 + 253 120 24 253 253 78 253 65 81 253 253 253 118 253 115 28 + 0 107 253 253 28 89 253 253 253 77 54 89 34 32 253 105 56 + 39 253 253 253 253 253 253 253 84 87 102 17 76 253 48 6 9 + 253 253 253 14 60 65 253 51 253 45 102 103 1 100 253 253 + 121 5 78 69 99 253 253 54 253 253 253 253 253 253 253 77 11 + 253 253 39 17 71 112 253 23 28 253 35 253 253 62 253 53 253 + 253 253 253 45 33 253 253 253 0 44 253 98 253 253 19 36 117 + 72 253 253 253 42 72 253 38 120 62 253 112 27 80 5 35 111 + 253 253 118 19 120 253 1 96 253 253 1 253 253 44 253 80 110 + 253 253 253 105 253 64 253 30 253 21 253 25 100 25 82 48 69 + 84 253 0 18 122 82 19 35 253 101 32 253 100 10 253 3 46 56 + 96 104 109 66 253 27 253 253 253 253 253 253 253 40 253 27 + 28 253 253 253 91 253 253 253 91 253 43 63 253 20 71 60 253 + 253 0 74 125 253 93 69 117 98 88 93 253 22 253 92 4 253 253 + 253 91 253 253 76 108 253 72 253 80 51 253 253 106 253 253 + 253 41 68 253 111 29 253 8 253 253 253 253 113 253 124 37 + 103 124 36 253 42 253 44 121 46 108 53 253 253 253 69 253 + 108 253 65 253 253 253 119 253 253 23 253 253 104 37 253 + 253 10 63 253 253 253 253 253 37 253 253 58 253 112 253 253 + 64 253 48 79 253 89 90 93 253 253 253 253 89 253 103 253 + 253 253 123 15 113 253 253 71 43 253 103 52 253 46 52 253 + 27 93 253 99 116 253 253 44 86 253 253 69 253 44 253 253 + 253 84 30 253 64 107 107 253 253 253 56 31 46 7 253 118 253 + 253 253 90 253 253 93 253 54 253 118 57 42 57 253 253 253 + 106 125 33 253 253 120 100 88 86 104 253 96 101 107 253 50 + 253 37 105 28 253 253 253 116 14 253 253 253 253 253 55 51 + 49 253 253 253 253 253 125 55 253 253 54 253 45 253 253 72 + 253 253 70 55 15 122 253 52 46 253 253 253 253 55 253 253 + 20 253 253 99 253 83 253 90 104 253 84 253 97 253 86 49 253 + 36 96 253 53 253 253 253 37 253 253 253 110 253 253 116 79 + 10 253 121 20 253 253 253 4 124 253 107 253 253 253 253 253 + 54 253 105 24 72 253 55 253 253 253 253 53 253 253 253 253 + 109 253 36 253 112 30 68 114 253 253 114 77 87 253 73 121 + 253 91 253 253 87 46 253 121 71 253 253 73 101 116 253 253 + 253 253 51 45 96 106 26 253 253 253 122 253 99 253 45 253 5 + 54 253 30 253 253 253 253 253 253 253 3 20 253 253 253 253 + 253 30 40 253 253 253 253 70 25 253 26 253 253 111 253 99 + 253 253 60 253 70 37 3 253 92 80 79 108 76 253 56 253 25 + 116 63 79 253 253 253 253 253 79 253 125 79 253 74 23 253 + 25 253 28 115 88 253 253 12 33 19 253 119 253 253 58 38 55 + 56 31 90 253 253 253 105 253 99 58 253 46 253 96 253 118 + 253 253 253 52 67 253 102 253 48 253 253 51 69 253 44 126 + 25 60 253 253 14 253 253 253 96 84 253 253 253 5 253 32 253 + 69 103 253 40 114 26 253 15 253 253 81 253 253 253 253 80 + 83 95 73 253 253 33 56 253 0 91 253 253 253 29 68 108 99 48 + 253 9 253 0 124 253 24 63 110 106 11 253 117 110 253 53 253 + 253 253 253 253 253 253 112 114 253 253 88 253 44 46 253 + 253 33 253 79 253 253 73 85 84 16 253 253 253 87 37 124 96 + 253 11 91 253 78 75 11 75 253 21 253 19 253 70 56 253 39 86 + 253 53 253 70 57 32 253 253 82 253 14 28 13 253 87 253 253 + 253 69 253 58 29 253 253 253 42 67 113 123 118 92 253 253 0 + 99 253 107 112 79 253 106 253 45 253 37 253 105 14 112 123 + 31 122 33 253 253 253 60 55 108 125 40 253 99 104 81 97 112 + 253 253 253 253 65 22 96 73 253 253 74 253 253 27 60 53 9 + 253 43 43 104 253 112 57 253 21 253 33 253 253 253 98 253 + 253 13 32 12 253 65 7 253 74 253 253 253 57 253 111 83 253 + 253 73 38 127 24 71 253 60 69 253 25 253 253 49 253 120 253 + 253 103 117 253 253 253 253 113 253 253 253 253 253 31 106 + 22 253 40 253 253 253 253 253 62 105 253 25 253 30 109 42 + 253 113 253 253 253 253 253 57 253 44 44 48 59 119 253 52 + 103 85 253 44 253 253 76 8 127 93 253 85 253 253 253 253 42 + 71 74 116 70 253 2 253 94 14 113 253 97 253 253 87 65 253 + 36 253 253 253 40 253 8 253 47 113 253 253 253 109 253 107 + 253 37 60 253 253 253 83 253 253 253 253 39 87 0 110 35 253 + 253 253 253 253 102 253 253 253 253 253 58 103 253 253 35 + 48 52 114 32 24 253 253 253 253 91 107 253 253 253 5 253 4 + 24 253 56 253 253 77 253 253 89 68 253 55 253 83 253 76 14 + 126 253 52 253 253 55 253 253 76 253 253 126 87 3 253 90 82 + 85 70 74 253 44 116 24 253 253 78 119 103 253 253 48 71 253 + 253 92 104 253 253 253 17 76 111 253 253 253 253 109 38 72 + 100 253 6 253 253 253 118 253 123 253 253 253 11 109 9 28 + 253 253 253 32 100 84 69 110 253 253 253 253 66 253 111 253 + 253 253 47 253 78 114 5 72 45 253 86 253 253 253 114 40 93 + 253 253 57 253 41 93 253 81 253 127 253 15 253 38 120 34 + 253 253 106 64 58 253 28 121 80 57 111 115 72 60 23 253 253 + 29 74 89 38 86 253 45 253 253 253 253 253 253 253 121 8 5 + 253 64 9 253 72 253 253 55 48 253 4 253 253 253 49 30 104 + 253 111 253 253 253 253 253 19 253 253 253 124 39 95 253 + 253 78 76 87 75 253 253 253 113 121 98 20 253 253 57 35 253 + 253 253 93 11 13 253 253 253 54 84 253 253 80 7 38 253 58 + 35 53 253 253 93 253 104 253 253 73 253 1 253 108 253 253 + 253 253 253 253 69 41 253 253 5 253 253 37 253 253 253 253 + 17 59 84 14 253 253 81 253 253 109 67 78 253 253 11 34 253 + 253 253 253 253 253 101 253 253 49 253 253 253 73 253 104 + 253 253 105 253 253 253 253 113 72 253 253 253 253 103 253 + 253 253 253 46 253 253 56 253 78 253 253 253 253 253 101 + 107 253 23 37 89 253 253 70 77 253 78 15 53 53 253 253 108 + 253 253 253 107 120 253 42 253 253 65 65 253 253 104 253 54 + 107 253 253 88 253 36 82 253 253 125 253 111 253 53 101 253 + 127 253 40 122 253 253 253 86 41 3 253 253 15 106 253 125 + 123 253 253 253 253 109 253 54 3 253 253 253 74 253 253 253 + 53 75 253 109 97 70 253 253 253 253 253 105 90 109 253 111 + 253 253 9 253 253 253 41 253 253 105 253 78 253 21 78 253 + 253 55 253 72 253 33 98 31 253 253 253 15 253 75 116 79 253 + 114 8 253 111 35 253 123 118 253 119 31 90 253 52 253 54 27 + 24 253 253 125 253 253 253 113 84 73 62 253 253 253 18 122 + 100 95 253 253 102 29 46 97 253 64 253 23 253 253 253 253 + 253 83 253 28 108 25 253 31 111 122 253 43 108 253 71 253 + 253 253 80 109 253 109 77 253 253 17 30 121 25 253 77 72 + 253 83 126 253 253 23 107 26 253 60 253 253 40 24 111 253 + 253 111 14 8 253 253 78 75 103 253 253 87 50 5 253 253 2 59 + 253 79 21 253 11 103 110 253 18 6 62 253 253 105 28 253 10 + 253 85 123 38 253 45 253 88 253 81 253 67 32 30 253 253 253 + 253 253 80 253 114 253 22 10 253 108 30 62 253 253 79 46 46 + 86 123 98 100 102 253 7 30 94 253 253 26 28 69 253 52 56 95 + 109 253 109 253 108 51 253 253 23 253 104 253 253 25 13 31 + 253 253 253 253 253 27 253 6 56 84 253 253 46 120 12 253 2 + 253 115 20 110 253 110 19 253 253 110 21 62 253 253 253 253 + 52 101 253 43 64 253 253 253 253 104 69 127 74 253 80 253 + 253 253 253 253 51 253 253 14 15 253 106 253 253 253 39 75 + 253 253 253 253 253 21 253 112 126 84 98 23 253 253 39 87 + 253 253 253 49 71 82 114 25 71 106 253 122 253 37 253 40 50 + 77 55 253 64 0 15 253 86 253 53 20 87 81 74 253 253 253 35 + 67 39 101 253 36 99 253 104 9 50 253 54 253 253 35 253 13 + 19 253 45 36 96 65 27 253 253 57 253 253 253 253 253 253 20 + 4 73 253 103 24 253 20 253 122 116 122 47 253 253 253 9 253 + 253 72 253 253 253 32 3 253 122 253 63 53 253 253 253 253 + 34 253 253 60 253 253 61 253 253 253 253 12 102 253 69 26 + 253 253 253 253 253 253 253 92 5 253 253 253 70 253 105 11 + 47 253 253 253 80 87 253 0 253 253 63 253 253 253 86 253 + 253 253 3 253 253 253 99 253 41 253 253 0 253 122 253 17 92 + 253 118 127 253 253 253 1 253 30 18 86 253 51 253 253 253 + 87 253 253 13 50 12 253 64 27 31 253 76 253 253 253 253 253 + 253 120 123 80 41 253 115 253 106 40 253 98 43 123 253 111 + 55 253 253 113 253 253 86 7 70 253 76 253 253 31 253 68 253 + 253 253 253 253 96 62 253 253 253 253 90 28 253 253 99 253 + 253 253 59 253 0 253 15 253 253 83 110 253 253 9 102 253 45 + 253 253 102 253 39 28 253 253 253 98 41 253 253 39 68 253 0 + 253 253 253 253 58 253 253 73 253 253 253 253 73 253 1 30 + 253 97 104 253 253 253 253 253 103 118 253 253 71 253 25 + 253 253 253 63 70 253 253 62 253 253 253 21 253 118 253 70 + 253 253 27 99 71 253 253 253 65 53 34 253 253 77 74 253 47 + 253 114 58 253 68 253 253 31 99 89 253 11 253 253 253 253 + 99 253 30 56 253 54 253 74 253 102 50 61 253 253 253 253 + 120 56 63 32 61 253 78 23 253 53 94 105 26 253 253 253 34 + 65 253 88 253 66 253 253 253 253 253 63 92 122 84 253 253 + 253 75 253 253 68 253 34 253 79 253 1 253 253 74 70 19 118 + 253 11 253 67 44 253 253 18 6 253 253 253 75 253 90 253 71 + 102 253 253 124 253 253 64 253 253 253 253 97 253 253 50 + 253 253 82 7 96 253 253 91 106 39 253 253 253 253 253 253 + 253 253 253 71 253 35 84 253 21 253 253 253 49 34 253 13 + 253 24 253 103 45 29 253 253 82 84 253 253 56 81 69 253 110 + 49 40 48 52 89 28 253 19 253 21 253 253 253 73 253 104 253 + 253 125 8 28 253 253 108 77 38 107 71 120 253 109 66 69 16 + 38 82 253 253 28 253 80 86 73 58 66 99 117 124 253 57 70 + 253 0 253 100 253 60 78 89 81 253 49 253 8 114 63 253 253 + 116 48 99 44 253 63 45 253 123 253 253 253 253 120 253 253 + 97 102 63 253 69 97 52 253 253 253 68 253 253 57 253 109 + 253 0 106 85 253 92 92 253 21 69 112 253 253 32 253 22 253 + 24 41 50 63 253 253 253 253 253 87 118 253 253 73 27 253 + 253 101 126 253 253 122 253 93 117 30 253 38 253 253 94 253 + 253 253 19 253 109 30 48 78 61 8 253 253 253 253 253 92 25 + 97 105 87 253 253 253 253 85 253 17 253 3 72 253 125 66 13 + 98 253 253 253 253 71 112 23 37 99 32 78 61 73 24 253 79 39 + 25 253 120 253 253 253 253 1 253 55 105 253 17 253 253 253 + 253 253 50 253 52 253 253 7 253 23 253 0 253 253 253 253 66 + 253 253 52 253 253 253 253 253 28 253 253 104 115 253 97 + 103 13 253 253 96 253 28 40 253 253 253 253 253 63 253 52 + 253 46 47 253 253 48 50 253 253 253 253 253 71 81 68 114 91 + 118 253 97 253 253 253 85 49 253 102 253 253 67 253 110 96 + 88 253 77 109 119 50 253 253 24 253 45 253 71 109 24 101 + 102 64 253 57 11 253 253 73 253 73 79 253 253 37 253 253 + 253 253 40 14 253 253 115 253 7 253 7 113 54 253 48 253 253 + 85 126 253 253 71 11 42 110 109 253 253 0 253 108 127 253 + 105 72 101 253 253 253 253 88 253 253 2 54 15 253 83 59 253 + 85 5 105 253 55 253 93 253 253 118 52 46 253 34 67 3 253 + 253 93 253 101 3 36 83 68 253 84 92 253 100 125 253 38 253 + 36 253 4 253 253 108 253 30 253 253 253 94 253 253 12 253 + 253 90 253 253 99 86 111 12 54 91 105 253 21 39 253 85 253 + 253 98 82 253 253 6 60 79 253 82 253 46 253 253 253 104 12 + 1 253 78 253 114 104 253 253 253 253 253 57 60 253 6 101 + 253 253 253 253 81 253 62 94 77 44 253 253 83 42 23 253 253 + 253 253 21 29 253 253 34 253 253 253 253 69 1 3 45 52 253 + 103 31 65 253 0 106 47 91 253 45 44 81 253 95 21 253 29 253 + 26 33 44 253 253 21 16 253 126 253 253 8 253 109 13 253 253 + 253 253 253 99 113 253 253 253 41 1 253 62 253 253 104 253 + 69 36 253 49 42 23 253 52 253 253 99 253 61 253 253 253 53 + 253 37 34 253 253 253 253 253 253 60 253 253 76 125 9 253 + 86 14 253 253 114 73 40 253 253 54 109 253 45 253 72 253 + 253 253 253 117 47 253 253 253 253 93 78 253 76 35 253 253 + 253 253 253 253 79 21 253 253 253 253 58 253 253 253 39 253 + 64 253 43 3 253 34 253 253 253 16 253 70 253 253 253 253 69 + 75 117 253 253 253 253 253 253 37 253 253 15 253 253 112 + 253 61 253 71 36 253 44 93 253 85 69 253 253 85 253 3 253 + 253 253 253 96 253 253 253 253 253 63 74 253 29 253 53 253 + 102 73 6 253 253 253 253 253 0 253 106 85 253 253 99 253 79 + 45 253 38 30 253 253 253 253 253 120 253 253 64 8 253 15 + 253 1 253 70 11 124 253 253 253 35 20 253 9 35 116 37 90 + 253 5 253 29 253 65 253 18 253 0 67 253 253 0 116 253 90 41 + 16 1 253 253 253 253 106 24 253 61 253 110 27 253 54 253 61 + 253 78 253 253 110 34 253 47 253 55 253 253 253 253 253 253 + 253 85 253 253 73 118 116 253 253 109 63 253 253 83 53 253 + 253 126 253 253 253 80 80 253 253 253 15 253 122 95 253 253 + 253 122 253 88 253 253 253 253 95 253 253 253 107 86 253 + 253 253 253 253 87 253 31 253 253 77 253 121 253 0 253 253 + 49 127 90 95 253 253 122 253 74 253 253 99 253 253 104 22 + 253 253 125 253 253 253 253 69 126 253 253 253 253 253 79 + 253 253 94 253 80 8 60 253 253 95 253 100 253 253 74 253 + 122 253 253 62 46 253 26 253 253 253 79 253 253 94 253 47 + 30 253 253 126 253 81 253 253 253 253 253 253 100 253 253 + 63 45 125 253 253 253 253 0 109 122 253 80 253 253 51 91 + 253 253 253 253 253 94 253 85 95 253 253 253 253 253 126 + 253 111 253 63 253 94 253 83 46 253 253 253 253 253 253 91 + 117 15 253 253 253 122 253 253 58 253 253 253 111 253 253 + 253 127 253 39 253 85 253 253 17 88 116 253 253 253 253 253 + 253 253 253 87 253 253 16 77 109 253 105 105 76 253 253 253 + 253 94 253 253 253 87 253 0 50 253 0 253 88 71 253 10 253 + 122 253 64 253 253 253 253 253 253 85 253 0 106 253 94 253 + 125 253 35 47 253 58 105 99 253 68 253 0 253 253 87 253 253 + 253 63 253 253 13 10 45 45 45 45 45 45 87 101 98 75 105 116 + 70 111 114 109 66 111 117 110 100 97 114 121 115 105 103 + 113 43 53 113 87 116 54 79 114 122 56 76 79 45 45 13 10 + } >string ; + diff --git a/basis/mime/multipart/multipart.factor b/basis/mime/multipart/multipart.factor new file mode 100644 index 0000000000..4c7b95699e --- /dev/null +++ b/basis/mime/multipart/multipart.factor @@ -0,0 +1,63 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators io kernel locals math multiline +sequences splitting prettyprint ; +IN: mime.multipart + +TUPLE: multipart-stream stream n leftover separator ; + +: ( stream separator -- multipart-stream ) + multipart-stream new + swap >>separator + swap >>stream + 16 2^ >>n ; + +> ] [ stream>> ] bi stream-read [ ?append ] keep not ; + +: multipart-split ( bytes separator -- before after seq=? ) + 2dup sequence= [ 2drop f f t ] [ split1 f ] if ; + +:: multipart-step-found ( bytes stream quot -- ? ) + bytes [ + quot unless-empty + ] [ + stream (>>leftover) + quot unless-empty + ] if-empty f quot call f ; + +:: multipart-step-not-found ( stream end-stream? separator quot -- ? ) + end-stream? [ + quot unless-empty f + ] [ + separator length 1- ?cut* stream (>>leftover) + quot unless-empty t + ] if ; + +:: multipart-step ( stream bytes end-stream? separator quot: ( bytes -- ) -- ? end-stream? ) + #! return t to loop again + bytes separator multipart-split + [ 2drop f quot call f ] + [ + [ stream quot multipart-step-found ] + [ stream end-stream? separator quot multipart-step-not-found ] if* + ] if stream leftover>> end-stream? not or ; + +PRIVATE> + +:: multipart-step-loop ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ? ) + stream dup [ read-n ] [ separator>> ] bi quot1 multipart-step + swap [ drop stream quot1 quot2 multipart-step-loop ] quot2 if ; + +: multipart-loop-all ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ) + 3dup multipart-step-loop + [ multipart-loop-all ] [ 3drop ] if ; diff --git a/basis/mime-types/authors.txt b/basis/mime/types/authors.txt similarity index 100% rename from basis/mime-types/authors.txt rename to basis/mime/types/authors.txt diff --git a/basis/mime-types/mime.types b/basis/mime/types/mime.types similarity index 100% rename from basis/mime-types/mime.types rename to basis/mime/types/mime.types diff --git a/basis/mime-types/mime-types-docs.factor b/basis/mime/types/types-docs.factor similarity index 90% rename from basis/mime-types/mime-types-docs.factor rename to basis/mime/types/types-docs.factor index b7fa46d587..fc14227e2d 100644 --- a/basis/mime-types/mime-types-docs.factor +++ b/basis/mime/types/types-docs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: assocs help.markup help.syntax io.streams.string sequences ; -IN: mime-types +IN: mime.types HELP: mime-db { $values @@ -27,9 +27,9 @@ HELP: nonstandard-mime-types { "assoc" assoc } } { $description "A list of Factor-specific MIME types that are added to the MIME database loaded from disk." } ; -ARTICLE: "mime-types" "MIME types" -"The " { $vocab-link "mime-types" } " vocabulary loads a file of MIME types and provides a word to look up the MIME type based on a file extension." $nl +ARTICLE: "mime.types" "MIME types" +"The " { $vocab-link "mime.types" } " vocabulary loads a file of MIME types and provides a word to look up the MIME type based on a file extension." $nl "Looking up a MIME type:" { $subsection mime-type } ; -ABOUT: "mime-types" +ABOUT: "mime.types" diff --git a/basis/mime-types/mime-types-tests.factor b/basis/mime/types/types-tests.factor similarity index 77% rename from basis/mime-types/mime-types-tests.factor rename to basis/mime/types/types-tests.factor index 925eca2e9d..63535afa9a 100644 --- a/basis/mime-types/mime-types-tests.factor +++ b/basis/mime/types/types-tests.factor @@ -1,5 +1,5 @@ -IN: mime-types.tests -USING: mime-types tools.test ; +IN: mime.types.tests +USING: mime.types tools.test ; [ "application/postscript" ] [ "foo.ps" mime-type ] unit-test [ "application/octet-stream" ] [ "foo.ps.gz" mime-type ] unit-test diff --git a/basis/mime-types/mime-types.factor b/basis/mime/types/types.factor similarity index 91% rename from basis/mime-types/mime-types.factor rename to basis/mime/types/types.factor index 909f762c50..bb0d674f23 100644 --- a/basis/mime-types/mime-types.factor +++ b/basis/mime/types/types.factor @@ -2,10 +2,10 @@ ! See http://factorcode.org/license.txt for BSD license. USING: io.files io.encodings.ascii assocs sequences splitting kernel namespaces fry memoize ; -IN: mime-types +IN: mime.types MEMO: mime-db ( -- seq ) - "resource:basis/mime-types/mime.types" ascii file-lines + "resource:basis/mime/types/mime.types" ascii file-lines [ "#" head? not ] filter [ " \t" split harvest ] map harvest ; : nonstandard-mime-types ( -- assoc ) diff --git a/basis/openssl/openssl.factor b/basis/openssl/openssl.factor index 284e42cd1b..8f14c60e14 100644 --- a/basis/openssl/openssl.factor +++ b/basis/openssl/openssl.factor @@ -1,25 +1,13 @@ ! Copyright (C) 2007, 2008, Slava Pestov, Elie CHAFTARI. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors byte-arrays kernel debugger sequences namespaces math -math.order combinators init alien alien.c-types alien.strings libc -continuations destructors debugger summary splitting assocs -random math.parser locals unicode.case -openssl.libcrypto openssl.libssl -io.backend io.ports io.files io.encodings.8-bit io.sockets.secure -io.timeouts ; +USING: init kernel namespaces openssl.libcrypto openssl.libssl +sequences ; IN: openssl ! This code is based on http://www.rtfm.com/openssl-examples/ SINGLETON: openssl -GENERIC: ssl-method ( symbol -- method ) - -M: SSLv2 ssl-method drop SSLv2_client_method ; -M: SSLv23 ssl-method drop SSLv23_method ; -M: SSLv3 ssl-method drop SSLv3_method ; -M: TLSv1 ssl-method drop TLSv1_method ; - : (ssl-error-string) ( n -- string ) ERR_clear_error f ERR_error_string ; @@ -47,183 +35,3 @@ SYMBOL: ssl-initialized? ] unless ; [ f ssl-initialized? set-global ] "openssl" add-init-hook - -TUPLE: openssl-context < secure-context aliens sessions ; - -: set-session-cache ( ctx -- ) - handle>> - [ SSL_SESS_CACHE_BOTH SSL_CTX_set_session_cache_mode ssl-error ] - [ 32 random-bits >hex dup length SSL_CTX_set_session_id_context ssl-error ] - bi ; - -: load-certificate-chain ( ctx -- ) - dup config>> key-file>> [ - [ handle>> ] [ config>> key-file>> (normalize-path) ] bi - SSL_CTX_use_certificate_chain_file - ssl-error - ] [ drop ] if ; - -: password-callback ( -- alien ) - "int" { "void*" "int" "bool" "void*" } "cdecl" - [| buf size rwflag password! | - password [ B{ 0 } password! ] unless - - [let | len [ password strlen ] | - buf password len 1+ size min memcpy - len - ] - ] alien-callback ; - -: default-pasword ( ctx -- alien ) - [ config>> password>> latin1 malloc-string ] [ aliens>> ] bi - [ push ] [ drop ] 2bi ; - -: set-default-password ( ctx -- ) - [ handle>> password-callback SSL_CTX_set_default_passwd_cb ] - [ - [ handle>> ] [ default-pasword ] bi - SSL_CTX_set_default_passwd_cb_userdata - ] bi ; - -: use-private-key-file ( ctx -- ) - dup config>> key-file>> [ - [ handle>> ] [ config>> key-file>> (normalize-path) ] bi - SSL_FILETYPE_PEM SSL_CTX_use_PrivateKey_file - ssl-error - ] [ drop ] if ; - -: load-verify-locations ( ctx -- ) - dup config>> [ ca-file>> ] [ ca-path>> ] bi or [ - [ handle>> ] - [ - config>> - [ ca-file>> dup [ (normalize-path) ] when ] - [ ca-path>> dup [ (normalize-path) ] when ] bi - ] bi - SSL_CTX_load_verify_locations - ] [ handle>> SSL_CTX_set_default_verify_paths ] if ssl-error ; - -: set-verify-depth ( ctx -- ) - dup config>> verify-depth>> [ - [ handle>> ] [ config>> verify-depth>> ] bi - SSL_CTX_set_verify_depth - ] [ drop ] if ; - -TUPLE: bio handle disposed ; - -: ( handle -- bio ) f bio boa ; - -M: bio dispose* handle>> BIO_free ssl-error ; - -: ( path -- bio ) - normalize-path "r" BIO_new_file dup ssl-error ; - -: load-dh-params ( ctx -- ) - dup config>> dh-file>> [ - [ handle>> ] [ config>> dh-file>> ] bi &dispose - handle>> f f f PEM_read_bio_DHparams dup ssl-error - SSL_CTX_set_tmp_dh ssl-error - ] [ drop ] if ; - -TUPLE: rsa handle disposed ; - -: ( handle -- rsa ) f rsa boa ; - -M: rsa dispose* handle>> RSA_free ; - -: generate-eph-rsa-key ( ctx -- ) - [ handle>> ] - [ - config>> ephemeral-key-bits>> RSA_F4 f f RSA_generate_key - dup ssl-error &dispose handle>> - ] bi - SSL_CTX_set_tmp_rsa ssl-error ; - -: ( config ctx -- context ) - openssl-context new - swap >>handle - swap >>config - V{ } clone >>aliens - H{ } clone >>sessions ; - -M: openssl ( config -- context ) - maybe-init-ssl - [ - dup method>> ssl-method SSL_CTX_new - dup ssl-error |dispose - { - [ set-session-cache ] - [ load-certificate-chain ] - [ set-default-password ] - [ use-private-key-file ] - [ load-verify-locations ] - [ set-verify-depth ] - [ load-dh-params ] - [ generate-eph-rsa-key ] - [ ] - } cleave - ] with-destructors ; - -M: openssl-context dispose* - [ aliens>> [ free ] each ] - [ sessions>> values [ SSL_SESSION_free ] each ] - [ handle>> SSL_CTX_free ] - tri ; - -TUPLE: ssl-handle file handle connected disposed ; - -SYMBOL: default-secure-context - -: context-expired? ( context -- ? ) - dup [ handle>> expired? ] [ drop t ] if ; - -: current-secure-context ( -- ctx ) - secure-context get [ - default-secure-context get dup context-expired? [ - drop - default-secure-context set-global - current-secure-context - ] when - ] unless* ; - -: ( fd -- ssl ) - current-secure-context handle>> SSL_new dup ssl-error - f f ssl-handle boa ; - -M: ssl-handle dispose* - [ handle>> SSL_free ] [ file>> dispose ] bi ; - -: check-verify-result ( ssl-handle -- ) - SSL_get_verify_result dup X509_V_OK = - [ drop ] [ verify-message certificate-verify-error ] if ; - -: common-name ( certificate -- host ) - X509_get_subject_name - NID_commonName 256 - [ 256 X509_NAME_get_text_by_NID ] keep - swap -1 = [ drop f ] [ latin1 alien>string ] if ; - -: common-names-match? ( expected actual -- ? ) - [ >lower ] bi@ "*." ?head [ tail? ] [ = ] if ; - -: check-common-name ( host ssl-handle -- ) - SSL_get_peer_certificate common-name - 2dup common-names-match? - [ 2drop ] [ common-name-verify-error ] if ; - -M: openssl check-certificate ( host ssl -- ) - current-secure-context config>> verify>> [ - handle>> - [ nip check-verify-result ] - [ check-common-name ] - 2bi - ] [ 2drop ] if ; - -: get-session ( addrspec -- session/f ) - current-secure-context sessions>> at - dup expired? [ drop f ] when ; - -: save-session ( session addrspec -- ) - current-secure-context sessions>> set-at ; - -openssl secure-socket-backend set-global diff --git a/basis/peg/parsers/parsers.factor b/basis/peg/parsers/parsers.factor index 5739482093..af1b4aec04 100644 --- a/basis/peg/parsers/parsers.factor +++ b/basis/peg/parsers/parsers.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2007, 2008 Chris Double, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences strings namespaces make math assocs -shuffle vectors arrays math.parser accessors unicode.categories +vectors arrays math.parser accessors unicode.categories sequences.deep peg peg.private peg.search math.ranges words ; IN: peg.parsers diff --git a/basis/peg/peg.factor b/basis/peg/peg.factor index cc13d5d425..2dabf1edf7 100644 --- a/basis/peg/peg.factor +++ b/basis/peg/peg.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2007, 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences strings fry namespaces make math assocs -shuffle debugger io vectors arrays math.parser math.order +debugger io vectors arrays math.parser math.order vectors combinators classes sets unicode.categories compiler.units parser words quotations effects memoize accessors locals effects splitting combinators.short-circuit diff --git a/basis/prettyprint/backend/backend.factor b/basis/prettyprint/backend/backend.factor index 31b6ba3f26..f1fd749666 100644 --- a/basis/prettyprint/backend/backend.factor +++ b/basis/prettyprint/backend/backend.factor @@ -216,17 +216,8 @@ M: object pprint* pprint-object ; M: vector pprint* pprint-object ; M: byte-vector pprint* pprint-object ; M: hashtable pprint* pprint-object ; - -M: curry pprint* - dup quot>> callable? [ pprint-object ] [ - "( invalid curry )" swap present-text - ] if ; - -M: compose pprint* - dup [ first>> callable? ] [ second>> callable? ] bi and - [ pprint-object ] [ - "( invalid compose )" swap present-text - ] if ; +M: curry pprint* pprint-object ; +M: compose pprint* pprint-object ; M: wrapper pprint* dup wrapped>> word? [ diff --git a/basis/prettyprint/prettyprint-docs.factor b/basis/prettyprint/prettyprint-docs.factor index 159421c18c..3c004e5b30 100644 --- a/basis/prettyprint/prettyprint-docs.factor +++ b/basis/prettyprint/prettyprint-docs.factor @@ -17,7 +17,8 @@ ARTICLE: "prettyprint-stacks" "Prettyprinting stacks" "Prettyprinting any stack:" { $subsection stack. } "Prettyprinting any call stack:" -{ $subsection callstack. } ; +{ $subsection callstack. } +"Note that calls to " { $link .s } " can also be included inside words as a debugging aid, however a more convenient way to achieve this is to use the annotation facility. See " { $link "tools.annotations" } "." ; ARTICLE: "prettyprint-variables" "Prettyprint control variables" "The following variables affect the " { $link . } " and " { $link pprint } " words if set in the current dynamic scope:" diff --git a/basis/prettyprint/prettyprint-tests.factor b/basis/prettyprint/prettyprint-tests.factor index 8eaaab3c1d..96698fc18f 100644 --- a/basis/prettyprint/prettyprint-tests.factor +++ b/basis/prettyprint/prettyprint-tests.factor @@ -323,10 +323,6 @@ M: class-see-layout class-see-layout ; [ 2 break 2 \ + (step-into-execute) . ] (remove-breakpoints) ] unit-test -[ ] [ 1 \ + curry unparse drop ] unit-test - -[ ] [ 1 \ + compose unparse drop ] unit-test - GENERIC: generic-see-test-with-f ( obj -- obj ) M: f generic-see-test-with-f ; diff --git a/basis/prettyprint/prettyprint.factor b/basis/prettyprint/prettyprint.factor index 3befdaff2b..6dd7175db8 100644 --- a/basis/prettyprint/prettyprint.factor +++ b/basis/prettyprint/prettyprint.factor @@ -7,7 +7,7 @@ prettyprint.config sorting splitting grouping math.parser vocabs definitions effects classes.builtin classes.tuple io.files classes continuations hashtables classes.mixin classes.union classes.intersection classes.predicate classes.singleton -combinators quotations sets accessors colors ; +combinators quotations sets accessors colors parser ; IN: prettyprint : make-pprint ( obj quot -- block in use ) @@ -44,12 +44,28 @@ IN: prettyprint ] with-pprint nl ] unless-empty ; -: vocabs. ( in use -- ) +: use/in. ( in use -- ) dupd remove [ { "syntax" "scratchpad" } member? not ] filter use. in. ; +: vocab-names ( words -- vocabs ) + dictionary get + [ [ words>> eq? nip ] with assoc-find 2drop ] curry map sift ; + +: prelude. ( -- ) + in get use get vocab-names use/in. ; + +[ + nl + "Restarts were invoked adding vocabularies to the search path." print + "To avoid doing this in the future, add the following USING:" print + "and IN: forms at the top of the source file:" print nl + prelude. + nl +] print-use-hook set-global + : with-use ( obj quot -- ) - make-pprint vocabs. do-pprint ; inline + make-pprint use/in. do-pprint ; inline : with-in ( obj quot -- ) make-pprint drop [ write-in bl ] when* do-pprint ; inline diff --git a/basis/qualified/qualified.factor b/basis/qualified/qualified.factor index d387ef4b0e..25d04ed929 100644 --- a/basis/qualified/qualified.factor +++ b/basis/qualified/qualified.factor @@ -17,15 +17,13 @@ IN: qualified #! Syntax: QUALIFIED-WITH: vocab prefix scan scan define-qualified ; parsing -: expect=> ( -- ) scan "=>" assert= ; - : partial-vocab ( words vocab -- assoc ) '[ dup _ lookup [ no-word-error ] unless* ] { } map>assoc ; : FROM: #! Syntax: FROM: vocab => words... ; - scan dup load-vocab drop expect=> + scan dup load-vocab drop "=>" expect ";" parse-tokens swap partial-vocab use get push ; parsing : partial-vocab-excluding ( words vocab -- assoc ) @@ -33,13 +31,13 @@ IN: qualified : EXCLUDE: #! Syntax: EXCLUDE: vocab => words ... ; - scan expect=> + scan "=>" expect ";" parse-tokens swap partial-vocab-excluding use get push ; parsing : RENAME: #! Syntax: RENAME: word vocab => newname scan scan dup load-vocab drop dupd lookup [ ] [ no-word-error ] ?if - expect=> + "=>" expect scan associate use get push ; parsing diff --git a/basis/regexp/classes/classes.factor b/basis/regexp/classes/classes.factor index 240b27a9cc..7b729b2e50 100644 --- a/basis/regexp/classes/classes.factor +++ b/basis/regexp/classes/classes.factor @@ -14,6 +14,9 @@ M: character-class-range class-member? ( obj class -- ? ) M: any-char class-member? ( obj class -- ? ) 2drop t ; + +M: any-char-no-nl class-member? ( obj class -- ? ) + drop CHAR: \n = not ; M: letter-class class-member? ( obj class -- ? ) drop letter? ; diff --git a/basis/regexp/parser/parser.factor b/basis/regexp/parser/parser.factor index b5022c602e..7f1d92a1ab 100644 --- a/basis/regexp/parser/parser.factor +++ b/basis/regexp/parser/parser.factor @@ -43,6 +43,7 @@ INSTANCE: comment-group parentheses-group TUPLE: character-class-range from to ; INSTANCE: character-class-range node SINGLETON: epsilon INSTANCE: epsilon node SINGLETON: any-char INSTANCE: any-char node +SINGLETON: any-char-no-nl INSTANCE: any-char-no-nl node SINGLETON: front-anchor INSTANCE: front-anchor node SINGLETON: back-anchor INSTANCE: back-anchor node @@ -172,7 +173,7 @@ DEFER: (parse-regexp) [ drop1 (parse-special-group) ] [ capture-group f nested-parse-regexp ] if ; -: handle-dot ( -- ) any-char push-stack ; +: handle-dot ( -- ) get-dotall any-char any-char-no-nl ? push-stack ; : handle-pipe ( -- ) pipe push-stack ; : (handle-star) ( obj -- kleene-star ) peek1 { @@ -288,28 +289,9 @@ ERROR: bad-escaped-literals seq ; first|concatenation ] if-empty ; -ERROR: unrecognized-escape char ; - : parse-escaped ( -- obj ) read1 { - { CHAR: \ [ CHAR: \ ] } - { CHAR: / [ CHAR: / ] } - { CHAR: ^ [ CHAR: ^ ] } - { CHAR: $ [ CHAR: $ ] } - { CHAR: - [ CHAR: - ] } - { CHAR: { [ CHAR: { ] } - { CHAR: } [ CHAR: } ] } - { CHAR: [ [ CHAR: [ ] } - { CHAR: ] [ CHAR: ] ] } - { CHAR: ( [ CHAR: ( ] } - { CHAR: ) [ CHAR: ) ] } - { CHAR: @ [ CHAR: @ ] } - { CHAR: * [ CHAR: * ] } - { CHAR: + [ CHAR: + ] } - { CHAR: ? [ CHAR: ? ] } - { CHAR: . [ CHAR: . ] } - { CHAR: : [ CHAR: : ] } { CHAR: t [ CHAR: \t ] } { CHAR: n [ CHAR: \n ] } { CHAR: r [ CHAR: \r ] } @@ -349,7 +331,7 @@ ERROR: unrecognized-escape char ; ! { CHAR: 9 [ CHAR: 9 ] } { CHAR: Q [ parse-escaped-literals ] } - [ unrecognized-escape ] + [ ] } case ; : handle-escape ( -- ) parse-escaped push-stack ; diff --git a/basis/regexp/regexp-tests.factor b/basis/regexp/regexp-tests.factor index 4878b67d0f..777d0985e4 100644 --- a/basis/regexp/regexp-tests.factor +++ b/basis/regexp/regexp-tests.factor @@ -1,5 +1,5 @@ USING: regexp tools.test kernel sequences regexp.parser -regexp.traversal eval ; +regexp.traversal eval strings ; IN: regexp-tests \ must-infer @@ -40,7 +40,12 @@ IN: regexp-tests [ f ] [ "" "." matches? ] unit-test [ t ] [ "a" "." matches? ] unit-test [ t ] [ "." "." matches? ] unit-test -! [ f ] [ "\n" "." matches? ] unit-test + +! Dotall mode -- when on, . matches newlines. +! Off by default. +[ f ] [ "\n" "." matches? ] unit-test +[ t ] [ "\n" "(?s)." matches? ] unit-test +[ f ] [ "\n\n" "(?s).(?-s)." matches? ] unit-test [ f ] [ "" ".+" matches? ] unit-test [ t ] [ "a" ".+" matches? ] unit-test @@ -170,7 +175,6 @@ IN: regexp-tests [ f ] [ "ABC" "\\p{Lower}{3}" matches? ] unit-test [ t ] [ "ABC" "\\p{Upper}{3}" matches? ] unit-test [ f ] [ "abc" "\\p{Upper}{3}" matches? ] unit-test -! [ f ] [ "abc" "[\\p{Upper}]{3}" matches? ] unit-test [ t ] [ "ABC" "[\\p{Upper}]{3}" matches? ] unit-test @@ -252,7 +256,40 @@ IN: regexp-tests ! Comment [ t ] [ "ac" "a(?#boo)c" matches? ] unit-test +[ ] [ "USING: regexp kernel ; R' -{3}[+]{1,6}(?:!!)?\\s' drop" eval ] unit-test +[ ] [ "USING: regexp kernel ; R' (ftp|http|https)://(\\w+:?\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-/]))?' drop" eval ] unit-test + +[ ] [ "USING: regexp kernel ; R' \\*[^\s*][^*]*\\*' drop" eval ] unit-test + +[ "ab" ] [ "ab" "(a|ab)(bc)?" first-match >string ] unit-test +[ "abc" ] [ "abc" "(a|ab)(bc)?" first-match >string ] unit-test + +[ "ab" ] [ "ab" "(ab|a)(bc)?" first-match >string ] unit-test +[ "abc" ] [ "abc" "(ab|a)(bc)?" first-match >string ] unit-test + +[ "b" ] [ "aaaaaaaaaaaaaaaaaaaaaaab" "((a*)*b)*b" first-match >string ] unit-test + +[ t ] [ "a:b" ".+:?" matches? ] unit-test + +[ 1 ] [ "hello" ".+?" match length ] unit-test + +[ { "1" "2" "3" "4" } ] +[ "1ABC2DEF3GHI4" R/ [A-Z]+/ re-split [ >string ] map ] unit-test + +[ { "1" "2" "3" "4" } ] +[ "1ABC2DEF3GHI4JK" R/ [A-Z]+/ re-split [ >string ] map ] unit-test + +[ { "ABC" "DEF" "GHI" } ] +[ "1ABC2DEF3GHI4" R/ [A-Z]+/ all-matches [ >string ] map ] unit-test + +[ "1.2.3.4" ] +[ "1ABC2DEF3GHI4JK" R/ [A-Z]+/ "." re-replace ] unit-test + +[ f ] [ "ab" "a(?!b)" first-match ] unit-test +[ "a" ] [ "ab" "a(?=b)(?=b)" first-match >string ] unit-test +[ "a" ] [ "ba" "a(?<=b)(?<=b)" first-match >string ] unit-test +[ "a" ] [ "cab" "a(?=b)(?<=c)" first-match >string ] unit-test ! [ "{Lower}" ] [ invalid-range? ] must-fail-with @@ -286,21 +323,10 @@ IN: regexp-tests ! [ t ] [ "fooxbar" "foo\\Bxbar" matches? ] unit-test ! [ f ] [ "foo" "foo\\Bbar" matches? ] unit-test -[ ] [ "USING: regexp kernel ; R' -{3}[+]{1,6}(?:!!)?\\s' drop" eval ] unit-test - -[ ] [ "USING: regexp kernel ; R' (ftp|http|https)://(\\w+:?\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-/]))?' drop" eval ] unit-test - -[ ] [ "USING: regexp kernel ; R' \\*[^\s*][^*]*\\*' drop" eval ] unit-test ! Bug in parsing word ! [ t ] [ "a" R' a' matches? ] unit-test -! ((A)(B(C))) -! 1. ((A)(B(C))) -! 2. (A) -! 3. (B(C)) -! 4. (C) - ! clear "a(?=b*)" "ab" over match ! clear "a(?=b*c)" "abbbbbc" over match ! clear "a(?=b*)" "ab" over match @@ -326,27 +352,11 @@ IN: regexp-tests ! "a(?#bcdefg)bcd" "abcdefg" over first-match ! "a(?:bcdefg)" "abcdefg" over first-match -[ { 0 1 } ] [ "ac" "a(?!b)" first-match ] unit-test -[ f ] [ "ab" "a(?!b)" first-match ] unit-test +[ "a" ] [ "ac" "a(?!b)" first-match >string ] unit-test ! "a(?<=b)" "caba" over first-match -[ { 0 1 } ] [ "ab" "a(?=b)(?=b)" first-match ] unit-test -[ { 1 2 } ] [ "ba" "a(?<=b)(?<=b)" first-match ] unit-test -[ { 1 2 } ] [ "cab" "a(?=b)(?<=c)" first-match ] unit-test ! capture group 1: "aaaa" 2: "" ! "aaaa" "(a*)(a*)" match* ! "aaaa" "(a*)(a+)" match* - -[ { 0 2 } ] [ "ab" "(a|ab)(bc)?" first-match ] unit-test -[ { 0 3 } ] [ "abc" "(a|ab)(bc)?" first-match ] unit-test - -[ { 0 2 } ] [ "ab" "(ab|a)(bc)?" first-match ] unit-test -[ { 0 3 } ] [ "abc" "(ab|a)(bc)?" first-match ] unit-test - -[ { 23 24 } ] [ "aaaaaaaaaaaaaaaaaaaaaaab" "((a*)*b)*b" first-match ] unit-test - -[ t ] [ "a:b" ".+:?" matches? ] unit-test - -[ 1 ] [ "hello" ".+?" match length ] unit-test diff --git a/basis/regexp/regexp.factor b/basis/regexp/regexp.factor index c9a1d2f47d..66bc39415b 100644 --- a/basis/regexp/regexp.factor +++ b/basis/regexp/regexp.factor @@ -1,9 +1,9 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors combinators kernel math math.ranges sequences +USING: accessors combinators kernel math sequences sets assocs prettyprint.backend make lexer namespaces parser arrays fry regexp.backend regexp.utils regexp.parser regexp.nfa -regexp.dfa regexp.traversal regexp.transition-tables ; +regexp.dfa regexp.traversal regexp.transition-tables splitting ; IN: regexp : default-regexp ( string -- regexp ) @@ -25,17 +25,20 @@ IN: regexp [ ] } cleave ; -: match ( string regexp -- pair ) - do-match return-match ; +: (match) ( string regexp -- dfa-traverser ) + do-match ; inline -: match* ( string regexp -- pair captured-groups ) - do-match [ return-match ] [ captured-groups>> ] bi ; +: match ( string regexp -- slice/f ) + (match) return-match ; + +: match* ( string regexp -- slice/f captured-groups ) + (match) [ return-match ] [ captured-groups>> ] bi ; : matches? ( string regexp -- ? ) dupd match - [ [ length ] [ length>> 1- ] bi* = ] [ drop f ] if* ; + [ [ length ] bi@ = ] [ drop f ] if* ; -: match-head ( string regexp -- end/f ) match [ length>> 1- ] [ f ] if* ; +: match-head ( string regexp -- end/f ) match [ length ] [ f ] if* ; : match-at ( string m regexp -- n/f finished? ) [ @@ -49,29 +52,25 @@ IN: regexp [ 3drop drop f f ] [ drop [ 1+ ] dip match-range ] if ] if ; -: first-match ( string regexp -- pair/f ) - 0 swap match-range dup [ 2array ] [ 2drop f ] if ; +: first-match ( string regexp -- slice/f ) + dupd 0 swap match-range rot over [ ] [ 3drop f ] if ; : re-cut ( string regexp -- end/f start ) dupd first-match - [ [ second tail-slice ] [ first head ] 2bi ] - [ "" like f swap ] - if* ; + [ split1-slice swap ] [ "" like f swap ] if* ; : re-split ( string regexp -- seq ) - [ dup ] swap '[ _ re-cut ] [ ] produce nip ; + [ dup length 0 > ] swap '[ _ re-cut ] [ ] produce nip ; : re-replace ( string regexp replacement -- result ) [ re-split ] dip join ; : next-match ( string regexp -- end/f match/f ) dupd first-match dup - [ [ second tail-slice ] keep ] - [ 2drop f f ] - if ; + [ [ split1-slice nip ] keep ] [ 2drop f f ] if ; : all-matches ( string regexp -- seq ) - [ dup ] swap '[ _ next-match ] [ ] produce nip ; + [ dup ] swap '[ _ next-match ] [ ] produce nip harvest ; : count-matches ( string regexp -- n ) all-matches length 1- ; diff --git a/basis/regexp/traversal/traversal.factor b/basis/regexp/traversal/traversal.factor index c9e8a54348..86d315ee2f 100644 --- a/basis/regexp/traversal/traversal.factor +++ b/basis/regexp/traversal/traversal.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs combinators kernel math math.ranges +USING: accessors assocs combinators kernel math quotations sequences regexp.parser regexp.classes fry arrays combinators.short-circuit regexp.utils prettyprint regexp.nfa shuffle ; @@ -144,7 +144,10 @@ M: capture-group-off flag-action ( dfa-traverser flag -- ) [ increment-state do-match ] when* ] unless ; -: return-match ( dfa-traverser -- interval/f ) +: return-match ( dfa-traverser -- slice/f ) dup matches>> [ drop f ] - [ [ start-index>> ] [ peek ] bi* 1 ] if-empty ; + [ + [ [ text>> ] [ start-index>> ] bi ] + [ peek ] bi* rot + ] if-empty ; diff --git a/basis/smtp/smtp.factor b/basis/smtp/smtp.factor index 63603ad131..9dc03dfac2 100644 --- a/basis/smtp/smtp.factor +++ b/basis/smtp/smtp.factor @@ -153,7 +153,7 @@ ERROR: invalid-header-string string ; : extract-email ( recepient -- email ) ! This could be much smarter. - " " last-split1 swap or "<" ?head drop ">" ?tail drop ; + " " split1-last swap or "<" ?head drop ">" ?tail drop ; : email>headers ( email -- hashtable ) [ diff --git a/basis/stack-checker/known-words/known-words.factor b/basis/stack-checker/known-words/known-words.factor index 7ee46cb440..986bbe4c72 100644 --- a/basis/stack-checker/known-words/known-words.factor +++ b/basis/stack-checker/known-words/known-words.factor @@ -87,6 +87,15 @@ M: composed infer-call* M: object infer-call* \ literal-expected inference-warning ; +: infer-slip ( -- ) + 1 infer->r pop-d infer-call 1 infer-r> ; + +: infer-2slip ( -- ) + 2 infer->r pop-d infer-call 2 infer-r> ; + +: infer-3slip ( -- ) + 3 infer->r pop-d infer-call 3 infer-r> ; + : infer-curry ( -- ) 2 consume-d dup first2 make-known @@ -150,6 +159,9 @@ M: object infer-call* { \ declare [ infer-declare ] } { \ call [ pop-d infer-call ] } { \ (call) [ pop-d infer-call ] } + { \ slip [ infer-slip ] } + { \ 2slip [ infer-2slip ] } + { \ 3slip [ infer-3slip ] } { \ curry [ infer-curry ] } { \ compose [ infer-compose ] } { \ execute [ infer-execute ] } @@ -175,9 +187,10 @@ M: object infer-call* (( value -- )) apply-word/effect ; { - >r r> declare call (call) curry compose execute (execute) if -dispatch (throw) load-locals get-local drop-locals -do-primitive alien-invoke alien-indirect alien-callback + >r r> declare call (call) slip 2slip 3slip curry compose + execute (execute) if dispatch (throw) + load-locals get-local drop-locals do-primitive alien-invoke + alien-indirect alien-callback } [ t "special" set-word-prop ] each { call execute dispatch load-locals get-local drop-locals } diff --git a/basis/stack-checker/transforms/transforms.factor b/basis/stack-checker/transforms/transforms.factor index e4f8c50eeb..6e11eb1189 100644 --- a/basis/stack-checker/transforms/transforms.factor +++ b/basis/stack-checker/transforms/transforms.factor @@ -90,8 +90,12 @@ IN: stack-checker.transforms \ spread [ spread>quot ] 1 define-transform \ (call-next-method) [ - [ [ inlined-dependency depends-on ] bi@ ] [ next-method-quot ] 2bi -] 2 define-transform + [ + [ "method-class" word-prop ] + [ "method-generic" word-prop ] bi + [ inlined-dependency depends-on ] bi@ + ] [ next-method-quot ] bi +] 1 define-transform ! Constructors \ boa [ diff --git a/basis/tools/completion/completion.factor b/basis/tools/completion/completion.factor index 4bb6d6142f..2306ff53a8 100644 --- a/basis/tools/completion/completion.factor +++ b/basis/tools/completion/completion.factor @@ -72,7 +72,9 @@ IN: tools.completion ] if ; : string-completions ( short strs -- seq ) - [ dup ] { } map>assoc completions ; + dup zip completions ; : limited-completions ( short candidates -- seq ) - completions dup length 1000 > [ drop f ] when ; + [ completions ] [ drop ] 2bi + 2dup [ length 50 > ] [ empty? ] bi* and + [ 2drop f ] [ drop 50 short head ] if ; diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor index 9431cb2c19..18713c7b0c 100644 --- a/basis/tools/deploy/backend/backend.factor +++ b/basis/tools/deploy/backend/backend.factor @@ -55,6 +55,8 @@ DEFER: ?make-staging-image : staging-command-line ( profile -- flags ) [ + "-staging" , + dup empty? [ "-i=" my-boot-image-name append , ] [ diff --git a/basis/tools/deploy/deploy-tests.factor b/basis/tools/deploy/deploy-tests.factor index 226cf654b1..e0ac391fdf 100644 --- a/basis/tools/deploy/deploy-tests.factor +++ b/basis/tools/deploy/deploy-tests.factor @@ -106,3 +106,8 @@ M: quit-responder call-responder* "tools.deploy.test.6" shake-and-bake run-temp-image ] unit-test + +[ ] [ + "tools.deploy.test.7" shake-and-bake + run-temp-image +] unit-test diff --git a/basis/tools/deploy/shaker/next-methods.factor b/basis/tools/deploy/shaker/next-methods.factor new file mode 100644 index 0000000000..2bff407525 --- /dev/null +++ b/basis/tools/deploy/shaker/next-methods.factor @@ -0,0 +1,4 @@ +USING: words ; +IN: generic + +: next-method-quot ( method -- quot ) "next-method-quot" word-prop ; diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor index f8f9680c16..9cc5a66f70 100755 --- a/basis/tools/deploy/shaker/shaker.factor +++ b/basis/tools/deploy/shaker/shaker.factor @@ -5,7 +5,7 @@ namespaces make assocs kernel parser lexer strings.parser tools.deploy.config vocabs sequences words words.private memory kernel.private continuations io prettyprint vocabs.loader debugger system strings sets vectors quotations byte-arrays -sorting compiler.units definitions ; +sorting compiler.units definitions generic generic.standard ; QUALIFIED: bootstrap.stage2 QUALIFIED: classes QUALIFIED: command-line @@ -14,7 +14,6 @@ QUALIFIED: continuations QUALIFIED: definitions QUALIFIED: init QUALIFIED: layouts -QUALIFIED: listener QUALIFIED: prettyprint.config QUALIFIED: source-files QUALIFIED: vocabs @@ -95,20 +94,13 @@ IN: tools.deploy.shaker : stripped-word-props ( -- seq ) [ - strip-dictionary? deploy-compiler? get and [ - { - "combination" - "members" - "methods" - } % - ] when - strip-dictionary? [ { "alias" "boa-check" "cannot-infer" "coercer" + "combination" "compiled-effect" "compiled-generic-uses" "compiled-uses" @@ -138,7 +130,9 @@ IN: tools.deploy.shaker "local-writer?" "local?" "macro" + "members" "memo-quot" + "methods" "mixin" "method-class" "method-generic" @@ -201,17 +195,13 @@ IN: tools.deploy.shaker : stripped-globals ( -- seq ) [ - "callbacks" "alien.compiler" lookup , - "inspector-hook" "inspector" lookup , { - bootstrap.stage2:bootstrap-time continuations:error continuations:error-continuation continuations:error-thread continuations:restarts - listener:error-hook init:init-hooks source-files:source-files input-stream @@ -234,6 +224,10 @@ IN: tools.deploy.shaker "tools" "io.launcher" "random" + "compiler" + "stack-checker" + "bootstrap" + "listener" } strip-vocab-globals % strip-dictionary? [ @@ -244,6 +238,7 @@ IN: tools.deploy.shaker { gensym name>char-hook + classes:next-method-quot-cache classes:class-and-cache classes:class-not-cache classes:class-or-cache @@ -266,7 +261,7 @@ IN: tools.deploy.shaker layouts:tag-numbers layouts:type-numbers lexer-factory - listener:listener-hook + print-use-hook root-cache vocab-roots vocabs:dictionary @@ -304,10 +299,7 @@ IN: tools.deploy.shaker "ui-error-hook" "ui.gadgets.worlds" lookup , ] when - "" "stack-checker.state" lookup [ , ] when* - "windows-messages" "windows.messages" lookup [ , ] when* - ] { } make ; : strip-globals ( stripped-globals -- ) @@ -368,11 +360,21 @@ SYMBOL: deploy-vocab t "quiet" set-global f output-stream set-global ; +: compute-next-methods ( -- ) + [ standard-generic? ] instances [ + "methods" word-prop [ + nip + dup next-method-quot "next-method-quot" set-word-prop + ] assoc-each + ] each + "resource:basis/tools/deploy/shaker/next-methods.factor" run-file ; + : strip ( -- ) init-stripper strip-libc strip-cocoa strip-debugger + compute-next-methods strip-init-hooks strip-c-io f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore @@ -382,8 +384,7 @@ SYMBOL: deploy-vocab r> strip-words compress-byte-arrays compress-quotations - compress-strings - H{ } clone classes:next-method-quot-cache set-global ; + compress-strings ; : (deploy) ( final-image vocab config -- ) #! Does the actual work of a deployment in the slave diff --git a/basis/tools/deploy/shaker/strip-debugger.factor b/basis/tools/deploy/shaker/strip-debugger.factor index bdcc6c237e..db7eb63bbf 100644 --- a/basis/tools/deploy/shaker/strip-debugger.factor +++ b/basis/tools/deploy/shaker/strip-debugger.factor @@ -1,9 +1,13 @@ USING: compiler.units words vocabs kernel threads.private ; IN: debugger -: print-error ( error -- ) die drop ; +: consume ( error -- ) + #! We don't want DCE to drop the error before the die call! + drop ; -: error. ( error -- ) die drop ; +: print-error ( error -- ) die consume ; + +: error. ( error -- ) die consume ; "threads" vocab [ [ diff --git a/basis/tools/deploy/test/7/7.factor b/basis/tools/deploy/test/7/7.factor new file mode 100644 index 0000000000..a16e3c82c5 --- /dev/null +++ b/basis/tools/deploy/test/7/7.factor @@ -0,0 +1,18 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel math namespaces ; +IN: tools.deploy.test.7 + +SYMBOL: my-var + +GENERIC: my-generic ( x -- b ) + +M: integer my-generic sq ; + +M: fixnum my-generic call-next-method my-var get call ; + +: test-7 ( -- ) + [ 1 + ] my-var set-global + 12 my-generic 145 assert= ; + +MAIN: test-7 diff --git a/basis/tools/deploy/test/7/deploy.factor b/basis/tools/deploy/test/7/deploy.factor new file mode 100644 index 0000000000..bc374f1088 --- /dev/null +++ b/basis/tools/deploy/test/7/deploy.factor @@ -0,0 +1,15 @@ +USING: tools.deploy.config ; +H{ + { deploy-threads? t } + { deploy-word-props? f } + { deploy-ui? f } + { deploy-io 2 } + { deploy-math? t } + { "stop-after-last-window?" t } + { deploy-compiler? t } + { deploy-unicode? f } + { deploy-c-types? f } + { deploy-reflection 1 } + { deploy-word-defs? f } + { deploy-name "tools.deploy.test.7" } +} diff --git a/basis/tools/test/test.factor b/basis/tools/test/test.factor index 5c2bd8f4e3..73b261bf13 100644 --- a/basis/tools/test/test.factor +++ b/basis/tools/test/test.factor @@ -49,7 +49,7 @@ SYMBOL: this-test [ drop t ] must-fail-with ; : (run-test) ( vocab -- ) - dup vocab-source-loaded? [ + dup vocab source-loaded?>> [ vocab-tests [ run-file ] each ] [ drop ] if ; diff --git a/basis/tools/vocabs/browser/authors.txt b/basis/tools/vocabs/browser/authors.txt index 1901f27a24..e1907c6d91 100755 --- a/basis/tools/vocabs/browser/authors.txt +++ b/basis/tools/vocabs/browser/authors.txt @@ -1 +1,2 @@ Slava Pestov +Eduardo Cavazos diff --git a/basis/tools/vocabs/browser/browser-docs.factor b/basis/tools/vocabs/browser/browser-docs.factor index 3765efb863..6c5fb596e8 100644 --- a/basis/tools/vocabs/browser/browser-docs.factor +++ b/basis/tools/vocabs/browser/browser-docs.factor @@ -1,7 +1,13 @@ USING: help.markup help.syntax io strings ; IN: tools.vocabs.browser +ARTICLE: "vocab-tags" "Vocabulary tags" +{ $all-tags } ; + +ARTICLE: "vocab-authors" "Vocabulary authors" +{ $all-authors } ; + ARTICLE: "vocab-index" "Vocabulary index" -{ $tags } -{ $authors } +{ $subsection "vocab-tags" } +{ $subsection "vocab-authors" } { $describe-vocab "" } ; diff --git a/basis/tools/vocabs/browser/browser.factor b/basis/tools/vocabs/browser/browser.factor index c3296df280..cfc541d9bc 100644 --- a/basis/tools/vocabs/browser/browser.factor +++ b/basis/tools/vocabs/browser/browser.factor @@ -1,9 +1,12 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel combinators vocabs vocabs.loader -tools.vocabs io io.files io.styles help.markup help.stylesheet -sequences assocs help.topics namespaces prettyprint words -sorting definitions arrays summary sets generic ; +USING: accessors arrays assocs classes classes.builtin +classes.intersection classes.mixin classes.predicate +classes.singleton classes.tuple classes.union combinators +definitions effects fry generic help help.markup +help.stylesheet help.topics io io.files io.styles kernel macros +make namespaces prettyprint sequences sets sorting summary +tools.vocabs vocabs vocabs.loader words ; IN: tools.vocabs.browser : vocab-status-string ( vocab -- string ) @@ -18,9 +21,9 @@ IN: tools.vocabs.browser : vocab. ( vocab -- ) [ - dup [ write-status ] with-cell - dup [ ($link) ] with-cell - [ vocab-summary write ] with-cell + [ [ write-status ] with-cell ] + [ [ ($link) ] with-cell ] + [ [ vocab-summary write ] with-cell ] tri ] with-row ; : vocab-headings. ( -- ) @@ -34,35 +37,25 @@ IN: tools.vocabs.browser [ "Children from " prepend ] [ "Children" ] if* $heading ; -: vocabs. ( assoc -- ) +: $vocabs ( assoc -- ) [ - [ - drop - ] [ - swap root-heading. - standard-table-style [ - vocab-headings. [ vocab. ] each - ] ($grid) + [ drop ] [ + [ root-heading. ] + [ + standard-table-style [ + vocab-headings. [ vocab. ] each + ] ($grid) + ] bi* ] if-empty ] assoc-each ; -: describe-summary ( vocab -- ) - vocab-summary [ - "Summary" $heading print-element - ] when* ; - TUPLE: vocab-tag name ; INSTANCE: vocab-tag topic C: vocab-tag -: tags. ( seq -- ) [ ] map $links ; - -: describe-tags ( vocab -- ) - vocab-tags f like [ - "Tags" $heading tags. - ] when* ; +: $tags ( seq -- ) [ ] map $links ; TUPLE: vocab-author name ; @@ -70,20 +63,18 @@ INSTANCE: vocab-author topic C: vocab-author -: authors. ( seq -- ) [ ] map $links ; - -: describe-authors ( vocab -- ) - vocab-authors f like [ - "Authors" $heading authors. - ] when* ; +: $authors ( seq -- ) [ ] map $links ; : describe-help ( vocab -- ) - vocab-help [ - "Documentation" $heading ($link) - ] when* ; + [ + dup vocab-help + [ "Documentation" $heading ($link) ] + [ "Summary" $heading vocab-summary print-element ] + ?if + ] unless-empty ; : describe-children ( vocab -- ) - vocab-name all-child-vocabs vocabs. ; + vocab-name all-child-vocabs $vocabs ; : describe-files ( vocab -- ) vocab-files [ ] map [ @@ -95,50 +86,167 @@ C: vocab-author ] with-nesting ] with-style ] ($block) - ] when* ; + ] unless-empty ; + +: describe-tuple-classes ( classes -- ) + [ + "Tuple classes" $subheading + [ + [ <$link> ] + [ superclass <$link> ] + [ "slots" word-prop [ name>> ] map " " join \ $snippet swap 2array ] + tri 3array + ] map + { { $strong "Class" } { $strong "Superclass" } { $strong "Slots" } } prefix + $table + ] unless-empty ; + +: describe-predicate-classes ( classes -- ) + [ + "Predicate classes" $subheading + [ + [ <$link> ] + [ superclass <$link> ] + bi 2array + ] map + { { $strong "Class" } { $strong "Superclass" } } prefix + $table + ] unless-empty ; + +: (describe-classes) ( classes heading -- ) + '[ + _ $subheading + [ <$link> 1array ] map $table + ] unless-empty ; + +: describe-builtin-classes ( classes -- ) + "Builtin classes" (describe-classes) ; + +: describe-singleton-classes ( classes -- ) + "Singleton classes" (describe-classes) ; + +: describe-mixin-classes ( classes -- ) + "Mixin classes" (describe-classes) ; + +: describe-union-classes ( classes -- ) + "Union classes" (describe-classes) ; + +: describe-intersection-classes ( classes -- ) + "Intersection classes" (describe-classes) ; + +: describe-classes ( classes -- ) + [ builtin-class? ] partition + [ tuple-class? ] partition + [ singleton-class? ] partition + [ predicate-class? ] partition + [ mixin-class? ] partition + [ union-class? ] partition + [ intersection-class? ] filter + { + [ describe-builtin-classes ] + [ describe-tuple-classes ] + [ describe-singleton-classes ] + [ describe-predicate-classes ] + [ describe-mixin-classes ] + [ describe-union-classes ] + [ describe-intersection-classes ] + } spread ; + +: word-syntax ( word -- string/f ) + \ $syntax swap word-help elements dup length 1 = + [ first second ] [ drop f ] if ; + +: describe-parsing ( words -- ) + [ + "Parsing words" $subheading + [ + [ <$link> ] + [ word-syntax dup [ \ $snippet swap 2array ] when ] + bi 2array + ] map + { { $strong "Word" } { $strong "Syntax" } } prefix + $table + ] unless-empty ; + +: (describe-words) ( words heading -- ) + '[ + _ $subheading + [ + [ <$link> ] + [ stack-effect dup [ effect>string \ $snippet swap 2array ] when ] + bi 2array + ] map + { { $strong "Word" } { $strong "Stack effect" } } prefix + $table + ] unless-empty ; + +: describe-generics ( words -- ) + "Generic words" (describe-words) ; + +: describe-macros ( words -- ) + "Macro words" (describe-words) ; + +: describe-primitives ( words -- ) + "Primitives" (describe-words) ; + +: describe-compounds ( words -- ) + "Ordinary words" (describe-words) ; + +: describe-predicates ( words -- ) + "Class predicate words" (describe-words) ; + +: describe-symbols ( words -- ) + [ + "Symbol words" $subheading + [ <$link> 1array ] map $table + ] unless-empty ; : describe-words ( vocab -- ) words [ "Words" $heading - natural-sort $links + + natural-sort + [ [ class? ] filter describe-classes ] + [ + [ [ class? ] [ symbol? ] bi and not ] filter + [ parsing-word? ] partition + [ generic? ] partition + [ macro? ] partition + [ symbol? ] partition + [ primitive? ] partition + [ predicate? ] partition swap + { + [ describe-parsing ] + [ describe-generics ] + [ describe-macros ] + [ describe-symbols ] + [ describe-primitives ] + [ describe-compounds ] + [ describe-predicates ] + } spread + ] bi ] unless-empty ; -: vocab-xref ( vocab quot -- vocabs ) - >r dup vocab-name swap words [ generic? not ] filter r> map - [ [ word? ] filter [ vocabulary>> ] map ] gather natural-sort - remove sift ; inline +: words. ( vocab -- ) + last-element off + vocab-name describe-words ; -: vocab-uses ( vocab -- vocabs ) [ uses ] vocab-xref ; - -: vocab-usage ( vocab -- vocabs ) [ usage ] vocab-xref ; - -: describe-uses ( vocab -- ) - vocab-uses [ - "Uses" $heading - $vocab-links - ] unless-empty ; - -: describe-usage ( vocab -- ) - vocab-usage [ - "Used by" $heading - $vocab-links - ] unless-empty ; +: describe-metadata ( vocab -- ) + [ + [ vocab-tags [ "Tags:" swap \ $tags prefix 2array , ] unless-empty ] + [ vocab-authors [ "Authors:" swap \ $authors prefix 2array , ] unless-empty ] + bi + ] { } make + [ "Meta-data" $heading $table ] unless-empty ; : $describe-vocab ( element -- ) - first - dup describe-children - dup find-vocab-root [ - dup describe-summary - dup describe-tags - dup describe-authors - dup describe-files - ] when - dup vocab [ - dup describe-help - dup describe-words - dup describe-uses - dup describe-usage - ] when drop ; + first { + [ describe-help ] + [ describe-metadata ] + [ describe-words ] + [ describe-files ] + [ describe-children ] + } cleave ; : keyed-vocabs ( str quot -- seq ) all-vocabs [ @@ -154,16 +262,16 @@ C: vocab-author [ vocab-authors ] keyed-vocabs ; : $tagged-vocabs ( element -- ) - first tagged vocabs. ; + first tagged $vocabs ; : $authored-vocabs ( element -- ) - first authored vocabs. ; + first authored $vocabs ; -: $tags ( element -- ) - drop "Tags" $heading all-tags tags. ; +: $all-tags ( element -- ) + drop "Tags" $heading all-tags $tags ; -: $authors ( element -- ) - drop "Authors" $heading all-authors authors. ; +: $all-authors ( element -- ) + drop "Authors" $heading all-authors $authors ; INSTANCE: vocab topic diff --git a/basis/tools/vocabs/vocabs.factor b/basis/tools/vocabs/vocabs.factor index b929c62e04..d926b67078 100644 --- a/basis/tools/vocabs/vocabs.factor +++ b/basis/tools/vocabs/vocabs.factor @@ -4,9 +4,31 @@ USING: kernel io io.styles io.files io.encodings.utf8 vocabs.loader vocabs sequences namespaces make math.parser arrays hashtables assocs memoize summary sorting splitting combinators source-files debugger continuations compiler.errors -init checksums checksums.crc32 sets accessors ; +init checksums checksums.crc32 sets accessors generic +definitions words ; IN: tools.vocabs +: vocab-xref ( vocab quot -- vocabs ) + [ [ vocab-name ] [ words [ generic? not ] filter ] bi ] dip map + [ + [ [ word? ] [ generic? not ] bi and ] filter [ + dup method-body? + [ "method-generic" word-prop ] when + vocabulary>> + ] map + ] gather natural-sort remove sift ; inline + +: vocabs. ( seq -- ) + [ dup >vocab-link write-object nl ] each ; + +: vocab-uses ( vocab -- vocabs ) [ uses ] vocab-xref ; + +: vocab-uses. ( vocab -- ) vocab-uses vocabs. ; + +: vocab-usage ( vocab -- vocabs ) [ usage ] vocab-xref ; + +: vocab-usage. ( vocab -- ) vocab-usage vocabs. ; + : vocab-tests-file ( vocab -- path ) dup "-tests.factor" vocab-dir+ vocab-append-path dup [ dup exists? [ drop f ] unless ] [ drop f ] if ; @@ -112,12 +134,12 @@ SYMBOL: modified-docs [ [ [ modified-sources ] - [ vocab-source-loaded? ] + [ vocab source-loaded?>> ] [ vocab-source-path ] tri (to-refresh) ] [ [ modified-docs ] - [ vocab-docs-loaded? ] + [ vocab docs-loaded?>> ] [ vocab-docs-path ] tri (to-refresh) ] bi @@ -132,8 +154,8 @@ SYMBOL: modified-docs : do-refresh ( modified-sources modified-docs unchanged -- ) unchanged-vocabs [ - [ [ f swap set-vocab-source-loaded? ] each ] - [ [ f swap set-vocab-docs-loaded? ] each ] bi* + [ [ vocab f >>source-loaded? drop ] each ] + [ [ vocab f >>docs-loaded? drop ] each ] bi* ] [ append prune diff --git a/basis/tools/walker/walker.factor b/basis/tools/walker/walker.factor index 9775bdff81..1d26567952 100644 --- a/basis/tools/walker/walker.factor +++ b/basis/tools/walker/walker.factor @@ -83,7 +83,7 @@ M: object add-breakpoint ; : (step-into-continuation) ( -- ) continuation callstack >>call break ; -: (step-into-call-next-method) ( class generic -- ) +: (step-into-call-next-method) ( method -- ) next-method-quot (step-into-quot) ; ! Messages sent to walker thread diff --git a/basis/ui/cocoa/cocoa.factor b/basis/ui/cocoa/cocoa.factor index 1a05d23aa0..9ff3a59f71 100644 --- a/basis/ui/cocoa/cocoa.factor +++ b/basis/ui/cocoa/cocoa.factor @@ -15,9 +15,7 @@ C: handle SINGLETON: cocoa-ui-backend M: cocoa-ui-backend do-events ( -- ) - [ - [ NSApp [ do-event ] curry loop ui-wait ] ui-try - ] with-autorelease-pool ; + [ NSApp [ do-event ] curry loop ui-wait ] with-autorelease-pool ; TUPLE: pasteboard handle ; diff --git a/basis/ui/cocoa/views/views.factor b/basis/ui/cocoa/views/views.factor index c6942a8158..82a31ad0d9 100644 --- a/basis/ui/cocoa/views/views.factor +++ b/basis/ui/cocoa/views/views.factor @@ -18,8 +18,8 @@ IN: ui.cocoa.views { { S+ HEX: 20000 } { C+ HEX: 40000 } - { A+ HEX: 80000 } - { M+ HEX: 100000 } + { A+ HEX: 100000 } + { M+ HEX: 80000 } } ; : key-codes @@ -59,29 +59,26 @@ IN: ui.cocoa.views : key-event>gesture ( event -- modifiers keycode action? ) dup event-modifiers swap key-code ; -: send-key-event ( view event quot -- ? ) - >r key-event>gesture r> call swap window-focus - send-gesture ; inline - -: send-user-input ( view string -- ) - CF>string swap window-focus user-input ; +: send-key-event ( view gesture -- ) + swap window-focus propagate-gesture ; : interpret-key-event ( view event -- ) NSArray swap -> arrayWithObject: -> interpretKeyEvents: ; : send-key-down-event ( view event -- ) - 2dup [ ] send-key-event - [ interpret-key-event ] [ 2drop ] if ; + [ key-event>gesture send-key-event ] + [ interpret-key-event ] + 2bi ; : send-key-up-event ( view event -- ) - [ ] send-key-event drop ; + key-event>gesture send-key-event ; : mouse-event>gesture ( event -- modifiers button ) dup event-modifiers swap button ; : send-button-down$ ( view event -- ) - [ mouse-event>gesture ] 2keep - mouse-location rot window send-button-down ; + [ mouse-event>gesture ] + [ mouse-location rot window send-button-down ] 2bi ; : send-button-up$ ( view event -- ) [ mouse-event>gesture ] 2keep @@ -138,83 +135,83 @@ CLASS: { } { "mouseEntered:" "void" { "id" "SEL" "id" } - [ [ nip send-mouse-moved ] ui-try ] + [ nip send-mouse-moved ] } { "mouseExited:" "void" { "id" "SEL" "id" } - [ [ 3drop forget-rollover ] ui-try ] + [ 3drop forget-rollover ] } { "mouseMoved:" "void" { "id" "SEL" "id" } - [ [ nip send-mouse-moved ] ui-try ] + [ nip send-mouse-moved ] } { "mouseDragged:" "void" { "id" "SEL" "id" } - [ [ nip send-mouse-moved ] ui-try ] + [ nip send-mouse-moved ] } { "rightMouseDragged:" "void" { "id" "SEL" "id" } - [ [ nip send-mouse-moved ] ui-try ] + [ nip send-mouse-moved ] } { "otherMouseDragged:" "void" { "id" "SEL" "id" } - [ [ nip send-mouse-moved ] ui-try ] + [ nip send-mouse-moved ] } { "mouseDown:" "void" { "id" "SEL" "id" } - [ [ nip send-button-down$ ] ui-try ] + [ nip send-button-down$ ] } { "mouseUp:" "void" { "id" "SEL" "id" } - [ [ nip send-button-up$ ] ui-try ] + [ nip send-button-up$ ] } { "rightMouseDown:" "void" { "id" "SEL" "id" } - [ [ nip send-button-down$ ] ui-try ] + [ nip send-button-down$ ] } { "rightMouseUp:" "void" { "id" "SEL" "id" } - [ [ nip send-button-up$ ] ui-try ] + [ nip send-button-up$ ] } { "otherMouseDown:" "void" { "id" "SEL" "id" } - [ [ nip send-button-down$ ] ui-try ] + [ nip send-button-down$ ] } { "otherMouseUp:" "void" { "id" "SEL" "id" } - [ [ nip send-button-up$ ] ui-try ] + [ nip send-button-up$ ] } { "scrollWheel:" "void" { "id" "SEL" "id" } - [ [ nip send-wheel$ ] ui-try ] + [ nip send-wheel$ ] } { "keyDown:" "void" { "id" "SEL" "id" } - [ [ nip send-key-down-event ] ui-try ] + [ nip send-key-down-event ] } { "keyUp:" "void" { "id" "SEL" "id" } - [ [ nip send-key-up-event ] ui-try ] + [ nip send-key-up-event ] } { "cut:" "id" { "id" "SEL" "id" } - [ [ nip T{ cut-action } send-action$ ] ui-try ] + [ nip T{ cut-action } send-action$ ] } { "copy:" "id" { "id" "SEL" "id" } - [ [ nip T{ copy-action } send-action$ ] ui-try ] + [ nip T{ copy-action } send-action$ ] } { "paste:" "id" { "id" "SEL" "id" } - [ [ nip T{ paste-action } send-action$ ] ui-try ] + [ nip T{ paste-action } send-action$ ] } { "delete:" "id" { "id" "SEL" "id" } - [ [ nip T{ delete-action } send-action$ ] ui-try ] + [ nip T{ delete-action } send-action$ ] } { "selectAll:" "id" { "id" "SEL" "id" } - [ [ nip T{ select-all-action } send-action$ ] ui-try ] + [ nip T{ select-all-action } send-action$ ] } ! Multi-touch gestures: this is undocumented. @@ -290,7 +287,7 @@ CLASS: { ! Text input { "insertText:" "void" { "id" "SEL" "id" } - [ [ nip send-user-input ] ui-try ] + [ nip CF>string swap window-focus user-input ] } { "hasMarkedText" "char" { "id" "SEL" } @@ -335,11 +332,11 @@ CLASS: { ! Initialization { "updateFactorGadgetSize:" "void" { "id" "SEL" "id" } - [ - [ - 2drop dup view-dim swap window (>>dim) yield - ] ui-try - ] + [ 2drop dup view-dim swap window (>>dim) yield ] +} + +{ "doCommandBySelector:" "void" { "id" "SEL" "SEL" } + [ 3drop ] } { "initWithFrame:pixelFormat:" "id" { "id" "SEL" "NSRect" "id" } diff --git a/basis/ui/commands/commands-docs.factor b/basis/ui/commands/commands-docs.factor index 5f1ff6dabd..78b82a345c 100644 --- a/basis/ui/commands/commands-docs.factor +++ b/basis/ui/commands/commands-docs.factor @@ -8,7 +8,7 @@ IN: ui.commands [ gesture>string , ] [ [ command-name , ] - [ command-word \ $link swap 2array , ] + [ command-word <$link> , ] [ command-description , ] tri ] bi* diff --git a/basis/ui/gadgets/buttons/buttons.factor b/basis/ui/gadgets/buttons/buttons.factor index d74284cbd6..88d957f8cc 100644 --- a/basis/ui/gadgets/buttons/buttons.factor +++ b/basis/ui/gadgets/buttons/buttons.factor @@ -2,10 +2,11 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays kernel math models namespaces sequences strings quotations assocs combinators classes colors -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 ; +classes.tuple locals alien.c-types fry 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 ; IN: ui.gadgets.buttons TUPLE: button < border pressed? selected? quot ; @@ -27,7 +28,7 @@ TUPLE: button < border pressed? selected? quot ; relayout-1 ; : if-clicked ( button quot -- ) - >r dup button-update dup button-rollover? r> [ drop ] if ; + [ dup button-update dup button-rollover? ] dip [ drop ] if ; : button-clicked ( button -- ) dup quot>> if-clicked ; @@ -70,6 +71,7 @@ M: button-paint draw-boundary : roll-button-theme ( button -- button ) f black dup f >>boundary + f f pressed-gradient f >>interior align-left ; inline : ( label quot -- button ) @@ -219,9 +221,8 @@ M: radio-control model-changed over value>> = >>selected? relayout-1 ; -: ( parent model assoc quot -- parent ) - #! quot has stack effect ( value model label -- ) - swapd [ swapd call add-gadget ] 2curry assoc-each ; inline +: ( assoc model parent quot: ( value model label -- ) -- parent ) + '[ _ swap _ call add-gadget ] assoc-each ; inline : radio-button-theme ( gadget -- gadget ) { 5 5 } >>gap @@ -232,8 +233,7 @@ M: radio-control model-changed : ( model assoc -- gadget ) - -rot - [ ] + spin [ ] { 5 5 } >>gap ; : ( value model label -- gadget ) @@ -241,20 +241,19 @@ M: radio-control model-changed : ( model assoc -- gadget ) - -rot - [ ] ; + spin [ ] ; : command-button-quot ( target command -- quot ) - [ invoke-command drop ] 2curry ; + '[ _ _ invoke-command drop ] ; : ( target gesture command -- button ) - [ command-string ] keep - swapd - command-button-quot - ; + [ command-string swap ] keep command-button-quot ; : ( target -- toolbar ) swap "toolbar" over class command-map commands>> swap - [ -rot add-gadget ] curry assoc-each ; + '[ [ _ ] 2dip add-gadget ] assoc-each ; + +: add-toolbar ( track -- track ) + dup f track-add ; diff --git a/basis/ui/gadgets/editors/editors.factor b/basis/ui/gadgets/editors/editors.factor index 2cf6d24154..856795e4ed 100644 --- a/basis/ui/gadgets/editors/editors.factor +++ b/basis/ui/gadgets/editors/editors.factor @@ -2,17 +2,17 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays documents io kernel math models namespaces make opengl opengl.gl sequences strings io.styles -math.vectors sorting colors combinators assocs math.order -ui.clipboards ui.commands ui.gadgets ui.gadgets.borders -ui.gadgets.buttons ui.gadgets.labels ui.gadgets.scrollers -ui.gadgets.theme ui.gadgets.wrappers ui.render ui.gestures -math.geometry.rect ; +math.vectors sorting colors combinators assocs math.order fry +calendar alarms ui.clipboards ui.commands ui.gadgets +ui.gadgets.borders ui.gadgets.buttons ui.gadgets.labels +ui.gadgets.scrollers ui.gadgets.theme ui.gadgets.wrappers +ui.render ui.gestures math.geometry.rect ; IN: ui.gadgets.editors TUPLE: editor < gadget font color caret-color selection-color caret mark -focused? ; +focused? blink blink-alarm ; : ( -- loc ) { 0 0 } ; @@ -45,6 +45,28 @@ focused? ; dup deactivate-model swap model>> remove-loc ; +: blink-caret ( editor -- ) + [ not ] change-blink relayout-1 ; + +SYMBOL: blink-interval + +750 milliseconds blink-interval set-global + +: start-blinking ( editor -- ) + t >>blink + dup '[ _ blink-caret ] blink-interval get every >>blink-alarm drop ; + +: stop-blinking ( editor -- ) + [ [ cancel-alarm ] when* f ] change-blink-alarm drop ; + +: restart-blinking ( editor -- ) + dup focused?>> [ + [ stop-blinking ] + [ start-blinking ] + [ relayout-1 ] + tri + ] [ drop ] if ; + M: editor graft* dup dup caret>> activate-editor-model @@ -52,6 +74,7 @@ M: editor graft* M: editor ungraft* dup + dup stop-blinking dup caret>> deactivate-editor-model dup mark>> deactivate-editor-model ; @@ -64,14 +87,14 @@ M: editor ungraft* caret>> set-model ; : change-caret ( editor quot -- ) - over >r >r dup editor-caret* swap model>> r> call r> + [ [ [ editor-caret* ] [ model>> ] bi ] dip call ] [ drop ] 2bi set-caret ; inline : mark>caret ( editor -- ) - dup editor-caret* swap mark>> set-model ; + [ editor-caret* ] [ mark>> ] bi set-model ; : change-caret&mark ( editor quot -- ) - over >r change-caret r> mark>caret ; inline + [ change-caret ] [ drop mark>caret ] 2bi ; inline : editor-line ( n editor -- str ) control-value nth ; @@ -85,8 +108,8 @@ M: editor ungraft* : point>loc ( point editor -- loc ) [ - >r first2 r> tuck y>line dup , - >r dup editor-font* r> + [ first2 ] dip tuck y>line dup , + [ dup editor-font* ] dip rot editor-line x>offset , ] { } make ; @@ -94,11 +117,17 @@ M: editor ungraft* [ hand-rel ] keep point>loc ; : click-loc ( editor model -- ) - >r clicked-loc r> set-model ; + [ clicked-loc ] dip set-model ; -: focus-editor ( editor -- ) t >>focused? relayout-1 ; +: focus-editor ( editor -- ) + dup start-blinking + t >>focused? + relayout-1 ; -: unfocus-editor ( editor -- ) f >>focused? relayout-1 ; +: unfocus-editor ( editor -- ) + dup stop-blinking + f >>focused? + relayout-1 ; : (offset>x) ( font col# str -- x ) swap head-slice string-width ; @@ -106,7 +135,7 @@ M: editor ungraft* : offset>x ( col# line# editor -- x ) [ editor-line ] keep editor-font* -rot (offset>x) ; -: loc>x ( loc editor -- x ) >r first2 swap r> offset>x ; +: loc>x ( loc editor -- x ) [ first2 swap ] dip offset>x ; : line>y ( lines# editor -- y ) line-height * ; @@ -120,12 +149,13 @@ M: editor ungraft* : scroll>caret ( editor -- ) dup graft-state>> second [ - dup caret-loc over caret-dim - over scroll>rect - ] when drop ; + [ + [ caret-loc ] [ caret-dim { 1 0 } v+ ] bi + ] keep scroll>rect + ] [ drop ] if ; : draw-caret ( -- ) - editor get focused?>> [ + editor get [ focused?>> ] [ blink>> ] bi and [ editor get [ caret-color>> gl-color ] [ @@ -142,7 +172,7 @@ M: editor ungraft* line-translation gl-translate ; : draw-line ( editor str -- ) - >r font>> r> { 0 0 } draw-string ; + [ font>> ] dip { 0 0 } draw-string ; : first-visible-line ( editor -- n ) clip get rect-loc second origin get second - @@ -168,7 +198,7 @@ M: editor ungraft* rot control-value ; : with-editor-translation ( n quot -- ) - >r line-translation origin get v+ r> with-translation ; + [ line-translation origin get v+ ] dip with-translation ; inline : draw-lines ( -- ) @@ -198,7 +228,7 @@ M: editor ungraft* editor get selection-start/end over first [ 2dup [ - >r 2dup r> draw-selected-line + [ 2dup ] dip draw-selected-line 1 translate-lines ] each-line 2drop ] with-editor-translation ; @@ -216,7 +246,7 @@ M: editor pref-dim* drop relayout ; : caret/mark-changed ( model editor -- ) - nip [ relayout-1 ] [ scroll>caret ] bi ; + nip [ restart-blinking ] [ scroll>caret ] bi ; M: editor model-changed { @@ -246,7 +276,9 @@ M: editor user-input* M: editor gadget-text* editor-string % ; : extend-selection ( editor -- ) - dup request-focus dup caret>> click-loc ; + dup request-focus + dup restart-blinking + dup caret>> click-loc ; : mouse-elt ( -- element ) hand-click# get { @@ -258,14 +290,15 @@ M: editor gadget-text* editor-string % ; editor-mark* before? ; : drag-selection-caret ( loc editor element -- loc ) - >r [ drag-direction? ] 2keep - model>> - r> prev/next-elt ? ; + [ + [ drag-direction? ] 2keep model>> + ] dip prev/next-elt ? ; : drag-selection-mark ( loc editor element -- loc ) - >r [ drag-direction? not ] 2keep - nip dup editor-mark* swap model>> - r> prev/next-elt ? ; + [ + [ drag-direction? not ] keep + [ editor-mark* ] [ model>> ] bi + ] dip prev/next-elt ? ; : drag-caret&mark ( editor -- caret mark ) dup clicked-loc swap mouse-elt @@ -284,15 +317,16 @@ M: editor gadget-text* editor-string % ; over gadget-selection? [ drop nip remove-selection ] [ - over >r >r dup editor-caret* swap model>> - r> call r> model>> remove-doc-range + [ [ [ editor-caret* ] [ model>> ] bi ] dip call ] + [ drop model>> ] + 2bi remove-doc-range ] if ; inline : editor-delete ( editor elt -- ) - swap [ over >r rot next-elt r> swap ] delete/backspace ; + swap [ over [ rot next-elt ] dip swap ] delete/backspace ; : editor-backspace ( editor elt -- ) - swap [ over >r rot prev-elt r> ] delete/backspace ; + swap [ over [ rot prev-elt ] dip ] delete/backspace ; : editor-select-prev ( editor elt -- ) swap [ rot prev-elt ] change-caret ; @@ -310,9 +344,8 @@ M: editor gadget-text* editor-string % ; tuck caret>> set-model mark>> set-model ; : select-elt ( editor elt -- ) - over >r - >r dup editor-caret* swap model>> r> prev/next-elt - r> editor-select ; + [ [ [ editor-caret* ] [ model>> ] bi ] dip prev/next-elt ] [ drop ] 2bi + editor-select ; : start-of-document ( editor -- ) T{ doc-elt } editor-prev ; @@ -323,7 +356,7 @@ M: editor gadget-text* editor-string % ; [ drop dup extend-selection dup mark>> click-loc ] [ select-elt ] if ; -: insert-newline ( editor -- ) "\n" swap user-input ; +: insert-newline ( editor -- ) "\n" swap user-input* drop ; : delete-next-character ( editor -- ) T{ char-elt } editor-delete ; @@ -452,7 +485,7 @@ editor "caret-motion" f { T{ doc-elt } editor-select-next ; editor "selection" f { - { T{ button-down f { S+ } } extend-selection } + { T{ button-down f { S+ } 1 } extend-selection } { T{ drag } drag-selection } { T{ gain-focus } focus-editor } { T{ lose-focus } unfocus-editor } diff --git a/basis/ui/gadgets/frames/frames.factor b/basis/ui/gadgets/frames/frames.factor index c210d1b7e2..b5c3736896 100644 --- a/basis/ui/gadgets/frames/frames.factor +++ b/basis/ui/gadgets/frames/frames.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2005, 2007 Slava Pestov. +! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays generic kernel math namespaces sequences words splitting grouping math.vectors ui.gadgets.grids ui.gadgets @@ -11,16 +11,16 @@ TUPLE: frame < grid ; : ( -- grid ) 9 [ ] replicate 3 group ; -: @center 1 1 ; -: @left 0 1 ; -: @right 2 1 ; -: @top 1 0 ; -: @bottom 1 2 ; +: @center 1 1 ; inline +: @left 0 1 ; inline +: @right 2 1 ; inline +: @top 1 0 ; inline +: @bottom 1 2 ; inline -: @top-left 0 0 ; -: @top-right 2 0 ; -: @bottom-left 0 2 ; -: @bottom-right 2 2 ; +: @top-left 0 0 ; inline +: @top-right 2 0 ; inline +: @bottom-left 0 2 ; inline +: @bottom-right 2 2 ; inline : new-frame ( class -- frame ) swap new-grid ; inline @@ -28,13 +28,12 @@ TUPLE: frame < grid ; : ( -- frame ) frame new-frame ; -: (fill-center) ( vec n -- ) - over first pick third v+ [v-] 1 rot set-nth ; +: (fill-center) ( n vec -- ) + [ [ first ] [ third ] bi v+ [v-] ] keep set-second ; -: fill-center ( horiz vert dim -- ) - tuck (fill-center) (fill-center) ; +: fill-center ( dim horiz vert -- ) + [ over ] dip [ (fill-center) ] 2bi@ ; M: frame layout* dup compute-grid - [ rot rect-dim fill-center ] 3keep - grid-layout ; + [ [ rect-dim ] 2dip fill-center ] [ grid-layout ] 3bi ; diff --git a/basis/ui/gadgets/gadgets.factor b/basis/ui/gadgets/gadgets.factor index a18571d472..7d33ec21fd 100644 --- a/basis/ui/gadgets/gadgets.factor +++ b/basis/ui/gadgets/gadgets.factor @@ -10,11 +10,9 @@ SYMBOL: ui-notify-flag : notify-ui-thread ( -- ) ui-notify-flag get-global raise-flag ; -TUPLE: gadget < rect - pref-dim parent children orientation focus - visible? root? clipped? layout-state graft-state graft-node - interior boundary - model ; +TUPLE: gadget < rect pref-dim parent children orientation focus +visible? root? clipped? layout-state graft-state graft-node +interior boundary model ; M: gadget equal? 2drop f ; diff --git a/basis/ui/gadgets/labels/labels-tests.factor b/basis/ui/gadgets/labels/labels-tests.factor new file mode 100644 index 0000000000..a9b5074e4c --- /dev/null +++ b/basis/ui/gadgets/labels/labels-tests.factor @@ -0,0 +1,9 @@ +USING: accessors tools.test ui.gadgets ui.gadgets.labels ; +IN: ui.gadgets.labels.tests + +[ { 119 14 } ] [ + { 100 14 } >>dim + { 14 14 } >>dim + label-on-right { 5 5 } >>gap + pref-dim +] unit-test diff --git a/basis/ui/gadgets/panes/panes-tests.factor b/basis/ui/gadgets/panes/panes-tests.factor index 109c0a1461..8627f7fbfe 100644 --- a/basis/ui/gadgets/panes/panes-tests.factor +++ b/basis/ui/gadgets/panes/panes-tests.factor @@ -40,7 +40,7 @@ IN: ui.gadgets.panes.tests [ t ] [ [ [ 1 2 3 ] pprint ] test-gadget-text ] unit-test [ t ] [ [ \ + describe ] test-gadget-text ] unit-test [ t ] [ [ \ = see ] test-gadget-text ] unit-test -[ t ] [ [ \ = help ] test-gadget-text ] unit-test +[ t ] [ [ \ = print-topic ] test-gadget-text ] unit-test [ t ] [ [ @@ -84,16 +84,16 @@ ARTICLE: "test-article-1" "This is a test article" [ t ] [ [ "test-article-1" $title ] test-gadget-text ] unit-test -[ t ] [ [ "test-article-1" help ] test-gadget-text ] unit-test +[ t ] [ [ "test-article-1" print-topic ] test-gadget-text ] unit-test ARTICLE: "test-article-2" "This is a test article" "Hello world, how are you today." { $table { "a" "b" } { "c" "d" } } ; -[ t ] [ [ "test-article-2" help ] test-gadget-text ] unit-test +[ t ] [ [ "test-article-2" print-topic ] test-gadget-text ] unit-test [ \ = see ] with-pane - [ \ = help ] with-pane + [ \ = print-topic ] with-pane [ ] [ \ = [ see ] [ ] with-grafted-gadget diff --git a/basis/ui/gadgets/panes/panes.factor b/basis/ui/gadgets/panes/panes.factor index ef5745809e..c612cbef0a 100644 --- a/basis/ui/gadgets/panes/panes.factor +++ b/basis/ui/gadgets/panes/panes.factor @@ -10,7 +10,6 @@ io.streams.nested assocs ui.gadgets.presentations ui.gadgets.slots ui.gadgets.grids ui.gadgets.grid-lines classes.tuple models continuations destructors accessors math.geometry.rect ; - IN: ui.gadgets.panes TUPLE: pane < pack @@ -363,7 +362,11 @@ M: f sloppy-pick-up* dup hand-rel over sloppy-pick-up >>caret dup relayout-1 ; -: begin-selection ( pane -- ) move-caret f >>mark drop ; +: begin-selection ( pane -- ) + f >>selecting? + move-caret + f >>mark + drop ; : extend-selection ( pane -- ) hand-moved? [ @@ -389,6 +392,7 @@ M: f sloppy-pick-up* ] if ; : select-to-caret ( pane -- ) + t >>selecting? dup mark>> [ caret>mark ] unless move-caret dup request-focus @@ -397,7 +401,7 @@ M: f sloppy-pick-up* pane H{ { T{ button-down } [ begin-selection ] } { T{ button-down f { S+ } 1 } [ select-to-caret ] } - { T{ button-up f { S+ } 1 } [ drop ] } + { T{ button-up f { S+ } 1 } [ end-selection ] } { T{ button-up } [ end-selection ] } { T{ drag } [ extend-selection ] } { T{ copy-action } [ com-copy ] } diff --git a/basis/ui/gadgets/scrollers/scrollers-tests.factor b/basis/ui/gadgets/scrollers/scrollers-tests.factor index 625bfd7880..d6792abd49 100644 --- a/basis/ui/gadgets/scrollers/scrollers-tests.factor +++ b/basis/ui/gadgets/scrollers/scrollers-tests.factor @@ -2,7 +2,8 @@ USING: ui.gadgets ui.gadgets.scrollers namespaces tools.test kernel models models.compose models.range ui.gadgets.viewports ui.gadgets.labels ui.gadgets.grids ui.gadgets.frames ui.gadgets.sliders math math.vectors arrays sequences -tools.test.ui math.geometry.rect accessors ; +tools.test.ui math.geometry.rect accessors ui.gadgets.buttons +ui.gadgets.packs ; IN: ui.gadgets.scrollers.tests [ ] [ @@ -74,7 +75,7 @@ dup layout "g2" get scroll>gadget "s" get layout "s" get scroller-value - ] map [ { 3 0 } = ] all? + ] map [ { 2 0 } = ] all? ] unit-test [ ] [ "Hi"