M: string-type c-type-setter
drop [ set-alien-cell ] ;
-TUPLE: utf16n ;
-
! Native-order UTF-16
+SINGLETON: utf16n
+
: utf16n ( -- descriptor )
little-endian? utf16le utf16be ? ; foldable
USING: io.encodings kernel ;
IN: io.encodings.binary
-TUPLE: binary ;
+SINGLETON: binary
M: binary <encoder> drop ;
M: binary <decoder> drop ;
-USING: io.files io.streams.string io
-tools.test kernel io.encodings.ascii ;
+USING: io.files io.streams.string io io.streams.byte-array
+tools.test kernel io.encodings.ascii io.encodings.utf8
+namespaces accessors io.encodings ;
IN: io.streams.encodings.tests
[ { } ]
dup stream-readln drop
stream-read1
] unit-test
+
+[ utf8 ascii ] [
+ "foo" utf8 [
+ input-stream get code>>
+ ascii decode-input
+ input-stream get code>>
+ ] with-byte-reader
+] unit-test
+
+[ utf8 ascii ] [
+ utf8 [
+ output-stream get code>>
+ ascii encode-output
+ output-stream get code>>
+ ] with-byte-writer drop
+] unit-test
<PRIVATE
-M: tuple-class <decoder> new <decoder> ;
-M: tuple <decoder> f decoder boa ;
+M: object <decoder> f decoder boa ;
: >decoder< ( decoder -- stream encoding )
[ stream>> ] [ code>> ] bi ;
M: decoder dispose decoder-stream dispose ;
! Encoding
-M: tuple-class <encoder> new <encoder> ;
-M: tuple <encoder> encoder boa ;
+M: object <encoder> encoder boa ;
: >encoder< ( encoder -- stream encoding )
[ stream>> ] [ code>> ] bi ;
M: encoder stream-flush encoder-stream stream-flush ;
INSTANCE: encoder plain-writer
+PRIVATE>
-! Rebinding duplex streams which have not read anything yet
-
-: reencode ( stream encoding -- newstream )
+: re-encode ( stream encoding -- newstream )
over encoder? [ >r encoder-stream r> ] when <encoder> ;
-: redecode ( stream encoding -- newstream )
+: encode-output ( encoding -- )
+ output-stream [ swap re-encode ] change ;
+
+: re-decode ( stream encoding -- newstream )
over decoder? [ >r decoder-stream r> ] when <decoder> ;
-PRIVATE>
+: decode-input ( encoding -- )
+ input-stream [ swap re-decode ] change ;
[ { HEX: ff HEX: fe 120 0 52 216 30 221 } ] [ { CHAR: x HEX: 1d11e } utf16 encode >array ] unit-test
: correct-endian
- code>> class little-endian? [ utf16le = ] [ utf16be = ] if ;
+ code>> little-endian? [ utf16le = ] [ utf16be = ] if ;
[ t ] [ B{ } utf16n <byte-reader> correct-endian ] unit-test
[ t ] [ utf16n <byte-writer> correct-endian ] unit-test
io.encodings combinators splitting io byte-arrays inspector ;
IN: io.encodings.utf16
-TUPLE: utf16be ;
+SINGLETON: utf16be
-TUPLE: utf16le ;
+SINGLETON: utf16le
-TUPLE: utf16 ;
+SINGLETON: utf16
<PRIVATE
! Decoding UTF-8
-TUPLE: utf8 ;
+SINGLETON: utf8
<PRIVATE
M: growable stream-read-partial
stream-read ;
-TUPLE: null ;
+SINGLETON: null
M: null decode-char drop stream-read1 ;
: <string-reader> ( str -- stream )
--- /dev/null
+Daniel Ehrenberg\r
--- /dev/null
+USING: help.syntax help.markup ;\r
+IN: descriptive\r
+\r
+HELP: DESCRIPTIVE:\r
+{ $syntax "DESCRIPTIVE: word ( inputs -- outputs ) definition ;" }\r
+{ $description "Defines a word such that, if an error is thrown from within it, that error is wrapped in a descriptive tag including the arguments to that word." } ;\r
+\r
+HELP: DESCRIPTIVE::\r
+{ $syntax "DESCRIPTIVE:: word ( inputs -- outputs ) definition ;" }\r
+{ $description "Defines a word which uses locals such that, if an error is thrown from within it, that error is wrapped in a descriptive tag including the arguments to that word." } ;\r
+\r
+HELP: descriptive\r
+{ $class-description "The class of errors wrapping another error (in the underlying slot) which were thrown in a word (in the word slot) with a given set of arguments (in the args slot)." } ;\r
+\r
+ARTICLE: "descriptive" "Descriptive errors"\r
+"This vocabulary defines automatic descriptive errors. Using it, you can define a word which acts as normal, except when it throws an error, the error is wrapped in a special descriptor declaring that an error was thrown from inside that word, and including the arguments given to that word. The error is of the following class:"\r
+{ $subsection descriptive }\r
+"To define words which throw descriptive errors, use the following words:"\r
+{ $subsection POSTPONE: DESCRIPTIVE: }\r
+{ $subsection POSTPONE: DESCRIPTIVE:: } ;\r
+\r
+ABOUT: "descriptive"\r
DESCRIPTIVE: divide ( num denom -- fraction ) / ;\r
\r
[ 3 ] [ 9 3 divide ] unit-test\r
-[ T{ known f H{ { "num" 3 } { "denom" 0 } } "Division by zero" divide } ] [ [ 3 0 divide ] [ ] recover ] unit-test\r
+[ T{ descriptive f { { "num" 3 } { "denom" 0 } } "Division by zero" divide } ] [ [ 3 0 divide ] [ ] recover ] unit-test\r
\r
[ "USING: descriptive math ;\nIN: descriptive.tests\nDESCRIPTIVE: divide ( num denom -- fraction ) / ;\n" ] [ \ divide [ see ] with-string-writer ] unit-test\r
\r
DESCRIPTIVE:: divide* ( num denom -- fraction ) num denom / ;\r
\r
[ 3 ] [ 9 3 divide* ] unit-test\r
-[ T{ known f H{ { "num" 3 } { "denom" 0 } } "Division by zero" divide* } ] [ [ 3 0 divide* ] [ ] recover ] unit-test\r
+[ T{ descriptive f { { "num" 3 } { "denom" 0 } } "Division by zero" divide* } ] [ [ 3 0 divide* ] [ ] recover ] unit-test\r
\r
[ "USING: descriptive math ;\nIN: descriptive.tests\nDESCRIPTIVE:: divide* ( num denom -- fraction ) num denom / ;\n" ] [ \ divide* [ see ] with-string-writer ] unit-test\r
USING: words kernel sequences combinators.lib locals\r
locals.private accessors parser namespaces continuations\r
-inspector definitions ;\r
+inspector definitions arrays.lib arrays ;\r
IN: descriptive\r
\r
-ERROR: known args underlying word ;\r
+ERROR: descriptive args underlying word ;\r
\r
-M: known summary\r
+M: descriptive summary\r
word>> "The " swap word-name " word encountered an error."\r
3append ;\r
\r
+<PRIVATE\r
: rethrower ( word inputs -- quot )\r
- reverse [ [ set ] curry ] map concat [ ] like\r
- [ H{ } make-assoc ] curry\r
- [ 2 ndip known ] 2curry ;\r
+ [ length ] keep [ >r narray r> swap 2array flip ] 2curry\r
+ [ 2 ndip descriptive ] 2curry ;\r
\r
: [descriptive] ( word def -- newdef )\r
swap dup "declared-effect" word-prop in>> rethrower\r
[ recover ] 2curry ;\r
+PRIVATE>\r
\r
: define-descriptive ( word def -- )\r
[ "descriptive-definition" set-word-prop ]\r
: DESCRIPTIVE:\r
(:) define-descriptive ; parsing\r
\r
-PREDICATE: descriptive-word < word\r
+PREDICATE: descriptive-def < word\r
"descriptive-definition" word-prop ;\r
\r
-M: descriptive-word definer drop \ DESCRIPTIVE: \ ; ;\r
+M: descriptive-def definer drop \ DESCRIPTIVE: \ ; ;\r
\r
-M: descriptive-word definition\r
+M: descriptive-def definition\r
"descriptive-definition" word-prop ;\r
\r
: DESCRIPTIVE::\r
--- /dev/null
+Descriptive errors generated automatically for specially defined words\r
[ drop f ] if* ;
PRIVATE>
-TUPLE: ascii ;
+SINGLETON: ascii
M: ascii encode-char
128 encode-if< ;
] unless drop ;
: <encoder-duplex> ( stream-in stream-out encoding -- duplex )
- tuck reencode >r redecode r> <duplex-stream> ;
+ tuck re-encode >r re-decode r> <duplex-stream> ;
: with-stream* ( stream quot -- )
>r [ in>> ] [ out>> ] bi r> with-streams* ; inline