From 38a8e80ba99cd6c9f722bbd0528134a5d8922e60 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Tue, 26 May 2009 17:46:41 -0500 Subject: [PATCH 1/8] unbackwardsify hmac keys --- basis/checksums/hmac/hmac-tests.factor | 22 +++++++++++----------- basis/checksums/hmac/hmac.factor | 21 ++++++++++----------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/basis/checksums/hmac/hmac-tests.factor b/basis/checksums/hmac/hmac-tests.factor index ffae146614..70451252f7 100755 --- a/basis/checksums/hmac/hmac-tests.factor +++ b/basis/checksums/hmac/hmac-tests.factor @@ -6,43 +6,43 @@ IN: checksums.hmac.tests [ "\u000092\u000094rz68\u0000bb\u00001c\u000013\u0000f4\u00008e\u0000f8\u000015\u00008b\u0000fc\u00009d" ] [ - 16 11 "Hi There" md5 hmac-bytes >string ] unit-test + "Hi There" 16 11 md5 hmac-bytes >string ] unit-test [ "u\u00000cx>j\u0000b0\u0000b5\u000003\u0000ea\u0000a8n1\n]\u0000b78" ] -[ "Jefe" "what do ya want for nothing?" md5 hmac-bytes >string ] unit-test +[ "what do ya want for nothing?" "Jefe" md5 hmac-bytes >string ] unit-test [ "V\u0000be4R\u00001d\u000014L\u000088\u0000db\u0000b8\u0000c73\u0000f0\u0000e8\u0000b3\u0000f6" ] [ - 16 HEX: aa - 50 HEX: dd md5 hmac-bytes >string + 50 HEX: dd + 16 HEX: aa md5 hmac-bytes >string ] unit-test [ "g[\u00000b:\eM\u0000dfN\u000012Hr\u0000dal/c+\u0000fe\u0000d9W\u0000e9" ] [ - 16 11 "Hi There" sha1 hmac-bytes >string + "Hi There" 16 11 sha1 hmac-bytes >string ] unit-test [ "\u0000ef\u0000fc\u0000dfj\u0000e5\u0000eb/\u0000a2\u0000d2t\u000016\u0000d5\u0000f1\u000084\u0000df\u00009c%\u00009a|y" ] [ - "Jefe" "what do ya want for nothing?" sha1 hmac-bytes >string + "what do ya want for nothing?" "Jefe" sha1 hmac-bytes >string ] unit-test [ "\u0000d70YM\u000016~5\u0000d5\u000095o\u0000d8\0=\r\u0000b3\u0000d3\u0000f4m\u0000c7\u0000bb" ] [ - 16 HEX: aa - 50 HEX: dd sha1 hmac-bytes >string + 50 HEX: dd + 16 HEX: aa sha1 hmac-bytes >string ] unit-test [ "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" ] -[ 20 HEX: b "Hi There" sha-256 hmac-bytes hex-string ] unit-test +[ "Hi There" 20 HEX: b sha-256 hmac-bytes hex-string ] unit-test [ "167f928588c5cc2eef8e3093caa0e87c9ff566a14794aa61648d81621a2a40c6" ] [ - "JefeJefeJefeJefeJefeJefeJefeJefe" - "what do ya want for nothing?" sha-256 hmac-bytes hex-string + "what do ya want for nothing?" + "JefeJefeJefeJefeJefeJefeJefeJefe" sha-256 hmac-bytes hex-string ] unit-test diff --git a/basis/checksums/hmac/hmac.factor b/basis/checksums/hmac/hmac.factor index b163766016..9ec78248a1 100755 --- a/basis/checksums/hmac/hmac.factor +++ b/basis/checksums/hmac/hmac.factor @@ -13,27 +13,26 @@ IN: checksums.hmac : ipad ( checksum-state -- seq ) block-size>> HEX: 36 ; -:: init-K ( K checksum checksum-state -- o i ) - checksum-state block-size>> K length < - [ K checksum checksum-bytes ] [ K ] if +:: init-key ( checksum key checksum-state -- o i ) + checksum-state block-size>> key length < + [ key checksum checksum-bytes ] [ key ] if checksum-state block-size>> 0 pad-tail [ checksum-state opad seq-bitxor ] [ checksum-state ipad seq-bitxor ] bi ; PRIVATE> -:: hmac-stream ( K stream checksum -- value ) - K checksum dup initialize-checksum-state - dup :> checksum-state - init-K :> Ki :> Ko +:: hmac-stream ( stream key checksum -- value ) + checksum initialize-checksum-state :> checksum-state + checksum key checksum-state init-key :> Ki :> Ko checksum-state Ki add-checksum-bytes stream add-checksum-stream get-checksum checksum initialize-checksum-state Ko add-checksum-bytes swap add-checksum-bytes get-checksum ; -: hmac-file ( K path checksum -- value ) - [ binary ] dip hmac-stream ; +: hmac-file ( path key checksum -- value ) + [ binary ] 2dip hmac-stream ; -: hmac-bytes ( K seq checksum -- value ) - [ binary ] dip hmac-stream ; +: hmac-bytes ( seq key checksum -- value ) + [ binary ] 2dip hmac-stream ; From 1d721a32c15de6e3c3cb8b29b1337b523c325144 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Tue, 26 May 2009 21:05:46 -0500 Subject: [PATCH 2/8] check in kobie's image rotation code --- extra/images/processing/rotation/authors.txt | 2 + .../processing/rotation/rotation-tests.factor | 77 ++++++++++++++++++ .../processing/rotation/rotation.factor | 71 ++++++++++++++++ .../rotation/test-bitmaps/PastedImage.bmp | Bin 0 -> 43702 bytes .../rotation/test-bitmaps/PastedImage90.bmp | Bin 0 -> 43578 bytes .../processing/rotation/test-bitmaps/lake.bmp | Bin 0 -> 485 bytes .../rotation/test-bitmaps/small-rotated.bmp | Bin 0 -> 454 bytes .../rotation/test-bitmaps/small.bmp | Bin 0 -> 470 bytes 8 files changed, 150 insertions(+) create mode 100644 extra/images/processing/rotation/authors.txt create mode 100755 extra/images/processing/rotation/rotation-tests.factor create mode 100644 extra/images/processing/rotation/rotation.factor create mode 100755 extra/images/processing/rotation/test-bitmaps/PastedImage.bmp create mode 100755 extra/images/processing/rotation/test-bitmaps/PastedImage90.bmp create mode 100755 extra/images/processing/rotation/test-bitmaps/lake.bmp create mode 100755 extra/images/processing/rotation/test-bitmaps/small-rotated.bmp create mode 100755 extra/images/processing/rotation/test-bitmaps/small.bmp diff --git a/extra/images/processing/rotation/authors.txt b/extra/images/processing/rotation/authors.txt new file mode 100644 index 0000000000..07c95811a0 --- /dev/null +++ b/extra/images/processing/rotation/authors.txt @@ -0,0 +1,2 @@ +Kobie Lurie +Doug Coleman diff --git a/extra/images/processing/rotation/rotation-tests.factor b/extra/images/processing/rotation/rotation-tests.factor new file mode 100755 index 0000000000..ffad4130b5 --- /dev/null +++ b/extra/images/processing/rotation/rotation-tests.factor @@ -0,0 +1,77 @@ +! Copyright (C) 2009 Kobie Lurie, Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors fry images.loader images.normalization +images.processing.rotation kernel literals math sequences +tools.test images.processing.rotation.private ; +IN: images.processing.rotation.tests + +: first-row ( seq^2 -- seq ) first ; +: first-col ( seq^2 -- item ) harvest [ first ] map ; +: last-row ( seq^2 -- item ) last ; +: last-col ( seq^2 -- item ) harvest [ last ] map ; +: end-of-first-row ( seq^2 -- item ) first-row last ; +: first-of-first-row ( seq^2 -- item ) first-row first ; +: end-of-last-row ( seq^2 -- item ) last-row last ; +: first-of-last-row ( seq^2 -- item ) last-row first ; + +<< + +: clone-image ( image -- new-image ) + clone [ clone ] change-bitmap ; + +>> + +CONSTANT: pasted-image + $[ + "vocab:images/processing/rotation/test-bitmaps/PastedImage.bmp" + load-image normalize-image clone-image + ] + +CONSTANT: pasted-image90 + $[ + "vocab:images/processing/rotation/test-bitmaps/PastedImage90.bmp" + load-image normalize-image clone-image + ] + +CONSTANT: lake-image + $[ + "vocab:images/processing/rotation/test-bitmaps/lake.bmp" + load-image preprocess + ] + +[ t ] [ pasted-image dup clone-image 4 [ 90 rotate ] times = ] unit-test +[ t ] [ pasted-image dup clone-image 2 [ 180 rotate ] times = ] unit-test +[ t ] [ pasted-image dup clone-image 270 rotate 90 rotate = ] unit-test +[ t ] [ + pasted-image dup clone-image dup { 90 180 90 } [ rotate drop ] with each = +] unit-test + +[ t ] [ + pasted-image 90 rotate + pasted-image90 = +] unit-test + +[ t ] [ + "vocab:images/processing/rotation/test-bitmaps/small.bmp" + load-image 90 rotate + "vocab:images/processing/rotation/test-bitmaps/small-rotated.bmp" + load-image normalize-image = +] unit-test + +[ t ] [ + lake-image + [ first-of-first-row ] + [ 90 (rotate) end-of-first-row ] bi = +] unit-test + +[ t ] +[ lake-image [ first-row ] [ 90 (rotate) last-col ] bi = ] unit-test + +[ t ] +[ lake-image [ last-col ] [ 90 (rotate) last-row reverse ] bi = ] unit-test + +[ t ] +[ lake-image [ last-row ] [ 90 (rotate) first-col ] bi = ] unit-test + +[ t ] +[ lake-image [ first-col ] [ 90 (rotate) first-row reverse ] bi = ] unit-test diff --git a/extra/images/processing/rotation/rotation.factor b/extra/images/processing/rotation/rotation.factor new file mode 100644 index 0000000000..93b67e3b34 --- /dev/null +++ b/extra/images/processing/rotation/rotation.factor @@ -0,0 +1,71 @@ +! Copyright (C) 2009 Kobie Lurie. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays colors combinators +combinators.short-circuit fry grouping images images.bitmap +images.loader images.normalization kernel locals math sequences ; +IN: images.processing.rotation + +ERROR: unsupported-rotation degrees ; + +> length ] [ dim>> second ] bi /i ; + +: image>byte-rows ( image -- byte-rows ) + [ bitmap>> ] [ row-length ] bi group rows-remove-pad ; + +: (seperate-to-pixels) ( byte-rows image -- pixel-rows ) + component-order>> bytes-per-pixel '[ _ group ] map ; + +: image>pixel-rows ( image -- pixel-rows ) + [ image>byte-rows ] keep (seperate-to-pixels) ; + +: flatten-table ( seq^3 -- seq ) + [ concat ] map concat ; + +: preprocess ( image -- pixelrows ) + normalize-image image>pixel-rows ; + +: ?reverse-dimensions ( image n -- ) + { 270 90 } member? [ [ reverse ] change-dim ] when drop ; + +: normalize-degree ( n -- n' ) 360 rem ; + +: processing-effect ( image quot -- image' ) + '[ preprocess @ flatten-table ] [ (>>bitmap) ] [ ] tri ; inline + +:: rotate' ( image n -- image ) + n normalize-degree :> n' + image preprocess :> pixel-table + image n' ?reverse-dimensions + pixel-table n' (rotate) :> table-rotated + image table-rotated flatten-table >>bitmap ; + +PRIVATE> + +: rotate ( image n -- image' ) + normalize-degree + [ '[ _ (rotate) ] processing-effect ] [ ?reverse-dimensions ] 2bi ; + +: reflect-y-axis ( image -- image ) + [ [ reverse ] map ] processing-effect ; + +: reflect-x-axis ( image -- image ) + [ reverse ] processing-effect ; diff --git a/extra/images/processing/rotation/test-bitmaps/PastedImage.bmp b/extra/images/processing/rotation/test-bitmaps/PastedImage.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8edfedd4b55c01573c53caab5380b867826904cd GIT binary patch literal 43702 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 z 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 J1HW*U|36r0nGpa0 literal 0 HcmV?d00001 diff --git a/extra/images/processing/rotation/test-bitmaps/lake.bmp b/extra/images/processing/rotation/test-bitmaps/lake.bmp new file mode 100755 index 0000000000000000000000000000000000000000..431e4ef8ae54a49e6fe9dcfbb7dfe6611921cf3b GIT binary patch literal 485 zcma)%%L#x$3`EDP;N23e!1LnWp3;$3Sx1~r)`-jc36nw1!kU;vcJ~>mrCY$3(1C_5x)prJUxt$(sLR UkU%|9cvQr5i9Vt1`U7R|0QP}-@c;k- literal 0 HcmV?d00001 diff --git a/extra/images/processing/rotation/test-bitmaps/small-rotated.bmp b/extra/images/processing/rotation/test-bitmaps/small-rotated.bmp new file mode 100755 index 0000000000000000000000000000000000000000..571ea835ffe7948a5c48c781b78905126194bb26 GIT binary patch literal 454 zcmcJI!3}^g3(p>h>6M}?ogZW%8LrgEpDXcIlp4l8h=*DOtzk@D{_AhyVtLa5 literal 0 HcmV?d00001 From 5e4506c98794ec2157506d24a4b0b985e44ae13e Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Tue, 26 May 2009 21:07:14 -0500 Subject: [PATCH 3/8] misspelled kobi's name --- extra/images/processing/rotation/authors.txt | 2 +- extra/images/processing/rotation/rotation-tests.factor | 2 +- extra/images/processing/rotation/rotation.factor | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extra/images/processing/rotation/authors.txt b/extra/images/processing/rotation/authors.txt index 07c95811a0..09801441c8 100644 --- a/extra/images/processing/rotation/authors.txt +++ b/extra/images/processing/rotation/authors.txt @@ -1,2 +1,2 @@ -Kobie Lurie +Kobi Lurie Doug Coleman diff --git a/extra/images/processing/rotation/rotation-tests.factor b/extra/images/processing/rotation/rotation-tests.factor index ffad4130b5..493f09b145 100755 --- a/extra/images/processing/rotation/rotation-tests.factor +++ b/extra/images/processing/rotation/rotation-tests.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2009 Kobie Lurie, Doug Coleman. +! Copyright (C) 2009 Kobi Lurie, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors fry images.loader images.normalization images.processing.rotation kernel literals math sequences diff --git a/extra/images/processing/rotation/rotation.factor b/extra/images/processing/rotation/rotation.factor index 93b67e3b34..c10bfa0ee0 100644 --- a/extra/images/processing/rotation/rotation.factor +++ b/extra/images/processing/rotation/rotation.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2009 Kobie Lurie. +! Copyright (C) 2009 Kobi Lurie. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays colors combinators combinators.short-circuit fry grouping images images.bitmap From d44216735484cc6259e6a7f78955522621322c90 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 27 May 2009 19:36:52 -0500 Subject: [PATCH 4/8] tools.annotations: work better on generic words --- .../tools/annotations/annotations-docs.factor | 5 --- .../annotations/annotations-tests.factor | 3 ++ basis/tools/annotations/annotations.factor | 35 ++++++++----------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/basis/tools/annotations/annotations-docs.factor b/basis/tools/annotations/annotations-docs.factor index 005f5f7af8..8d73d85fb5 100644 --- a/basis/tools/annotations/annotations-docs.factor +++ b/basis/tools/annotations/annotations-docs.factor @@ -39,11 +39,6 @@ HELP: breakpoint-if { $values { "quot" { $quotation "( -- ? )" } } { "word" word } } { $description "Annotates a word definition to enter the single stepper if the quotation yields true." } ; -HELP: annotate-methods -{ $values - { "word" word } { "quot" quotation } } -{ $description "Annotates the word -- for generic words, all its methods -- with the quotation." } ; - HELP: reset { $values { "word" word } } diff --git a/basis/tools/annotations/annotations-tests.factor b/basis/tools/annotations/annotations-tests.factor index bbd2ac2ca8..c312b54edb 100644 --- a/basis/tools/annotations/annotations-tests.factor +++ b/basis/tools/annotations/annotations-tests.factor @@ -39,6 +39,9 @@ M: object another-generic ; [ "" ] [ [ 3 another-generic drop ] with-string-writer ] unit-test +! reset should do the right thing for generic words +[ ] [ \ another-generic watch ] unit-test + GENERIC: blah-generic ( a -- b ) M: string blah-generic ; diff --git a/basis/tools/annotations/annotations.factor b/basis/tools/annotations/annotations.factor index 3cb74fb00b..3aac371a6a 100644 --- a/basis/tools/annotations/annotations.factor +++ b/basis/tools/annotations/annotations.factor @@ -9,8 +9,7 @@ IN: tools.annotations GENERIC: reset ( word -- ) M: generic reset - [ call-next-method ] - [ subwords [ reset ] each ] bi ; + subwords [ reset ] each ; M: word reset dup "unannotated-def" word-prop [ @@ -22,6 +21,8 @@ M: word reset ERROR: cannot-annotate-twice word ; +M: cannot-annotate-twice summary drop "Cannot annotate a word twice" ; + > "unannotated-def" set-word-prop ; - -: (annotate) ( word quot -- ) - [ dup def>> ] dip call( old -- new ) define ; - PRIVATE> -: annotate ( word quot -- ) +GENERIC# annotate 1 ( word quot -- ) + +M: generic annotate + [ "methods" word-prop values ] dip '[ _ annotate ] each ; + +M: word annotate [ check-annotate-twice ] dip - [ over save-unannotated-def (annotate) ] with-compilation-unit ; + [ + [ dup def>> 2dup "unannotated-def" set-word-prop ] dip + call( old -- new ) define + ] with-compilation-unit ; : watch-vars ( word vars -- ) dupd '[ [ _ _ ] dip (watch-vars) ] annotate ; -GENERIC# annotate-methods 1 ( word quot -- ) - -M: generic annotate-methods - [ "methods" word-prop values ] dip [ annotate ] curry each ; - -M: word annotate-methods - annotate ; - : breakpoint ( word -- ) - [ add-breakpoint ] annotate-methods ; + [ add-breakpoint ] annotate ; : breakpoint-if ( word quot -- ) - '[ [ _ [ [ break ] when ] ] dip 3append ] annotate-methods ; + '[ [ _ [ [ break ] when ] ] dip 3append ] annotate ; SYMBOL: word-timing From a4b2fa2aeb2cb90e0ece2b5b2eed8c1273930ba8 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 27 May 2009 19:37:03 -0500 Subject: [PATCH 5/8] destructors: improve docs --- core/destructors/destructors-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/destructors/destructors-docs.factor b/core/destructors/destructors-docs.factor index 0b6ca15f31..536ee19c8b 100644 --- a/core/destructors/destructors-docs.factor +++ b/core/destructors/destructors-docs.factor @@ -26,7 +26,7 @@ HELP: with-disposal HELP: with-destructors { $values { "quot" "a quotation" } } -{ $description "Calls a quotation within a new dynamic scope. This quotation may register destructors, on any object, by wrapping the object in a destructor and implementing " { $link dispose } " on that object type. After the quotation finishes, if an error was thrown, all destructors are called and the error is then rethrown. However, if the quotation was successful, only those destructors created with an 'always cleanup' flag will be destroyed." } +{ $description "Calls a quotation within a new dynamic scope. This quotation may register destructors using " { $link &dispose } " or " { $link |dispose } ". The former registers a destructor that will always run whether or not the quotation threw an error, and the latter registers a destructor that only runs if the quotation throws an error only. Destructors are run in reverse order from the order in which they were registered." } { $notes "Destructors generalize " { $link with-disposal } ". The following two lines are equivalent, except that the second line establishes a new dynamic scope:" { $code From 430b1f50b9a0ac45aa3d7f651f33a376450ee60c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 27 May 2009 19:37:12 -0500 Subject: [PATCH 6/8] webapps.planet: fix edit-blog action --- extra/webapps/planet/planet.factor | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index 52d64f0f9e..12b7ccda24 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -166,9 +166,7 @@ posting "POSTINGS" [ f [ deposit-blog-slots ] - [ "id" value >>id ] - [ update-tuple ] - tri + [ "id" value >>id update-tuple ] bi "$planet/admin" >>path From ef73bc67321f5fa59aafc8f5c12a01f3a90a4ab0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 28 May 2009 02:50:57 -0500 Subject: [PATCH 7/8] io.encodings.utf16: cleanup --- core/io/encodings/utf16/utf16.factor | 40 +++++++++++++--------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/core/io/encodings/utf16/utf16.factor b/core/io/encodings/utf16/utf16.factor index a6ccc95bf5..1fb5ad1116 100644 --- a/core/io/encodings/utf16/utf16.factor +++ b/core/io/encodings/utf16/utf16.factor @@ -59,7 +59,7 @@ M: utf16be decode-char ] [ append-nums ] if ; : begin-utf16le ( stream byte -- stream char ) - over stream-read1 [ double-le ] [ drop replacement-char ] if* ; + over stream-read1 dup [ double-le ] [ 2drop replacement-char ] if ; M: utf16le decode-char drop dup stream-read1 dup [ begin-utf16le ] when nip ; @@ -68,36 +68,34 @@ M: utf16le decode-char : encode-first ( char -- byte1 byte2 ) -10 shift - dup -8 shift BIN: 11011000 bitor - swap HEX: FF bitand ; + [ -8 shift BIN: 11011000 bitor ] [ HEX: FF bitand ] bi ; : encode-second ( char -- byte3 byte4 ) BIN: 1111111111 bitand - dup -8 shift BIN: 11011100 bitor - swap BIN: 11111111 bitand ; + [ -8 shift BIN: 11011100 bitor ] [ BIN: 11111111 bitand ] bi ; -: stream-write2 ( stream char1 char2 -- ) - rot [ stream-write1 ] curry bi@ ; +: stream-write2 ( char1 char2 stream -- ) + [ stream-write1 ] curry bi@ ; -: char>utf16be ( stream char -- ) - dup HEX: FFFF > [ - HEX: 10000 - - 2dup encode-first stream-write2 - encode-second stream-write2 - ] [ h>b/b swap stream-write2 ] if ; +: char>utf16be ( char stream -- ) + over HEX: FFFF > [ + [ HEX: 10000 - ] dip + [ [ encode-first ] dip stream-write2 ] + [ [ encode-second ] dip stream-write2 ] 2bi + ] [ [ h>b/b swap ] dip stream-write2 ] if ; M: utf16be encode-char ( char stream encoding -- ) - drop swap char>utf16be ; + drop char>utf16be ; -: char>utf16le ( char stream -- ) - dup HEX: FFFF > [ - HEX: 10000 - - 2dup encode-first swap stream-write2 - encode-second swap stream-write2 - ] [ h>b/b stream-write2 ] if ; +: char>utf16le ( stream char -- ) + over HEX: FFFF > [ + [ HEX: 10000 - ] dip + [ [ encode-first swap ] dip stream-write2 ] + [ [ encode-second swap ] dip stream-write2 ] 2bi + ] [ [ h>b/b ] dip stream-write2 ] if ; M: utf16le encode-char ( char stream encoding -- ) - drop swap char>utf16le ; + drop char>utf16le ; ! UTF-16 From 0dffd311a530f9f6c53619bf0418613ab9c73ede Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 28 May 2009 02:52:05 -0500 Subject: [PATCH 8/8] descriptive: update for tools.annotations change --- extra/descriptive/descriptive.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/descriptive/descriptive.factor b/extra/descriptive/descriptive.factor index 9af94aa4ed..0756c5c975 100755 --- a/extra/descriptive/descriptive.factor +++ b/extra/descriptive/descriptive.factor @@ -28,7 +28,7 @@ PRIVATE> : make-descriptive ( word -- ) dup [ ] [ def>> ] [ stack-effect ] tri [descriptive] - '[ drop _ ] annotate-methods ; + '[ drop _ ] annotate ; : define-descriptive ( word def effect -- ) [ drop "descriptive-definition" set-word-prop ]